mirror of
https://github.com/zulip/zulip.git
synced 2025-11-12 01:47:41 +00:00
Compare commits
1069 Commits
enterprise
...
enterprise
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a67775c27 | ||
|
|
bf08e33648 | ||
|
|
afe893b324 | ||
|
|
ea8d9efa00 | ||
|
|
5b920a5226 | ||
|
|
a2acce2905 | ||
|
|
2ad006aac9 | ||
|
|
c87b77e52e | ||
|
|
92b249a0a1 | ||
|
|
3de8bb7f80 | ||
|
|
37dffa0f2d | ||
|
|
c028dbe6b9 | ||
|
|
47ca6b2800 | ||
|
|
233cfc2593 | ||
|
|
6b93315cc3 | ||
|
|
10b24f77b6 | ||
|
|
9a01c0f3e4 | ||
|
|
42a67576b4 | ||
|
|
bb60e96910 | ||
|
|
74b86c88b8 | ||
|
|
298af207f7 | ||
|
|
32d66d6f73 | ||
|
|
631783f3cd | ||
|
|
1d7976d332 | ||
|
|
4d91bb39d3 | ||
|
|
6691789cce | ||
|
|
6ea795915e | ||
|
|
9a2bf4f359 | ||
|
|
b35b3e584c | ||
|
|
639a39aace | ||
|
|
4891da83ad | ||
|
|
72ee636571 | ||
|
|
194464f596 | ||
|
|
bb0608b55a | ||
|
|
2fb70eb38c | ||
|
|
5c2a41f8b7 | ||
|
|
8d81ea33da | ||
|
|
fe55127eee | ||
|
|
1e87e7c5c1 | ||
|
|
c7565222f0 | ||
|
|
602f7f96e5 | ||
|
|
8ad2ca15cd | ||
|
|
1c332f5d6a | ||
|
|
f1e110c177 | ||
|
|
fc78a2cc66 | ||
|
|
60cfd3cfb0 | ||
|
|
da858afacf | ||
|
|
90f6eb0661 | ||
|
|
3a96686cbc | ||
|
|
0366659bee | ||
|
|
07e337ff8a | ||
|
|
583dae72a3 | ||
|
|
dbcc406272 | ||
|
|
ffdc254e2d | ||
|
|
24f8492236 | ||
|
|
ca3430862c | ||
|
|
d595714a1c | ||
|
|
02d69f18ac | ||
|
|
1bd9e5809c | ||
|
|
e8834c2a9b | ||
|
|
73fc65eb99 | ||
|
|
f3d33c1aa0 | ||
|
|
d961829355 | ||
|
|
c218fc98b1 | ||
|
|
556dfd2724 | ||
|
|
1136d399ca | ||
|
|
515e64175f | ||
|
|
0dd61e9222 | ||
|
|
7449079191 | ||
|
|
9252b3f336 | ||
|
|
a32b326ff2 | ||
|
|
da757b7195 | ||
|
|
20c0afca1d | ||
|
|
9c48ba43fb | ||
|
|
7fb7950f70 | ||
|
|
89ea079dce | ||
|
|
112bc5ceda | ||
|
|
889adfa0e0 | ||
|
|
eea8c0d1d5 | ||
|
|
8266ac3cf9 | ||
|
|
30a6fd3bd7 | ||
|
|
882047515c | ||
|
|
cdffc5a418 | ||
|
|
374acb7f24 | ||
|
|
de56b947d4 | ||
|
|
9f8e57a1cd | ||
|
|
395bf9abf6 | ||
|
|
4c2800ef9d | ||
|
|
bf85a3cebc | ||
|
|
662459b9e1 | ||
|
|
cfb2312cb6 | ||
|
|
e8d4723d44 | ||
|
|
0e1909f489 | ||
|
|
a4ff866571 | ||
|
|
7b8acfea8e | ||
|
|
c504435bc3 | ||
|
|
84e2c2b9da | ||
|
|
9107c67d88 | ||
|
|
8c733fde8f | ||
|
|
30056197a6 | ||
|
|
7e6bb801e2 | ||
|
|
0b12681558 | ||
|
|
f26af47fb6 | ||
|
|
9224d4b521 | ||
|
|
259f6123e6 | ||
|
|
be115a2914 | ||
|
|
0a9f54369a | ||
|
|
f8a9f36dfa | ||
|
|
bb21400732 | ||
|
|
85381a62b9 | ||
|
|
4b095cbad1 | ||
|
|
c8f134370b | ||
|
|
bb0784d9aa | ||
|
|
80d2ecdd1e | ||
|
|
b52749d2ce | ||
|
|
001d447e0f | ||
|
|
ac57c3c16b | ||
|
|
2faf29408a | ||
|
|
fa69047613 | ||
|
|
d8eb8792ef | ||
|
|
20cfb9fe84 | ||
|
|
945df53280 | ||
|
|
c8a573a0f2 | ||
|
|
b8b2551e60 | ||
|
|
8d88d04148 | ||
|
|
4b30afbb27 | ||
|
|
3287169771 | ||
|
|
e2a6adc143 | ||
|
|
ea934cf286 | ||
|
|
1c5110dbad | ||
|
|
7c788c1a17 | ||
|
|
f42b526749 | ||
|
|
88fbd5d16a | ||
|
|
f5d3a6ddc7 | ||
|
|
171005a9de | ||
|
|
425b2df4b4 | ||
|
|
38636d5125 | ||
|
|
0f96d2229e | ||
|
|
abc0be9c8c | ||
|
|
179be2051d | ||
|
|
760cd7a474 | ||
|
|
004fd0eab8 | ||
|
|
c8d57fcafb | ||
|
|
55a88f049c | ||
|
|
9a1159fb09 | ||
|
|
3263d09939 | ||
|
|
aa52475e96 | ||
|
|
364bbf08cf | ||
|
|
655bacc06d | ||
|
|
8767c33536 | ||
|
|
17826dba42 | ||
|
|
2b1a5ae141 | ||
|
|
3212ced8e7 | ||
|
|
c67ae498ff | ||
|
|
9b1090506e | ||
|
|
ec88b3abaf | ||
|
|
c4c5ac210e | ||
|
|
db4cbcd438 | ||
|
|
5acf8ac0b6 | ||
|
|
6e5e5596fd | ||
|
|
70df0b933c | ||
|
|
00673534ba | ||
|
|
2fac412119 | ||
|
|
01e948ac97 | ||
|
|
1056078415 | ||
|
|
e505583f52 | ||
|
|
d0ae8795c3 | ||
|
|
2fb9baafb4 | ||
|
|
f27edcd50a | ||
|
|
1eb294ed11 | ||
|
|
e60f148a3e | ||
|
|
189743e813 | ||
|
|
3a412b35e1 | ||
|
|
15b0f9dcc7 | ||
|
|
796ebfd007 | ||
|
|
de7708ed6e | ||
|
|
a2d989b318 | ||
|
|
50e1cb7ab3 | ||
|
|
3df1097c95 | ||
|
|
9020f37141 | ||
|
|
b8444daddd | ||
|
|
1ed176b5ef | ||
|
|
b3a551f402 | ||
|
|
a7b1b29bf0 | ||
|
|
33690d1dc6 | ||
|
|
90995889fc | ||
|
|
bf57839e85 | ||
|
|
21c2aea755 | ||
|
|
b0c5e2dbd0 | ||
|
|
9cc1dc242c | ||
|
|
198648447f | ||
|
|
dedd3cf03c | ||
|
|
967d3c9c65 | ||
|
|
53027b71a4 | ||
|
|
b18307b667 | ||
|
|
12626ead66 | ||
|
|
df19f4283d | ||
|
|
fdd57f5abe | ||
|
|
abbe0f781f | ||
|
|
20457d695d | ||
|
|
7ef68f19da | ||
|
|
82fc7a0a39 | ||
|
|
1016686397 | ||
|
|
cbec4126c8 | ||
|
|
9a0aca6878 | ||
|
|
6a327a2a9c | ||
|
|
27aeebddb7 | ||
|
|
532cd061fb | ||
|
|
bea12cdadd | ||
|
|
7151af5119 | ||
|
|
7dbebf4e05 | ||
|
|
ec29373f19 | ||
|
|
233ce4360f | ||
|
|
da3fc3fede | ||
|
|
7085dca1ce | ||
|
|
ac3f93d760 | ||
|
|
3d234e1b84 | ||
|
|
c0bc7abbc5 | ||
|
|
20f2baa614 | ||
|
|
eeb8464f4d | ||
|
|
ac06d8870f | ||
|
|
99d58fe8b5 | ||
|
|
de522029d5 | ||
|
|
a028bda264 | ||
|
|
582f7eb24d | ||
|
|
58ca46530e | ||
|
|
12c095fd4b | ||
|
|
5ba716cf42 | ||
|
|
1b987b0803 | ||
|
|
a8bf9dfaf2 | ||
|
|
4562e43aee | ||
|
|
34f6c705e9 | ||
|
|
75555ff16c | ||
|
|
912f96e7ec | ||
|
|
1e948d2d51 | ||
|
|
c5edb58cd4 | ||
|
|
57030f53cc | ||
|
|
bbafd1dda8 | ||
|
|
0eed5d20d2 | ||
|
|
dbc1172a20 | ||
|
|
3776d11c3a | ||
|
|
aca5586cc0 | ||
|
|
e716a75d22 | ||
|
|
1666403850 | ||
|
|
05e00575bb | ||
|
|
c573efd437 | ||
|
|
1dd674c7ae | ||
|
|
80af0b8134 | ||
|
|
a8f2ecf48c | ||
|
|
91fb4f6b8c | ||
|
|
ffb816391c | ||
|
|
420a7cab7a | ||
|
|
daecc7993a | ||
|
|
dd7d31c7a6 | ||
|
|
8aaf1cf8c2 | ||
|
|
af9a1e967f | ||
|
|
4cf677eb6d | ||
|
|
38668adcec | ||
|
|
4ed661ca71 | ||
|
|
b5e0eb35be | ||
|
|
af00f4609a | ||
|
|
a126292431 | ||
|
|
439959592f | ||
|
|
3fddc11cc2 | ||
|
|
934ac3fc88 | ||
|
|
1a90d50a1f | ||
|
|
1cc3a6a903 | ||
|
|
167b883c38 | ||
|
|
0507b1bb06 | ||
|
|
5ccb8b1bea | ||
|
|
98e4d7aeb3 | ||
|
|
01dedb67f4 | ||
|
|
bf0b0e24f2 | ||
|
|
3bcba79e77 | ||
|
|
fd3fc095b5 | ||
|
|
07344bb283 | ||
|
|
0917a27b79 | ||
|
|
dc3c6f34fc | ||
|
|
b83be2cd32 | ||
|
|
1fdb586c13 | ||
|
|
a82bc689e8 | ||
|
|
883157893c | ||
|
|
b119bf74ca | ||
|
|
5441409044 | ||
|
|
78f0cc1c4d | ||
|
|
6fff91493c | ||
|
|
6d64427c46 | ||
|
|
da90d63046 | ||
|
|
cf16d95437 | ||
|
|
1d95812770 | ||
|
|
4ad8ad2b5a | ||
|
|
6d9edcf06f | ||
|
|
3b07c164fb | ||
|
|
97fb3e74af | ||
|
|
d7c274fcfa | ||
|
|
62435e167f | ||
|
|
1f98c4f4ce | ||
|
|
4104f00229 | ||
|
|
0c9271212d | ||
|
|
1184a4f824 | ||
|
|
ea04d027cf | ||
|
|
9ec5cde8b0 | ||
|
|
f528ac659d | ||
|
|
b1ac754448 | ||
|
|
063484a917 | ||
|
|
5108253e97 | ||
|
|
e63d9d32e2 | ||
|
|
4015189094 | ||
|
|
b82ed52e7b | ||
|
|
ee0f569c59 | ||
|
|
1c67d05e5f | ||
|
|
c01c7285db | ||
|
|
ee7a1f0953 | ||
|
|
086eab8bb5 | ||
|
|
6aaa11027f | ||
|
|
993a20bdee | ||
|
|
117c98796e | ||
|
|
a62c720e0e | ||
|
|
fcd89d5861 | ||
|
|
ebd6408ec7 | ||
|
|
a677db4672 | ||
|
|
7702461700 | ||
|
|
e5a24c2d21 | ||
|
|
1c9a59fd3f | ||
|
|
aee127cdbe | ||
|
|
07dae5fcb9 | ||
|
|
4ac59a71bd | ||
|
|
fd4b68aa72 | ||
|
|
56d9446c41 | ||
|
|
24cb5fb079 | ||
|
|
e24dcb3952 | ||
|
|
7743aa191c | ||
|
|
439633fd03 | ||
|
|
c1442f386f | ||
|
|
86cb451dcb | ||
|
|
97a69cbc12 | ||
|
|
b1a6fdf5e2 | ||
|
|
c0d56c822f | ||
|
|
b7b322d8cd | ||
|
|
0f8cb25d89 | ||
|
|
0de824f73e | ||
|
|
87ce2bd0be | ||
|
|
53739622fd | ||
|
|
03ceef0c40 | ||
|
|
34722de1da | ||
|
|
883122b129 | ||
|
|
c3f798297e | ||
|
|
00f64113e9 | ||
|
|
5b8e46f971 | ||
|
|
835e385b75 | ||
|
|
0b2ba855f9 | ||
|
|
f5af245c09 | ||
|
|
9b42cdd826 | ||
|
|
6d332151d2 | ||
|
|
759d33fad1 | ||
|
|
d5c6408efe | ||
|
|
49c4ad61a1 | ||
|
|
2283aa52cb | ||
|
|
09dbaabcb6 | ||
|
|
8fa49388c0 | ||
|
|
59cd1663df | ||
|
|
59b0af835e | ||
|
|
bc6da3717f | ||
|
|
10533291e9 | ||
|
|
57c7634a4e | ||
|
|
d8b15f4202 | ||
|
|
c93d0abfb0 | ||
|
|
290aa4b350 | ||
|
|
0439b2bf58 | ||
|
|
7ecace0066 | ||
|
|
1746af4df6 | ||
|
|
887c2059b1 | ||
|
|
90ba39d02e | ||
|
|
551e7513b3 | ||
|
|
d431206a3f | ||
|
|
3b12e63d8d | ||
|
|
81d975c5ff | ||
|
|
93deefec8d | ||
|
|
9160fb3ed5 | ||
|
|
c0fdbf81cf | ||
|
|
4b7d061bbf | ||
|
|
de1ec7ae43 | ||
|
|
f05d817fb4 | ||
|
|
c4e1d9f02a | ||
|
|
49f2657c8d | ||
|
|
3840cf760f | ||
|
|
1ae040c7fb | ||
|
|
a974301b8b | ||
|
|
41e274a8e4 | ||
|
|
4dac0e7d37 | ||
|
|
6903d87809 | ||
|
|
c0d3b2fd89 | ||
|
|
226d894257 | ||
|
|
d4aece75a5 | ||
|
|
d8a6ec3507 | ||
|
|
c30a411c10 | ||
|
|
033e0e5969 | ||
|
|
30ae1c3463 | ||
|
|
e734155a1c | ||
|
|
6c6d1ee474 | ||
|
|
8f9d29189c | ||
|
|
3b8f45a78b | ||
|
|
a0c5c7d088 | ||
|
|
669951b631 | ||
|
|
13d015f81e | ||
|
|
92ae790130 | ||
|
|
e852580a0e | ||
|
|
3dbc7d3524 | ||
|
|
816fce50f7 | ||
|
|
ecd288f144 | ||
|
|
5a3d338937 | ||
|
|
59ac5cce72 | ||
|
|
004d84f6e2 | ||
|
|
bca0311b53 | ||
|
|
a9e621fff4 | ||
|
|
137a1b7799 | ||
|
|
84ea28ae25 | ||
|
|
c7bf349e70 | ||
|
|
56dc4e0b8e | ||
|
|
c9158dd3d9 | ||
|
|
7ce692b3c3 | ||
|
|
846be23ce2 | ||
|
|
06cb0c8d22 | ||
|
|
8b09d4da6c | ||
|
|
4c90392261 | ||
|
|
d6c1bbb5fa | ||
|
|
607274c0ba | ||
|
|
4477ee4bba | ||
|
|
73a05d52f5 | ||
|
|
1edcbfb8b0 | ||
|
|
907e9688fe | ||
|
|
bc22b1eb16 | ||
|
|
1835848782 | ||
|
|
c3eac38fa4 | ||
|
|
ce50478a1e | ||
|
|
2c86c5c8ee | ||
|
|
b6a2208d84 | ||
|
|
8ebf0a414c | ||
|
|
20e4e31dcf | ||
|
|
4d03fd984f | ||
|
|
ec91ece6ed | ||
|
|
8bf9068d0b | ||
|
|
f60d5c64c3 | ||
|
|
447c99aa66 | ||
|
|
6d963c4a85 | ||
|
|
81de08f067 | ||
|
|
fd5fd7e61b | ||
|
|
e837f8bf8b | ||
|
|
a1d128b6cb | ||
|
|
07b2eed389 | ||
|
|
6443aead67 | ||
|
|
fa097a1201 | ||
|
|
3bd0bfd4fd | ||
|
|
f015d27d31 | ||
|
|
d8d1d6ea40 | ||
|
|
9eed2c50b9 | ||
|
|
60f878b45e | ||
|
|
b1cf9c3e25 | ||
|
|
895b7dc9b1 | ||
|
|
fbb2b6945b | ||
|
|
0b5036e0fb | ||
|
|
1005e2ae7c | ||
|
|
cf5b7dc0e4 | ||
|
|
f85d45a781 | ||
|
|
86f9ea0cd2 | ||
|
|
4d5d0d636f | ||
|
|
1887b59504 | ||
|
|
aae001fa8e | ||
|
|
fafb6f3bb5 | ||
|
|
33494dc342 | ||
|
|
85ff523965 | ||
|
|
892b4b5db2 | ||
|
|
d14e200ecd | ||
|
|
7e301425fc | ||
|
|
2ebb962114 | ||
|
|
c943ca6b0d | ||
|
|
43f6ce9624 | ||
|
|
dfcb7529ed | ||
|
|
42d561546b | ||
|
|
4b86ef59f1 | ||
|
|
3679889be2 | ||
|
|
45ab625616 | ||
|
|
ced2f86fd7 | ||
|
|
db23674749 | ||
|
|
df4d4beb6c | ||
|
|
81010c6c3d | ||
|
|
64c6bfecac | ||
|
|
fe6dc2ef81 | ||
|
|
ab1aafeb1c | ||
|
|
8142646938 | ||
|
|
6c96561624 | ||
|
|
ef5ed9f9b9 | ||
|
|
a8825e1c5d | ||
|
|
eaeb097026 | ||
|
|
bc29c3a789 | ||
|
|
cbc655bd4d | ||
|
|
e38ac2f9ac | ||
|
|
e890f06c1c | ||
|
|
a05e24667e | ||
|
|
000beafc7f | ||
|
|
16ae70948f | ||
|
|
cb6438234a | ||
|
|
0a574eeefa | ||
|
|
3948e1673d | ||
|
|
2627f229c4 | ||
|
|
f971d36515 | ||
|
|
8976057b45 | ||
|
|
33bcd1977a | ||
|
|
2543aea3b8 | ||
|
|
02d8f2f0f0 | ||
|
|
e9dc149340 | ||
|
|
88f5a89c93 | ||
|
|
a9faaecb97 | ||
|
|
e8632635d0 | ||
|
|
22ae828685 | ||
|
|
a1e7d2123d | ||
|
|
e832e937c5 | ||
|
|
1a679795e1 | ||
|
|
760d3e78d9 | ||
|
|
accbe1c16d | ||
|
|
8ad66575cd | ||
|
|
fe748f7633 | ||
|
|
b880b9426f | ||
|
|
b52d9c8c00 | ||
|
|
4c3d22baf5 | ||
|
|
2504baf783 | ||
|
|
1ad82b1f70 | ||
|
|
d256994528 | ||
|
|
1f82cb2138 | ||
|
|
22dcf2e883 | ||
|
|
813fc05b5b | ||
|
|
117915edc5 | ||
|
|
3e48b4fd95 | ||
|
|
997eb82f85 | ||
|
|
8d79606136 | ||
|
|
0326fa92b4 | ||
|
|
175aeef09a | ||
|
|
9e822403bb | ||
|
|
3eaf77d532 | ||
|
|
4fb3b39077 | ||
|
|
2632b130a5 | ||
|
|
5cd851ca4e | ||
|
|
1352dccea5 | ||
|
|
45d3bb4f04 | ||
|
|
7fa3bdba72 | ||
|
|
7f174213ed | ||
|
|
53b5a62b23 | ||
|
|
5bdb0c9d6d | ||
|
|
1470cb8bf4 | ||
|
|
4bf3ace444 | ||
|
|
75d1366ae1 | ||
|
|
3720cb1c33 | ||
|
|
d3f6c4ef36 | ||
|
|
20f3b3af8f | ||
|
|
68335d9124 | ||
|
|
0e7e6610ce | ||
|
|
7d23bffa42 | ||
|
|
17adab9a5d | ||
|
|
d043c373b4 | ||
|
|
91c54754fb | ||
|
|
8ccf3ad36a | ||
|
|
7f668463ac | ||
|
|
0b9eb74f93 | ||
|
|
2c87cb5101 | ||
|
|
47500d8352 | ||
|
|
8e3911269e | ||
|
|
0e120c9bbf | ||
|
|
33e8822165 | ||
|
|
32549ec135 | ||
|
|
511e1a12e3 | ||
|
|
a06b5bd720 | ||
|
|
e0c9397c62 | ||
|
|
c7836626ea | ||
|
|
651382b313 | ||
|
|
685ab1a583 | ||
|
|
76892c52aa | ||
|
|
80e6dab78a | ||
|
|
f0e3afe0d3 | ||
|
|
4a15f9a2cc | ||
|
|
2b68a1520a | ||
|
|
175d47f104 | ||
|
|
9d7ee674c6 | ||
|
|
1246ee3acd | ||
|
|
7f72b7ce34 | ||
|
|
2a8f0b4b3b | ||
|
|
14c0f3def9 | ||
|
|
5f7c3a959e | ||
|
|
b082c99267 | ||
|
|
c045644097 | ||
|
|
225b4c6925 | ||
|
|
8f865af0c1 | ||
|
|
827cd50849 | ||
|
|
df4b2d9f85 | ||
|
|
266c0f4886 | ||
|
|
ff44d4acde | ||
|
|
8606a88279 | ||
|
|
badeb70be2 | ||
|
|
654ce3e0c7 | ||
|
|
e0c62c5eda | ||
|
|
34af2b0828 | ||
|
|
b3d307b465 | ||
|
|
2079cb995a | ||
|
|
492159c312 | ||
|
|
26548da779 | ||
|
|
96ebf7e147 | ||
|
|
40eed36499 | ||
|
|
02116e2b63 | ||
|
|
1b59bb82b9 | ||
|
|
12b921c9a3 | ||
|
|
4900ac4b20 | ||
|
|
fb602da502 | ||
|
|
9ace9232b7 | ||
|
|
055cc2d984 | ||
|
|
aa36b7fb5f | ||
|
|
692ad53941 | ||
|
|
fb0c78b946 | ||
|
|
3ceb43dccd | ||
|
|
72bfc12f18 | ||
|
|
30367d0c0f | ||
|
|
8091634814 | ||
|
|
a20894d847 | ||
|
|
4a7a5d5d10 | ||
|
|
7f25c356ea | ||
|
|
8c15b89278 | ||
|
|
5dc3d9abce | ||
|
|
eb6868704f | ||
|
|
f61740551c | ||
|
|
89f3a7c72f | ||
|
|
e0a1841b1c | ||
|
|
c906db1c21 | ||
|
|
d7acc94a0b | ||
|
|
f58a3ca1fa | ||
|
|
7b3d9255bc | ||
|
|
0c5f543433 | ||
|
|
fcbc7e1516 | ||
|
|
61d660f9f3 | ||
|
|
61103d8349 | ||
|
|
235c4d5f8f | ||
|
|
c7ce0547f4 | ||
|
|
63810131e3 | ||
|
|
0d08acaa1b | ||
|
|
91fc3fb7d7 | ||
|
|
b5754758a7 | ||
|
|
d218ce3306 | ||
|
|
71a55808f7 | ||
|
|
bdcc2e5c52 | ||
|
|
9918b8f039 | ||
|
|
2264a07c03 | ||
|
|
b2d01e2da0 | ||
|
|
66e72d4705 | ||
|
|
e77b34ed82 | ||
|
|
453a05996e | ||
|
|
8c8c5337ef | ||
|
|
0e8fc2a26a | ||
|
|
a70072f5cf | ||
|
|
e76eac49cb | ||
|
|
795930c803 | ||
|
|
8c6ac1288d | ||
|
|
2ca5f43f05 | ||
|
|
b30afe432e | ||
|
|
014b5e8a91 | ||
|
|
c91415f318 | ||
|
|
ea1fefa5b5 | ||
|
|
fc7b8b1254 | ||
|
|
986c46d417 | ||
|
|
304da1d01b | ||
|
|
23ddf7b88c | ||
|
|
ef089692ed | ||
|
|
5d85bfbf6b | ||
|
|
ef959a748e | ||
|
|
50e8d8b69a | ||
|
|
a5775d94ef | ||
|
|
9c82e869c2 | ||
|
|
7cded2a956 | ||
|
|
411b0a8777 | ||
|
|
ab9f6b301f | ||
|
|
ea42d0bb16 | ||
|
|
f7ec8cccc7 | ||
|
|
48319f9763 | ||
|
|
28b5b175a3 | ||
|
|
0d7ea7353f | ||
|
|
96ea91056e | ||
|
|
2f59f69a1f | ||
|
|
5e217a1079 | ||
|
|
73643acd03 | ||
|
|
0a1febacb3 | ||
|
|
45dd03bfc7 | ||
|
|
532fa9fae8 | ||
|
|
0c1f57815c | ||
|
|
be1857ceb3 | ||
|
|
9df608c612 | ||
|
|
6f573feaeb | ||
|
|
b2bffc26f9 | ||
|
|
e7a42ffd02 | ||
|
|
0311bf8e4b | ||
|
|
b764bb427b | ||
|
|
94e3c02649 | ||
|
|
d62ca820db | ||
|
|
ae6c17a87d | ||
|
|
3b7bf691e7 | ||
|
|
6ccf19bed6 | ||
|
|
ea49e9d1b0 | ||
|
|
c30f2bbe3e | ||
|
|
f174038100 | ||
|
|
8dcf7d4cc3 | ||
|
|
1c67fdb95d | ||
|
|
a8cd91d6c7 | ||
|
|
6b64ef6be3 | ||
|
|
71f5b4e0ae | ||
|
|
8bb1caec8f | ||
|
|
1d11e2cce0 | ||
|
|
67b6b05f26 | ||
|
|
3418c1852f | ||
|
|
321fa338e5 | ||
|
|
150ca939b1 | ||
|
|
2276c6e524 | ||
|
|
8e6728f206 | ||
|
|
7c829c4024 | ||
|
|
af347acf99 | ||
|
|
28c03e3f0d | ||
|
|
827aa0e752 | ||
|
|
751f400afb | ||
|
|
b6acbe040c | ||
|
|
c872866289 | ||
|
|
9b58aef815 | ||
|
|
fa17fb0da1 | ||
|
|
1ca8804468 | ||
|
|
f8fe9d1dd4 | ||
|
|
3b0a563730 | ||
|
|
cc2779c80e | ||
|
|
a20270dbc7 | ||
|
|
bfb54b5a4d | ||
|
|
60917c83d6 | ||
|
|
668c0ab529 | ||
|
|
7e04b205fa | ||
|
|
0cdcf102a0 | ||
|
|
6b70e9ddb7 | ||
|
|
4184b9d56f | ||
|
|
7800a34d84 | ||
|
|
14a5c6bf66 | ||
|
|
1370c014a5 | ||
|
|
104c2a06ae | ||
|
|
9329109391 | ||
|
|
44b738ab75 | ||
|
|
f929e51776 | ||
|
|
ebab4a59c9 | ||
|
|
11aec0104e | ||
|
|
29907f3c71 | ||
|
|
685830b66a | ||
|
|
70b8d09391 | ||
|
|
e85566cbb2 | ||
|
|
129d01e139 | ||
|
|
8651e205be | ||
|
|
040cdc2f91 | ||
|
|
67088b15a4 | ||
|
|
4740bc7e3a | ||
|
|
35c2804c13 | ||
|
|
c89c3443a8 | ||
|
|
91a08fc162 | ||
|
|
07501cd12c | ||
|
|
cff1714209 | ||
|
|
59bbe33954 | ||
|
|
1bd420f12c | ||
|
|
0fd492a817 | ||
|
|
5c9def5be4 | ||
|
|
6958b63c58 | ||
|
|
504d882090 | ||
|
|
218321deb6 | ||
|
|
2e62cd5a74 | ||
|
|
a3d67a7fe7 | ||
|
|
8af0fae335 | ||
|
|
afdf7897e6 | ||
|
|
a3fe72642b | ||
|
|
71ad82b6aa | ||
|
|
48963c1cdf | ||
|
|
bd977e9e5c | ||
|
|
d6aa8ecaff | ||
|
|
b8579c6848 | ||
|
|
cc0ce6b437 | ||
|
|
950e4c800b | ||
|
|
7159564881 | ||
|
|
2aad7baac0 | ||
|
|
7a397480e5 | ||
|
|
ae4d214c49 | ||
|
|
73f04b21e9 | ||
|
|
c21e85e569 | ||
|
|
da69fc19de | ||
|
|
009d1ed88a | ||
|
|
b53513a5e7 | ||
|
|
7427fb8d98 | ||
|
|
e1727844d7 | ||
|
|
cb00b56b8f | ||
|
|
b6e46986f0 | ||
|
|
14cbcfce3b | ||
|
|
ebb0d82c83 | ||
|
|
680cd159c5 | ||
|
|
bc2848b41e | ||
|
|
08ac439d0f | ||
|
|
0a7c6ac261 | ||
|
|
0c79465950 | ||
|
|
01428e5076 | ||
|
|
795f716daf | ||
|
|
2f1382d0b8 | ||
|
|
0a952b1a66 | ||
|
|
33cdf0d019 | ||
|
|
46760e91cd | ||
|
|
664270a1c4 | ||
|
|
752e7aa84a | ||
|
|
23a3b078d6 | ||
|
|
cacd60860a | ||
|
|
fe2e5cdcf1 | ||
|
|
77c2a14822 | ||
|
|
85ef4988e1 | ||
|
|
86fe801944 | ||
|
|
291506a2b2 | ||
|
|
fcf6ec16aa | ||
|
|
b10278c8e0 | ||
|
|
df730ec163 | ||
|
|
858d67e769 | ||
|
|
5e9ff76d26 | ||
|
|
662edc2558 | ||
|
|
e4589700b6 | ||
|
|
0a35ca2ff7 | ||
|
|
2c39e28ff6 | ||
|
|
4d30756e72 | ||
|
|
e377be96d4 | ||
|
|
2c4efecee2 | ||
|
|
1fb9c09f02 | ||
|
|
419a3d3098 | ||
|
|
aea01d54ac | ||
|
|
d25f0a7580 | ||
|
|
17a4d6654f | ||
|
|
b0a0853bd2 | ||
|
|
510b3349a7 | ||
|
|
490af28958 | ||
|
|
874d4282c0 | ||
|
|
b566c0f201 | ||
|
|
c7abaff9e9 | ||
|
|
a59760883d | ||
|
|
8a56bc70a4 | ||
|
|
c51a2355ee | ||
|
|
6721c465c9 | ||
|
|
995141954f | ||
|
|
51dcf85fa0 | ||
|
|
3516279cdd | ||
|
|
cd45cdd451 | ||
|
|
8e0cf79f91 | ||
|
|
6460ecdc18 | ||
|
|
068fac2d7e | ||
|
|
06c689738e | ||
|
|
3542b63bb7 | ||
|
|
e1a9a71759 | ||
|
|
0d989a6972 | ||
|
|
6443a3ed78 | ||
|
|
59e16feae1 | ||
|
|
dd3ef9fe47 | ||
|
|
40c95c971c | ||
|
|
dc6ae6dc15 | ||
|
|
1b5c1ac021 | ||
|
|
663d7483f2 | ||
|
|
a49c48a53b | ||
|
|
bb3c6ce173 | ||
|
|
a119a22988 | ||
|
|
33ddba3d30 | ||
|
|
81b493ba0b | ||
|
|
7c9e7e57b9 | ||
|
|
d4fae47430 | ||
|
|
5e19ad31bf | ||
|
|
47e20f9ecd | ||
|
|
e39cc5324b | ||
|
|
f70878e6c5 | ||
|
|
abeb29c226 | ||
|
|
09a61e8128 | ||
|
|
a337638f7f | ||
|
|
6663247e22 | ||
|
|
4490881685 | ||
|
|
0a8afbeff6 | ||
|
|
a9d37ebfb9 | ||
|
|
6f0477f491 | ||
|
|
0bf60e243a | ||
|
|
7de3c63146 | ||
|
|
e4f917aa9c | ||
|
|
1c5d642672 | ||
|
|
f607b24ee5 | ||
|
|
90d97a39c6 | ||
|
|
c1dcf38b0a | ||
|
|
c2034c210c | ||
|
|
f519fa907c | ||
|
|
6354b712fc | ||
|
|
2f6d722d9b | ||
|
|
755f2e043e | ||
|
|
0181ec3ef8 | ||
|
|
e56e892578 | ||
|
|
96bb739157 | ||
|
|
8535669d46 | ||
|
|
f55067a3db | ||
|
|
4f2cb1bc1c | ||
|
|
da81bcae0e | ||
|
|
54d9a733c2 | ||
|
|
479e3bfbd0 | ||
|
|
5ada0ab93e | ||
|
|
08973733a7 | ||
|
|
a0595e8c60 | ||
|
|
458c066925 | ||
|
|
b815203b0b | ||
|
|
a4111a2426 | ||
|
|
f923c15ba8 | ||
|
|
983f29eac4 | ||
|
|
2452a5c0b2 | ||
|
|
657a750550 | ||
|
|
e7b31fd6ad | ||
|
|
3bd3991d1b | ||
|
|
682a1c92e0 | ||
|
|
cd9a44f35b | ||
|
|
002df64811 | ||
|
|
6eeee0a4f3 | ||
|
|
1843262672 | ||
|
|
64807c0628 | ||
|
|
676e9d90ff | ||
|
|
cc00ed6d7e | ||
|
|
afaff0c2cf | ||
|
|
afe167ea58 | ||
|
|
21a69f2188 | ||
|
|
9e24558092 | ||
|
|
3760609f3f | ||
|
|
953c3578dc | ||
|
|
79910fa2b3 | ||
|
|
30de0b3e77 | ||
|
|
07cbbfdfda | ||
|
|
fed3902fc5 | ||
|
|
70b0e73a24 | ||
|
|
5e4e8af0c4 | ||
|
|
ce57cbf22a | ||
|
|
40057b2fd0 | ||
|
|
b612d0a53f | ||
|
|
424994ec9b | ||
|
|
686c039c81 | ||
|
|
052b8a3b59 | ||
|
|
bd68884607 | ||
|
|
feaf6843de | ||
|
|
97dd4b0cb3 | ||
|
|
5d454afb74 | ||
|
|
9f016ed827 | ||
|
|
d7c7913a11 | ||
|
|
44386b3615 | ||
|
|
4e52ecce0f | ||
|
|
a33eb6f61f | ||
|
|
e5be713103 | ||
|
|
02304ca4a0 | ||
|
|
010475d49f | ||
|
|
87814572c9 | ||
|
|
55047280c9 | ||
|
|
56e5bce173 | ||
|
|
9f226e4cd2 | ||
|
|
1a21db1170 | ||
|
|
b8a151ca4e | ||
|
|
f7ac58bab5 | ||
|
|
606d8a4f9b | ||
|
|
a4c92093a0 | ||
|
|
d5b0093d0f | ||
|
|
51fe87fcd6 | ||
|
|
ec56e946a7 | ||
|
|
2cd7c35875 | ||
|
|
da3f1704ed | ||
|
|
850eae3e8e | ||
|
|
30eaae72e4 | ||
|
|
1e7a22f14e | ||
|
|
6808b5b5fe | ||
|
|
5007d4d87a | ||
|
|
1b53a77f1b | ||
|
|
5d79796465 | ||
|
|
878e07a5d8 | ||
|
|
f86de8c7a0 | ||
|
|
f765c88ac9 | ||
|
|
abded5f886 | ||
|
|
d2486670a8 | ||
|
|
0156e72352 | ||
|
|
54b06d046b | ||
|
|
ad9659ea54 | ||
|
|
dc5c410257 | ||
|
|
80ec6ff8bc | ||
|
|
fa5681d93b | ||
|
|
36a7944d2a | ||
|
|
2223d2e465 | ||
|
|
b09884e589 | ||
|
|
c46e5fd0f1 | ||
|
|
11d5f8bbc5 | ||
|
|
e15cc972ec | ||
|
|
c1058355f6 | ||
|
|
207cfc449d | ||
|
|
1b068d5433 | ||
|
|
7aef6423de | ||
|
|
16f3f585c3 | ||
|
|
d57404683f | ||
|
|
2423c9bc15 | ||
|
|
3e51ac2f3d | ||
|
|
72e2fbd725 | ||
|
|
95320b7369 | ||
|
|
55acdb546e | ||
|
|
9d8adba30c | ||
|
|
ef906c3cd3 | ||
|
|
da1466cfa9 | ||
|
|
00946f97df | ||
|
|
45a23712ff | ||
|
|
42e23dc82e | ||
|
|
9fa9f81a0a | ||
|
|
ca85e5bc51 | ||
|
|
89844c6ced | ||
|
|
559f0896a1 | ||
|
|
2a0c2207d2 | ||
|
|
5b601d8492 | ||
|
|
2c2f404cb6 | ||
|
|
10bce7ffe8 | ||
|
|
5bc826067e | ||
|
|
ebfcdfd35e | ||
|
|
aeaac45fd0 | ||
|
|
57b6ba4250 | ||
|
|
20cf06013e | ||
|
|
c6a5e8de34 | ||
|
|
15d520ae1d | ||
|
|
7479ba8c8e | ||
|
|
39288d78d8 | ||
|
|
b66bccb068 | ||
|
|
eb7be522ac | ||
|
|
717e06d94c | ||
|
|
8800dcdce4 | ||
|
|
8ee7536012 | ||
|
|
bbda1d93c4 | ||
|
|
6a3089a803 | ||
|
|
4f2b292289 | ||
|
|
c53845a69c | ||
|
|
3459962e69 | ||
|
|
53059bb10c | ||
|
|
56fb3dd877 | ||
|
|
22d0ee55f6 | ||
|
|
3a41184533 | ||
|
|
9d0f801ad6 | ||
|
|
c0a8fc459a | ||
|
|
09481aab69 | ||
|
|
3d9ad287fa | ||
|
|
4563271a1b | ||
|
|
848c9ec7be | ||
|
|
2ba9415178 | ||
|
|
8e72084fcb | ||
|
|
8899c62567 | ||
|
|
ce00fe0cd5 | ||
|
|
eb9f7a04b7 | ||
|
|
90bb398784 | ||
|
|
e9f4612281 | ||
|
|
fb5c42707e | ||
|
|
5a4df81202 | ||
|
|
1db8fba5aa | ||
|
|
afa2cc25d1 | ||
|
|
d36510e4c3 | ||
|
|
c1358ac9d4 | ||
|
|
24978224a3 | ||
|
|
1202cacffd | ||
|
|
3971f18de8 | ||
|
|
c710a54a99 | ||
|
|
b3e0c93ca6 | ||
|
|
b7d13d542c | ||
|
|
501f063426 | ||
|
|
78e936fc36 | ||
|
|
41eded47d2 | ||
|
|
fd9d48f6df | ||
|
|
44f575c812 | ||
|
|
1080b4239d | ||
|
|
60a8e6e769 | ||
|
|
d39141039b |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -14,8 +14,15 @@ zerver/fixtures/available-migrations
|
|||||||
zerver/fixtures/migration-status
|
zerver/fixtures/migration-status
|
||||||
zerver/fixtures/test_data1.json
|
zerver/fixtures/test_data1.json
|
||||||
.kdev4
|
.kdev4
|
||||||
humbug.kdev4
|
zulip.kdev4
|
||||||
memcached_prefix
|
memcached_prefix
|
||||||
coverage/
|
coverage/
|
||||||
/queue_error
|
/queue_error
|
||||||
/workers.log
|
/workers.log
|
||||||
|
.test-js-with-node.html
|
||||||
|
digest.log
|
||||||
|
errors.log
|
||||||
|
manage.log
|
||||||
|
.kateproject.d/
|
||||||
|
.kateproject
|
||||||
|
*.kate-swp
|
||||||
|
|||||||
24
analytics/management/commands/active_user_stats_by_day.py
Normal file
24
analytics/management/commands/active_user_stats_by_day.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import pytz
|
||||||
|
|
||||||
|
from optparse import make_option
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from zerver.lib.statistics import activity_averages_during_day
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = "Generate statistics on user activity for a given day."
|
||||||
|
|
||||||
|
option_list = BaseCommand.option_list + \
|
||||||
|
(make_option('--date', default=None, action='store',
|
||||||
|
help="Day to query in format 2013-12-05. Default is yesterday"),)
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
if options["date"] is None:
|
||||||
|
date = datetime.datetime.now() - datetime.timedelta(days=1)
|
||||||
|
else:
|
||||||
|
date = datetime.datetime.strptime(options["date"], "%Y-%m-%d")
|
||||||
|
print "Activity data for", date
|
||||||
|
print activity_averages_during_day(date)
|
||||||
|
print "Please note that the total registered user count is a total for today"
|
||||||
@@ -8,7 +8,7 @@ from django.db.models import Count
|
|||||||
from zerver.models import UserProfile, Realm, Stream, Message, Recipient, UserActivity, \
|
from zerver.models import UserProfile, Realm, Stream, Message, Recipient, UserActivity, \
|
||||||
Subscription, UserMessage
|
Subscription, UserMessage
|
||||||
|
|
||||||
MOBILE_CLIENT_LIST = ["Android", "iPhone"]
|
MOBILE_CLIENT_LIST = ["Android", "ios"]
|
||||||
HUMAN_CLIENT_LIST = MOBILE_CLIENT_LIST + ["website"]
|
HUMAN_CLIENT_LIST = MOBILE_CLIENT_LIST + ["website"]
|
||||||
|
|
||||||
human_messages = Message.objects.filter(sending_client__name__in=HUMAN_CLIENT_LIST)
|
human_messages = Message.objects.filter(sending_client__name__in=HUMAN_CLIENT_LIST)
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ from django.template import RequestContext, loader
|
|||||||
from django.utils.html import mark_safe
|
from django.utils.html import mark_safe
|
||||||
from django.shortcuts import render_to_response
|
from django.shortcuts import render_to_response
|
||||||
from django.core import urlresolvers
|
from django.core import urlresolvers
|
||||||
|
from django.http import HttpResponseNotFound
|
||||||
|
|
||||||
from zerver.decorator import has_request_variables, REQ, zulip_internal
|
from zerver.decorator import has_request_variables, REQ, zulip_internal
|
||||||
from zerver.models import get_realm, UserActivity, UserActivityInterval, Realm
|
from zerver.models import get_realm, UserActivity, UserActivityInterval, Realm
|
||||||
from zerver.lib.timestamp import timestamp_to_datetime
|
from zerver.lib.timestamp import timestamp_to_datetime
|
||||||
|
|
||||||
|
from collections import defaultdict
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import itertools
|
import itertools
|
||||||
import time
|
import time
|
||||||
@@ -39,6 +41,61 @@ def dictfetchall(cursor):
|
|||||||
for row in cursor.fetchall()
|
for row in cursor.fetchall()
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_realm_day_counts():
|
||||||
|
query = '''
|
||||||
|
select
|
||||||
|
r.domain,
|
||||||
|
(now()::date - pub_date::date) age,
|
||||||
|
count(*) cnt
|
||||||
|
from zerver_message m
|
||||||
|
join zerver_userprofile up on up.id = m.sender_id
|
||||||
|
join zerver_realm r on r.id = up.realm_id
|
||||||
|
join zerver_client c on c.id = m.sending_client_id
|
||||||
|
where
|
||||||
|
(not up.is_bot)
|
||||||
|
and
|
||||||
|
pub_date > now()::date - interval '8 day'
|
||||||
|
and
|
||||||
|
c.name not in ('zephyr_mirror', 'ZulipMonitoring')
|
||||||
|
group by
|
||||||
|
r.domain,
|
||||||
|
age
|
||||||
|
order by
|
||||||
|
r.domain,
|
||||||
|
age
|
||||||
|
'''
|
||||||
|
cursor = connection.cursor()
|
||||||
|
cursor.execute(query)
|
||||||
|
rows = dictfetchall(cursor)
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
counts = defaultdict(dict)
|
||||||
|
for row in rows:
|
||||||
|
counts[row['domain']][row['age']] = row['cnt']
|
||||||
|
|
||||||
|
|
||||||
|
result = {}
|
||||||
|
for domain in counts:
|
||||||
|
cnts = [counts[domain].get(age, 0) for age in range(8)]
|
||||||
|
min_cnt = min(cnts)
|
||||||
|
max_cnt = max(cnts)
|
||||||
|
|
||||||
|
def format_count(cnt):
|
||||||
|
if cnt == min_cnt:
|
||||||
|
good_bad = 'bad'
|
||||||
|
elif cnt == max_cnt:
|
||||||
|
good_bad = 'good'
|
||||||
|
else:
|
||||||
|
good_bad = 'neutral'
|
||||||
|
|
||||||
|
return '<td class="number %s">%s</td>' % (good_bad, cnt)
|
||||||
|
|
||||||
|
cnts = ''.join(map(format_count, cnts))
|
||||||
|
result[domain] = dict(cnts=cnts)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
def realm_summary_table(realm_minutes):
|
def realm_summary_table(realm_minutes):
|
||||||
query = '''
|
query = '''
|
||||||
SELECT
|
SELECT
|
||||||
@@ -74,6 +131,7 @@ def realm_summary_table(realm_minutes):
|
|||||||
query in (
|
query in (
|
||||||
'/json/send_message',
|
'/json/send_message',
|
||||||
'send_message_backend',
|
'send_message_backend',
|
||||||
|
'/api/v1/send_message',
|
||||||
'/json/update_pointer'
|
'/json/update_pointer'
|
||||||
)
|
)
|
||||||
AND
|
AND
|
||||||
@@ -103,6 +161,7 @@ def realm_summary_table(realm_minutes):
|
|||||||
ua.query in (
|
ua.query in (
|
||||||
'/json/send_message',
|
'/json/send_message',
|
||||||
'send_message_backend',
|
'send_message_backend',
|
||||||
|
'/api/v1/send_message',
|
||||||
'/json/update_pointer'
|
'/json/update_pointer'
|
||||||
)
|
)
|
||||||
GROUP by realm.id, up.email
|
GROUP by realm.id, up.email
|
||||||
@@ -114,7 +173,7 @@ def realm_summary_table(realm_minutes):
|
|||||||
) at_risk_counts
|
) at_risk_counts
|
||||||
ON at_risk_counts.realm_id = realm.id
|
ON at_risk_counts.realm_id = realm.id
|
||||||
WHERE
|
WHERE
|
||||||
realm.domain not in ('zulip.com', 'customer4.invalid', 'wdaher.com')
|
realm.domain not in ('customer4.invalid', 'wdaher.com')
|
||||||
AND EXISTS (
|
AND EXISTS (
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM zerver_useractivity ua
|
FROM zerver_useractivity ua
|
||||||
@@ -123,6 +182,7 @@ def realm_summary_table(realm_minutes):
|
|||||||
WHERE
|
WHERE
|
||||||
query in (
|
query in (
|
||||||
'/json/send_message',
|
'/json/send_message',
|
||||||
|
'/api/v1/send_message',
|
||||||
'send_message_backend',
|
'send_message_backend',
|
||||||
'/json/update_pointer'
|
'/json/update_pointer'
|
||||||
)
|
)
|
||||||
@@ -139,6 +199,14 @@ def realm_summary_table(realm_minutes):
|
|||||||
rows = dictfetchall(cursor)
|
rows = dictfetchall(cursor)
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
|
||||||
|
# get messages sent per day
|
||||||
|
counts = get_realm_day_counts()
|
||||||
|
for row in rows:
|
||||||
|
try:
|
||||||
|
row['history'] = counts[row['domain']]['cnts']
|
||||||
|
except:
|
||||||
|
row['history'] = ''
|
||||||
|
|
||||||
# augment data with realm_minutes
|
# augment data with realm_minutes
|
||||||
total_hours = 0
|
total_hours = 0
|
||||||
for row in rows:
|
for row in rows:
|
||||||
@@ -156,6 +224,17 @@ def realm_summary_table(realm_minutes):
|
|||||||
for row in rows:
|
for row in rows:
|
||||||
row['domain'] = realm_activity_link(row['domain'])
|
row['domain'] = realm_activity_link(row['domain'])
|
||||||
|
|
||||||
|
# Count active sites
|
||||||
|
def meets_goal(row):
|
||||||
|
# The wdaher.com realm doesn't count toward company goals for
|
||||||
|
# obvious reasons, and customer4.invalid is essentially a dup
|
||||||
|
# for users.customer4.invalid.
|
||||||
|
if row['domain'] in ['customer4.invalid', 'wdaher.com']:
|
||||||
|
return False
|
||||||
|
return row['active_user_count'] >= 5
|
||||||
|
|
||||||
|
num_active_sites = len(filter(meets_goal, rows))
|
||||||
|
|
||||||
# create totals
|
# create totals
|
||||||
total_active_user_count = 0
|
total_active_user_count = 0
|
||||||
total_user_profile_count = 0
|
total_user_profile_count = 0
|
||||||
@@ -165,6 +244,7 @@ def realm_summary_table(realm_minutes):
|
|||||||
total_user_profile_count += int(row['user_profile_count'])
|
total_user_profile_count += int(row['user_profile_count'])
|
||||||
total_bot_count += int(row['bot_count'])
|
total_bot_count += int(row['bot_count'])
|
||||||
|
|
||||||
|
|
||||||
rows.append(dict(
|
rows.append(dict(
|
||||||
domain='Total',
|
domain='Total',
|
||||||
active_user_count=total_active_user_count,
|
active_user_count=total_active_user_count,
|
||||||
@@ -173,16 +253,6 @@ def realm_summary_table(realm_minutes):
|
|||||||
hours=int(total_hours)
|
hours=int(total_hours)
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
def meets_goal(row):
|
|
||||||
# We don't count toward company goals for obvious reasons, and
|
|
||||||
# customer4.invalid is essentially a dup for users.customer4.invalid.
|
|
||||||
if row['domain'] in ['zulip.com', 'customer4.invalid']:
|
|
||||||
return False
|
|
||||||
return row['active_user_count'] >= 5
|
|
||||||
|
|
||||||
num_active_sites = len(filter(meets_goal, rows))
|
|
||||||
|
|
||||||
content = loader.render_to_string(
|
content = loader.render_to_string(
|
||||||
'analytics/realm_summary_table.html',
|
'analytics/realm_summary_table.html',
|
||||||
dict(rows=rows, num_active_sites=num_active_sites)
|
dict(rows=rows, num_active_sites=num_active_sites)
|
||||||
@@ -336,7 +406,8 @@ def ad_hoc_queries():
|
|||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
title = 'Android usage'
|
for mobile_type in ['Android', 'ZulipiOS']:
|
||||||
|
title = '%s usage' % (mobile_type,)
|
||||||
|
|
||||||
query = '''
|
query = '''
|
||||||
select
|
select
|
||||||
@@ -350,13 +421,11 @@ def ad_hoc_queries():
|
|||||||
join zerver_userprofile up on up.id = ua.user_profile_id
|
join zerver_userprofile up on up.id = ua.user_profile_id
|
||||||
join zerver_realm realm on realm.id = up.realm_id
|
join zerver_realm realm on realm.id = up.realm_id
|
||||||
where
|
where
|
||||||
client.name like 'Android'
|
client.name like '%s'
|
||||||
and
|
|
||||||
query = 'send_message_backend'
|
|
||||||
group by domain, up.id, client.name
|
group by domain, up.id, client.name
|
||||||
having max(last_visit) > now() - interval '2 week'
|
having max(last_visit) > now() - interval '2 week'
|
||||||
order by domain, up.id, client.name
|
order by domain, up.id, client.name
|
||||||
'''
|
''' % (mobile_type,)
|
||||||
|
|
||||||
cols = [
|
cols = [
|
||||||
'Domain',
|
'Domain',
|
||||||
@@ -400,38 +469,6 @@ def ad_hoc_queries():
|
|||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
title = 'Pure API'
|
|
||||||
|
|
||||||
query = '''
|
|
||||||
select
|
|
||||||
realm.domain,
|
|
||||||
sum(count) as hits,
|
|
||||||
max(last_visit) as last_time
|
|
||||||
from zerver_useractivity ua
|
|
||||||
join zerver_client client on client.id = ua.client_id
|
|
||||||
join zerver_userprofile up on up.id = ua.user_profile_id
|
|
||||||
join zerver_realm realm on realm.id = up.realm_id
|
|
||||||
where
|
|
||||||
query = '/api/v1/send_message'
|
|
||||||
and
|
|
||||||
client.name = 'API'
|
|
||||||
and
|
|
||||||
domain != 'zulip.com'
|
|
||||||
group by domain
|
|
||||||
having max(last_visit) > now() - interval '2 week'
|
|
||||||
order by domain
|
|
||||||
'''
|
|
||||||
|
|
||||||
cols = [
|
|
||||||
'Domain',
|
|
||||||
'Hits',
|
|
||||||
'Last time'
|
|
||||||
]
|
|
||||||
|
|
||||||
pages.append(get_page(query, cols, title))
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
title = 'Integrations by domain'
|
title = 'Integrations by domain'
|
||||||
|
|
||||||
query = '''
|
query = '''
|
||||||
@@ -448,8 +485,8 @@ def ad_hoc_queries():
|
|||||||
join zerver_userprofile up on up.id = ua.user_profile_id
|
join zerver_userprofile up on up.id = ua.user_profile_id
|
||||||
join zerver_realm realm on realm.id = up.realm_id
|
join zerver_realm realm on realm.id = up.realm_id
|
||||||
where
|
where
|
||||||
(query = 'send_message_backend'
|
(query in ('send_message_backend', '/api/v1/send_message')
|
||||||
and client.name not in ('Android', 'API', 'API: Python')
|
and client.name not in ('Android', 'ZulipiOS')
|
||||||
and client.name not like 'test: Zulip%%'
|
and client.name not like 'test: Zulip%%'
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
@@ -486,8 +523,8 @@ def ad_hoc_queries():
|
|||||||
join zerver_userprofile up on up.id = ua.user_profile_id
|
join zerver_userprofile up on up.id = ua.user_profile_id
|
||||||
join zerver_realm realm on realm.id = up.realm_id
|
join zerver_realm realm on realm.id = up.realm_id
|
||||||
where
|
where
|
||||||
(query = 'send_message_backend'
|
(query in ('send_message_backend', '/api/v1/send_message')
|
||||||
and client.name not in ('Android', 'API', 'API: Python')
|
and client.name not in ('Android', 'ZulipiOS')
|
||||||
and client.name not like 'test: Zulip%%'
|
and client.name not like 'test: Zulip%%'
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
@@ -510,7 +547,7 @@ def ad_hoc_queries():
|
|||||||
|
|
||||||
@zulip_internal
|
@zulip_internal
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def get_activity(request, realm=REQ(default=None)):
|
def get_activity(request):
|
||||||
duration_content, realm_minutes = user_activity_intervals()
|
duration_content, realm_minutes = user_activity_intervals()
|
||||||
counts_content = realm_summary_table(realm_minutes)
|
counts_content = realm_summary_table(realm_minutes)
|
||||||
data = [
|
data = [
|
||||||
@@ -524,7 +561,7 @@ def get_activity(request, realm=REQ(default=None)):
|
|||||||
|
|
||||||
return render_to_response(
|
return render_to_response(
|
||||||
'analytics/activity.html',
|
'analytics/activity.html',
|
||||||
dict(data=data, realm=realm, title=title, is_home=True),
|
dict(data=data, title=title, is_home=True),
|
||||||
context_instance=RequestContext(request)
|
context_instance=RequestContext(request)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -745,7 +782,7 @@ def realm_user_summary_table(all_records, admin_emails):
|
|||||||
sent_count = get_count(user_summary, 'send')
|
sent_count = get_count(user_summary, 'send')
|
||||||
cells = [user_summary['name'], email_link, sent_count]
|
cells = [user_summary['name'], email_link, sent_count]
|
||||||
row_class = ''
|
row_class = ''
|
||||||
for field in ['use', 'send', 'pointer', 'desktop', 'iPhone', 'Android']:
|
for field in ['use', 'send', 'pointer', 'desktop', 'ZulipiOS', 'Android']:
|
||||||
val = get_last_visit(user_summary, field)
|
val = get_last_visit(user_summary, field)
|
||||||
if field == 'use':
|
if field == 'use':
|
||||||
if val and is_recent(val):
|
if val and is_recent(val):
|
||||||
@@ -770,7 +807,7 @@ def realm_user_summary_table(all_records, admin_emails):
|
|||||||
'Message sent',
|
'Message sent',
|
||||||
'Pointer motion',
|
'Pointer motion',
|
||||||
'Desktop',
|
'Desktop',
|
||||||
'iPhone',
|
'ZulipiOS',
|
||||||
'Android'
|
'Android'
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -785,7 +822,11 @@ def get_realm_activity(request, realm):
|
|||||||
all_records = {}
|
all_records = {}
|
||||||
all_user_records = {}
|
all_user_records = {}
|
||||||
|
|
||||||
|
try:
|
||||||
admins = Realm.objects.get(domain=realm).get_admin_users()
|
admins = Realm.objects.get(domain=realm).get_admin_users()
|
||||||
|
except Realm.DoesNotExist:
|
||||||
|
return HttpResponseNotFound("Realm %s does not exist" % (realm,))
|
||||||
|
|
||||||
admin_emails = {admin.email for admin in admins}
|
admin_emails = {admin.email for admin in admins}
|
||||||
|
|
||||||
for is_bot, page_title in [(False, 'Humans'), (True, 'Bots')]:
|
for is_bot, page_title in [(False, 'Humans'), (True, 'Bots')]:
|
||||||
@@ -806,10 +847,15 @@ def get_realm_activity(request, realm):
|
|||||||
content = sent_messages_report(realm)
|
content = sent_messages_report(realm)
|
||||||
data += [(page_title, content)]
|
data += [(page_title, content)]
|
||||||
|
|
||||||
|
fix_name = lambda realm: realm.replace('.', '_')
|
||||||
|
|
||||||
|
realm_link = 'https://stats1.zulip.net:444/render/?from=-7days'
|
||||||
|
realm_link += '&target=stats.gauges.staging.users.active.%s.0_16hr' % (fix_name(realm),)
|
||||||
|
|
||||||
title = realm
|
title = realm
|
||||||
return render_to_response(
|
return render_to_response(
|
||||||
'analytics/activity.html',
|
'analytics/activity.html',
|
||||||
dict(data=data, realm=realm, title=title),
|
dict(data=data, realm_link=realm_link, title=title),
|
||||||
context_instance=RequestContext(request)
|
context_instance=RequestContext(request)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -826,10 +872,9 @@ def get_user_activity(request, email):
|
|||||||
content = raw_user_activity_table(records)
|
content = raw_user_activity_table(records)
|
||||||
data += [('Info', content)]
|
data += [('Info', content)]
|
||||||
|
|
||||||
realm = None
|
|
||||||
title = email
|
title = email
|
||||||
return render_to_response(
|
return render_to_response(
|
||||||
'analytics/activity.html',
|
'analytics/activity.html',
|
||||||
dict(data=data, realm=realm, title=title),
|
dict(data=data, title=title),
|
||||||
context_instance=RequestContext(request)
|
context_instance=RequestContext(request)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#### Dependencies
|
#### Dependencies
|
||||||
|
|
||||||
The Zulip API Python bindings require the following Python libraries:
|
The [Zulip API](https://zulip.com/api) Python bindings require the
|
||||||
|
following Python libraries:
|
||||||
|
|
||||||
* simplejson
|
* simplejson
|
||||||
* requests (version >= 0.12.1)
|
* requests (version >= 0.12.1)
|
||||||
@@ -30,9 +31,14 @@ file is as follows:
|
|||||||
key=<api key from the web interface>
|
key=<api key from the web interface>
|
||||||
email=<your email address>
|
email=<your email address>
|
||||||
|
|
||||||
|
If you are using Zulip Enterprise, you should also add
|
||||||
|
|
||||||
|
site=<your Zulip Enterprise server's URI>
|
||||||
|
|
||||||
Alternatively, you may explicitly use "--user" and "--api-key" in our
|
Alternatively, you may explicitly use "--user" and "--api-key" in our
|
||||||
examples, which is especially useful if you are running several bots
|
examples, which is especially useful if you are running several bots
|
||||||
which share a home directory.
|
which share a home directory. There is also a "--site" option for
|
||||||
|
setting the Zulip Enterprise server on the command line.
|
||||||
|
|
||||||
You can obtain your Zulip API key, create bots, and manage bots all
|
You can obtain your Zulip API key, create bots, and manage bots all
|
||||||
from your Zulip [settings page](https://zulip.com/#settings).
|
from your Zulip [settings page](https://zulip.com/#settings).
|
||||||
@@ -43,7 +49,7 @@ At the top of the file:
|
|||||||
|
|
||||||
# Make sure the Zulip API distribution's root directory is in sys.path, then:
|
# Make sure the Zulip API distribution's root directory is in sys.path, then:
|
||||||
import zulip
|
import zulip
|
||||||
zulip_client = zulip.Client(email="your-bot@example.com")
|
zulip_client = zulip.Client(email="your-bot@example.com", client="MyTestClient/0.1")
|
||||||
|
|
||||||
When you want to send a message:
|
When you want to send a message:
|
||||||
|
|
||||||
|
|||||||
54
api/examples/create-user
Executable file
54
api/examples/create-user
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright © 2012-2014 Zulip, Inc.
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from os import path
|
||||||
|
import optparse
|
||||||
|
|
||||||
|
usage = """create-user --new-email=<email address> --new-password=<password> --new-full-name=<full name> --new-short-name=<short name> [options]
|
||||||
|
|
||||||
|
Create a user. You must be a realm admin to use this API, and the user
|
||||||
|
will be created in your realm.
|
||||||
|
|
||||||
|
Example: create-user --site=http://localhost:9991 --user=rwbarton@zulip.com --new-email=jarthur@zulip.com --new-password=random17 --new-full-name 'J. Arthur Random' --new-short-name='jarthur'
|
||||||
|
"""
|
||||||
|
|
||||||
|
sys.path.append(path.join(path.dirname(__file__), '..'))
|
||||||
|
import zulip
|
||||||
|
|
||||||
|
parser = optparse.OptionParser(usage=usage)
|
||||||
|
parser.add_option_group(zulip.generate_option_group(parser))
|
||||||
|
parser.add_option('--new-email')
|
||||||
|
parser.add_option('--new-password')
|
||||||
|
parser.add_option('--new-full-name')
|
||||||
|
parser.add_option('--new-short-name')
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
client = zulip.init_from_options(options)
|
||||||
|
|
||||||
|
print client.create_user({
|
||||||
|
'email': options.new_email,
|
||||||
|
'password': options.new_password,
|
||||||
|
'full_name': options.new_full_name,
|
||||||
|
'short_name': options.new_short_name
|
||||||
|
})
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# Two quick API tests using curl
|
|
||||||
|
|
||||||
curl https://api.zulip.com/v1/send_message \
|
|
||||||
-d "api-key=BOT_API_KEY" \
|
|
||||||
-d "email=BOT_EMAIL" \
|
|
||||||
-d "type=private" -d "content=test" \
|
|
||||||
-d "to=RECIPIENT_EMAIL"
|
|
||||||
|
|
||||||
curl https://api.zulip.com/v1/get_messages \
|
|
||||||
-d "api-key=BOT_API_KEY" \
|
|
||||||
-d "email=BOT_EMAIL"
|
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Copyright © 2013 Zulip, Inc.
|
# Copyright © 2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright © 2013 Zulip, Inc.
|
# Copyright © 2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -49,8 +49,7 @@ RESUME_FILE = "/var/tmp/zulip_asana.state"
|
|||||||
# When initially started, how many hours of messages to include.
|
# When initially started, how many hours of messages to include.
|
||||||
ASANA_INITIAL_HISTORY_HOURS = 1
|
ASANA_INITIAL_HISTORY_HOURS = 1
|
||||||
|
|
||||||
# This should not need to change unless you have a custom Zulip
|
# If you're using Zulip Enterprise, set this to your Zulip Enterprise server
|
||||||
# subdomain.
|
|
||||||
ZULIP_SITE = "https://api.zulip.com"
|
ZULIP_SITE = "https://api.zulip.com"
|
||||||
|
|
||||||
# If properly installed, the Zulip API should be in your import
|
# If properly installed, the Zulip API should be in your import
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
# Asana integration for Zulip
|
# Asana integration for Zulip
|
||||||
#
|
#
|
||||||
# Copyright © 2013 Zulip, Inc.
|
# Copyright © 2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -36,6 +36,7 @@ import urllib2
|
|||||||
import sys
|
import sys
|
||||||
sys.path.insert(0, os.path.dirname(__file__))
|
sys.path.insert(0, os.path.dirname(__file__))
|
||||||
import zulip_asana_config as config
|
import zulip_asana_config as config
|
||||||
|
VERSION = "0.9"
|
||||||
|
|
||||||
if config.ZULIP_API_PATH is not None:
|
if config.ZULIP_API_PATH is not None:
|
||||||
sys.path.append(config.ZULIP_API_PATH)
|
sys.path.append(config.ZULIP_API_PATH)
|
||||||
@@ -47,7 +48,7 @@ else:
|
|||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
client = zulip.Client(email=config.ZULIP_USER, api_key=config.ZULIP_API_KEY,
|
client = zulip.Client(email=config.ZULIP_USER, api_key=config.ZULIP_API_KEY,
|
||||||
site=config.ZULIP_SITE)
|
site=config.ZULIP_SITE, client="ZulipAsana/" + VERSION)
|
||||||
|
|
||||||
def fetch_from_asana(path):
|
def fetch_from_asana(path):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright © 2013 Zulip, Inc.
|
# Copyright © 2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -41,7 +41,7 @@ ZULIP_STREAM_NAME = "basecamp"
|
|||||||
## path, but if not, set a custom path below
|
## path, but if not, set a custom path below
|
||||||
ZULIP_API_PATH = None
|
ZULIP_API_PATH = None
|
||||||
|
|
||||||
# This should not need to change unless you have a custom Zulip subdomain.
|
# If you're using Zulip Enterprise, set this to your Zulip Enterprise server
|
||||||
ZULIP_SITE = "https://api.zulip.com"
|
ZULIP_SITE = "https://api.zulip.com"
|
||||||
|
|
||||||
# If you wish to log to a file rather than stdout/stderr,
|
# If you wish to log to a file rather than stdout/stderr,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Zulip mirror of Basecamp activity
|
# Zulip mirror of Basecamp activity
|
||||||
# Copyright © 2013 Zulip, Inc.
|
# Copyright © 2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -37,6 +37,7 @@ from HTMLParser import HTMLParser
|
|||||||
|
|
||||||
sys.path.insert(0, os.path.dirname(__file__))
|
sys.path.insert(0, os.path.dirname(__file__))
|
||||||
import zulip_basecamp_config as config
|
import zulip_basecamp_config as config
|
||||||
|
VERSION = "0.9"
|
||||||
|
|
||||||
if config.ZULIP_API_PATH is not None:
|
if config.ZULIP_API_PATH is not None:
|
||||||
sys.path.append(config.ZULIP_API_PATH)
|
sys.path.append(config.ZULIP_API_PATH)
|
||||||
@@ -46,7 +47,8 @@ import zulip
|
|||||||
client = zulip.Client(
|
client = zulip.Client(
|
||||||
email=config.ZULIP_USER,
|
email=config.ZULIP_USER,
|
||||||
site=config.ZULIP_SITE,
|
site=config.ZULIP_SITE,
|
||||||
api_key=config.ZULIP_API_KEY)
|
api_key=config.ZULIP_API_KEY,
|
||||||
|
client="ZulipBasecamp/" + VERSION)
|
||||||
user_agent = "Basecamp To Zulip Mirroring script (support@zulip.com)"
|
user_agent = "Basecamp To Zulip Mirroring script (support@zulip.com)"
|
||||||
htmlParser = HTMLParser()
|
htmlParser = HTMLParser()
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright © 2013 Zulip, Inc.
|
# Copyright © 2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -50,7 +50,7 @@ ZULIP_TICKETS_STREAM_NAME = "tickets"
|
|||||||
# path, but if not, set a custom path below
|
# path, but if not, set a custom path below
|
||||||
ZULIP_API_PATH = None
|
ZULIP_API_PATH = None
|
||||||
|
|
||||||
# This should not need to change unless you have a custom Zulip subdomain.
|
# If you're using Zulip Enterprise, set this to your Zulip Enterprise server
|
||||||
ZULIP_SITE = "https://api.zulip.com"
|
ZULIP_SITE = "https://api.zulip.com"
|
||||||
|
|
||||||
# If you wish to log to a file rather than stdout/stderr,
|
# If you wish to log to a file rather than stdout/stderr,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Zulip mirror of Codebase HQ activity
|
# Zulip mirror of Codebase HQ activity
|
||||||
# Copyright © 2013 Zulip, Inc.
|
# Copyright © 2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -41,6 +41,7 @@ import dateutil.parser
|
|||||||
|
|
||||||
sys.path.insert(0, os.path.dirname(__file__))
|
sys.path.insert(0, os.path.dirname(__file__))
|
||||||
import zulip_codebase_config as config
|
import zulip_codebase_config as config
|
||||||
|
VERSION = "0.9"
|
||||||
|
|
||||||
if config.ZULIP_API_PATH is not None:
|
if config.ZULIP_API_PATH is not None:
|
||||||
sys.path.append(config.ZULIP_API_PATH)
|
sys.path.append(config.ZULIP_API_PATH)
|
||||||
@@ -49,7 +50,8 @@ import zulip
|
|||||||
client = zulip.Client(
|
client = zulip.Client(
|
||||||
email=config.ZULIP_USER,
|
email=config.ZULIP_USER,
|
||||||
site=config.ZULIP_SITE,
|
site=config.ZULIP_SITE,
|
||||||
api_key=config.ZULIP_API_KEY)
|
api_key=config.ZULIP_API_KEY,
|
||||||
|
client="ZulipCodebase/" + VERSION)
|
||||||
user_agent = "Codebase To Zulip Mirroring script (support@zulip.com)"
|
user_agent = "Codebase To Zulip Mirroring script (support@zulip.com)"
|
||||||
|
|
||||||
# find some form of JSON loader/dumper, with a preference order for speed.
|
# find some form of JSON loader/dumper, with a preference order for speed.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Zulip notification post-receive hook.
|
# Zulip notification post-receive hook.
|
||||||
# Copyright © 2012-2013 Zulip, Inc.
|
# Copyright © 2012-2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -36,6 +36,7 @@ import os.path
|
|||||||
|
|
||||||
sys.path.insert(0, os.path.dirname(__file__))
|
sys.path.insert(0, os.path.dirname(__file__))
|
||||||
import zulip_git_config as config
|
import zulip_git_config as config
|
||||||
|
VERSION = "0.9"
|
||||||
|
|
||||||
if config.ZULIP_API_PATH is not None:
|
if config.ZULIP_API_PATH is not None:
|
||||||
sys.path.append(config.ZULIP_API_PATH)
|
sys.path.append(config.ZULIP_API_PATH)
|
||||||
@@ -44,7 +45,8 @@ import zulip
|
|||||||
client = zulip.Client(
|
client = zulip.Client(
|
||||||
email=config.ZULIP_USER,
|
email=config.ZULIP_USER,
|
||||||
site=config.ZULIP_SITE,
|
site=config.ZULIP_SITE,
|
||||||
api_key=config.ZULIP_API_KEY)
|
api_key=config.ZULIP_API_KEY,
|
||||||
|
client="ZulipGit/" + VERSION)
|
||||||
|
|
||||||
# check_output is backported from subprocess.py in Python 2.7
|
# check_output is backported from subprocess.py in Python 2.7
|
||||||
def check_output(*popenargs, **kwargs):
|
def check_output(*popenargs, **kwargs):
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright © 2013 Zulip, Inc.
|
# Copyright © 2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -39,12 +39,12 @@ ZULIP_API_KEY = "0123456789abcdef0123456789abcdef"
|
|||||||
#
|
#
|
||||||
# The default code below will send every commit pushed to "master" to
|
# The default code below will send every commit pushed to "master" to
|
||||||
# * stream "commits"
|
# * stream "commits"
|
||||||
# * subject "deploy => master" (using a pretty unicode right arrow)
|
# * topic "master"
|
||||||
# And similarly for branch "test-post-receive" (for use when testing).
|
# And similarly for branch "test-post-receive" (for use when testing).
|
||||||
def commit_notice_destination(repo, branch, commit):
|
def commit_notice_destination(repo, branch, commit):
|
||||||
if branch in ["master", "test-post-receive"]:
|
if branch in ["master", "test-post-receive"]:
|
||||||
return dict(stream = "commits",
|
return dict(stream = "commits",
|
||||||
subject = u"deploy \u21D2 %s" % (branch,))
|
subject = u"%s" % (branch,))
|
||||||
|
|
||||||
# Return None for cases where you don't want a notice sent
|
# Return None for cases where you don't want a notice sent
|
||||||
return None
|
return None
|
||||||
@@ -61,5 +61,5 @@ def format_commit_message(author, subject, commit_id):
|
|||||||
## path, but if not, set a custom path below
|
## path, but if not, set a custom path below
|
||||||
ZULIP_API_PATH = None
|
ZULIP_API_PATH = None
|
||||||
|
|
||||||
# This should not need to change unless you have a custom Zulip subdomain.
|
# If you're using Zulip Enterprise, set this to your Zulip Enterprise server
|
||||||
ZULIP_SITE = "https://api.zulip.com"
|
ZULIP_SITE = "https://api.zulip.com"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Zulip hook for Mercurial changeset pushes.
|
# Zulip hook for Mercurial changeset pushes.
|
||||||
# Copyright © 2012-2013 Zulip, Inc.
|
# Copyright © 2012-2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -80,13 +80,14 @@ def format_commit_lines(web_url, repo, base, tip):
|
|||||||
|
|
||||||
return "\n".join(summary for summary in commit_summaries)
|
return "\n".join(summary for summary in commit_summaries)
|
||||||
|
|
||||||
def send_zulip(email, api_key, stream, subject, content):
|
def send_zulip(email, api_key, site, stream, subject, content):
|
||||||
"""
|
"""
|
||||||
Send a message to Zulip using the provided credentials, which should be for
|
Send a message to Zulip using the provided credentials, which should be for
|
||||||
a bot in most cases.
|
a bot in most cases.
|
||||||
"""
|
"""
|
||||||
client = zulip.Client(email=email, api_key=api_key,
|
client = zulip.Client(email=email, api_key=api_key,
|
||||||
client="mercurial " + VERSION)
|
site=site,
|
||||||
|
client="ZulipMercurial/" + VERSION)
|
||||||
|
|
||||||
message_data = {
|
message_data = {
|
||||||
"type": "stream",
|
"type": "stream",
|
||||||
@@ -144,6 +145,7 @@ def hook(ui, repo, **kwargs):
|
|||||||
|
|
||||||
email = get_config(ui, "email")
|
email = get_config(ui, "email")
|
||||||
api_key = get_config(ui, "api_key")
|
api_key = get_config(ui, "api_key")
|
||||||
|
site = get_config(ui, "site")
|
||||||
|
|
||||||
if not (email and api_key):
|
if not (email and api_key):
|
||||||
ui.warn("Zulip: missing email or api_key configurations\n")
|
ui.warn("Zulip: missing email or api_key configurations\n")
|
||||||
@@ -165,4 +167,4 @@ def hook(ui, repo, **kwargs):
|
|||||||
ui.debug("Sending to Zulip:\n")
|
ui.debug("Sending to Zulip:\n")
|
||||||
ui.debug(content + "\n")
|
ui.debug(content + "\n")
|
||||||
|
|
||||||
send_zulip(email, api_key, stream, subject, content)
|
send_zulip(email, api_key, site, stream, subject, content)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013 Zulip, Inc
|
* Copyright (c) 2014 Zulip, Inc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.zulip.jira
|
package org.zulip.jira
|
||||||
@@ -103,6 +103,8 @@ class ZulipListener extends AbstractIssueEventListener {
|
|||||||
String post(String method, NameValuePair[] parameters) {
|
String post(String method, NameValuePair[] parameters) {
|
||||||
PostMethod post = new PostMethod(zulipUrl(method))
|
PostMethod post = new PostMethod(zulipUrl(method))
|
||||||
post.setRequestHeader("Content-Type", post.FORM_URL_ENCODED_CONTENT_TYPE)
|
post.setRequestHeader("Content-Type", post.FORM_URL_ENCODED_CONTENT_TYPE)
|
||||||
|
// TODO: Include more useful data in the User-agent
|
||||||
|
post.setRequestHeader("User-agent", "ZulipJira/0.1")
|
||||||
try {
|
try {
|
||||||
post.setRequestBody(parameters)
|
post.setRequestBody(parameters)
|
||||||
HttpClient client = new HttpClient()
|
HttpClient client = new HttpClient()
|
||||||
@@ -134,7 +136,6 @@ class ZulipListener extends AbstractIssueEventListener {
|
|||||||
String sendStreamMessage(String stream, String subject, String message) {
|
String sendStreamMessage(String stream, String subject, String message) {
|
||||||
NameValuePair[] body = [new NameValuePair("api-key", zulipAPIKey),
|
NameValuePair[] body = [new NameValuePair("api-key", zulipAPIKey),
|
||||||
new NameValuePair("email", zulipEmail),
|
new NameValuePair("email", zulipEmail),
|
||||||
new NameValuePair("client", "jira-groovy"),
|
|
||||||
new NameValuePair("type", "stream"),
|
new NameValuePair("type", "stream"),
|
||||||
new NameValuePair("to", stream),
|
new NameValuePair("to", stream),
|
||||||
new NameValuePair("subject", subject),
|
new NameValuePair("subject", subject),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import optparse
|
import optparse
|
||||||
import zulip
|
import zulip
|
||||||
|
|
||||||
|
VERSION = "0.9"
|
||||||
# Nagios passes the notification details as command line options.
|
# Nagios passes the notification details as command line options.
|
||||||
# In Nagios, "output" means "first line of output", and "long
|
# In Nagios, "output" means "first line of output", and "long
|
||||||
# output" means "other lines of output".
|
# output" means "other lines of output".
|
||||||
@@ -14,7 +15,7 @@ for opt in ('type', 'host', 'service', 'state'):
|
|||||||
parser.add_option('--' + opt)
|
parser.add_option('--' + opt)
|
||||||
(opts, args) = parser.parse_args()
|
(opts, args) = parser.parse_args()
|
||||||
|
|
||||||
client = zulip.Client(config_file=opts.config)
|
client = zulip.Client(config_file=opts.config, client="ZulipNagios/" + VERSION)
|
||||||
|
|
||||||
msg = dict(type='stream', to=opts.stream)
|
msg = dict(type='stream', to=opts.stream)
|
||||||
|
|
||||||
|
|||||||
3266
api/integrations/perforce/git_p4.py
Normal file
3266
api/integrations/perforce/git_p4.py
Normal file
File diff suppressed because it is too large
Load Diff
26
api/integrations/perforce/license.txt
Normal file
26
api/integrations/perforce/license.txt
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
git_p4.py was downloaded from https://raw.github.com/git/git/34022ba/git-p4.py
|
||||||
|
|
||||||
|
The header of that file references <http://opensource.org/licenses/mit-license.php>,
|
||||||
|
the textual contents of which are included below.
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) <year> <copyright holders>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
88
api/integrations/perforce/zulip_change-commit.py
Executable file
88
api/integrations/perforce/zulip_change-commit.py
Executable file
@@ -0,0 +1,88 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright © 2012-2014 Zulip, Inc.
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
'''Zulip notification change-commit hook.
|
||||||
|
|
||||||
|
In Perforce, The "change-commit" trigger is fired after a metadata has been
|
||||||
|
created, files have been transferred, and the changelist comitted to the depot
|
||||||
|
database.
|
||||||
|
|
||||||
|
This specific trigger expects command-line arguments in the form:
|
||||||
|
%change% %changeroot%
|
||||||
|
|
||||||
|
For example:
|
||||||
|
1234 //depot/security/src/
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
import git_p4
|
||||||
|
|
||||||
|
__version__ = "0.1"
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.dirname(__file__))
|
||||||
|
import zulip_perforce_config as config
|
||||||
|
|
||||||
|
if config.ZULIP_API_PATH is not None:
|
||||||
|
sys.path.append(config.ZULIP_API_PATH)
|
||||||
|
|
||||||
|
import zulip
|
||||||
|
client = zulip.Client(
|
||||||
|
email=config.ZULIP_USER,
|
||||||
|
site=config.ZULIP_SITE,
|
||||||
|
api_key=config.ZULIP_API_KEY,
|
||||||
|
client="ZulipPerforce/" + __version__)
|
||||||
|
|
||||||
|
try:
|
||||||
|
changelist = int(sys.argv[1])
|
||||||
|
changeroot = sys.argv[2]
|
||||||
|
except IndexError:
|
||||||
|
print >> sys.stderr, "Wrong number of arguments.\n\n",
|
||||||
|
print >> sys.stderr, __doc__
|
||||||
|
sys.exit(-1)
|
||||||
|
except ValueError:
|
||||||
|
print >> sys.stderr, "First argument must be an integer.\n\n",
|
||||||
|
print >> sys.stderr, __doc__
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
metadata = git_p4.p4_describe(changelist)
|
||||||
|
|
||||||
|
destination = config.commit_notice_destination(changeroot, changelist)
|
||||||
|
if destination is None:
|
||||||
|
# Don't forward the notice anywhere
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
message = """**{0}** committed revision @{1} to `{2}`.
|
||||||
|
|
||||||
|
> {3}
|
||||||
|
""".format(metadata["user"], metadata["change"], changeroot, metadata["desc"])
|
||||||
|
|
||||||
|
message_data = {
|
||||||
|
"type": "stream",
|
||||||
|
"to": destination["stream"],
|
||||||
|
"subject": destination["subject"],
|
||||||
|
"content": message,
|
||||||
|
}
|
||||||
|
client.send_message(message_data)
|
||||||
63
api/integrations/perforce/zulip_perforce_config.py
Normal file
63
api/integrations/perforce/zulip_perforce_config.py
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright © 2014 Zulip, Inc.
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
# Change these values to configure authentication for the plugin
|
||||||
|
ZULIP_USER = "p4-bot@example.com"
|
||||||
|
ZULIP_API_KEY = "0123456789abcdef0123456789abcdef"
|
||||||
|
|
||||||
|
# commit_notice_destination() lets you customize where commit notices
|
||||||
|
# are sent to with the full power of a Python function.
|
||||||
|
#
|
||||||
|
# It takes the following arguments:
|
||||||
|
# * path = the path to the Perforce depot on the server
|
||||||
|
# * changelist = the changelist id
|
||||||
|
#
|
||||||
|
# Returns a dictionary encoding the stream and topic to send the
|
||||||
|
# notification to (or None to send no notification).
|
||||||
|
#
|
||||||
|
# The default code below will send every commit except for ones in the
|
||||||
|
# "master-plan" and "secret" subdirectories of //depot/ to:
|
||||||
|
# * stream "depot_subdirectory-commits"
|
||||||
|
# * subject "change_root"
|
||||||
|
def commit_notice_destination(path, changelist):
|
||||||
|
dirs = path.split('/')
|
||||||
|
if len(dirs) >= 4 and dirs[3] not in ("*", "..."):
|
||||||
|
directory = dirs[3]
|
||||||
|
else:
|
||||||
|
# No subdirectory, so just use "depot"
|
||||||
|
directory = dirs[2]
|
||||||
|
|
||||||
|
if directory not in ["evil-master-plan", "my-super-secret-repository"]:
|
||||||
|
return dict(stream = "%s-commits" % (directory,),
|
||||||
|
subject = path)
|
||||||
|
|
||||||
|
# Return None for cases where you don't want a notice sent
|
||||||
|
return None
|
||||||
|
|
||||||
|
## If properly installed, the Zulip API should be in your import
|
||||||
|
## path, but if not, set a custom path below
|
||||||
|
ZULIP_API_PATH = None
|
||||||
|
|
||||||
|
# This should not need to change unless you have a custom Zulip subdomain.
|
||||||
|
ZULIP_SITE = "https://api.zulip.com"
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
# RSS integration for Zulip
|
# RSS integration for Zulip
|
||||||
#
|
#
|
||||||
# Copyright © 2013 Zulip, Inc.
|
# Copyright © 2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -36,7 +36,7 @@ import urlparse
|
|||||||
|
|
||||||
import feedparser
|
import feedparser
|
||||||
import zulip
|
import zulip
|
||||||
|
VERSION = "0.9"
|
||||||
RSS_DATA_DIR = os.path.expanduser(os.path.join('~', '.cache', 'zulip-rss'))
|
RSS_DATA_DIR = os.path.expanduser(os.path.join('~', '.cache', 'zulip-rss'))
|
||||||
OLDNESS_THRESHOLD = 30 # days
|
OLDNESS_THRESHOLD = 30 # days
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ To use this script:
|
|||||||
1. Create an RSS feed file containing 1 feed URL per line (default feed
|
1. Create an RSS feed file containing 1 feed URL per line (default feed
|
||||||
file location: ~/.cache/zulip-rss/rss-feeds)
|
file location: ~/.cache/zulip-rss/rss-feeds)
|
||||||
2. Subscribe to the stream that will receive RSS updates (default stream: rss)
|
2. Subscribe to the stream that will receive RSS updates (default stream: rss)
|
||||||
3. create a ~/.zuliprc, or specify user and api-key with command line arguments
|
3. create a ~/.zuliprc as described on https://zulip.com/api#api_keys
|
||||||
4. Test the script by running it manually, like this:
|
4. Test the script by running it manually, like this:
|
||||||
|
|
||||||
/usr/local/share/zulip/integrations/rss/rss-bot
|
/usr/local/share/zulip/integrations/rss/rss-bot
|
||||||
@@ -164,7 +164,7 @@ except IOError:
|
|||||||
log_error_and_exit("Unable to read feed file at %s." % (opts.feed_file,))
|
log_error_and_exit("Unable to read feed file at %s." % (opts.feed_file,))
|
||||||
|
|
||||||
client = zulip.Client(email=opts.email, api_key=opts.api_key,
|
client = zulip.Client(email=opts.email, api_key=opts.api_key,
|
||||||
site=opts.site)
|
site=opts.site, client="ZulipRSS/" + VERSION)
|
||||||
|
|
||||||
first_message = True
|
first_message = True
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Zulip notification post-commit hook.
|
# Zulip notification post-commit hook.
|
||||||
# Copyright © 2012-2013 Zulip, Inc.
|
# Copyright © 2012-2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -36,6 +36,7 @@ import pysvn
|
|||||||
|
|
||||||
sys.path.insert(0, os.path.dirname(__file__))
|
sys.path.insert(0, os.path.dirname(__file__))
|
||||||
import zulip_svn_config as config
|
import zulip_svn_config as config
|
||||||
|
VERSION = "0.9"
|
||||||
|
|
||||||
if config.ZULIP_API_PATH is not None:
|
if config.ZULIP_API_PATH is not None:
|
||||||
sys.path.append(config.ZULIP_API_PATH)
|
sys.path.append(config.ZULIP_API_PATH)
|
||||||
@@ -44,7 +45,8 @@ import zulip
|
|||||||
client = zulip.Client(
|
client = zulip.Client(
|
||||||
email=config.ZULIP_USER,
|
email=config.ZULIP_USER,
|
||||||
site=config.ZULIP_SITE,
|
site=config.ZULIP_SITE,
|
||||||
api_key=config.ZULIP_API_KEY)
|
api_key=config.ZULIP_API_KEY,
|
||||||
|
client="ZulipSVN/" + VERSION)
|
||||||
svn = pysvn.Client()
|
svn = pysvn.Client()
|
||||||
|
|
||||||
path, rev = sys.argv[1:]
|
path, rev = sys.argv[1:]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright © 2013 Zulip, Inc.
|
# Copyright © 2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -36,15 +36,15 @@ ZULIP_API_KEY = "0123456789abcdef0123456789abcdef"
|
|||||||
# Returns a dictionary encoding the stream and subject to send the
|
# Returns a dictionary encoding the stream and subject to send the
|
||||||
# notification to (or None to send no notification).
|
# notification to (or None to send no notification).
|
||||||
#
|
#
|
||||||
# The default code below will send every commit except for the "master-plan"
|
# The default code below will send every commit except for the "evil-master-plan"
|
||||||
# and "secret" repos to
|
# and "my-super-secret-repository" repos to
|
||||||
# * stream "commits"
|
# * stream "commits"
|
||||||
# * subject "deploy => branch_name" (using a pretty unicode right arrow)
|
# * topic "branch_name"
|
||||||
def commit_notice_destination(path, commit):
|
def commit_notice_destination(path, commit):
|
||||||
repo = path.split('/')[-1]
|
repo = path.split('/')[-1]
|
||||||
if repo not in ["evil-master-plan", "my-super-secret-repository"]:
|
if repo not in ["evil-master-plan", "my-super-secret-repository"]:
|
||||||
return dict(stream = "commits",
|
return dict(stream = "commits",
|
||||||
subject = u"deploy \u21D2 %s" % (repo,))
|
subject = u"%s" % (repo,))
|
||||||
|
|
||||||
# Return None for cases where you don't want a notice sent
|
# Return None for cases where you don't want a notice sent
|
||||||
return None
|
return None
|
||||||
@@ -53,5 +53,5 @@ def commit_notice_destination(path, commit):
|
|||||||
## path, but if not, set a custom path below
|
## path, but if not, set a custom path below
|
||||||
ZULIP_API_PATH = None
|
ZULIP_API_PATH = None
|
||||||
|
|
||||||
# This should not need to change unless you have a custom Zulip subdomain.
|
# If you're using Zulip Enterprise, set this to your Zulip Enterprise server
|
||||||
ZULIP_SITE = "https://api.zulip.com"
|
ZULIP_SITE = "https://api.zulip.com"
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import sys
|
|||||||
import os.path
|
import os.path
|
||||||
sys.path.insert(0, os.path.dirname(__file__))
|
sys.path.insert(0, os.path.dirname(__file__))
|
||||||
import zulip_trac_config as config
|
import zulip_trac_config as config
|
||||||
|
VERSION = "0.9"
|
||||||
|
|
||||||
if config.ZULIP_API_PATH is not None:
|
if config.ZULIP_API_PATH is not None:
|
||||||
sys.path.append(config.ZULIP_API_PATH)
|
sys.path.append(config.ZULIP_API_PATH)
|
||||||
@@ -48,7 +49,8 @@ import zulip
|
|||||||
client = zulip.Client(
|
client = zulip.Client(
|
||||||
email=config.ZULIP_USER,
|
email=config.ZULIP_USER,
|
||||||
site=config.ZULIP_SITE,
|
site=config.ZULIP_SITE,
|
||||||
api_key=config.ZULIP_API_KEY)
|
api_key=config.ZULIP_API_KEY,
|
||||||
|
client="ZulipTrac/" + VERSION)
|
||||||
|
|
||||||
def markdown_ticket_url(ticket, heading="ticket"):
|
def markdown_ticket_url(ticket, heading="ticket"):
|
||||||
return "[%s #%s](%s/%s)" % (heading, ticket.id, config.TRAC_BASE_TICKET_URL, ticket.id)
|
return "[%s #%s](%s/%s)" % (heading, ticket.id, config.TRAC_BASE_TICKET_URL, ticket.id)
|
||||||
|
|||||||
@@ -47,5 +47,5 @@ TRAC_NOTIFY_FIELDS = ["description", "summary", "resolution", "comment", "owner"
|
|||||||
## path, but if not, set a custom path below
|
## path, but if not, set a custom path below
|
||||||
ZULIP_API_PATH = None
|
ZULIP_API_PATH = None
|
||||||
|
|
||||||
# This should not need to change unless you have a custom Zulip subdomain.
|
# If you're using Zulip Enterprise, set this to your Zulip Enterprise server
|
||||||
ZULIP_SITE = "https://api.zulip.com"
|
ZULIP_SITE = "https://api.zulip.com"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
# Twitter integration for Zulip
|
# Twitter integration for Zulip
|
||||||
#
|
#
|
||||||
# Copyright © 2013 Zulip, Inc.
|
# Copyright © 2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -29,7 +29,7 @@ import optparse
|
|||||||
import ConfigParser
|
import ConfigParser
|
||||||
|
|
||||||
import zulip
|
import zulip
|
||||||
|
VERSION = "0.9"
|
||||||
CONFIGFILE = os.path.expanduser("~/.zulip_twitterrc")
|
CONFIGFILE = os.path.expanduser("~/.zulip_twitterrc")
|
||||||
|
|
||||||
def write_config(config, since_id, user):
|
def write_config(config, since_id, user):
|
||||||
@@ -129,6 +129,7 @@ client = zulip.Client(
|
|||||||
email=options.email,
|
email=options.email,
|
||||||
api_key=options.api_key,
|
api_key=options.api_key,
|
||||||
site=options.site,
|
site=options.site,
|
||||||
|
client="ZulipTwitter/" + VERSION,
|
||||||
verbose=True)
|
verbose=True)
|
||||||
|
|
||||||
if since_id < 0 or options.twitter_id != user_id:
|
if since_id < 0 or options.twitter_id != user_id:
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
# Twitter search integration for Zulip
|
# Twitter search integration for Zulip
|
||||||
#
|
#
|
||||||
# Copyright © 2013 Zulip, Inc.
|
# Copyright © 2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -29,7 +29,7 @@ import optparse
|
|||||||
import ConfigParser
|
import ConfigParser
|
||||||
|
|
||||||
import zulip
|
import zulip
|
||||||
|
VERSION = "0.9"
|
||||||
CONFIGFILE = os.path.expanduser("~/.zulip_twitterrc")
|
CONFIGFILE = os.path.expanduser("~/.zulip_twitterrc")
|
||||||
|
|
||||||
def write_config(config, since_id):
|
def write_config(config, since_id):
|
||||||
@@ -146,6 +146,7 @@ client = zulip.Client(
|
|||||||
email=opts.email,
|
email=opts.email,
|
||||||
api_key=opts.api_key,
|
api_key=opts.api_key,
|
||||||
site=opts.site,
|
site=opts.site,
|
||||||
|
client="ZulipTwitterSearch/" + VERSION,
|
||||||
verbose=True)
|
verbose=True)
|
||||||
|
|
||||||
search_query = " OR ".join(opts.search_terms.split(","))
|
search_query = " OR ".join(opts.search_terms.split(","))
|
||||||
|
|||||||
3
api/setup.cfg
Normal file
3
api/setup.cfg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# This way our scripts are installed in the data directory
|
||||||
|
[aliases]
|
||||||
|
install = install_data install
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Copyright © 2012-2013 Zulip, Inc.
|
# Copyright © 2012-2014 Zulip, Inc.
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -28,13 +28,14 @@ import urlparse
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import optparse
|
import optparse
|
||||||
|
import platform
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
|
|
||||||
from ConfigParser import SafeConfigParser
|
from ConfigParser import SafeConfigParser
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|
||||||
__version__ = "0.2.2"
|
__version__ = "0.2.4"
|
||||||
|
|
||||||
# Check that we have a recent enough version
|
# Check that we have a recent enough version
|
||||||
# Older versions don't provide the 'json' attribute on responses.
|
# Older versions don't provide the 'json' attribute on responses.
|
||||||
@@ -44,11 +45,14 @@ requests_json_is_function = callable(requests.Response.json)
|
|||||||
|
|
||||||
API_VERSTRING = "v1/"
|
API_VERSTRING = "v1/"
|
||||||
|
|
||||||
|
def _default_client():
|
||||||
|
return "ZulipPython/" + __version__
|
||||||
|
|
||||||
def generate_option_group(parser):
|
def generate_option_group(parser):
|
||||||
group = optparse.OptionGroup(parser, 'API configuration')
|
group = optparse.OptionGroup(parser, 'API configuration')
|
||||||
group.add_option('--site',
|
group.add_option('--site',
|
||||||
default=None,
|
help="Zulip Enterprise server URI (if using Zulip Enterprise)",
|
||||||
help=optparse.SUPPRESS_HELP)
|
default=None)
|
||||||
group.add_option('--api-key',
|
group.add_option('--api-key',
|
||||||
action='store')
|
action='store')
|
||||||
group.add_option('--user',
|
group.add_option('--user',
|
||||||
@@ -62,19 +66,25 @@ def generate_option_group(parser):
|
|||||||
help='Provide detailed output.')
|
help='Provide detailed output.')
|
||||||
group.add_option('--client',
|
group.add_option('--client',
|
||||||
action='store',
|
action='store',
|
||||||
default="API: Python",
|
default=None,
|
||||||
help=optparse.SUPPRESS_HELP)
|
help=optparse.SUPPRESS_HELP)
|
||||||
|
|
||||||
return group
|
return group
|
||||||
|
|
||||||
def init_from_options(options):
|
def init_from_options(options, client=None):
|
||||||
return Client(email=options.email, api_key=options.api_key, config_file=options.config_file,
|
if options.client is not None:
|
||||||
verbose=options.verbose, site=options.site, client=options.client)
|
client = options.client
|
||||||
|
elif client is None:
|
||||||
|
client = _default_client()
|
||||||
|
return Client(email=options.email, api_key=options.api_key,
|
||||||
|
config_file=options.config_file, verbose=options.verbose,
|
||||||
|
site=options.site, client=client)
|
||||||
|
|
||||||
class Client(object):
|
class Client(object):
|
||||||
def __init__(self, email=None, api_key=None, config_file=None,
|
def __init__(self, email=None, api_key=None, config_file=None,
|
||||||
verbose=False, retry_on_errors=True,
|
verbose=False, retry_on_errors=True,
|
||||||
site=None, client="API: Python"):
|
site=None, client=None):
|
||||||
|
if client is None:
|
||||||
|
client = _default_client()
|
||||||
if None in (api_key, email):
|
if None in (api_key, email):
|
||||||
if config_file is None:
|
if config_file is None:
|
||||||
config_file = os.path.join(os.environ["HOME"], ".zuliprc")
|
config_file = os.path.join(os.environ["HOME"], ".zuliprc")
|
||||||
@@ -112,9 +122,25 @@ class Client(object):
|
|||||||
self.retry_on_errors = retry_on_errors
|
self.retry_on_errors = retry_on_errors
|
||||||
self.client_name = client
|
self.client_name = client
|
||||||
|
|
||||||
|
def get_user_agent(self):
|
||||||
|
vendor = platform.system()
|
||||||
|
vendor_version = platform.release()
|
||||||
|
|
||||||
|
if vendor == "Linux":
|
||||||
|
vendor, vendor_version, dummy = platform.linux_distribution()
|
||||||
|
elif vendor == "Windows":
|
||||||
|
vendor_version = platform.win32_ver()[1]
|
||||||
|
elif vendor == "Darwin":
|
||||||
|
vendor_version = platform.mac_ver()[0]
|
||||||
|
|
||||||
|
return "{client_name} ({vendor}; {vendor_version})".format(
|
||||||
|
client_name=self.client_name,
|
||||||
|
vendor=vendor,
|
||||||
|
vendor_version=vendor_version,
|
||||||
|
)
|
||||||
|
|
||||||
def do_api_query(self, orig_request, url, method="POST", longpolling = False):
|
def do_api_query(self, orig_request, url, method="POST", longpolling = False):
|
||||||
request = {}
|
request = {}
|
||||||
request["client"] = self.client_name
|
|
||||||
|
|
||||||
for (key, val) in orig_request.iteritems():
|
for (key, val) in orig_request.iteritems():
|
||||||
if not (isinstance(val, str) or isinstance(val, unicode)):
|
if not (isinstance(val, str) or isinstance(val, unicode)):
|
||||||
@@ -164,6 +190,7 @@ class Client(object):
|
|||||||
auth=requests.auth.HTTPBasicAuth(self.email,
|
auth=requests.auth.HTTPBasicAuth(self.email,
|
||||||
self.api_key),
|
self.api_key),
|
||||||
verify=True, timeout=90,
|
verify=True, timeout=90,
|
||||||
|
headers={"User-agent": self.get_user_agent()},
|
||||||
**kwargs)
|
**kwargs)
|
||||||
|
|
||||||
# On 50x errors, try again after a short sleep
|
# On 50x errors, try again after a short sleep
|
||||||
@@ -223,13 +250,13 @@ class Client(object):
|
|||||||
call.func_name = name
|
call.func_name = name
|
||||||
setattr(cls, name, call)
|
setattr(cls, name, call)
|
||||||
|
|
||||||
def call_on_each_event(self, callback, event_types=None):
|
def call_on_each_event(self, callback, event_types=None, narrow=[]):
|
||||||
def do_register():
|
def do_register():
|
||||||
while True:
|
while True:
|
||||||
if event_types is None:
|
if event_types is None:
|
||||||
res = self.register()
|
res = self.register()
|
||||||
else:
|
else:
|
||||||
res = self.register(event_types=event_types)
|
res = self.register(event_types=event_types, narrow=narrow)
|
||||||
|
|
||||||
if 'error' in res.get('result'):
|
if 'error' in res.get('result'):
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
@@ -291,10 +318,10 @@ def _mk_rm_subs(streams):
|
|||||||
def _mk_deregister(queue_id):
|
def _mk_deregister(queue_id):
|
||||||
return {'queue_id': queue_id}
|
return {'queue_id': queue_id}
|
||||||
|
|
||||||
def _mk_events(event_types=None):
|
def _mk_events(event_types=None, narrow=[]):
|
||||||
if event_types is None:
|
if event_types is None:
|
||||||
return dict()
|
return dict()
|
||||||
return dict(event_types=event_types)
|
return dict(event_types=event_types, narrow=narrow)
|
||||||
|
|
||||||
def _kwargs_to_dict(**kwargs):
|
def _kwargs_to_dict(**kwargs):
|
||||||
return kwargs
|
return kwargs
|
||||||
@@ -333,3 +360,4 @@ Client._register('list_subscriptions', method='GET', url='users/me/subscriptions
|
|||||||
Client._register('add_subscriptions', url='users/me/subscriptions', make_request=_mk_subs)
|
Client._register('add_subscriptions', url='users/me/subscriptions', make_request=_mk_subs)
|
||||||
Client._register('remove_subscriptions', method='PATCH', url='users/me/subscriptions', make_request=_mk_rm_subs)
|
Client._register('remove_subscriptions', method='PATCH', url='users/me/subscriptions', make_request=_mk_rm_subs)
|
||||||
Client._register('render_message', method='GET', url='messages/render')
|
Client._register('render_message', method='GET', url='messages/render')
|
||||||
|
Client._register('create_user', method='POST', url='users')
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ zulip_client = zulip.Client(
|
|||||||
email=zulip_user,
|
email=zulip_user,
|
||||||
api_key="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
api_key="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||||
verbose=True,
|
verbose=True,
|
||||||
client="test: Zulip monitoring",
|
client="ZulipMonitoring/0.1",
|
||||||
site=options.site)
|
site=options.site)
|
||||||
|
|
||||||
# Configure logging
|
# Configure logging
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import time
|
|||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
WARN_THRESHOLD = 50
|
WARN_THRESHOLD = 10
|
||||||
CRIT_THRESHOLD = 100
|
CRIT_THRESHOLD = 50
|
||||||
|
|
||||||
states = {
|
states = {
|
||||||
0: "OK",
|
0: "OK",
|
||||||
@@ -45,6 +45,16 @@ for line in output.split("\n"):
|
|||||||
|
|
||||||
warn_about = ", ".join(warn_queues)
|
warn_about = ", ".join(warn_queues)
|
||||||
now = int(time.time())
|
now = int(time.time())
|
||||||
|
now_struct = time.gmtime(now)
|
||||||
|
|
||||||
|
# While we are sending digest emails, at 11am each weekday, the mail queues can
|
||||||
|
# get backed up; don't alert on those.
|
||||||
|
if not set(warn_queues) - set(("missedmessage_emails", "digest_emails")) and \
|
||||||
|
now_struct.tm_hour == 16 and now_struct.tm_min < 15:
|
||||||
|
status = 0
|
||||||
|
print("%s|%s|%s|processing digests, not alerting on elevated mail queues" % (
|
||||||
|
now, status, states[status]))
|
||||||
|
exit(0)
|
||||||
|
|
||||||
if status > 0:
|
if status > 0:
|
||||||
print("%s|%s|%s|max count %s, queues affected: %s" % (now, status, states[status], max_count, warn_about))
|
print("%s|%s|%s|max count %s, queues affected: %s" % (now, status, states[status], max_count, warn_about))
|
||||||
|
|||||||
103
bots/log2zulip
Executable file
103
bots/log2zulip
Executable file
@@ -0,0 +1,103 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
import subprocess
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import shutil
|
||||||
|
import errno
|
||||||
|
import json
|
||||||
|
import ujson
|
||||||
|
import platform
|
||||||
|
import re
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../api"))
|
||||||
|
import zulip
|
||||||
|
|
||||||
|
lock_path = "/var/tmp/log2zulip.lock"
|
||||||
|
control_path = "/etc/log2zulip.conf"
|
||||||
|
|
||||||
|
def mkdir_p(path):
|
||||||
|
# Python doesn't have an analog to `mkdir -p` < Python 3.2.
|
||||||
|
try:
|
||||||
|
os.makedirs(path)
|
||||||
|
except OSError, e:
|
||||||
|
if e.errno == errno.EEXIST and os.path.isdir(path):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
|
def send_log_zulip(file_name, count, lines, extra=""):
|
||||||
|
content = "%s new errors%s:\n```\n%s\n```" % (count, extra, "\n".join(lines))
|
||||||
|
zulip_client.send_message({
|
||||||
|
"type": "stream",
|
||||||
|
"to": "logs",
|
||||||
|
"subject": "%s on %s" % (file_name, platform.node()),
|
||||||
|
"content": content,
|
||||||
|
})
|
||||||
|
|
||||||
|
def process_lines(raw_lines, file_name):
|
||||||
|
lines = []
|
||||||
|
for line in raw_lines:
|
||||||
|
# Add any filtering or modification code here
|
||||||
|
if re.match(".*upstream timed out.*while reading upstream.*", line):
|
||||||
|
continue
|
||||||
|
lines.append(line)
|
||||||
|
|
||||||
|
if len(lines) == 0:
|
||||||
|
return
|
||||||
|
elif len(lines) > 10:
|
||||||
|
send_log_zulip(file_name, len(lines), lines[0:3], extra=", examples include")
|
||||||
|
else:
|
||||||
|
send_log_zulip(file_name, len(lines), lines)
|
||||||
|
|
||||||
|
def process_logs():
|
||||||
|
for filename in log_files:
|
||||||
|
data_file_path = "/var/tmp/log2zulip.state"
|
||||||
|
mkdir_p(os.path.dirname(data_file_path))
|
||||||
|
if not os.path.exists(data_file_path):
|
||||||
|
file(data_file_path, "w").write("{}")
|
||||||
|
last_data = ujson.loads(file(data_file_path).read())
|
||||||
|
new_data = {}
|
||||||
|
for log_file in log_files:
|
||||||
|
file_data = last_data.get(log_file, {})
|
||||||
|
if not os.path.exists(log_file):
|
||||||
|
# If the file doesn't exist, log an error and then move on to the next file
|
||||||
|
print "Log file %s does not exist!" % (log_file,)
|
||||||
|
continue
|
||||||
|
length = int(subprocess.check_output(["wc", "-l", log_file]).split()[0])
|
||||||
|
if file_data.get("last") is None:
|
||||||
|
file_data["last"] = 1
|
||||||
|
if length + 1 < file_data["last"]:
|
||||||
|
# The log file was rotated, restart from empty. Note that
|
||||||
|
# because we don't actually store the log file content, if
|
||||||
|
# a log file ends up at the same line length as before
|
||||||
|
# immediately after rotation, this tool won't notice.
|
||||||
|
file_data["last"] = 1
|
||||||
|
new_lines = subprocess.check_output(["tail", "-n+%s" % (file_data["last"],), log_file]).split('\n')[:-1]
|
||||||
|
if len(new_lines) > 0:
|
||||||
|
process_lines(new_lines, filename)
|
||||||
|
file_data["last"] += len(new_lines)
|
||||||
|
new_data[log_file] = file_data
|
||||||
|
file(data_file_path, "w").write(ujson.dumps(new_data))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if os.path.exists(lock_path):
|
||||||
|
print "Log2zulip lock held; not doing anything"
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
file(lock_path, "w").write("1")
|
||||||
|
zulip_client = zulip.Client(config_file="/etc/log2zulip.zuliprc")
|
||||||
|
try:
|
||||||
|
log_files = ujson.loads(file(control_path, "r").read())
|
||||||
|
except Exception:
|
||||||
|
print "Could not load control data from %s" % (control_path,)
|
||||||
|
traceback.print_exc()
|
||||||
|
sys.exit(1)
|
||||||
|
process_logs()
|
||||||
|
finally:
|
||||||
|
try:
|
||||||
|
os.remove(lock_path)
|
||||||
|
except OSError, IOError:
|
||||||
|
pass
|
||||||
|
|
||||||
79
bots/summarize_stream.py
Normal file
79
bots/summarize_stream.py
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
# This is hacky code to analyze data on our support stream. The main
|
||||||
|
# reusable bits are get_recent_messages and get_words.
|
||||||
|
|
||||||
|
import zulip
|
||||||
|
import re
|
||||||
|
import collections
|
||||||
|
|
||||||
|
def get_recent_messages(client, narrow, count=100):
|
||||||
|
narrow = [word.split(':') for word in narrow.split()]
|
||||||
|
req = {
|
||||||
|
'narrow': narrow,
|
||||||
|
'num_before': count,
|
||||||
|
'num_after': 0,
|
||||||
|
'anchor': 1000000000,
|
||||||
|
'apply_markdown': False
|
||||||
|
}
|
||||||
|
old_messages = client.do_api_query(req, zulip.API_VERSTRING + 'messages', method='GET')
|
||||||
|
if 'messages' not in old_messages:
|
||||||
|
return []
|
||||||
|
return old_messages['messages']
|
||||||
|
|
||||||
|
def get_words(content):
|
||||||
|
regex = "[A-Z]{2,}(?![a-z])|[A-Z][a-z]+(?=[A-Z])|[\'\w\-]+"
|
||||||
|
words = re.findall(regex, content, re.M)
|
||||||
|
words = [w.lower() for w in words]
|
||||||
|
# words = [w.rstrip('s') for w in words]
|
||||||
|
return words
|
||||||
|
|
||||||
|
def analyze_messages(msgs, word_count, email_count):
|
||||||
|
for msg in msgs:
|
||||||
|
if False:
|
||||||
|
if ' ack' in msg['content']:
|
||||||
|
name = msg['sender_full_name'].split()[0]
|
||||||
|
print 'ACK', name
|
||||||
|
m = re.search('ticket (Z....).*email: (\S+).*~~~(.*)', msg['content'], re.M | re.S)
|
||||||
|
if m:
|
||||||
|
ticket, email, req = m.groups()
|
||||||
|
words = get_words(req)
|
||||||
|
for word in words:
|
||||||
|
word_count[word] += 1
|
||||||
|
email_count[email] += 1
|
||||||
|
if False:
|
||||||
|
print
|
||||||
|
for k, v in msg.items():
|
||||||
|
print '%-20s: %s' % (k, v)
|
||||||
|
|
||||||
|
def generate_support_stats():
|
||||||
|
client = zulip.Client()
|
||||||
|
narrow = 'stream:support'
|
||||||
|
count = 2000
|
||||||
|
msgs = get_recent_messages(client, narrow, count)
|
||||||
|
msgs_by_topic = collections.defaultdict(list)
|
||||||
|
for msg in msgs:
|
||||||
|
topic = msg['subject']
|
||||||
|
msgs_by_topic[topic].append(msg)
|
||||||
|
|
||||||
|
word_count = collections.defaultdict(int)
|
||||||
|
email_count = collections.defaultdict(int)
|
||||||
|
|
||||||
|
if False:
|
||||||
|
for topic in msgs_by_topic:
|
||||||
|
msgs = msgs_by_topic[topic]
|
||||||
|
analyze_messages(msgs, word_count, email_count)
|
||||||
|
|
||||||
|
if True:
|
||||||
|
words = word_count.keys()
|
||||||
|
words = filter(lambda w: word_count[w] >= 10, words)
|
||||||
|
words = filter(lambda w: len(w) >= 5, words)
|
||||||
|
words = sorted(words, key=lambda w: word_count[w], reverse=True)
|
||||||
|
for word in words:
|
||||||
|
print word, word_count[word]
|
||||||
|
|
||||||
|
if False:
|
||||||
|
emails = email_count.keys()
|
||||||
|
emails = sorted(emails, key=lambda w: email_count[w], reverse=True)
|
||||||
|
for email in emails:
|
||||||
|
print email, email_count[email]
|
||||||
|
|
||||||
|
generate_support_stats()
|
||||||
@@ -10,7 +10,7 @@ import unicodedata
|
|||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'api'))
|
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'api'))
|
||||||
import zulip
|
import zulip
|
||||||
|
|
||||||
zulip_client = zulip.Client()
|
zulip_client = zulip.Client(client="ZulipSyncPublicStreamsBot/0.1")
|
||||||
|
|
||||||
def fetch_public_streams():
|
def fetch_public_streams():
|
||||||
public_streams = set()
|
public_streams = set()
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ sys.path.append(zulip_directory)
|
|||||||
import zulip
|
import zulip
|
||||||
|
|
||||||
client = zulip.Client(
|
client = zulip.Client(
|
||||||
|
client = "ZulipTddiumNotifier/0.1",
|
||||||
email = os.environ['ZULIP_USER'],
|
email = os.environ['ZULIP_USER'],
|
||||||
api_key = os.environ.get('ZULIP_API_KEY'))
|
api_key = os.environ.get('ZULIP_API_KEY'))
|
||||||
|
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ ZULIP_API_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|||||||
#
|
#
|
||||||
# The default code below will send every commit pushed to "master" to
|
# The default code below will send every commit pushed to "master" to
|
||||||
# * stream "commits"
|
# * stream "commits"
|
||||||
# * subject "deploy => master" (using a pretty unicode right arrow)
|
# * topic "master"
|
||||||
# And similarly for branch "test-post-receive" (for use when testing).
|
# And similarly for branch "test-post-receive" (for use when testing).
|
||||||
def commit_notice_destination(repo, branch, commit):
|
def commit_notice_destination(repo, branch, commit):
|
||||||
if branch in ["master", "prod", "test-post-receive"]:
|
if branch in ["master", "prod", "test-post-receive"]:
|
||||||
return dict(stream = 'test' if 'test-' in branch else 'commits',
|
return dict(stream = 'test' if 'test-' in branch else 'commits',
|
||||||
subject = u"deploy \u21D2 %s" % (branch,))
|
subject = u"%s" % (branch,))
|
||||||
|
|
||||||
# Return None for cases where you don't want a notice sent
|
# Return None for cases where you don't want a notice sent
|
||||||
return None
|
return None
|
||||||
|
|||||||
52
node_modules/handlebars/.jshintrc
generated
vendored
52
node_modules/handlebars/.jshintrc
generated
vendored
@@ -1,52 +0,0 @@
|
|||||||
{
|
|
||||||
"predef": [
|
|
||||||
"console",
|
|
||||||
"Ember",
|
|
||||||
"DS",
|
|
||||||
"Handlebars",
|
|
||||||
"Metamorph",
|
|
||||||
"ember_assert",
|
|
||||||
"ember_warn",
|
|
||||||
"ember_deprecate",
|
|
||||||
"ember_deprecateFunc",
|
|
||||||
"require",
|
|
||||||
"suite",
|
|
||||||
"equal",
|
|
||||||
"equals",
|
|
||||||
"test",
|
|
||||||
"testBoth",
|
|
||||||
"raises",
|
|
||||||
"deepEqual",
|
|
||||||
"start",
|
|
||||||
"stop",
|
|
||||||
"ok",
|
|
||||||
"strictEqual",
|
|
||||||
"module"
|
|
||||||
],
|
|
||||||
|
|
||||||
"node" : true,
|
|
||||||
"es5" : true,
|
|
||||||
"browser" : true,
|
|
||||||
|
|
||||||
"boss" : true,
|
|
||||||
"curly": false,
|
|
||||||
"debug": false,
|
|
||||||
"devel": false,
|
|
||||||
"eqeqeq": true,
|
|
||||||
"evil": true,
|
|
||||||
"forin": false,
|
|
||||||
"immed": false,
|
|
||||||
"laxbreak": false,
|
|
||||||
"newcap": true,
|
|
||||||
"noarg": true,
|
|
||||||
"noempty": false,
|
|
||||||
"nonew": false,
|
|
||||||
"nomen": false,
|
|
||||||
"onevar": false,
|
|
||||||
"plusplus": false,
|
|
||||||
"regexp": false,
|
|
||||||
"undef": true,
|
|
||||||
"sub": true,
|
|
||||||
"strict": false,
|
|
||||||
"white": false
|
|
||||||
}
|
|
||||||
13
node_modules/handlebars/.npmignore
generated
vendored
13
node_modules/handlebars/.npmignore
generated
vendored
@@ -1,10 +1,23 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.gitignore
|
.gitignore
|
||||||
.rvmrc
|
.rvmrc
|
||||||
|
.jshintrc
|
||||||
|
.travis.yml
|
||||||
|
.rspec
|
||||||
Gemfile
|
Gemfile
|
||||||
Gemfile.lock
|
Gemfile.lock
|
||||||
Rakefile
|
Rakefile
|
||||||
|
Gruntfile.js
|
||||||
|
*.gemspec
|
||||||
|
*.nuspec
|
||||||
bench/*
|
bench/*
|
||||||
|
configurations/*
|
||||||
|
components/*
|
||||||
|
dist/cdnjs/*
|
||||||
|
dist/components/*
|
||||||
spec/*
|
spec/*
|
||||||
src/*
|
src/*
|
||||||
|
tasks/*
|
||||||
|
tmp/*
|
||||||
|
publish/*
|
||||||
vendor/*
|
vendor/*
|
||||||
|
|||||||
1
node_modules/handlebars/.rspec
generated
vendored
1
node_modules/handlebars/.rspec
generated
vendored
@@ -1 +0,0 @@
|
|||||||
-cfs
|
|
||||||
261
node_modules/handlebars/README.markdown
generated
vendored
261
node_modules/handlebars/README.markdown
generated
vendored
@@ -1,22 +1,41 @@
|
|||||||
[](http://travis-ci.org/wycats/handlebars.js)
|
[](https://travis-ci.org/wycats/handlebars.js)
|
||||||
|
[](https://saucelabs.com/u/handlebars)
|
||||||
|
|
||||||
Handlebars.js
|
Handlebars.js
|
||||||
=============
|
=============
|
||||||
|
|
||||||
Handlebars.js is an extension to the [Mustache templating language](http://mustache.github.com/) created by Chris Wanstrath. Handlebars.js and Mustache are both logicless templating languages that keep the view and the code separated like we all know they should be.
|
Handlebars.js is an extension to the [Mustache templating
|
||||||
|
language](http://mustache.github.com/) created by Chris Wanstrath.
|
||||||
Checkout the official Handlebars docs site at [http://www.handlebarsjs.com](http://www.handlebarsjs.com).
|
Handlebars.js and Mustache are both logicless templating languages that
|
||||||
|
keep the view and the code separated like we all know they should be.
|
||||||
|
|
||||||
|
Checkout the official Handlebars docs site at
|
||||||
|
[http://www.handlebarsjs.com](http://www.handlebarsjs.com).
|
||||||
|
|
||||||
Installing
|
Installing
|
||||||
----------
|
----------
|
||||||
Installing Handlebars is easy. Simply [download the package from GitHub](https://github.com/wycats/handlebars.js/archives/master) and add it to your web pages (you should usually use the most recent version).
|
Installing Handlebars is easy. Simply download the package [from the official site](http://handlebarsjs.com/) or the [bower repository][bower-repo] and add it to your web pages (you should usually use the most recent version).
|
||||||
|
|
||||||
|
Alternatively, if you prefer having the latest version of handlebars from
|
||||||
|
the 'master' branch, passing builds of the 'master' branch are automatically
|
||||||
|
published to S3. You may download the latest passing master build by grabbing
|
||||||
|
a `handlebars-latest.js` file from the [builds page][builds-page]. When the
|
||||||
|
build is published, it is also available as a `handlebars-gitSHA.js` file on
|
||||||
|
the builds page if you need a version to refer to others.
|
||||||
|
`handlebars-runtime.js` builds are also available.
|
||||||
|
|
||||||
|
**Note**: The S3 builds page is provided as a convenience for the community,
|
||||||
|
but you should not use it for hosting Handlebars in production.
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
In general, the syntax of Handlebars.js templates is a superset of Mustache templates. For basic syntax, check out the [Mustache manpage](http://mustache.github.com/mustache.5.html).
|
In general, the syntax of Handlebars.js templates is a superset
|
||||||
|
of Mustache templates. For basic syntax, check out the [Mustache
|
||||||
|
manpage](http://mustache.github.com/mustache.5.html).
|
||||||
|
|
||||||
Once you have a template, use the Handlebars.compile method to compile the template into a function. The generated function takes a context argument, which will be used to render the template.
|
Once you have a template, use the `Handlebars.compile` method to compile
|
||||||
|
the template into a function. The generated function takes a context
|
||||||
|
argument, which will be used to render the template.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var source = "<p>Hello, my name is {{name}}. I am from {{hometown}}. I have " +
|
var source = "<p>Hello, my name is {{name}}. I am from {{hometown}}. I have " +
|
||||||
@@ -45,12 +64,12 @@ template. Here's an example, which assumes that your objects have a URL
|
|||||||
embedded in them, as well as the text for a link:
|
embedded in them, as well as the text for a link:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
Handlebars.registerHelper('link_to', function(context) {
|
Handlebars.registerHelper('link_to', function() {
|
||||||
return "<a href='" + context.url + "'>" + context.body + "</a>";
|
return "<a href='" + this.url + "'>" + this.body + "</a>";
|
||||||
});
|
});
|
||||||
|
|
||||||
var context = { posts: [{url: "/hello-world", body: "Hello World!"}] };
|
var context = { posts: [{url: "/hello-world", body: "Hello World!"}] };
|
||||||
var source = "<ul>{{#posts}}<li>{{{link_to this}}}</li>{{/posts}}</ul>"
|
var source = "<ul>{{#posts}}<li>{{{link_to}}}</li>{{/posts}}</ul>"
|
||||||
|
|
||||||
var template = Handlebars.compile(source);
|
var template = Handlebars.compile(source);
|
||||||
template(context);
|
template(context);
|
||||||
@@ -62,6 +81,14 @@ template(context);
|
|||||||
// </ul>
|
// </ul>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Helpers take precedence over fields defined on the context. To access a field
|
||||||
|
that is masked by a helper, a path reference may be used. In the example above
|
||||||
|
a field named `link_to` on the `context` object would be referenced using:
|
||||||
|
|
||||||
|
```
|
||||||
|
{{./link_to}}
|
||||||
|
```
|
||||||
|
|
||||||
Escaping
|
Escaping
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@@ -75,25 +102,34 @@ To explicitly *not* escape the contents, use the triple-mustache
|
|||||||
|
|
||||||
Differences Between Handlebars.js and Mustache
|
Differences Between Handlebars.js and Mustache
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
Handlebars.js adds a couple of additional features to make writing templates easier and also changes a tiny detail of how partials work.
|
Handlebars.js adds a couple of additional features to make writing
|
||||||
|
templates easier and also changes a tiny detail of how partials work.
|
||||||
|
|
||||||
### Paths
|
### Paths
|
||||||
|
|
||||||
Handlebars.js supports an extended expression syntax that we call paths. Paths are made up of typical expressions and . characters. Expressions allow you to not only display data from the current context, but to display data from contexts that are descendents and ancestors of the current context.
|
Handlebars.js supports an extended expression syntax that we call paths.
|
||||||
|
Paths are made up of typical expressions and . characters. Expressions
|
||||||
|
allow you to not only display data from the current context, but to
|
||||||
|
display data from contexts that are descendants and ancestors of the
|
||||||
|
current context.
|
||||||
|
|
||||||
To display data from descendent contexts, use the `.` character. So, for example, if your data were structured like:
|
To display data from descendant contexts, use the `.` character. So, for
|
||||||
|
example, if your data were structured like:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var data = {"person": { "name": "Alan" }, company: {"name": "Rad, Inc." } };
|
var data = {"person": { "name": "Alan" }, "company": {"name": "Rad, Inc." } };
|
||||||
```
|
```
|
||||||
|
|
||||||
you could display the person's name from the top-level context with the following expression:
|
You could display the person's name from the top-level context with the
|
||||||
|
following expression:
|
||||||
|
|
||||||
```
|
```
|
||||||
{{person.name}}
|
{{person.name}}
|
||||||
```
|
```
|
||||||
|
|
||||||
You can backtrack using `../`. For example, if you've already traversed into the person object you could still display the company's name with an expression like `{{../company.name}}`, so:
|
You can backtrack using `../`. For example, if you've already traversed
|
||||||
|
into the person object you could still display the company's name with
|
||||||
|
an expression like `{{../company.name}}`, so:
|
||||||
|
|
||||||
```
|
```
|
||||||
{{#person}}{{name}} - {{../company.name}}{{/person}}
|
{{#person}}{{name}} - {{../company.name}}{{/person}}
|
||||||
@@ -111,12 +147,12 @@ When calling a helper, you can pass paths or Strings as parameters. For
|
|||||||
instance:
|
instance:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
Handlebars.registerHelper('link_to', function(title, context) {
|
Handlebars.registerHelper('link_to', function(title, options) {
|
||||||
return "<a href='/posts" + context.url + "'>" + title + "!</a>"
|
return "<a href='/posts" + this.url + "'>" + title + "!</a>"
|
||||||
});
|
});
|
||||||
|
|
||||||
var context = { posts: [{url: "/hello-world", body: "Hello World!"}] };
|
var context = { posts: [{url: "/hello-world", body: "Hello World!"}] };
|
||||||
var source = '<ul>{{#posts}}<li>{{{link_to "Post" this}}}</li>{{/posts}}</ul>'
|
var source = '<ul>{{#posts}}<li>{{{link_to "Post"}}}</li>{{/posts}}</ul>'
|
||||||
|
|
||||||
var template = Handlebars.compile(source);
|
var template = Handlebars.compile(source);
|
||||||
template(context);
|
template(context);
|
||||||
@@ -134,7 +170,9 @@ gets passed to the helper function.
|
|||||||
|
|
||||||
### Block Helpers
|
### Block Helpers
|
||||||
|
|
||||||
Handlebars.js also adds the ability to define block helpers. Block helpers are functions that can be called from anywhere in the template. Here's an example:
|
Handlebars.js also adds the ability to define block helpers. Block
|
||||||
|
helpers are functions that can be called from anywhere in the template.
|
||||||
|
Here's an example:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var source = "<ul>{{#people}}<li>{{#link}}{{name}}{{/link}}</li>{{/people}}</ul>";
|
var source = "<ul>{{#people}}<li>{{#link}}{{name}}{{/link}}</li>{{/people}}</ul>";
|
||||||
@@ -156,7 +194,18 @@ template(data);
|
|||||||
// </ul>
|
// </ul>
|
||||||
```
|
```
|
||||||
|
|
||||||
Whenever the block helper is called it is given two parameters, the argument that is passed to the helper, or the current context if no argument is passed and the compiled contents of the block. Inside of the block helper the value of `this` is the current context, wrapped to include a method named `__get__` that helps translate paths into values within the helpers.
|
Whenever the block helper is called it is given one or more parameters,
|
||||||
|
any arguments that are passed in the helper in the call and an `options`
|
||||||
|
object containing the `fn` function which executes the block's child.
|
||||||
|
The block's current context may be accessed through `this`.
|
||||||
|
|
||||||
|
Block helpers have the same syntax as mustache sections but should not be
|
||||||
|
confused with one another. Sections are akin to an implicit `each` or
|
||||||
|
`with` statement depending on the input data and helpers are explicit
|
||||||
|
pieces of code that are free to implement whatever behavior they like.
|
||||||
|
The [mustache spec](http://mustache.github.io/mustache.5.html)
|
||||||
|
defines the exact behavior of sections. In the case of name conflicts,
|
||||||
|
helpers are given priority.
|
||||||
|
|
||||||
### Partials
|
### Partials
|
||||||
|
|
||||||
@@ -227,15 +276,24 @@ Options:
|
|||||||
-m, --min Minimize output [boolean]
|
-m, --min Minimize output [boolean]
|
||||||
-s, --simple Output template function only. [boolean]
|
-s, --simple Output template function only. [boolean]
|
||||||
-r, --root Template root. Base value that will be stripped from template names. [string]
|
-r, --root Template root. Base value that will be stripped from template names. [string]
|
||||||
|
-c, --commonjs Exports CommonJS style, path to Handlebars module [string]
|
||||||
|
-h, --handlebarPath Path to handlebar.js (only valid for amd-style) [string]
|
||||||
|
-n, --namespace Template namespace [string]
|
||||||
|
-p, --partial Compiling a partial template [boolean]
|
||||||
|
-d, --data Include data when compiling [boolean]
|
||||||
|
-e, --extension Template extension. [string]
|
||||||
|
-b, --bom Removes the BOM (Byte Order Mark) from the beginning of the templates. [boolean]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
If using the precompiler's normal mode, the resulting templates will be stored
|
If using the precompiler's normal mode, the resulting templates will be
|
||||||
to the `Handlebars.templates` object using the relative template name sans the
|
stored to the `Handlebars.templates` object using the relative template
|
||||||
extension. These templates may be executed in the same manner as templates.
|
name sans the extension. These templates may be executed in the same
|
||||||
|
manner as templates.
|
||||||
|
|
||||||
If using the simple mode the precompiler will generate a single javascript method.
|
If using the simple mode the precompiler will generate a single
|
||||||
To execute this method it must be passed to the using the `Handlebars.template`
|
javascript method. To execute this method it must be passed to the using
|
||||||
method and the resulting object may be as normal.
|
the `Handlebars.template` method and the resulting object may be as
|
||||||
|
normal.
|
||||||
|
|
||||||
### Optimizations
|
### Optimizations
|
||||||
|
|
||||||
@@ -247,39 +305,50 @@ method and the resulting object may be as normal.
|
|||||||
helpers for size and speed.
|
helpers for size and speed.
|
||||||
- When all helpers are known in advance the `--knownOnly` argument may be used
|
- When all helpers are known in advance the `--knownOnly` argument may be used
|
||||||
to optimize all block helper references.
|
to optimize all block helper references.
|
||||||
|
- Implementations that do not use `@data` variables can improve performance of
|
||||||
|
iteration centric templates by specifying `{data: false}` in the compiler options.
|
||||||
|
|
||||||
|
Supported Environments
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Handlebars has been designed to work in any ECMAScript 3 environment. This includes
|
||||||
|
|
||||||
|
- Node.js
|
||||||
|
- Chrome
|
||||||
|
- Firefox
|
||||||
|
- Safari 5+
|
||||||
|
- Opera 11+
|
||||||
|
- IE 6+
|
||||||
|
|
||||||
|
Older versions and other runtimes are likely to work but have not been formally
|
||||||
|
tested.
|
||||||
|
|
||||||
|
[](https://saucelabs.com/u/handlebars)
|
||||||
|
|
||||||
Performance
|
Performance
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
In a rough performance test, precompiled Handlebars.js templates (in the original version of Handlebars.js) rendered in about half the time of Mustache templates. It would be a shame if it were any other way, since they were precompiled, but the difference in architecture does have some big performance advantages. Justin Marney, a.k.a. [gotascii](http://github.com/gotascii), confirmed that with an [independent test](http://sorescode.com/2010/09/12/benchmarks.html). The rewritten Handlebars (current version) is faster than the old version, and we will have some benchmarks in the near future.
|
In a rough performance test, precompiled Handlebars.js templates (in
|
||||||
|
the original version of Handlebars.js) rendered in about half the
|
||||||
|
time of Mustache templates. It would be a shame if it were any other
|
||||||
|
way, since they were precompiled, but the difference in architecture
|
||||||
|
does have some big performance advantages. Justin Marney, a.k.a.
|
||||||
|
[gotascii](http://github.com/gotascii), confirmed that with an
|
||||||
|
[independent test](http://sorescode.com/2010/09/12/benchmarks.html). The
|
||||||
|
rewritten Handlebars (current version) is faster than the old version,
|
||||||
|
and we will have some benchmarks in the near future.
|
||||||
|
|
||||||
|
|
||||||
Building
|
Building
|
||||||
--------
|
--------
|
||||||
|
|
||||||
To build handlebars, just run `rake release`, and you will get two files
|
To build handlebars, just run `grunt build`, and the build will output to the `dist` directory.
|
||||||
in the `dist` directory.
|
|
||||||
|
|
||||||
|
|
||||||
Upgrading
|
Upgrading
|
||||||
---------
|
---------
|
||||||
|
|
||||||
When upgrading from the Handlebars 0.9 series, be aware that the
|
See [release-notes.md](https://github.com/wycats/handlebars.js/blob/master/release-notes.md) for upgrade notes.
|
||||||
signature for passing custom helpers or partials to templates has
|
|
||||||
changed.
|
|
||||||
|
|
||||||
Instead of:
|
|
||||||
|
|
||||||
```js
|
|
||||||
template(context, helpers, partials, [data])
|
|
||||||
```
|
|
||||||
|
|
||||||
Use:
|
|
||||||
|
|
||||||
```js
|
|
||||||
template(context, {helpers: helpers, partials: partials, data: data})
|
|
||||||
```
|
|
||||||
|
|
||||||
Known Issues
|
Known Issues
|
||||||
------------
|
------------
|
||||||
@@ -287,31 +356,103 @@ Known Issues
|
|||||||
* Using a variable, helper, or partial named `class` causes errors in IE browsers. (Instead, use `className`)
|
* Using a variable, helper, or partial named `class` causes errors in IE browsers. (Instead, use `className`)
|
||||||
|
|
||||||
Handlebars in the Wild
|
Handlebars in the Wild
|
||||||
-----------------
|
----------------------
|
||||||
* [jblotus](http://github.com/jblotus) created [http://tryhandlebarsjs.com](http://tryhandlebarsjs.com) for anyone who would
|
|
||||||
like to try out Handlebars.js in their browser.
|
* [Assemble](http://assemble.io), by [@jonschlinkert](https://github.com/jonschlinkert)
|
||||||
* Don Park wrote an Express.js view engine adapter for Handlebars.js called [hbs](http://github.com/donpark/hbs).
|
and [@doowb](https://github.com/doowb), is a static site generator that uses Handlebars.js
|
||||||
* [sammy.js](http://github.com/quirkey/sammy) by Aaron Quint, a.k.a. quirkey, supports Handlebars.js as one of its template plugins.
|
as its template engine.
|
||||||
* [SproutCore](http://www.sproutcore.com) uses Handlebars.js as its main templating engine, extending it with automatic data binding support.
|
* [CoSchedule](http://coschedule.com) An editorial calendar for WordPress that uses Handlebars.js
|
||||||
* [Ember.js](http://www.emberjs.com) makes Handlebars.js the primary way to structure your views, also with automatic data binding support.
|
* [Ember.js](http://www.emberjs.com) makes Handlebars.js the primary way to
|
||||||
* Les Hill (@leshill) wrote a Rails Asset Pipeline gem named [handlebars_assets](http://github.com/leshill/handlebars_assets).
|
structure your views, also with automatic data binding support.
|
||||||
|
* [Ghost](https://ghost.org/) Just a blogging platform.
|
||||||
|
* [handlebars_assets](http://github.com/leshill/handlebars_assets): A Rails Asset Pipeline gem
|
||||||
|
from Les Hill (@leshill).
|
||||||
|
* [handlebars-helpers](https://github.com/assemble/handlebars-helpers) is an extensive library
|
||||||
|
with 100+ handlebars helpers.
|
||||||
|
* [hbs](http://github.com/donpark/hbs): An Express.js view engine adapter for Handlebars.js,
|
||||||
|
from Don Park.
|
||||||
|
* [jblotus](http://github.com/jblotus) created [http://tryhandlebarsjs.com](http://tryhandlebarsjs.com)
|
||||||
|
for anyone who would like to try out Handlebars.js in their browser.
|
||||||
|
* [jQuery plugin](http://71104.github.io/jquery-handlebars/): allows you to use
|
||||||
|
Handlebars.js with [jQuery](http://jquery.com/).
|
||||||
|
* [Lumbar](http://walmartlabs.github.io/lumbar) provides easy module-based template management for
|
||||||
|
handlebars projects.
|
||||||
|
* [sammy.js](http://github.com/quirkey/sammy) by Aaron Quint, a.k.a. quirkey,
|
||||||
|
supports Handlebars.js as one of its template plugins.
|
||||||
|
* [SproutCore](http://www.sproutcore.com) uses Handlebars.js as its main
|
||||||
|
templating engine, extending it with automatic data binding support.
|
||||||
|
* [YUI](http://yuilibrary.com/yui/docs/handlebars/) implements a port of handlebars
|
||||||
|
* [Swag](https://github.com/elving/swag) by [@elving](https://github.com/elving) is a growing collection of helpers for handlebars.js. Give your handlebars.js templates some swag son!
|
||||||
|
* [DOMBars](https://github.com/blakeembrey/dombars) is a DOM-based templating engine built on the Handlebars parser and runtime
|
||||||
|
|
||||||
|
External Resources
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* [Gist about Synchronous and asynchronous loading of external handlebars templates](https://gist.github.com/2287070)
|
||||||
|
|
||||||
|
Have a project using Handlebars? Send us a [pull request][pull-request]!
|
||||||
|
|
||||||
Helping Out
|
Helping Out
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
To build Handlebars.js you'll need a few things installed.
|
To build Handlebars.js you'll need a few things installed.
|
||||||
|
|
||||||
* Node.js
|
* Node.js
|
||||||
* Jison, for building the compiler - `npm install jison`
|
* [Grunt](http://gruntjs.com/getting-started)
|
||||||
* Ruby
|
|
||||||
* therubyracer, for running tests - `gem install therubyracer`
|
|
||||||
* rspec, for running tests - `gem install rspec`
|
|
||||||
|
|
||||||
There's a Gemfile in the repo, so you can run `bundle` to install rspec and therubyracer if you've got bundler installed.
|
Project dependencies may be installed via `npm install`.
|
||||||
|
|
||||||
To build Handlebars.js from scratch, you'll want to run `rake compile` in the root of the project. That will build Handlebars and output the results to the dist/ folder. To run tests, run `rake spec`. You can also run our set of benchmarks with `rake bench`.
|
To build Handlebars.js from scratch, you'll want to run `grunt`
|
||||||
|
in the root of the project. That will build Handlebars and output the
|
||||||
|
results to the dist/ folder. To re-run tests, run `grunt test` or `npm test`.
|
||||||
|
You can also run our set of benchmarks with `grunt bench`.
|
||||||
|
|
||||||
If you notice any problems, please report them to the GitHub issue tracker at [http://github.com/wycats/handlebars.js/issues](http://github.com/wycats/handlebars.js/issues). Feel free to contact commondream or wycats through GitHub with any other questions or feature requests. To submit changes fork the project and send a pull request.
|
The `grunt dev` implements watching for tests and allows for in browser testing at `http://localhost:9999/spec/`.
|
||||||
|
|
||||||
|
If you notice any problems, please report them to the GitHub issue tracker at
|
||||||
|
[http://github.com/wycats/handlebars.js/issues](http://github.com/wycats/handlebars.js/issues).
|
||||||
|
Feel free to contact commondream or wycats through GitHub with any other
|
||||||
|
questions or feature requests. To submit changes fork the project and
|
||||||
|
send a pull request.
|
||||||
|
|
||||||
|
### Ember testing
|
||||||
|
|
||||||
|
The current ember distribution should be tested as part of the handlebars release process. This requires building the `handlebars-source` gem locally and then executing the ember test script.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
grunt build release
|
||||||
|
export HANDLEBARS_PATH=`pwd`
|
||||||
|
|
||||||
|
cd $emberRepoDir
|
||||||
|
bundle exec rake clean
|
||||||
|
bundle exec rake test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Releasing
|
||||||
|
|
||||||
|
Handlebars utilizes the [release yeoman generator][generator-release] to perform most release tasks.
|
||||||
|
|
||||||
|
A full release may be completed with the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
yo release:notes patch
|
||||||
|
yo release:release patch
|
||||||
|
npm publish
|
||||||
|
yo release:publish cdnjs handlebars.js dist/cdnjs/
|
||||||
|
yo release:publish components handlebars.js dist/components/
|
||||||
|
|
||||||
|
cd dist/components/
|
||||||
|
gem build handlebars-source.gemspec
|
||||||
|
gem push handlebars-source-*.gem
|
||||||
|
```
|
||||||
|
|
||||||
|
After this point the handlebars site needs to be updated to point to the new version numbers.
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
Handlebars.js is released under the MIT license.
|
Handlebars.js is released under the MIT license.
|
||||||
|
|
||||||
|
[bower-repo]: https://github.com/components/handlebars.js
|
||||||
|
[builds-page]: http://builds.handlebarsjs.com.s3.amazonaws.com/bucket-listing.html?sort=lastmod&sortdir=desc
|
||||||
|
[generator-release]: https://github.com/walmartlabs/generator-release
|
||||||
|
[pull-request]: https://github.com/wycats/handlebars.js/pull/new/master
|
||||||
|
|||||||
47
node_modules/handlebars/bin/handlebars
generated
vendored
47
node_modules/handlebars/bin/handlebars
generated
vendored
@@ -64,6 +64,17 @@ var optimist = require('optimist')
|
|||||||
'type': 'boolean',
|
'type': 'boolean',
|
||||||
'description': 'Include data when compiling',
|
'description': 'Include data when compiling',
|
||||||
'alias': 'data'
|
'alias': 'data'
|
||||||
|
},
|
||||||
|
'e': {
|
||||||
|
'type': 'string',
|
||||||
|
'description': 'Template extension.',
|
||||||
|
'alias': 'extension',
|
||||||
|
'default': 'handlebars'
|
||||||
|
},
|
||||||
|
'b': {
|
||||||
|
'type': 'boolean',
|
||||||
|
'description': 'Removes the BOM (Byte Order Mark) from the beginning of the templates.',
|
||||||
|
'alias': 'bom'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -91,7 +102,7 @@ var optimist = require('optimist')
|
|||||||
});
|
});
|
||||||
|
|
||||||
var fs = require('fs'),
|
var fs = require('fs'),
|
||||||
handlebars = require('../lib/handlebars'),
|
handlebars = require('../lib'),
|
||||||
basename = require('path').basename,
|
basename = require('path').basename,
|
||||||
uglify = require('uglify-js');
|
uglify = require('uglify-js');
|
||||||
|
|
||||||
@@ -109,10 +120,14 @@ if (argv.known) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build file extension pattern
|
||||||
|
var extension = argv.extension.replace(/[\\^$*+?.():=!|{}\-\[\]]/g, function(arg) { return '\\' + arg; });
|
||||||
|
extension = new RegExp('\\.' + extension + '$');
|
||||||
|
|
||||||
var output = [];
|
var output = [];
|
||||||
if (!argv.simple) {
|
if (!argv.simple) {
|
||||||
if (argv.amd) {
|
if (argv.amd) {
|
||||||
output.push('define([\'' + argv.handlebarPath + 'handlebars\'], function(Handlebars) {\n');
|
output.push('define([\'' + argv.handlebarPath + 'handlebars.runtime\'], function(Handlebars) {\n Handlebars = Handlebars["default"];');
|
||||||
} else if (argv.commonjs) {
|
} else if (argv.commonjs) {
|
||||||
output.push('var Handlebars = require("' + argv.commonjs + '");');
|
output.push('var Handlebars = require("' + argv.commonjs + '");');
|
||||||
} else {
|
} else {
|
||||||
@@ -131,13 +146,17 @@ function processTemplate(template, root) {
|
|||||||
fs.readdirSync(template).map(function(file) {
|
fs.readdirSync(template).map(function(file) {
|
||||||
var path = template + '/' + file;
|
var path = template + '/' + file;
|
||||||
|
|
||||||
if (/\.handlebars$/.test(path) || fs.statSync(path).isDirectory()) {
|
if (extension.test(path) || fs.statSync(path).isDirectory()) {
|
||||||
processTemplate(path, root || template);
|
processTemplate(path, root || template);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else if (extension.test(path)) {
|
||||||
var data = fs.readFileSync(path, 'utf8');
|
var data = fs.readFileSync(path, 'utf8');
|
||||||
|
|
||||||
|
if (argv.bom && data.indexOf('\uFEFF') === 0) {
|
||||||
|
data = data.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
knownHelpers: known,
|
knownHelpers: known,
|
||||||
knownHelpersOnly: argv.o
|
knownHelpersOnly: argv.o
|
||||||
@@ -153,13 +172,19 @@ function processTemplate(template, root) {
|
|||||||
} else if (template.indexOf(root) === 0) {
|
} else if (template.indexOf(root) === 0) {
|
||||||
template = template.substring(root.length+1);
|
template = template.substring(root.length+1);
|
||||||
}
|
}
|
||||||
template = template.replace(/\.handlebars$/, '');
|
template = template.replace(extension, '');
|
||||||
|
|
||||||
if (argv.simple) {
|
if (argv.simple) {
|
||||||
output.push(handlebars.precompile(data, options) + '\n');
|
output.push(handlebars.precompile(data, options) + '\n');
|
||||||
} else if (argv.partial) {
|
} else if (argv.partial) {
|
||||||
|
if(argv.amd && (argv._.length == 1 && !fs.statSync(argv._[0]).isDirectory())) {
|
||||||
|
output.push('return ');
|
||||||
|
}
|
||||||
output.push('Handlebars.partials[\'' + template + '\'] = template(' + handlebars.precompile(data, options) + ');\n');
|
output.push('Handlebars.partials[\'' + template + '\'] = template(' + handlebars.precompile(data, options) + ');\n');
|
||||||
} else {
|
} else {
|
||||||
|
if(argv.amd && (argv._.length == 1 && !fs.statSync(argv._[0]).isDirectory())) {
|
||||||
|
output.push('return ');
|
||||||
|
}
|
||||||
output.push('templates[\'' + template + '\'] = template(' + handlebars.precompile(data, options) + ');\n');
|
output.push('templates[\'' + template + '\'] = template(' + handlebars.precompile(data, options) + ');\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,6 +197,13 @@ argv._.forEach(function(template) {
|
|||||||
// Output the content
|
// Output the content
|
||||||
if (!argv.simple) {
|
if (!argv.simple) {
|
||||||
if (argv.amd) {
|
if (argv.amd) {
|
||||||
|
if(argv._.length > 1 || (argv._.length == 1 && fs.statSync(argv._[0]).isDirectory())) {
|
||||||
|
if(argv.partial){
|
||||||
|
output.push('return Handlebars.partials;\n');
|
||||||
|
} else {
|
||||||
|
output.push('return templates;\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
output.push('});');
|
output.push('});');
|
||||||
} else if (!argv.commonjs) {
|
} else if (!argv.commonjs) {
|
||||||
output.push('})();');
|
output.push('})();');
|
||||||
@@ -180,10 +212,7 @@ if (!argv.simple) {
|
|||||||
output = output.join('');
|
output = output.join('');
|
||||||
|
|
||||||
if (argv.min) {
|
if (argv.min) {
|
||||||
var ast = uglify.parser.parse(output);
|
output = uglify.minify(output, {fromString: true}).code;
|
||||||
ast = uglify.uglify.ast_mangle(ast);
|
|
||||||
ast = uglify.uglify.ast_squeeze(ast);
|
|
||||||
output = uglify.uglify.gen_code(ast);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv.output) {
|
if (argv.output) {
|
||||||
|
|||||||
41
node_modules/handlebars/dist/amd/handlebars.js
generated
vendored
Normal file
41
node_modules/handlebars/dist/amd/handlebars.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
define(
|
||||||
|
["./handlebars.runtime","./handlebars/compiler/ast","./handlebars/compiler/base","./handlebars/compiler/compiler","./handlebars/compiler/javascript-compiler","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
/*globals Handlebars: true */
|
||||||
|
var Handlebars = __dependency1__["default"];
|
||||||
|
|
||||||
|
// Compiler imports
|
||||||
|
var AST = __dependency2__["default"];
|
||||||
|
var Parser = __dependency3__.parser;
|
||||||
|
var parse = __dependency3__.parse;
|
||||||
|
var Compiler = __dependency4__.Compiler;
|
||||||
|
var compile = __dependency4__.compile;
|
||||||
|
var precompile = __dependency4__.precompile;
|
||||||
|
var JavaScriptCompiler = __dependency5__["default"];
|
||||||
|
|
||||||
|
var _create = Handlebars.create;
|
||||||
|
var create = function() {
|
||||||
|
var hb = _create();
|
||||||
|
|
||||||
|
hb.compile = function(input, options) {
|
||||||
|
return compile(input, options, hb);
|
||||||
|
};
|
||||||
|
hb.precompile = function (input, options) {
|
||||||
|
return precompile(input, options, hb);
|
||||||
|
};
|
||||||
|
|
||||||
|
hb.AST = AST;
|
||||||
|
hb.Compiler = Compiler;
|
||||||
|
hb.JavaScriptCompiler = JavaScriptCompiler;
|
||||||
|
hb.Parser = Parser;
|
||||||
|
hb.parse = parse;
|
||||||
|
|
||||||
|
return hb;
|
||||||
|
};
|
||||||
|
|
||||||
|
Handlebars = create();
|
||||||
|
Handlebars.create = create;
|
||||||
|
|
||||||
|
__exports__["default"] = Handlebars;
|
||||||
|
});
|
||||||
36
node_modules/handlebars/dist/amd/handlebars.runtime.js
generated
vendored
Normal file
36
node_modules/handlebars/dist/amd/handlebars.runtime.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
define(
|
||||||
|
["./handlebars/base","./handlebars/safe-string","./handlebars/exception","./handlebars/utils","./handlebars/runtime","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
/*globals Handlebars: true */
|
||||||
|
var base = __dependency1__;
|
||||||
|
|
||||||
|
// Each of these augment the Handlebars object. No need to setup here.
|
||||||
|
// (This is done to easily share code between commonjs and browse envs)
|
||||||
|
var SafeString = __dependency2__["default"];
|
||||||
|
var Exception = __dependency3__["default"];
|
||||||
|
var Utils = __dependency4__;
|
||||||
|
var runtime = __dependency5__;
|
||||||
|
|
||||||
|
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
|
||||||
|
var create = function() {
|
||||||
|
var hb = new base.HandlebarsEnvironment();
|
||||||
|
|
||||||
|
Utils.extend(hb, base);
|
||||||
|
hb.SafeString = SafeString;
|
||||||
|
hb.Exception = Exception;
|
||||||
|
hb.Utils = Utils;
|
||||||
|
|
||||||
|
hb.VM = runtime;
|
||||||
|
hb.template = function(spec) {
|
||||||
|
return runtime.template(spec, hb);
|
||||||
|
};
|
||||||
|
|
||||||
|
return hb;
|
||||||
|
};
|
||||||
|
|
||||||
|
var Handlebars = create();
|
||||||
|
Handlebars.create = create;
|
||||||
|
|
||||||
|
__exports__["default"] = Handlebars;
|
||||||
|
});
|
||||||
184
node_modules/handlebars/dist/amd/handlebars/base.js
generated
vendored
Normal file
184
node_modules/handlebars/dist/amd/handlebars/base.js
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
define(
|
||||||
|
["./utils","./exception","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
var Utils = __dependency1__;
|
||||||
|
var Exception = __dependency2__["default"];
|
||||||
|
|
||||||
|
var VERSION = "1.3.0";
|
||||||
|
__exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
|
||||||
|
__exports__.COMPILER_REVISION = COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = {
|
||||||
|
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
||||||
|
2: '== 1.0.0-rc.3',
|
||||||
|
3: '== 1.0.0-rc.4',
|
||||||
|
4: '>= 1.0.0'
|
||||||
|
};
|
||||||
|
__exports__.REVISION_CHANGES = REVISION_CHANGES;
|
||||||
|
var isArray = Utils.isArray,
|
||||||
|
isFunction = Utils.isFunction,
|
||||||
|
toString = Utils.toString,
|
||||||
|
objectType = '[object Object]';
|
||||||
|
|
||||||
|
function HandlebarsEnvironment(helpers, partials) {
|
||||||
|
this.helpers = helpers || {};
|
||||||
|
this.partials = partials || {};
|
||||||
|
|
||||||
|
registerDefaultHelpers(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
|
||||||
|
constructor: HandlebarsEnvironment,
|
||||||
|
|
||||||
|
logger: logger,
|
||||||
|
log: log,
|
||||||
|
|
||||||
|
registerHelper: function(name, fn, inverse) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
|
||||||
|
Utils.extend(this.helpers, name);
|
||||||
|
} else {
|
||||||
|
if (inverse) { fn.not = inverse; }
|
||||||
|
this.helpers[name] = fn;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
registerPartial: function(name, str) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
Utils.extend(this.partials, name);
|
||||||
|
} else {
|
||||||
|
this.partials[name] = str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function registerDefaultHelpers(instance) {
|
||||||
|
instance.registerHelper('helperMissing', function(arg) {
|
||||||
|
if(arguments.length === 2) {
|
||||||
|
return undefined;
|
||||||
|
} else {
|
||||||
|
throw new Exception("Missing helper: '" + arg + "'");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('blockHelperMissing', function(context, options) {
|
||||||
|
var inverse = options.inverse || function() {}, fn = options.fn;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if(context === true) {
|
||||||
|
return fn(this);
|
||||||
|
} else if(context === false || context == null) {
|
||||||
|
return inverse(this);
|
||||||
|
} else if (isArray(context)) {
|
||||||
|
if(context.length > 0) {
|
||||||
|
return instance.helpers.each(context, options);
|
||||||
|
} else {
|
||||||
|
return inverse(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fn(context);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('each', function(context, options) {
|
||||||
|
var fn = options.fn, inverse = options.inverse;
|
||||||
|
var i = 0, ret = "", data;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if (options.data) {
|
||||||
|
data = createFrame(options.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(context && typeof context === 'object') {
|
||||||
|
if (isArray(context)) {
|
||||||
|
for(var j = context.length; i<j; i++) {
|
||||||
|
if (data) {
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
data.last = (i === (context.length-1));
|
||||||
|
}
|
||||||
|
ret = ret + fn(context[i], { data: data });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(var key in context) {
|
||||||
|
if(context.hasOwnProperty(key)) {
|
||||||
|
if(data) {
|
||||||
|
data.key = key;
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
}
|
||||||
|
ret = ret + fn(context[key], {data: data});
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i === 0){
|
||||||
|
ret = inverse(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('if', function(conditional, options) {
|
||||||
|
if (isFunction(conditional)) { conditional = conditional.call(this); }
|
||||||
|
|
||||||
|
// Default behavior is to render the positive path if the value is truthy and not empty.
|
||||||
|
// The `includeZero` option may be set to treat the condtional as purely not empty based on the
|
||||||
|
// behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
|
||||||
|
if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
|
||||||
|
return options.inverse(this);
|
||||||
|
} else {
|
||||||
|
return options.fn(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('unless', function(conditional, options) {
|
||||||
|
return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('with', function(context, options) {
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if (!Utils.isEmpty(context)) return options.fn(context);
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('log', function(context, options) {
|
||||||
|
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
|
||||||
|
instance.log(level, context);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var logger = {
|
||||||
|
methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
|
||||||
|
|
||||||
|
// State enum
|
||||||
|
DEBUG: 0,
|
||||||
|
INFO: 1,
|
||||||
|
WARN: 2,
|
||||||
|
ERROR: 3,
|
||||||
|
level: 3,
|
||||||
|
|
||||||
|
// can be overridden in the host environment
|
||||||
|
log: function(level, obj) {
|
||||||
|
if (logger.level <= level) {
|
||||||
|
var method = logger.methodMap[level];
|
||||||
|
if (typeof console !== 'undefined' && console[method]) {
|
||||||
|
console[method].call(console, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__exports__.logger = logger;
|
||||||
|
function log(level, obj) { logger.log(level, obj); }
|
||||||
|
|
||||||
|
__exports__.log = log;var createFrame = function(object) {
|
||||||
|
var obj = {};
|
||||||
|
Utils.extend(obj, object);
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
__exports__.createFrame = createFrame;
|
||||||
|
});
|
||||||
231
node_modules/handlebars/dist/amd/handlebars/compiler/ast.js
generated
vendored
Normal file
231
node_modules/handlebars/dist/amd/handlebars/compiler/ast.js
generated
vendored
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
define(
|
||||||
|
["../exception","exports"],
|
||||||
|
function(__dependency1__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
var Exception = __dependency1__["default"];
|
||||||
|
|
||||||
|
function LocationInfo(locInfo){
|
||||||
|
locInfo = locInfo || {};
|
||||||
|
this.firstLine = locInfo.first_line;
|
||||||
|
this.firstColumn = locInfo.first_column;
|
||||||
|
this.lastColumn = locInfo.last_column;
|
||||||
|
this.lastLine = locInfo.last_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
var AST = {
|
||||||
|
ProgramNode: function(statements, inverseStrip, inverse, locInfo) {
|
||||||
|
var inverseLocationInfo, firstInverseNode;
|
||||||
|
if (arguments.length === 3) {
|
||||||
|
locInfo = inverse;
|
||||||
|
inverse = null;
|
||||||
|
} else if (arguments.length === 2) {
|
||||||
|
locInfo = inverseStrip;
|
||||||
|
inverseStrip = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "program";
|
||||||
|
this.statements = statements;
|
||||||
|
this.strip = {};
|
||||||
|
|
||||||
|
if(inverse) {
|
||||||
|
firstInverseNode = inverse[0];
|
||||||
|
if (firstInverseNode) {
|
||||||
|
inverseLocationInfo = {
|
||||||
|
first_line: firstInverseNode.firstLine,
|
||||||
|
last_line: firstInverseNode.lastLine,
|
||||||
|
last_column: firstInverseNode.lastColumn,
|
||||||
|
first_column: firstInverseNode.firstColumn
|
||||||
|
};
|
||||||
|
this.inverse = new AST.ProgramNode(inverse, inverseStrip, inverseLocationInfo);
|
||||||
|
} else {
|
||||||
|
this.inverse = new AST.ProgramNode(inverse, inverseStrip);
|
||||||
|
}
|
||||||
|
this.strip.right = inverseStrip.left;
|
||||||
|
} else if (inverseStrip) {
|
||||||
|
this.strip.left = inverseStrip.right;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
MustacheNode: function(rawParams, hash, open, strip, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "mustache";
|
||||||
|
this.strip = strip;
|
||||||
|
|
||||||
|
// Open may be a string parsed from the parser or a passed boolean flag
|
||||||
|
if (open != null && open.charAt) {
|
||||||
|
// Must use charAt to support IE pre-10
|
||||||
|
var escapeFlag = open.charAt(3) || open.charAt(2);
|
||||||
|
this.escaped = escapeFlag !== '{' && escapeFlag !== '&';
|
||||||
|
} else {
|
||||||
|
this.escaped = !!open;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawParams instanceof AST.SexprNode) {
|
||||||
|
this.sexpr = rawParams;
|
||||||
|
} else {
|
||||||
|
// Support old AST API
|
||||||
|
this.sexpr = new AST.SexprNode(rawParams, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sexpr.isRoot = true;
|
||||||
|
|
||||||
|
// Support old AST API that stored this info in MustacheNode
|
||||||
|
this.id = this.sexpr.id;
|
||||||
|
this.params = this.sexpr.params;
|
||||||
|
this.hash = this.sexpr.hash;
|
||||||
|
this.eligibleHelper = this.sexpr.eligibleHelper;
|
||||||
|
this.isHelper = this.sexpr.isHelper;
|
||||||
|
},
|
||||||
|
|
||||||
|
SexprNode: function(rawParams, hash, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
|
||||||
|
this.type = "sexpr";
|
||||||
|
this.hash = hash;
|
||||||
|
|
||||||
|
var id = this.id = rawParams[0];
|
||||||
|
var params = this.params = rawParams.slice(1);
|
||||||
|
|
||||||
|
// a mustache is an eligible helper if:
|
||||||
|
// * its id is simple (a single part, not `this` or `..`)
|
||||||
|
var eligibleHelper = this.eligibleHelper = id.isSimple;
|
||||||
|
|
||||||
|
// a mustache is definitely a helper if:
|
||||||
|
// * it is an eligible helper, and
|
||||||
|
// * it has at least one parameter or hash segment
|
||||||
|
this.isHelper = eligibleHelper && (params.length || hash);
|
||||||
|
|
||||||
|
// if a mustache is an eligible helper but not a definite
|
||||||
|
// helper, it is ambiguous, and will be resolved in a later
|
||||||
|
// pass or at runtime.
|
||||||
|
},
|
||||||
|
|
||||||
|
PartialNode: function(partialName, context, strip, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "partial";
|
||||||
|
this.partialName = partialName;
|
||||||
|
this.context = context;
|
||||||
|
this.strip = strip;
|
||||||
|
},
|
||||||
|
|
||||||
|
BlockNode: function(mustache, program, inverse, close, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
|
||||||
|
if(mustache.sexpr.id.original !== close.path.original) {
|
||||||
|
throw new Exception(mustache.sexpr.id.original + " doesn't match " + close.path.original, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.type = 'block';
|
||||||
|
this.mustache = mustache;
|
||||||
|
this.program = program;
|
||||||
|
this.inverse = inverse;
|
||||||
|
|
||||||
|
this.strip = {
|
||||||
|
left: mustache.strip.left,
|
||||||
|
right: close.strip.right
|
||||||
|
};
|
||||||
|
|
||||||
|
(program || inverse).strip.left = mustache.strip.right;
|
||||||
|
(inverse || program).strip.right = close.strip.left;
|
||||||
|
|
||||||
|
if (inverse && !program) {
|
||||||
|
this.isInverse = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ContentNode: function(string, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "content";
|
||||||
|
this.string = string;
|
||||||
|
},
|
||||||
|
|
||||||
|
HashNode: function(pairs, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "hash";
|
||||||
|
this.pairs = pairs;
|
||||||
|
},
|
||||||
|
|
||||||
|
IdNode: function(parts, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "ID";
|
||||||
|
|
||||||
|
var original = "",
|
||||||
|
dig = [],
|
||||||
|
depth = 0;
|
||||||
|
|
||||||
|
for(var i=0,l=parts.length; i<l; i++) {
|
||||||
|
var part = parts[i].part;
|
||||||
|
original += (parts[i].separator || '') + part;
|
||||||
|
|
||||||
|
if (part === ".." || part === "." || part === "this") {
|
||||||
|
if (dig.length > 0) {
|
||||||
|
throw new Exception("Invalid path: " + original, this);
|
||||||
|
} else if (part === "..") {
|
||||||
|
depth++;
|
||||||
|
} else {
|
||||||
|
this.isScoped = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dig.push(part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.original = original;
|
||||||
|
this.parts = dig;
|
||||||
|
this.string = dig.join('.');
|
||||||
|
this.depth = depth;
|
||||||
|
|
||||||
|
// an ID is simple if it only has one part, and that part is not
|
||||||
|
// `..` or `this`.
|
||||||
|
this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
|
||||||
|
|
||||||
|
this.stringModeValue = this.string;
|
||||||
|
},
|
||||||
|
|
||||||
|
PartialNameNode: function(name, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "PARTIAL_NAME";
|
||||||
|
this.name = name.original;
|
||||||
|
},
|
||||||
|
|
||||||
|
DataNode: function(id, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "DATA";
|
||||||
|
this.id = id;
|
||||||
|
},
|
||||||
|
|
||||||
|
StringNode: function(string, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "STRING";
|
||||||
|
this.original =
|
||||||
|
this.string =
|
||||||
|
this.stringModeValue = string;
|
||||||
|
},
|
||||||
|
|
||||||
|
IntegerNode: function(integer, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "INTEGER";
|
||||||
|
this.original =
|
||||||
|
this.integer = integer;
|
||||||
|
this.stringModeValue = Number(integer);
|
||||||
|
},
|
||||||
|
|
||||||
|
BooleanNode: function(bool, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "BOOLEAN";
|
||||||
|
this.bool = bool;
|
||||||
|
this.stringModeValue = bool === "true";
|
||||||
|
},
|
||||||
|
|
||||||
|
CommentNode: function(comment, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "comment";
|
||||||
|
this.comment = comment;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Must be exported as an object rather than the root of the module as the jison lexer
|
||||||
|
// most modify the object to operate properly.
|
||||||
|
__exports__["default"] = AST;
|
||||||
|
});
|
||||||
19
node_modules/handlebars/dist/amd/handlebars/compiler/base.js
generated
vendored
Normal file
19
node_modules/handlebars/dist/amd/handlebars/compiler/base.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
define(
|
||||||
|
["./parser","./ast","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
var parser = __dependency1__["default"];
|
||||||
|
var AST = __dependency2__["default"];
|
||||||
|
|
||||||
|
__exports__.parser = parser;
|
||||||
|
|
||||||
|
function parse(input) {
|
||||||
|
// Just return if an already-compile AST was passed in.
|
||||||
|
if(input.constructor === AST.ProgramNode) { return input; }
|
||||||
|
|
||||||
|
parser.yy = AST;
|
||||||
|
return parser.parse(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.parse = parse;
|
||||||
|
});
|
||||||
473
node_modules/handlebars/dist/amd/handlebars/compiler/compiler.js
generated
vendored
Normal file
473
node_modules/handlebars/dist/amd/handlebars/compiler/compiler.js
generated
vendored
Normal file
@@ -0,0 +1,473 @@
|
|||||||
|
define(
|
||||||
|
["../exception","exports"],
|
||||||
|
function(__dependency1__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
var Exception = __dependency1__["default"];
|
||||||
|
|
||||||
|
function Compiler() {}
|
||||||
|
|
||||||
|
__exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a
|
||||||
|
// function in a context. This is necessary for mustache compatibility, which
|
||||||
|
// requires that context functions in blocks are evaluated by blockHelperMissing,
|
||||||
|
// and then proceed as if the resulting value was provided to blockHelperMissing.
|
||||||
|
|
||||||
|
Compiler.prototype = {
|
||||||
|
compiler: Compiler,
|
||||||
|
|
||||||
|
disassemble: function() {
|
||||||
|
var opcodes = this.opcodes, opcode, out = [], params, param;
|
||||||
|
|
||||||
|
for (var i=0, l=opcodes.length; i<l; i++) {
|
||||||
|
opcode = opcodes[i];
|
||||||
|
|
||||||
|
if (opcode.opcode === 'DECLARE') {
|
||||||
|
out.push("DECLARE " + opcode.name + "=" + opcode.value);
|
||||||
|
} else {
|
||||||
|
params = [];
|
||||||
|
for (var j=0; j<opcode.args.length; j++) {
|
||||||
|
param = opcode.args[j];
|
||||||
|
if (typeof param === "string") {
|
||||||
|
param = "\"" + param.replace("\n", "\\n") + "\"";
|
||||||
|
}
|
||||||
|
params.push(param);
|
||||||
|
}
|
||||||
|
out.push(opcode.opcode + " " + params.join(" "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.join("\n");
|
||||||
|
},
|
||||||
|
|
||||||
|
equals: function(other) {
|
||||||
|
var len = this.opcodes.length;
|
||||||
|
if (other.opcodes.length !== len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
var opcode = this.opcodes[i],
|
||||||
|
otherOpcode = other.opcodes[i];
|
||||||
|
if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (var j = 0; j < opcode.args.length; j++) {
|
||||||
|
if (opcode.args[j] !== otherOpcode.args[j]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len = this.children.length;
|
||||||
|
if (other.children.length !== len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (!this.children[i].equals(other.children[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
guid: 0,
|
||||||
|
|
||||||
|
compile: function(program, options) {
|
||||||
|
this.opcodes = [];
|
||||||
|
this.children = [];
|
||||||
|
this.depths = {list: []};
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
|
// These changes will propagate to the other compiler components
|
||||||
|
var knownHelpers = this.options.knownHelpers;
|
||||||
|
this.options.knownHelpers = {
|
||||||
|
'helperMissing': true,
|
||||||
|
'blockHelperMissing': true,
|
||||||
|
'each': true,
|
||||||
|
'if': true,
|
||||||
|
'unless': true,
|
||||||
|
'with': true,
|
||||||
|
'log': true
|
||||||
|
};
|
||||||
|
if (knownHelpers) {
|
||||||
|
for (var name in knownHelpers) {
|
||||||
|
this.options.knownHelpers[name] = knownHelpers[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.accept(program);
|
||||||
|
},
|
||||||
|
|
||||||
|
accept: function(node) {
|
||||||
|
var strip = node.strip || {},
|
||||||
|
ret;
|
||||||
|
if (strip.left) {
|
||||||
|
this.opcode('strip');
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = this[node.type](node);
|
||||||
|
|
||||||
|
if (strip.right) {
|
||||||
|
this.opcode('strip');
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
|
||||||
|
program: function(program) {
|
||||||
|
var statements = program.statements;
|
||||||
|
|
||||||
|
for(var i=0, l=statements.length; i<l; i++) {
|
||||||
|
this.accept(statements[i]);
|
||||||
|
}
|
||||||
|
this.isSimple = l === 1;
|
||||||
|
|
||||||
|
this.depths.list = this.depths.list.sort(function(a, b) {
|
||||||
|
return a - b;
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
compileProgram: function(program) {
|
||||||
|
var result = new this.compiler().compile(program, this.options);
|
||||||
|
var guid = this.guid++, depth;
|
||||||
|
|
||||||
|
this.usePartial = this.usePartial || result.usePartial;
|
||||||
|
|
||||||
|
this.children[guid] = result;
|
||||||
|
|
||||||
|
for(var i=0, l=result.depths.list.length; i<l; i++) {
|
||||||
|
depth = result.depths.list[i];
|
||||||
|
|
||||||
|
if(depth < 2) { continue; }
|
||||||
|
else { this.addDepth(depth - 1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
return guid;
|
||||||
|
},
|
||||||
|
|
||||||
|
block: function(block) {
|
||||||
|
var mustache = block.mustache,
|
||||||
|
program = block.program,
|
||||||
|
inverse = block.inverse;
|
||||||
|
|
||||||
|
if (program) {
|
||||||
|
program = this.compileProgram(program);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inverse) {
|
||||||
|
inverse = this.compileProgram(inverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
var sexpr = mustache.sexpr;
|
||||||
|
var type = this.classifySexpr(sexpr);
|
||||||
|
|
||||||
|
if (type === "helper") {
|
||||||
|
this.helperSexpr(sexpr, program, inverse);
|
||||||
|
} else if (type === "simple") {
|
||||||
|
this.simpleSexpr(sexpr);
|
||||||
|
|
||||||
|
// now that the simple mustache is resolved, we need to
|
||||||
|
// evaluate it by executing `blockHelperMissing`
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
this.opcode('emptyHash');
|
||||||
|
this.opcode('blockValue');
|
||||||
|
} else {
|
||||||
|
this.ambiguousSexpr(sexpr, program, inverse);
|
||||||
|
|
||||||
|
// now that the simple mustache is resolved, we need to
|
||||||
|
// evaluate it by executing `blockHelperMissing`
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
this.opcode('emptyHash');
|
||||||
|
this.opcode('ambiguousBlockValue');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('append');
|
||||||
|
},
|
||||||
|
|
||||||
|
hash: function(hash) {
|
||||||
|
var pairs = hash.pairs, pair, val;
|
||||||
|
|
||||||
|
this.opcode('pushHash');
|
||||||
|
|
||||||
|
for(var i=0, l=pairs.length; i<l; i++) {
|
||||||
|
pair = pairs[i];
|
||||||
|
val = pair[1];
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
if(val.depth) {
|
||||||
|
this.addDepth(val.depth);
|
||||||
|
}
|
||||||
|
this.opcode('getContext', val.depth || 0);
|
||||||
|
this.opcode('pushStringParam', val.stringModeValue, val.type);
|
||||||
|
|
||||||
|
if (val.type === 'sexpr') {
|
||||||
|
// Subexpressions get evaluated and passed in
|
||||||
|
// in string params mode.
|
||||||
|
this.sexpr(val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.accept(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('assignToHash', pair[0]);
|
||||||
|
}
|
||||||
|
this.opcode('popHash');
|
||||||
|
},
|
||||||
|
|
||||||
|
partial: function(partial) {
|
||||||
|
var partialName = partial.partialName;
|
||||||
|
this.usePartial = true;
|
||||||
|
|
||||||
|
if(partial.context) {
|
||||||
|
this.ID(partial.context);
|
||||||
|
} else {
|
||||||
|
this.opcode('push', 'depth0');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('invokePartial', partialName.name);
|
||||||
|
this.opcode('append');
|
||||||
|
},
|
||||||
|
|
||||||
|
content: function(content) {
|
||||||
|
this.opcode('appendContent', content.string);
|
||||||
|
},
|
||||||
|
|
||||||
|
mustache: function(mustache) {
|
||||||
|
this.sexpr(mustache.sexpr);
|
||||||
|
|
||||||
|
if(mustache.escaped && !this.options.noEscape) {
|
||||||
|
this.opcode('appendEscaped');
|
||||||
|
} else {
|
||||||
|
this.opcode('append');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ambiguousSexpr: function(sexpr, program, inverse) {
|
||||||
|
var id = sexpr.id,
|
||||||
|
name = id.parts[0],
|
||||||
|
isBlock = program != null || inverse != null;
|
||||||
|
|
||||||
|
this.opcode('getContext', id.depth);
|
||||||
|
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
|
||||||
|
this.opcode('invokeAmbiguous', name, isBlock);
|
||||||
|
},
|
||||||
|
|
||||||
|
simpleSexpr: function(sexpr) {
|
||||||
|
var id = sexpr.id;
|
||||||
|
|
||||||
|
if (id.type === 'DATA') {
|
||||||
|
this.DATA(id);
|
||||||
|
} else if (id.parts.length) {
|
||||||
|
this.ID(id);
|
||||||
|
} else {
|
||||||
|
// Simplified ID for `this`
|
||||||
|
this.addDepth(id.depth);
|
||||||
|
this.opcode('getContext', id.depth);
|
||||||
|
this.opcode('pushContext');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('resolvePossibleLambda');
|
||||||
|
},
|
||||||
|
|
||||||
|
helperSexpr: function(sexpr, program, inverse) {
|
||||||
|
var params = this.setupFullMustacheParams(sexpr, program, inverse),
|
||||||
|
name = sexpr.id.parts[0];
|
||||||
|
|
||||||
|
if (this.options.knownHelpers[name]) {
|
||||||
|
this.opcode('invokeKnownHelper', params.length, name);
|
||||||
|
} else if (this.options.knownHelpersOnly) {
|
||||||
|
throw new Exception("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
|
||||||
|
} else {
|
||||||
|
this.opcode('invokeHelper', params.length, name, sexpr.isRoot);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
sexpr: function(sexpr) {
|
||||||
|
var type = this.classifySexpr(sexpr);
|
||||||
|
|
||||||
|
if (type === "simple") {
|
||||||
|
this.simpleSexpr(sexpr);
|
||||||
|
} else if (type === "helper") {
|
||||||
|
this.helperSexpr(sexpr);
|
||||||
|
} else {
|
||||||
|
this.ambiguousSexpr(sexpr);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ID: function(id) {
|
||||||
|
this.addDepth(id.depth);
|
||||||
|
this.opcode('getContext', id.depth);
|
||||||
|
|
||||||
|
var name = id.parts[0];
|
||||||
|
if (!name) {
|
||||||
|
this.opcode('pushContext');
|
||||||
|
} else {
|
||||||
|
this.opcode('lookupOnContext', id.parts[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i=1, l=id.parts.length; i<l; i++) {
|
||||||
|
this.opcode('lookup', id.parts[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DATA: function(data) {
|
||||||
|
this.options.data = true;
|
||||||
|
if (data.id.isScoped || data.id.depth) {
|
||||||
|
throw new Exception('Scoped data references are not supported: ' + data.original, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('lookupData');
|
||||||
|
var parts = data.id.parts;
|
||||||
|
for(var i=0, l=parts.length; i<l; i++) {
|
||||||
|
this.opcode('lookup', parts[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
STRING: function(string) {
|
||||||
|
this.opcode('pushString', string.string);
|
||||||
|
},
|
||||||
|
|
||||||
|
INTEGER: function(integer) {
|
||||||
|
this.opcode('pushLiteral', integer.integer);
|
||||||
|
},
|
||||||
|
|
||||||
|
BOOLEAN: function(bool) {
|
||||||
|
this.opcode('pushLiteral', bool.bool);
|
||||||
|
},
|
||||||
|
|
||||||
|
comment: function() {},
|
||||||
|
|
||||||
|
// HELPERS
|
||||||
|
opcode: function(name) {
|
||||||
|
this.opcodes.push({ opcode: name, args: [].slice.call(arguments, 1) });
|
||||||
|
},
|
||||||
|
|
||||||
|
declare: function(name, value) {
|
||||||
|
this.opcodes.push({ opcode: 'DECLARE', name: name, value: value });
|
||||||
|
},
|
||||||
|
|
||||||
|
addDepth: function(depth) {
|
||||||
|
if(depth === 0) { return; }
|
||||||
|
|
||||||
|
if(!this.depths[depth]) {
|
||||||
|
this.depths[depth] = true;
|
||||||
|
this.depths.list.push(depth);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
classifySexpr: function(sexpr) {
|
||||||
|
var isHelper = sexpr.isHelper;
|
||||||
|
var isEligible = sexpr.eligibleHelper;
|
||||||
|
var options = this.options;
|
||||||
|
|
||||||
|
// if ambiguous, we can possibly resolve the ambiguity now
|
||||||
|
if (isEligible && !isHelper) {
|
||||||
|
var name = sexpr.id.parts[0];
|
||||||
|
|
||||||
|
if (options.knownHelpers[name]) {
|
||||||
|
isHelper = true;
|
||||||
|
} else if (options.knownHelpersOnly) {
|
||||||
|
isEligible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isHelper) { return "helper"; }
|
||||||
|
else if (isEligible) { return "ambiguous"; }
|
||||||
|
else { return "simple"; }
|
||||||
|
},
|
||||||
|
|
||||||
|
pushParams: function(params) {
|
||||||
|
var i = params.length, param;
|
||||||
|
|
||||||
|
while(i--) {
|
||||||
|
param = params[i];
|
||||||
|
|
||||||
|
if(this.options.stringParams) {
|
||||||
|
if(param.depth) {
|
||||||
|
this.addDepth(param.depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('getContext', param.depth || 0);
|
||||||
|
this.opcode('pushStringParam', param.stringModeValue, param.type);
|
||||||
|
|
||||||
|
if (param.type === 'sexpr') {
|
||||||
|
// Subexpressions get evaluated and passed in
|
||||||
|
// in string params mode.
|
||||||
|
this.sexpr(param);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this[param.type](param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setupFullMustacheParams: function(sexpr, program, inverse) {
|
||||||
|
var params = sexpr.params;
|
||||||
|
this.pushParams(params);
|
||||||
|
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
|
||||||
|
if (sexpr.hash) {
|
||||||
|
this.hash(sexpr.hash);
|
||||||
|
} else {
|
||||||
|
this.opcode('emptyHash');
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function precompile(input, options, env) {
|
||||||
|
if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
|
||||||
|
throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
if (!('data' in options)) {
|
||||||
|
options.data = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ast = env.parse(input);
|
||||||
|
var environment = new env.Compiler().compile(ast, options);
|
||||||
|
return new env.JavaScriptCompiler().compile(environment, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.precompile = precompile;function compile(input, options, env) {
|
||||||
|
if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
|
||||||
|
throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
if (!('data' in options)) {
|
||||||
|
options.data = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var compiled;
|
||||||
|
|
||||||
|
function compileInput() {
|
||||||
|
var ast = env.parse(input);
|
||||||
|
var environment = new env.Compiler().compile(ast, options);
|
||||||
|
var templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
|
||||||
|
return env.template(templateSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Template is only compiled on first use and cached after that point.
|
||||||
|
return function(context, options) {
|
||||||
|
if (!compiled) {
|
||||||
|
compiled = compileInput();
|
||||||
|
}
|
||||||
|
return compiled.call(this, context, options);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.compile = compile;
|
||||||
|
});
|
||||||
946
node_modules/handlebars/dist/amd/handlebars/compiler/javascript-compiler.js
generated
vendored
Normal file
946
node_modules/handlebars/dist/amd/handlebars/compiler/javascript-compiler.js
generated
vendored
Normal file
@@ -0,0 +1,946 @@
|
|||||||
|
define(
|
||||||
|
["../base","../exception","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
var COMPILER_REVISION = __dependency1__.COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;
|
||||||
|
var log = __dependency1__.log;
|
||||||
|
var Exception = __dependency2__["default"];
|
||||||
|
|
||||||
|
function Literal(value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function JavaScriptCompiler() {}
|
||||||
|
|
||||||
|
JavaScriptCompiler.prototype = {
|
||||||
|
// PUBLIC API: You can override these methods in a subclass to provide
|
||||||
|
// alternative compiled forms for name lookup and buffering semantics
|
||||||
|
nameLookup: function(parent, name /* , type*/) {
|
||||||
|
var wrap,
|
||||||
|
ret;
|
||||||
|
if (parent.indexOf('depth') === 0) {
|
||||||
|
wrap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/^[0-9]+$/.test(name)) {
|
||||||
|
ret = parent + "[" + name + "]";
|
||||||
|
} else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
|
||||||
|
ret = parent + "." + name;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = parent + "['" + name + "']";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wrap) {
|
||||||
|
return '(' + parent + ' && ' + ret + ')';
|
||||||
|
} else {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
compilerInfo: function() {
|
||||||
|
var revision = COMPILER_REVISION,
|
||||||
|
versions = REVISION_CHANGES[revision];
|
||||||
|
return "this.compilerInfo = ["+revision+",'"+versions+"'];\n";
|
||||||
|
},
|
||||||
|
|
||||||
|
appendToBuffer: function(string) {
|
||||||
|
if (this.environment.isSimple) {
|
||||||
|
return "return " + string + ";";
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
appendToBuffer: true,
|
||||||
|
content: string,
|
||||||
|
toString: function() { return "buffer += " + string + ";"; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
initializeBuffer: function() {
|
||||||
|
return this.quotedString("");
|
||||||
|
},
|
||||||
|
|
||||||
|
namespace: "Handlebars",
|
||||||
|
// END PUBLIC API
|
||||||
|
|
||||||
|
compile: function(environment, options, context, asObject) {
|
||||||
|
this.environment = environment;
|
||||||
|
this.options = options || {};
|
||||||
|
|
||||||
|
log('debug', this.environment.disassemble() + "\n\n");
|
||||||
|
|
||||||
|
this.name = this.environment.name;
|
||||||
|
this.isChild = !!context;
|
||||||
|
this.context = context || {
|
||||||
|
programs: [],
|
||||||
|
environments: [],
|
||||||
|
aliases: { }
|
||||||
|
};
|
||||||
|
|
||||||
|
this.preamble();
|
||||||
|
|
||||||
|
this.stackSlot = 0;
|
||||||
|
this.stackVars = [];
|
||||||
|
this.registers = { list: [] };
|
||||||
|
this.hashes = [];
|
||||||
|
this.compileStack = [];
|
||||||
|
this.inlineStack = [];
|
||||||
|
|
||||||
|
this.compileChildren(environment, options);
|
||||||
|
|
||||||
|
var opcodes = environment.opcodes, opcode;
|
||||||
|
|
||||||
|
this.i = 0;
|
||||||
|
|
||||||
|
for(var l=opcodes.length; this.i<l; this.i++) {
|
||||||
|
opcode = opcodes[this.i];
|
||||||
|
|
||||||
|
if(opcode.opcode === 'DECLARE') {
|
||||||
|
this[opcode.name] = opcode.value;
|
||||||
|
} else {
|
||||||
|
this[opcode.opcode].apply(this, opcode.args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the stripNext flag if it was not set by this operation.
|
||||||
|
if (opcode.opcode !== this.stripNext) {
|
||||||
|
this.stripNext = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush any trailing content that might be pending.
|
||||||
|
this.pushSource('');
|
||||||
|
|
||||||
|
if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
|
||||||
|
throw new Exception('Compile completed with content left on stack');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.createFunctionContext(asObject);
|
||||||
|
},
|
||||||
|
|
||||||
|
preamble: function() {
|
||||||
|
var out = [];
|
||||||
|
|
||||||
|
if (!this.isChild) {
|
||||||
|
var namespace = this.namespace;
|
||||||
|
|
||||||
|
var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
|
||||||
|
if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
|
||||||
|
if (this.options.data) { copies = copies + " data = data || {};"; }
|
||||||
|
out.push(copies);
|
||||||
|
} else {
|
||||||
|
out.push('');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.environment.isSimple) {
|
||||||
|
out.push(", buffer = " + this.initializeBuffer());
|
||||||
|
} else {
|
||||||
|
out.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// track the last context pushed into place to allow skipping the
|
||||||
|
// getContext opcode when it would be a noop
|
||||||
|
this.lastContext = 0;
|
||||||
|
this.source = out;
|
||||||
|
},
|
||||||
|
|
||||||
|
createFunctionContext: function(asObject) {
|
||||||
|
var locals = this.stackVars.concat(this.registers.list);
|
||||||
|
|
||||||
|
if(locals.length > 0) {
|
||||||
|
this.source[1] = this.source[1] + ", " + locals.join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate minimizer alias mappings
|
||||||
|
if (!this.isChild) {
|
||||||
|
for (var alias in this.context.aliases) {
|
||||||
|
if (this.context.aliases.hasOwnProperty(alias)) {
|
||||||
|
this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.source[1]) {
|
||||||
|
this.source[1] = "var " + this.source[1].substring(2) + ";";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge children
|
||||||
|
if (!this.isChild) {
|
||||||
|
this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.environment.isSimple) {
|
||||||
|
this.pushSource("return buffer;");
|
||||||
|
}
|
||||||
|
|
||||||
|
var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
|
||||||
|
|
||||||
|
for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
|
||||||
|
params.push("depth" + this.environment.depths.list[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform a second pass over the output to merge content when possible
|
||||||
|
var source = this.mergeSource();
|
||||||
|
|
||||||
|
if (!this.isChild) {
|
||||||
|
source = this.compilerInfo()+source;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asObject) {
|
||||||
|
params.push(source);
|
||||||
|
|
||||||
|
return Function.apply(this, params);
|
||||||
|
} else {
|
||||||
|
var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + source + '}';
|
||||||
|
log('debug', functionSource + "\n\n");
|
||||||
|
return functionSource;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mergeSource: function() {
|
||||||
|
// WARN: We are not handling the case where buffer is still populated as the source should
|
||||||
|
// not have buffer append operations as their final action.
|
||||||
|
var source = '',
|
||||||
|
buffer;
|
||||||
|
for (var i = 0, len = this.source.length; i < len; i++) {
|
||||||
|
var line = this.source[i];
|
||||||
|
if (line.appendToBuffer) {
|
||||||
|
if (buffer) {
|
||||||
|
buffer = buffer + '\n + ' + line.content;
|
||||||
|
} else {
|
||||||
|
buffer = line.content;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (buffer) {
|
||||||
|
source += 'buffer += ' + buffer + ';\n ';
|
||||||
|
buffer = undefined;
|
||||||
|
}
|
||||||
|
source += line + '\n ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return source;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [blockValue]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, value
|
||||||
|
// On stack, after: return value of blockHelperMissing
|
||||||
|
//
|
||||||
|
// The purpose of this opcode is to take a block of the form
|
||||||
|
// `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
|
||||||
|
// replace it on the stack with the result of properly
|
||||||
|
// invoking blockHelperMissing.
|
||||||
|
blockValue: function() {
|
||||||
|
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||||
|
|
||||||
|
var params = ["depth0"];
|
||||||
|
this.setupParams(0, params);
|
||||||
|
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
params.splice(1, 0, current);
|
||||||
|
return "blockHelperMissing.call(" + params.join(", ") + ")";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [ambiguousBlockValue]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, value
|
||||||
|
// Compiler value, before: lastHelper=value of last found helper, if any
|
||||||
|
// On stack, after, if no lastHelper: same as [blockValue]
|
||||||
|
// On stack, after, if lastHelper: value
|
||||||
|
ambiguousBlockValue: function() {
|
||||||
|
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||||
|
|
||||||
|
var params = ["depth0"];
|
||||||
|
this.setupParams(0, params);
|
||||||
|
|
||||||
|
var current = this.topStack();
|
||||||
|
params.splice(1, 0, current);
|
||||||
|
|
||||||
|
this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [appendContent]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Appends the string value of `content` to the current buffer
|
||||||
|
appendContent: function(content) {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
content = this.pendingContent + content;
|
||||||
|
}
|
||||||
|
if (this.stripNext) {
|
||||||
|
content = content.replace(/^\s+/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pendingContent = content;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [strip]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Removes any trailing whitespace from the prior content node and flags
|
||||||
|
// the next operation for stripping if it is a content node.
|
||||||
|
strip: function() {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
this.pendingContent = this.pendingContent.replace(/\s+$/, '');
|
||||||
|
}
|
||||||
|
this.stripNext = 'strip';
|
||||||
|
},
|
||||||
|
|
||||||
|
// [append]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Coerces `value` to a String and appends it to the current buffer.
|
||||||
|
//
|
||||||
|
// If `value` is truthy, or 0, it is coerced into a string and appended
|
||||||
|
// Otherwise, the empty string is appended
|
||||||
|
append: function() {
|
||||||
|
// Force anything that is inlined onto the stack so we don't have duplication
|
||||||
|
// when we examine local
|
||||||
|
this.flushInline();
|
||||||
|
var local = this.popStack();
|
||||||
|
this.pushSource("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
|
||||||
|
if (this.environment.isSimple) {
|
||||||
|
this.pushSource("else { " + this.appendToBuffer("''") + " }");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [appendEscaped]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Escape `value` and append it to the buffer
|
||||||
|
appendEscaped: function() {
|
||||||
|
this.context.aliases.escapeExpression = 'this.escapeExpression';
|
||||||
|
|
||||||
|
this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [getContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
// Compiler value, after: lastContext=depth
|
||||||
|
//
|
||||||
|
// Set the value of the `lastContext` compiler value to the depth
|
||||||
|
getContext: function(depth) {
|
||||||
|
if(this.lastContext !== depth) {
|
||||||
|
this.lastContext = depth;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookupOnContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: currentContext[name], ...
|
||||||
|
//
|
||||||
|
// Looks up the value of `name` on the current context and pushes
|
||||||
|
// it onto the stack.
|
||||||
|
lookupOnContext: function(name) {
|
||||||
|
this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: currentContext, ...
|
||||||
|
//
|
||||||
|
// Pushes the value of the current context onto the stack.
|
||||||
|
pushContext: function() {
|
||||||
|
this.pushStackLiteral('depth' + this.lastContext);
|
||||||
|
},
|
||||||
|
|
||||||
|
// [resolvePossibleLambda]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: resolved value, ...
|
||||||
|
//
|
||||||
|
// If the `value` is a lambda, replace it on the stack by
|
||||||
|
// the return value of the lambda
|
||||||
|
resolvePossibleLambda: function() {
|
||||||
|
this.context.aliases.functionType = '"function"';
|
||||||
|
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookup]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: value[name], ...
|
||||||
|
//
|
||||||
|
// Replace the value on the stack with the result of looking
|
||||||
|
// up `name` on `value`
|
||||||
|
lookup: function(name) {
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookupData]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: data, ...
|
||||||
|
//
|
||||||
|
// Push the data lookup operator
|
||||||
|
lookupData: function() {
|
||||||
|
this.pushStackLiteral('data');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushStringParam]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: string, currentContext, ...
|
||||||
|
//
|
||||||
|
// This opcode is designed for use in string mode, which
|
||||||
|
// provides the string value of a parameter along with its
|
||||||
|
// depth rather than resolving it immediately.
|
||||||
|
pushStringParam: function(string, type) {
|
||||||
|
this.pushStackLiteral('depth' + this.lastContext);
|
||||||
|
|
||||||
|
this.pushString(type);
|
||||||
|
|
||||||
|
// If it's a subexpression, the string result
|
||||||
|
// will be pushed after this opcode.
|
||||||
|
if (type !== 'sexpr') {
|
||||||
|
if (typeof string === 'string') {
|
||||||
|
this.pushString(string);
|
||||||
|
} else {
|
||||||
|
this.pushStackLiteral(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
emptyHash: function() {
|
||||||
|
this.pushStackLiteral('{}');
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
this.push('{}'); // hashContexts
|
||||||
|
this.push('{}'); // hashTypes
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pushHash: function() {
|
||||||
|
if (this.hash) {
|
||||||
|
this.hashes.push(this.hash);
|
||||||
|
}
|
||||||
|
this.hash = {values: [], types: [], contexts: []};
|
||||||
|
},
|
||||||
|
popHash: function() {
|
||||||
|
var hash = this.hash;
|
||||||
|
this.hash = this.hashes.pop();
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
this.push('{' + hash.contexts.join(',') + '}');
|
||||||
|
this.push('{' + hash.types.join(',') + '}');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.push('{\n ' + hash.values.join(',\n ') + '\n }');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushString]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: quotedString(string), ...
|
||||||
|
//
|
||||||
|
// Push a quoted version of `string` onto the stack
|
||||||
|
pushString: function(string) {
|
||||||
|
this.pushStackLiteral(this.quotedString(string));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [push]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: expr, ...
|
||||||
|
//
|
||||||
|
// Push an expression onto the stack
|
||||||
|
push: function(expr) {
|
||||||
|
this.inlineStack.push(expr);
|
||||||
|
return expr;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushLiteral]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: value, ...
|
||||||
|
//
|
||||||
|
// Pushes a value onto the stack. This operation prevents
|
||||||
|
// the compiler from creating a temporary variable to hold
|
||||||
|
// it.
|
||||||
|
pushLiteral: function(value) {
|
||||||
|
this.pushStackLiteral(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushProgram]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: program(guid), ...
|
||||||
|
//
|
||||||
|
// Push a program expression onto the stack. This takes
|
||||||
|
// a compile-time guid and converts it into a runtime-accessible
|
||||||
|
// expression.
|
||||||
|
pushProgram: function(guid) {
|
||||||
|
if (guid != null) {
|
||||||
|
this.pushStackLiteral(this.programExpression(guid));
|
||||||
|
} else {
|
||||||
|
this.pushStackLiteral(null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeHelper]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of helper invocation
|
||||||
|
//
|
||||||
|
// Pops off the helper's parameters, invokes the helper,
|
||||||
|
// and pushes the helper's return value onto the stack.
|
||||||
|
//
|
||||||
|
// If the helper is not found, `helperMissing` is called.
|
||||||
|
invokeHelper: function(paramSize, name, isRoot) {
|
||||||
|
this.context.aliases.helperMissing = 'helpers.helperMissing';
|
||||||
|
this.useRegister('helper');
|
||||||
|
|
||||||
|
var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
|
||||||
|
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
|
||||||
|
|
||||||
|
var lookup = 'helper = ' + helper.name + ' || ' + nonHelper;
|
||||||
|
if (helper.paramsInit) {
|
||||||
|
lookup += ',' + helper.paramsInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.push(
|
||||||
|
'('
|
||||||
|
+ lookup
|
||||||
|
+ ',helper '
|
||||||
|
+ '? helper.call(' + helper.callParams + ') '
|
||||||
|
+ ': helperMissing.call(' + helper.helperMissingParams + '))');
|
||||||
|
|
||||||
|
// Always flush subexpressions. This is both to prevent the compounding size issue that
|
||||||
|
// occurs when the code has to be duplicated for inlining and also to prevent errors
|
||||||
|
// due to the incorrect options object being passed due to the shared register.
|
||||||
|
if (!isRoot) {
|
||||||
|
this.flushInline();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeKnownHelper]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of helper invocation
|
||||||
|
//
|
||||||
|
// This operation is used when the helper is known to exist,
|
||||||
|
// so a `helperMissing` fallback is not required.
|
||||||
|
invokeKnownHelper: function(paramSize, name) {
|
||||||
|
var helper = this.setupHelper(paramSize, name);
|
||||||
|
this.push(helper.name + ".call(" + helper.callParams + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeAmbiguous]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of disambiguation
|
||||||
|
//
|
||||||
|
// This operation is used when an expression like `{{foo}}`
|
||||||
|
// is provided, but we don't know at compile-time whether it
|
||||||
|
// is a helper or a path.
|
||||||
|
//
|
||||||
|
// This operation emits more code than the other options,
|
||||||
|
// and can be avoided by passing the `knownHelpers` and
|
||||||
|
// `knownHelpersOnly` flags at compile-time.
|
||||||
|
invokeAmbiguous: function(name, helperCall) {
|
||||||
|
this.context.aliases.functionType = '"function"';
|
||||||
|
this.useRegister('helper');
|
||||||
|
|
||||||
|
this.emptyHash();
|
||||||
|
var helper = this.setupHelper(0, name, helperCall);
|
||||||
|
|
||||||
|
var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
|
||||||
|
|
||||||
|
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
|
||||||
|
var nextStack = this.nextStack();
|
||||||
|
|
||||||
|
if (helper.paramsInit) {
|
||||||
|
this.pushSource(helper.paramsInit);
|
||||||
|
}
|
||||||
|
this.pushSource('if (helper = ' + helperName + ') { ' + nextStack + ' = helper.call(' + helper.callParams + '); }');
|
||||||
|
this.pushSource('else { helper = ' + nonHelper + '; ' + nextStack + ' = typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper; }');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokePartial]
|
||||||
|
//
|
||||||
|
// On stack, before: context, ...
|
||||||
|
// On stack after: result of partial invocation
|
||||||
|
//
|
||||||
|
// This operation pops off a context, invokes a partial with that context,
|
||||||
|
// and pushes the result of the invocation back.
|
||||||
|
invokePartial: function(name) {
|
||||||
|
var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
|
||||||
|
|
||||||
|
if (this.options.data) {
|
||||||
|
params.push("data");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
this.push("self.invokePartial(" + params.join(", ") + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [assignToHash]
|
||||||
|
//
|
||||||
|
// On stack, before: value, hash, ...
|
||||||
|
// On stack, after: hash, ...
|
||||||
|
//
|
||||||
|
// Pops a value and hash off the stack, assigns `hash[key] = value`
|
||||||
|
// and pushes the hash back onto the stack.
|
||||||
|
assignToHash: function(key) {
|
||||||
|
var value = this.popStack(),
|
||||||
|
context,
|
||||||
|
type;
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
type = this.popStack();
|
||||||
|
context = this.popStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
var hash = this.hash;
|
||||||
|
if (context) {
|
||||||
|
hash.contexts.push("'" + key + "': " + context);
|
||||||
|
}
|
||||||
|
if (type) {
|
||||||
|
hash.types.push("'" + key + "': " + type);
|
||||||
|
}
|
||||||
|
hash.values.push("'" + key + "': (" + value + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// HELPERS
|
||||||
|
|
||||||
|
compiler: JavaScriptCompiler,
|
||||||
|
|
||||||
|
compileChildren: function(environment, options) {
|
||||||
|
var children = environment.children, child, compiler;
|
||||||
|
|
||||||
|
for(var i=0, l=children.length; i<l; i++) {
|
||||||
|
child = children[i];
|
||||||
|
compiler = new this.compiler();
|
||||||
|
|
||||||
|
var index = this.matchExistingProgram(child);
|
||||||
|
|
||||||
|
if (index == null) {
|
||||||
|
this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
|
||||||
|
index = this.context.programs.length;
|
||||||
|
child.index = index;
|
||||||
|
child.name = 'program' + index;
|
||||||
|
this.context.programs[index] = compiler.compile(child, options, this.context);
|
||||||
|
this.context.environments[index] = child;
|
||||||
|
} else {
|
||||||
|
child.index = index;
|
||||||
|
child.name = 'program' + index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
matchExistingProgram: function(child) {
|
||||||
|
for (var i = 0, len = this.context.environments.length; i < len; i++) {
|
||||||
|
var environment = this.context.environments[i];
|
||||||
|
if (environment && environment.equals(child)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
programExpression: function(guid) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
|
||||||
|
if(guid == null) {
|
||||||
|
return "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
var child = this.environment.children[guid],
|
||||||
|
depths = child.depths.list, depth;
|
||||||
|
|
||||||
|
var programParams = [child.index, child.name, "data"];
|
||||||
|
|
||||||
|
for(var i=0, l = depths.length; i<l; i++) {
|
||||||
|
depth = depths[i];
|
||||||
|
|
||||||
|
if(depth === 1) { programParams.push("depth0"); }
|
||||||
|
else { programParams.push("depth" + (depth - 1)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
|
||||||
|
},
|
||||||
|
|
||||||
|
register: function(name, val) {
|
||||||
|
this.useRegister(name);
|
||||||
|
this.pushSource(name + " = " + val + ";");
|
||||||
|
},
|
||||||
|
|
||||||
|
useRegister: function(name) {
|
||||||
|
if(!this.registers[name]) {
|
||||||
|
this.registers[name] = true;
|
||||||
|
this.registers.list.push(name);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
pushStackLiteral: function(item) {
|
||||||
|
return this.push(new Literal(item));
|
||||||
|
},
|
||||||
|
|
||||||
|
pushSource: function(source) {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
|
||||||
|
this.pendingContent = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source) {
|
||||||
|
this.source.push(source);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
pushStack: function(item) {
|
||||||
|
this.flushInline();
|
||||||
|
|
||||||
|
var stack = this.incrStack();
|
||||||
|
if (item) {
|
||||||
|
this.pushSource(stack + " = " + item + ";");
|
||||||
|
}
|
||||||
|
this.compileStack.push(stack);
|
||||||
|
return stack;
|
||||||
|
},
|
||||||
|
|
||||||
|
replaceStack: function(callback) {
|
||||||
|
var prefix = '',
|
||||||
|
inline = this.isInline(),
|
||||||
|
stack,
|
||||||
|
createdStack,
|
||||||
|
usedLiteral;
|
||||||
|
|
||||||
|
// If we are currently inline then we want to merge the inline statement into the
|
||||||
|
// replacement statement via ','
|
||||||
|
if (inline) {
|
||||||
|
var top = this.popStack(true);
|
||||||
|
|
||||||
|
if (top instanceof Literal) {
|
||||||
|
// Literals do not need to be inlined
|
||||||
|
stack = top.value;
|
||||||
|
usedLiteral = true;
|
||||||
|
} else {
|
||||||
|
// Get or create the current stack name for use by the inline
|
||||||
|
createdStack = !this.stackSlot;
|
||||||
|
var name = !createdStack ? this.topStackName() : this.incrStack();
|
||||||
|
|
||||||
|
prefix = '(' + this.push(name) + ' = ' + top + '),';
|
||||||
|
stack = this.topStack();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stack = this.topStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = callback.call(this, stack);
|
||||||
|
|
||||||
|
if (inline) {
|
||||||
|
if (!usedLiteral) {
|
||||||
|
this.popStack();
|
||||||
|
}
|
||||||
|
if (createdStack) {
|
||||||
|
this.stackSlot--;
|
||||||
|
}
|
||||||
|
this.push('(' + prefix + item + ')');
|
||||||
|
} else {
|
||||||
|
// Prevent modification of the context depth variable. Through replaceStack
|
||||||
|
if (!/^stack/.test(stack)) {
|
||||||
|
stack = this.nextStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pushSource(stack + " = (" + prefix + item + ");");
|
||||||
|
}
|
||||||
|
return stack;
|
||||||
|
},
|
||||||
|
|
||||||
|
nextStack: function() {
|
||||||
|
return this.pushStack();
|
||||||
|
},
|
||||||
|
|
||||||
|
incrStack: function() {
|
||||||
|
this.stackSlot++;
|
||||||
|
if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
|
||||||
|
return this.topStackName();
|
||||||
|
},
|
||||||
|
topStackName: function() {
|
||||||
|
return "stack" + this.stackSlot;
|
||||||
|
},
|
||||||
|
flushInline: function() {
|
||||||
|
var inlineStack = this.inlineStack;
|
||||||
|
if (inlineStack.length) {
|
||||||
|
this.inlineStack = [];
|
||||||
|
for (var i = 0, len = inlineStack.length; i < len; i++) {
|
||||||
|
var entry = inlineStack[i];
|
||||||
|
if (entry instanceof Literal) {
|
||||||
|
this.compileStack.push(entry);
|
||||||
|
} else {
|
||||||
|
this.pushStack(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isInline: function() {
|
||||||
|
return this.inlineStack.length;
|
||||||
|
},
|
||||||
|
|
||||||
|
popStack: function(wrapped) {
|
||||||
|
var inline = this.isInline(),
|
||||||
|
item = (inline ? this.inlineStack : this.compileStack).pop();
|
||||||
|
|
||||||
|
if (!wrapped && (item instanceof Literal)) {
|
||||||
|
return item.value;
|
||||||
|
} else {
|
||||||
|
if (!inline) {
|
||||||
|
if (!this.stackSlot) {
|
||||||
|
throw new Exception('Invalid stack pop');
|
||||||
|
}
|
||||||
|
this.stackSlot--;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
topStack: function(wrapped) {
|
||||||
|
var stack = (this.isInline() ? this.inlineStack : this.compileStack),
|
||||||
|
item = stack[stack.length - 1];
|
||||||
|
|
||||||
|
if (!wrapped && (item instanceof Literal)) {
|
||||||
|
return item.value;
|
||||||
|
} else {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
quotedString: function(str) {
|
||||||
|
return '"' + str
|
||||||
|
.replace(/\\/g, '\\\\')
|
||||||
|
.replace(/"/g, '\\"')
|
||||||
|
.replace(/\n/g, '\\n')
|
||||||
|
.replace(/\r/g, '\\r')
|
||||||
|
.replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
|
||||||
|
.replace(/\u2029/g, '\\u2029') + '"';
|
||||||
|
},
|
||||||
|
|
||||||
|
setupHelper: function(paramSize, name, missingParams) {
|
||||||
|
var params = [],
|
||||||
|
paramsInit = this.setupParams(paramSize, params, missingParams);
|
||||||
|
var foundHelper = this.nameLookup('helpers', name, 'helper');
|
||||||
|
|
||||||
|
return {
|
||||||
|
params: params,
|
||||||
|
paramsInit: paramsInit,
|
||||||
|
name: foundHelper,
|
||||||
|
callParams: ["depth0"].concat(params).join(", "),
|
||||||
|
helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
setupOptions: function(paramSize, params) {
|
||||||
|
var options = [], contexts = [], types = [], param, inverse, program;
|
||||||
|
|
||||||
|
options.push("hash:" + this.popStack());
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
options.push("hashTypes:" + this.popStack());
|
||||||
|
options.push("hashContexts:" + this.popStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
inverse = this.popStack();
|
||||||
|
program = this.popStack();
|
||||||
|
|
||||||
|
// Avoid setting fn and inverse if neither are set. This allows
|
||||||
|
// helpers to do a check for `if (options.fn)`
|
||||||
|
if (program || inverse) {
|
||||||
|
if (!program) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
program = "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inverse) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
inverse = "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
options.push("inverse:" + inverse);
|
||||||
|
options.push("fn:" + program);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i=0; i<paramSize; i++) {
|
||||||
|
param = this.popStack();
|
||||||
|
params.push(param);
|
||||||
|
|
||||||
|
if(this.options.stringParams) {
|
||||||
|
types.push(this.popStack());
|
||||||
|
contexts.push(this.popStack());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
options.push("contexts:[" + contexts.join(",") + "]");
|
||||||
|
options.push("types:[" + types.join(",") + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.options.data) {
|
||||||
|
options.push("data:data");
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
},
|
||||||
|
|
||||||
|
// the params and contexts arguments are passed in arrays
|
||||||
|
// to fill in
|
||||||
|
setupParams: function(paramSize, params, useRegister) {
|
||||||
|
var options = '{' + this.setupOptions(paramSize, params).join(',') + '}';
|
||||||
|
|
||||||
|
if (useRegister) {
|
||||||
|
this.useRegister('options');
|
||||||
|
params.push('options');
|
||||||
|
return 'options=' + options;
|
||||||
|
} else {
|
||||||
|
params.push(options);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var reservedWords = (
|
||||||
|
"break else new var" +
|
||||||
|
" case finally return void" +
|
||||||
|
" catch for switch while" +
|
||||||
|
" continue function this with" +
|
||||||
|
" default if throw" +
|
||||||
|
" delete in try" +
|
||||||
|
" do instanceof typeof" +
|
||||||
|
" abstract enum int short" +
|
||||||
|
" boolean export interface static" +
|
||||||
|
" byte extends long super" +
|
||||||
|
" char final native synchronized" +
|
||||||
|
" class float package throws" +
|
||||||
|
" const goto private transient" +
|
||||||
|
" debugger implements protected volatile" +
|
||||||
|
" double import public let yield"
|
||||||
|
).split(" ");
|
||||||
|
|
||||||
|
var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
|
||||||
|
|
||||||
|
for(var i=0, l=reservedWords.length; i<l; i++) {
|
||||||
|
compilerWords[reservedWords[i]] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
|
||||||
|
if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
__exports__["default"] = JavaScriptCompiler;
|
||||||
|
});
|
||||||
494
node_modules/handlebars/dist/amd/handlebars/compiler/parser.js
generated
vendored
Normal file
494
node_modules/handlebars/dist/amd/handlebars/compiler/parser.js
generated
vendored
Normal file
@@ -0,0 +1,494 @@
|
|||||||
|
define(
|
||||||
|
["exports"],
|
||||||
|
function(__exports__) {
|
||||||
|
"use strict";
|
||||||
|
/* jshint ignore:start */
|
||||||
|
/* Jison generated parser */
|
||||||
|
var handlebars = (function(){
|
||||||
|
var parser = {trace: function trace() { },
|
||||||
|
yy: {},
|
||||||
|
symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"sexpr":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"partial_option0":27,"sexpr_repetition0":28,"sexpr_option0":29,"dataName":30,"param":31,"STRING":32,"INTEGER":33,"BOOLEAN":34,"OPEN_SEXPR":35,"CLOSE_SEXPR":36,"hash":37,"hash_repetition_plus0":38,"hashSegment":39,"ID":40,"EQUALS":41,"DATA":42,"pathSegments":43,"SEP":44,"$accept":0,"$end":1},
|
||||||
|
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:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",32:"STRING",33:"INTEGER",34:"BOOLEAN",35:"OPEN_SEXPR",36:"CLOSE_SEXPR",40:"ID",41:"EQUALS",42:"DATA",44:"SEP"},
|
||||||
|
productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[31,3],[37,1],[39,3],[26,1],[26,1],[26,1],[30,2],[21,1],[43,3],[43,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[38,1],[38,2]],
|
||||||
|
performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
|
||||||
|
|
||||||
|
var $0 = $$.length - 1;
|
||||||
|
switch (yystate) {
|
||||||
|
case 1: return new yy.ProgramNode($$[$0-1], this._$);
|
||||||
|
break;
|
||||||
|
case 2: return new yy.ProgramNode([], this._$);
|
||||||
|
break;
|
||||||
|
case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], [], this._$);
|
||||||
|
break;
|
||||||
|
case 6:this.$ = new yy.ProgramNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 7:this.$ = new yy.ProgramNode([], this._$);
|
||||||
|
break;
|
||||||
|
case 8:this.$ = new yy.ProgramNode([], this._$);
|
||||||
|
break;
|
||||||
|
case 9:this.$ = [$$[$0]];
|
||||||
|
break;
|
||||||
|
case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
|
||||||
|
break;
|
||||||
|
case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 13:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 14:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 15:this.$ = new yy.ContentNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 16:this.$ = new yy.CommentNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])};
|
||||||
|
break;
|
||||||
|
case 20:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 21:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 23:this.$ = stripFlags($$[$0-1], $$[$0]);
|
||||||
|
break;
|
||||||
|
case 24:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 25:this.$ = new yy.SexprNode([$$[$0]], null, this._$);
|
||||||
|
break;
|
||||||
|
case 26:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 27:this.$ = new yy.StringNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 28:this.$ = new yy.IntegerNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 29:this.$ = new yy.BooleanNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 30:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 31:$$[$0-1].isHelper = true; this.$ = $$[$0-1];
|
||||||
|
break;
|
||||||
|
case 32:this.$ = new yy.HashNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 33:this.$ = [$$[$0-2], $$[$0]];
|
||||||
|
break;
|
||||||
|
case 34:this.$ = new yy.PartialNameNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 35:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$);
|
||||||
|
break;
|
||||||
|
case 36:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0], this._$));
|
||||||
|
break;
|
||||||
|
case 37:this.$ = new yy.DataNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 38:this.$ = new yy.IdNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 39: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
|
||||||
|
break;
|
||||||
|
case 40:this.$ = [{part: $$[$0]}];
|
||||||
|
break;
|
||||||
|
case 43:this.$ = [];
|
||||||
|
break;
|
||||||
|
case 44:$$[$0-1].push($$[$0]);
|
||||||
|
break;
|
||||||
|
case 47:this.$ = [$$[$0]];
|
||||||
|
break;
|
||||||
|
case 48:$$[$0-1].push($$[$0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
table: [{3:1,4:2,5:[1,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],25:[1,15]},{1:[3]},{5:[1,16],8:17,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],25:[1,15]},{1:[2,2]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],25:[2,9]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],25:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],25:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],25:[2,15]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:29,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:30,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:31,21:24,30:25,40:[1,28],42:[1,27],43:26},{21:33,26:32,32:[1,34],33:[1,35],40:[1,28],43:26},{1:[2,1]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,40:[1,28],42:[1,27],43:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,43],24:[2,43],28:43,32:[2,43],33:[2,43],34:[2,43],35:[2,43],36:[2,43],40:[2,43],42:[2,43]},{18:[2,25],24:[2,25],36:[2,25]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],35:[2,38],36:[2,38],40:[2,38],42:[2,38],44:[1,44]},{21:45,40:[1,28],43:26},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],42:[2,40],44:[2,40]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,41],21:50,27:49,40:[1,28],43:26},{18:[2,34],40:[2,34]},{18:[2,35],40:[2,35]},{18:[2,36],40:[2,36]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],25:[2,11]},{21:51,40:[1,28],43:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],25:[2,12]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,45],21:56,24:[2,45],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:[1,61],36:[2,45],37:55,38:62,39:63,40:[1,64],42:[1,27],43:26},{40:[1,65]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],35:[2,37],36:[2,37],40:[2,37],42:[2,37]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],25:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],25:[2,21]},{18:[1,66]},{18:[2,42]},{18:[1,67]},{8:17,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],25:[1,15]},{18:[2,24],24:[2,24],36:[2,24]},{18:[2,44],24:[2,44],32:[2,44],33:[2,44],34:[2,44],35:[2,44],36:[2,44],40:[2,44],42:[2,44]},{18:[2,46],24:[2,46],36:[2,46]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],35:[2,26],36:[2,26],40:[2,26],42:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],35:[2,27],36:[2,27],40:[2,27],42:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],35:[2,28],36:[2,28],40:[2,28],42:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],35:[2,29],36:[2,29],40:[2,29],42:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],35:[2,30],36:[2,30],40:[2,30],42:[2,30]},{17:68,21:24,30:25,40:[1,28],42:[1,27],43:26},{18:[2,32],24:[2,32],36:[2,32],39:69,40:[1,70]},{18:[2,47],24:[2,47],36:[2,47],40:[2,47]},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],41:[1,71],42:[2,40],44:[2,40]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],35:[2,39],36:[2,39],40:[2,39],42:[2,39],44:[2,39]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],25:[2,19]},{36:[1,72]},{18:[2,48],24:[2,48],36:[2,48],40:[2,48]},{41:[1,71]},{21:56,30:60,31:73,32:[1,57],33:[1,58],34:[1,59],35:[1,61],40:[1,28],42:[1,27],43:26},{18:[2,31],24:[2,31],32:[2,31],33:[2,31],34:[2,31],35:[2,31],36:[2,31],40:[2,31],42:[2,31]},{18:[2,33],24:[2,33],36:[2,33],40:[2,33]}],
|
||||||
|
defaultActions: {3:[2,2],16:[2,1],50:[2,42]},
|
||||||
|
parseError: function parseError(str, hash) {
|
||||||
|
throw new Error(str);
|
||||||
|
},
|
||||||
|
parse: function parse(input) {
|
||||||
|
var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
|
||||||
|
this.lexer.setInput(input);
|
||||||
|
this.lexer.yy = this.yy;
|
||||||
|
this.yy.lexer = this.lexer;
|
||||||
|
this.yy.parser = this;
|
||||||
|
if (typeof this.lexer.yylloc == "undefined")
|
||||||
|
this.lexer.yylloc = {};
|
||||||
|
var yyloc = this.lexer.yylloc;
|
||||||
|
lstack.push(yyloc);
|
||||||
|
var ranges = this.lexer.options && this.lexer.options.ranges;
|
||||||
|
if (typeof this.yy.parseError === "function")
|
||||||
|
this.parseError = this.yy.parseError;
|
||||||
|
function popStack(n) {
|
||||||
|
stack.length = stack.length - 2 * n;
|
||||||
|
vstack.length = vstack.length - n;
|
||||||
|
lstack.length = lstack.length - n;
|
||||||
|
}
|
||||||
|
function lex() {
|
||||||
|
var token;
|
||||||
|
token = self.lexer.lex() || 1;
|
||||||
|
if (typeof token !== "number") {
|
||||||
|
token = self.symbols_[token] || token;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
|
||||||
|
while (true) {
|
||||||
|
state = stack[stack.length - 1];
|
||||||
|
if (this.defaultActions[state]) {
|
||||||
|
action = this.defaultActions[state];
|
||||||
|
} else {
|
||||||
|
if (symbol === null || typeof symbol == "undefined") {
|
||||||
|
symbol = lex();
|
||||||
|
}
|
||||||
|
action = table[state] && table[state][symbol];
|
||||||
|
}
|
||||||
|
if (typeof action === "undefined" || !action.length || !action[0]) {
|
||||||
|
var errStr = "";
|
||||||
|
if (!recovering) {
|
||||||
|
expected = [];
|
||||||
|
for (p in table[state])
|
||||||
|
if (this.terminals_[p] && p > 2) {
|
||||||
|
expected.push("'" + this.terminals_[p] + "'");
|
||||||
|
}
|
||||||
|
if (this.lexer.showPosition) {
|
||||||
|
errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
|
||||||
|
} else {
|
||||||
|
errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
|
||||||
|
}
|
||||||
|
this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (action[0] instanceof Array && action.length > 1) {
|
||||||
|
throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
|
||||||
|
}
|
||||||
|
switch (action[0]) {
|
||||||
|
case 1:
|
||||||
|
stack.push(symbol);
|
||||||
|
vstack.push(this.lexer.yytext);
|
||||||
|
lstack.push(this.lexer.yylloc);
|
||||||
|
stack.push(action[1]);
|
||||||
|
symbol = null;
|
||||||
|
if (!preErrorSymbol) {
|
||||||
|
yyleng = this.lexer.yyleng;
|
||||||
|
yytext = this.lexer.yytext;
|
||||||
|
yylineno = this.lexer.yylineno;
|
||||||
|
yyloc = this.lexer.yylloc;
|
||||||
|
if (recovering > 0)
|
||||||
|
recovering--;
|
||||||
|
} else {
|
||||||
|
symbol = preErrorSymbol;
|
||||||
|
preErrorSymbol = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
len = this.productions_[action[1]][1];
|
||||||
|
yyval.$ = vstack[vstack.length - len];
|
||||||
|
yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
|
||||||
|
if (ranges) {
|
||||||
|
yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
|
||||||
|
}
|
||||||
|
r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
|
||||||
|
if (typeof r !== "undefined") {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
if (len) {
|
||||||
|
stack = stack.slice(0, -1 * len * 2);
|
||||||
|
vstack = vstack.slice(0, -1 * len);
|
||||||
|
lstack = lstack.slice(0, -1 * len);
|
||||||
|
}
|
||||||
|
stack.push(this.productions_[action[1]][0]);
|
||||||
|
vstack.push(yyval.$);
|
||||||
|
lstack.push(yyval._$);
|
||||||
|
newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
|
||||||
|
stack.push(newState);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function stripFlags(open, close) {
|
||||||
|
return {
|
||||||
|
left: open.charAt(2) === '~',
|
||||||
|
right: close.charAt(0) === '~' || close.charAt(1) === '~'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Jison generated lexer */
|
||||||
|
var lexer = (function(){
|
||||||
|
var lexer = ({EOF:1,
|
||||||
|
parseError:function parseError(str, hash) {
|
||||||
|
if (this.yy.parser) {
|
||||||
|
this.yy.parser.parseError(str, hash);
|
||||||
|
} else {
|
||||||
|
throw new Error(str);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setInput:function (input) {
|
||||||
|
this._input = input;
|
||||||
|
this._more = this._less = this.done = false;
|
||||||
|
this.yylineno = this.yyleng = 0;
|
||||||
|
this.yytext = this.matched = this.match = '';
|
||||||
|
this.conditionStack = ['INITIAL'];
|
||||||
|
this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
|
||||||
|
if (this.options.ranges) this.yylloc.range = [0,0];
|
||||||
|
this.offset = 0;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
input:function () {
|
||||||
|
var ch = this._input[0];
|
||||||
|
this.yytext += ch;
|
||||||
|
this.yyleng++;
|
||||||
|
this.offset++;
|
||||||
|
this.match += ch;
|
||||||
|
this.matched += ch;
|
||||||
|
var lines = ch.match(/(?:\r\n?|\n).*/g);
|
||||||
|
if (lines) {
|
||||||
|
this.yylineno++;
|
||||||
|
this.yylloc.last_line++;
|
||||||
|
} else {
|
||||||
|
this.yylloc.last_column++;
|
||||||
|
}
|
||||||
|
if (this.options.ranges) this.yylloc.range[1]++;
|
||||||
|
|
||||||
|
this._input = this._input.slice(1);
|
||||||
|
return ch;
|
||||||
|
},
|
||||||
|
unput:function (ch) {
|
||||||
|
var len = ch.length;
|
||||||
|
var lines = ch.split(/(?:\r\n?|\n)/g);
|
||||||
|
|
||||||
|
this._input = ch + this._input;
|
||||||
|
this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
|
||||||
|
//this.yyleng -= len;
|
||||||
|
this.offset -= len;
|
||||||
|
var oldLines = this.match.split(/(?:\r\n?|\n)/g);
|
||||||
|
this.match = this.match.substr(0, this.match.length-1);
|
||||||
|
this.matched = this.matched.substr(0, this.matched.length-1);
|
||||||
|
|
||||||
|
if (lines.length-1) this.yylineno -= lines.length-1;
|
||||||
|
var r = this.yylloc.range;
|
||||||
|
|
||||||
|
this.yylloc = {first_line: this.yylloc.first_line,
|
||||||
|
last_line: this.yylineno+1,
|
||||||
|
first_column: this.yylloc.first_column,
|
||||||
|
last_column: lines ?
|
||||||
|
(lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
|
||||||
|
this.yylloc.first_column - len
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.options.ranges) {
|
||||||
|
this.yylloc.range = [r[0], r[0] + this.yyleng - len];
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
more:function () {
|
||||||
|
this._more = true;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
less:function (n) {
|
||||||
|
this.unput(this.match.slice(n));
|
||||||
|
},
|
||||||
|
pastInput:function () {
|
||||||
|
var past = this.matched.substr(0, this.matched.length - this.match.length);
|
||||||
|
return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
|
||||||
|
},
|
||||||
|
upcomingInput:function () {
|
||||||
|
var next = this.match;
|
||||||
|
if (next.length < 20) {
|
||||||
|
next += this._input.substr(0, 20-next.length);
|
||||||
|
}
|
||||||
|
return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
|
||||||
|
},
|
||||||
|
showPosition:function () {
|
||||||
|
var pre = this.pastInput();
|
||||||
|
var c = new Array(pre.length + 1).join("-");
|
||||||
|
return pre + this.upcomingInput() + "\n" + c+"^";
|
||||||
|
},
|
||||||
|
next:function () {
|
||||||
|
if (this.done) {
|
||||||
|
return this.EOF;
|
||||||
|
}
|
||||||
|
if (!this._input) this.done = true;
|
||||||
|
|
||||||
|
var token,
|
||||||
|
match,
|
||||||
|
tempMatch,
|
||||||
|
index,
|
||||||
|
col,
|
||||||
|
lines;
|
||||||
|
if (!this._more) {
|
||||||
|
this.yytext = '';
|
||||||
|
this.match = '';
|
||||||
|
}
|
||||||
|
var rules = this._currentRules();
|
||||||
|
for (var i=0;i < rules.length; i++) {
|
||||||
|
tempMatch = this._input.match(this.rules[rules[i]]);
|
||||||
|
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
|
||||||
|
match = tempMatch;
|
||||||
|
index = i;
|
||||||
|
if (!this.options.flex) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (match) {
|
||||||
|
lines = match[0].match(/(?:\r\n?|\n).*/g);
|
||||||
|
if (lines) this.yylineno += lines.length;
|
||||||
|
this.yylloc = {first_line: this.yylloc.last_line,
|
||||||
|
last_line: this.yylineno+1,
|
||||||
|
first_column: this.yylloc.last_column,
|
||||||
|
last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
|
||||||
|
this.yytext += match[0];
|
||||||
|
this.match += match[0];
|
||||||
|
this.matches = match;
|
||||||
|
this.yyleng = this.yytext.length;
|
||||||
|
if (this.options.ranges) {
|
||||||
|
this.yylloc.range = [this.offset, this.offset += this.yyleng];
|
||||||
|
}
|
||||||
|
this._more = false;
|
||||||
|
this._input = this._input.slice(match[0].length);
|
||||||
|
this.matched += match[0];
|
||||||
|
token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
|
||||||
|
if (this.done && this._input) this.done = false;
|
||||||
|
if (token) return token;
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
if (this._input === "") {
|
||||||
|
return this.EOF;
|
||||||
|
} else {
|
||||||
|
return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
|
||||||
|
{text: "", token: null, line: this.yylineno});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lex:function lex() {
|
||||||
|
var r = this.next();
|
||||||
|
if (typeof r !== 'undefined') {
|
||||||
|
return r;
|
||||||
|
} else {
|
||||||
|
return this.lex();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
begin:function begin(condition) {
|
||||||
|
this.conditionStack.push(condition);
|
||||||
|
},
|
||||||
|
popState:function popState() {
|
||||||
|
return this.conditionStack.pop();
|
||||||
|
},
|
||||||
|
_currentRules:function _currentRules() {
|
||||||
|
return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
|
||||||
|
},
|
||||||
|
topState:function () {
|
||||||
|
return this.conditionStack[this.conditionStack.length-2];
|
||||||
|
},
|
||||||
|
pushState:function begin(condition) {
|
||||||
|
this.begin(condition);
|
||||||
|
}});
|
||||||
|
lexer.options = {};
|
||||||
|
lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
|
||||||
|
|
||||||
|
|
||||||
|
function strip(start, end) {
|
||||||
|
return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var YYSTATE=YY_START
|
||||||
|
switch($avoiding_name_collisions) {
|
||||||
|
case 0:
|
||||||
|
if(yy_.yytext.slice(-2) === "\\\\") {
|
||||||
|
strip(0,1);
|
||||||
|
this.begin("mu");
|
||||||
|
} else if(yy_.yytext.slice(-1) === "\\") {
|
||||||
|
strip(0,1);
|
||||||
|
this.begin("emu");
|
||||||
|
} else {
|
||||||
|
this.begin("mu");
|
||||||
|
}
|
||||||
|
if(yy_.yytext) return 14;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 1:return 14;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this.popState();
|
||||||
|
return 14;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 3:strip(0,4); this.popState(); return 15;
|
||||||
|
break;
|
||||||
|
case 4:return 35;
|
||||||
|
break;
|
||||||
|
case 5:return 36;
|
||||||
|
break;
|
||||||
|
case 6:return 25;
|
||||||
|
break;
|
||||||
|
case 7:return 16;
|
||||||
|
break;
|
||||||
|
case 8:return 20;
|
||||||
|
break;
|
||||||
|
case 9:return 19;
|
||||||
|
break;
|
||||||
|
case 10:return 19;
|
||||||
|
break;
|
||||||
|
case 11:return 23;
|
||||||
|
break;
|
||||||
|
case 12:return 22;
|
||||||
|
break;
|
||||||
|
case 13:this.popState(); this.begin('com');
|
||||||
|
break;
|
||||||
|
case 14:strip(3,5); this.popState(); return 15;
|
||||||
|
break;
|
||||||
|
case 15:return 22;
|
||||||
|
break;
|
||||||
|
case 16:return 41;
|
||||||
|
break;
|
||||||
|
case 17:return 40;
|
||||||
|
break;
|
||||||
|
case 18:return 40;
|
||||||
|
break;
|
||||||
|
case 19:return 44;
|
||||||
|
break;
|
||||||
|
case 20:// ignore whitespace
|
||||||
|
break;
|
||||||
|
case 21:this.popState(); return 24;
|
||||||
|
break;
|
||||||
|
case 22:this.popState(); return 18;
|
||||||
|
break;
|
||||||
|
case 23:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 32;
|
||||||
|
break;
|
||||||
|
case 24:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 32;
|
||||||
|
break;
|
||||||
|
case 25:return 42;
|
||||||
|
break;
|
||||||
|
case 26:return 34;
|
||||||
|
break;
|
||||||
|
case 27:return 34;
|
||||||
|
break;
|
||||||
|
case 28:return 33;
|
||||||
|
break;
|
||||||
|
case 29:return 40;
|
||||||
|
break;
|
||||||
|
case 30:yy_.yytext = strip(1,2); return 40;
|
||||||
|
break;
|
||||||
|
case 31:return 'INVALID';
|
||||||
|
break;
|
||||||
|
case 32:return 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
|
||||||
|
lexer.conditions = {"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}};
|
||||||
|
return lexer;})()
|
||||||
|
parser.lexer = lexer;
|
||||||
|
function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
|
||||||
|
return new Parser;
|
||||||
|
})();__exports__["default"] = handlebars;
|
||||||
|
/* jshint ignore:end */
|
||||||
|
});
|
||||||
142
node_modules/handlebars/dist/amd/handlebars/compiler/printer.js
generated
vendored
Normal file
142
node_modules/handlebars/dist/amd/handlebars/compiler/printer.js
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
define(
|
||||||
|
["./visitor","exports"],
|
||||||
|
function(__dependency1__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
var Visitor = __dependency1__["default"];
|
||||||
|
|
||||||
|
function print(ast) {
|
||||||
|
return new PrintVisitor().accept(ast);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.print = print;function PrintVisitor() {
|
||||||
|
this.padding = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.PrintVisitor = PrintVisitor;PrintVisitor.prototype = new Visitor();
|
||||||
|
|
||||||
|
PrintVisitor.prototype.pad = function(string, newline) {
|
||||||
|
var out = "";
|
||||||
|
|
||||||
|
for(var i=0,l=this.padding; i<l; i++) {
|
||||||
|
out = out + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
out = out + string;
|
||||||
|
|
||||||
|
if(newline !== false) { out = out + "\n"; }
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.program = function(program) {
|
||||||
|
var out = "",
|
||||||
|
statements = program.statements,
|
||||||
|
i, l;
|
||||||
|
|
||||||
|
for(i=0, l=statements.length; i<l; i++) {
|
||||||
|
out = out + this.accept(statements[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.padding--;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.block = function(block) {
|
||||||
|
var out = "";
|
||||||
|
|
||||||
|
out = out + this.pad("BLOCK:");
|
||||||
|
this.padding++;
|
||||||
|
out = out + this.accept(block.mustache);
|
||||||
|
if (block.program) {
|
||||||
|
out = out + this.pad("PROGRAM:");
|
||||||
|
this.padding++;
|
||||||
|
out = out + this.accept(block.program);
|
||||||
|
this.padding--;
|
||||||
|
}
|
||||||
|
if (block.inverse) {
|
||||||
|
if (block.program) { this.padding++; }
|
||||||
|
out = out + this.pad("{{^}}");
|
||||||
|
this.padding++;
|
||||||
|
out = out + this.accept(block.inverse);
|
||||||
|
this.padding--;
|
||||||
|
if (block.program) { this.padding--; }
|
||||||
|
}
|
||||||
|
this.padding--;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.sexpr = function(sexpr) {
|
||||||
|
var params = sexpr.params, paramStrings = [], hash;
|
||||||
|
|
||||||
|
for(var i=0, l=params.length; i<l; i++) {
|
||||||
|
paramStrings.push(this.accept(params[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
params = "[" + paramStrings.join(", ") + "]";
|
||||||
|
|
||||||
|
hash = sexpr.hash ? " " + this.accept(sexpr.hash) : "";
|
||||||
|
|
||||||
|
return this.accept(sexpr.id) + " " + params + hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.mustache = function(mustache) {
|
||||||
|
return this.pad("{{ " + this.accept(mustache.sexpr) + " }}");
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.partial = function(partial) {
|
||||||
|
var content = this.accept(partial.partialName);
|
||||||
|
if(partial.context) { content = content + " " + this.accept(partial.context); }
|
||||||
|
return this.pad("{{> " + content + " }}");
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.hash = function(hash) {
|
||||||
|
var pairs = hash.pairs;
|
||||||
|
var joinedPairs = [], left, right;
|
||||||
|
|
||||||
|
for(var i=0, l=pairs.length; i<l; i++) {
|
||||||
|
left = pairs[i][0];
|
||||||
|
right = this.accept(pairs[i][1]);
|
||||||
|
joinedPairs.push( left + "=" + right );
|
||||||
|
}
|
||||||
|
|
||||||
|
return "HASH{" + joinedPairs.join(", ") + "}";
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.STRING = function(string) {
|
||||||
|
return '"' + string.string + '"';
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.INTEGER = function(integer) {
|
||||||
|
return "INTEGER{" + integer.integer + "}";
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.BOOLEAN = function(bool) {
|
||||||
|
return "BOOLEAN{" + bool.bool + "}";
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.ID = function(id) {
|
||||||
|
var path = id.parts.join("/");
|
||||||
|
if(id.parts.length > 1) {
|
||||||
|
return "PATH:" + path;
|
||||||
|
} else {
|
||||||
|
return "ID:" + path;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.PARTIAL_NAME = function(partialName) {
|
||||||
|
return "PARTIAL:" + partialName.name;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.DATA = function(data) {
|
||||||
|
return "@" + this.accept(data.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.content = function(content) {
|
||||||
|
return this.pad("CONTENT[ '" + content.string + "' ]");
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.comment = function(comment) {
|
||||||
|
return this.pad("{{! '" + comment.comment + "' }}");
|
||||||
|
};
|
||||||
|
});
|
||||||
16
node_modules/handlebars/dist/amd/handlebars/compiler/visitor.js
generated
vendored
Normal file
16
node_modules/handlebars/dist/amd/handlebars/compiler/visitor.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
define(
|
||||||
|
["exports"],
|
||||||
|
function(__exports__) {
|
||||||
|
"use strict";
|
||||||
|
function Visitor() {}
|
||||||
|
|
||||||
|
Visitor.prototype = {
|
||||||
|
constructor: Visitor,
|
||||||
|
|
||||||
|
accept: function(object) {
|
||||||
|
return this[object.type](object);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
__exports__["default"] = Visitor;
|
||||||
|
});
|
||||||
32
node_modules/handlebars/dist/amd/handlebars/exception.js
generated
vendored
Normal file
32
node_modules/handlebars/dist/amd/handlebars/exception.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
define(
|
||||||
|
["exports"],
|
||||||
|
function(__exports__) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
||||||
|
|
||||||
|
function Exception(message, node) {
|
||||||
|
var line;
|
||||||
|
if (node && node.firstLine) {
|
||||||
|
line = node.firstLine;
|
||||||
|
|
||||||
|
message += ' - ' + line + ':' + node.firstColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp = Error.prototype.constructor.call(this, message);
|
||||||
|
|
||||||
|
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
||||||
|
for (var idx = 0; idx < errorProps.length; idx++) {
|
||||||
|
this[errorProps[idx]] = tmp[errorProps[idx]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line) {
|
||||||
|
this.lineNumber = line;
|
||||||
|
this.column = node.firstColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Exception.prototype = new Error();
|
||||||
|
|
||||||
|
__exports__["default"] = Exception;
|
||||||
|
});
|
||||||
141
node_modules/handlebars/dist/amd/handlebars/runtime.js
generated
vendored
Normal file
141
node_modules/handlebars/dist/amd/handlebars/runtime.js
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
define(
|
||||||
|
["./utils","./exception","./base","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
var Utils = __dependency1__;
|
||||||
|
var Exception = __dependency2__["default"];
|
||||||
|
var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
|
||||||
|
|
||||||
|
function checkRevision(compilerInfo) {
|
||||||
|
var compilerRevision = compilerInfo && compilerInfo[0] || 1,
|
||||||
|
currentRevision = COMPILER_REVISION;
|
||||||
|
|
||||||
|
if (compilerRevision !== currentRevision) {
|
||||||
|
if (compilerRevision < currentRevision) {
|
||||||
|
var runtimeVersions = REVISION_CHANGES[currentRevision],
|
||||||
|
compilerVersions = REVISION_CHANGES[compilerRevision];
|
||||||
|
throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
|
||||||
|
} else {
|
||||||
|
// Use the embedded version info since the runtime doesn't know about this revision yet
|
||||||
|
throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your runtime to a newer version ("+compilerInfo[1]+").");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial
|
||||||
|
|
||||||
|
function template(templateSpec, env) {
|
||||||
|
if (!env) {
|
||||||
|
throw new Exception("No environment passed to template");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Using env.VM references rather than local var references throughout this section to allow
|
||||||
|
// for external users to override these as psuedo-supported APIs.
|
||||||
|
var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
|
||||||
|
var result = env.VM.invokePartial.apply(this, arguments);
|
||||||
|
if (result != null) { return result; }
|
||||||
|
|
||||||
|
if (env.compile) {
|
||||||
|
var options = { helpers: helpers, partials: partials, data: data };
|
||||||
|
partials[name] = env.compile(partial, { data: data !== undefined }, env);
|
||||||
|
return partials[name](context, options);
|
||||||
|
} else {
|
||||||
|
throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Just add water
|
||||||
|
var container = {
|
||||||
|
escapeExpression: Utils.escapeExpression,
|
||||||
|
invokePartial: invokePartialWrapper,
|
||||||
|
programs: [],
|
||||||
|
program: function(i, fn, data) {
|
||||||
|
var programWrapper = this.programs[i];
|
||||||
|
if(data) {
|
||||||
|
programWrapper = program(i, fn, data);
|
||||||
|
} else if (!programWrapper) {
|
||||||
|
programWrapper = this.programs[i] = program(i, fn);
|
||||||
|
}
|
||||||
|
return programWrapper;
|
||||||
|
},
|
||||||
|
merge: function(param, common) {
|
||||||
|
var ret = param || common;
|
||||||
|
|
||||||
|
if (param && common && (param !== common)) {
|
||||||
|
ret = {};
|
||||||
|
Utils.extend(ret, common);
|
||||||
|
Utils.extend(ret, param);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
programWithDepth: env.VM.programWithDepth,
|
||||||
|
noop: env.VM.noop,
|
||||||
|
compilerInfo: null
|
||||||
|
};
|
||||||
|
|
||||||
|
return function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
var namespace = options.partial ? options : env,
|
||||||
|
helpers,
|
||||||
|
partials;
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
helpers = options.helpers;
|
||||||
|
partials = options.partials;
|
||||||
|
}
|
||||||
|
var result = templateSpec.call(
|
||||||
|
container,
|
||||||
|
namespace, context,
|
||||||
|
helpers,
|
||||||
|
partials,
|
||||||
|
options.data);
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
env.VM.checkRevision(container.compilerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 3);
|
||||||
|
|
||||||
|
var prog = function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
return fn.apply(this, [context, options.data || data].concat(args));
|
||||||
|
};
|
||||||
|
prog.program = i;
|
||||||
|
prog.depth = args.length;
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
|
||||||
|
var prog = function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
return fn(context, options.data || data);
|
||||||
|
};
|
||||||
|
prog.program = i;
|
||||||
|
prog.depth = 0;
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
|
||||||
|
var options = { partial: true, helpers: helpers, partials: partials, data: data };
|
||||||
|
|
||||||
|
if(partial === undefined) {
|
||||||
|
throw new Exception("The partial " + name + " could not be found");
|
||||||
|
} else if(partial instanceof Function) {
|
||||||
|
return partial(context, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.invokePartial = invokePartial;function noop() { return ""; }
|
||||||
|
|
||||||
|
__exports__.noop = noop;
|
||||||
|
});
|
||||||
15
node_modules/handlebars/dist/amd/handlebars/safe-string.js
generated
vendored
Normal file
15
node_modules/handlebars/dist/amd/handlebars/safe-string.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
define(
|
||||||
|
["exports"],
|
||||||
|
function(__exports__) {
|
||||||
|
"use strict";
|
||||||
|
// Build out our basic SafeString type
|
||||||
|
function SafeString(string) {
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeString.prototype.toString = function() {
|
||||||
|
return "" + this.string;
|
||||||
|
};
|
||||||
|
|
||||||
|
__exports__["default"] = SafeString;
|
||||||
|
});
|
||||||
80
node_modules/handlebars/dist/amd/handlebars/utils.js
generated
vendored
Normal file
80
node_modules/handlebars/dist/amd/handlebars/utils.js
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
define(
|
||||||
|
["./safe-string","exports"],
|
||||||
|
function(__dependency1__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
/*jshint -W004 */
|
||||||
|
var SafeString = __dependency1__["default"];
|
||||||
|
|
||||||
|
var escape = {
|
||||||
|
"&": "&",
|
||||||
|
"<": "<",
|
||||||
|
">": ">",
|
||||||
|
'"': """,
|
||||||
|
"'": "'",
|
||||||
|
"`": "`"
|
||||||
|
};
|
||||||
|
|
||||||
|
var badChars = /[&<>"'`]/g;
|
||||||
|
var possible = /[&<>"'`]/;
|
||||||
|
|
||||||
|
function escapeChar(chr) {
|
||||||
|
return escape[chr] || "&";
|
||||||
|
}
|
||||||
|
|
||||||
|
function extend(obj, value) {
|
||||||
|
for(var key in value) {
|
||||||
|
if(Object.prototype.hasOwnProperty.call(value, key)) {
|
||||||
|
obj[key] = value[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.extend = extend;var toString = Object.prototype.toString;
|
||||||
|
__exports__.toString = toString;
|
||||||
|
// Sourced from lodash
|
||||||
|
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
|
||||||
|
var isFunction = function(value) {
|
||||||
|
return typeof value === 'function';
|
||||||
|
};
|
||||||
|
// fallback for older versions of Chrome and Safari
|
||||||
|
if (isFunction(/x/)) {
|
||||||
|
isFunction = function(value) {
|
||||||
|
return typeof value === 'function' && toString.call(value) === '[object Function]';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var isFunction;
|
||||||
|
__exports__.isFunction = isFunction;
|
||||||
|
var isArray = Array.isArray || function(value) {
|
||||||
|
return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
|
||||||
|
};
|
||||||
|
__exports__.isArray = isArray;
|
||||||
|
|
||||||
|
function escapeExpression(string) {
|
||||||
|
// don't escape SafeStrings, since they're already safe
|
||||||
|
if (string instanceof SafeString) {
|
||||||
|
return string.toString();
|
||||||
|
} else if (!string && string !== 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force a string conversion as this will be done by the append regardless and
|
||||||
|
// the regex test will do this transparently behind the scenes, causing issues if
|
||||||
|
// an object's to string has escaped characters in it.
|
||||||
|
string = "" + string;
|
||||||
|
|
||||||
|
if(!possible.test(string)) { return string; }
|
||||||
|
return string.replace(badChars, escapeChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.escapeExpression = escapeExpression;function isEmpty(value) {
|
||||||
|
if (!value && value !== 0) {
|
||||||
|
return true;
|
||||||
|
} else if (isArray(value) && value.length === 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.isEmpty = isEmpty;
|
||||||
|
});
|
||||||
37
node_modules/handlebars/dist/cjs/handlebars.js
generated
vendored
Normal file
37
node_modules/handlebars/dist/cjs/handlebars.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
"use strict";
|
||||||
|
/*globals Handlebars: true */
|
||||||
|
var Handlebars = require("./handlebars.runtime")["default"];
|
||||||
|
|
||||||
|
// Compiler imports
|
||||||
|
var AST = require("./handlebars/compiler/ast")["default"];
|
||||||
|
var Parser = require("./handlebars/compiler/base").parser;
|
||||||
|
var parse = require("./handlebars/compiler/base").parse;
|
||||||
|
var Compiler = require("./handlebars/compiler/compiler").Compiler;
|
||||||
|
var compile = require("./handlebars/compiler/compiler").compile;
|
||||||
|
var precompile = require("./handlebars/compiler/compiler").precompile;
|
||||||
|
var JavaScriptCompiler = require("./handlebars/compiler/javascript-compiler")["default"];
|
||||||
|
|
||||||
|
var _create = Handlebars.create;
|
||||||
|
var create = function() {
|
||||||
|
var hb = _create();
|
||||||
|
|
||||||
|
hb.compile = function(input, options) {
|
||||||
|
return compile(input, options, hb);
|
||||||
|
};
|
||||||
|
hb.precompile = function (input, options) {
|
||||||
|
return precompile(input, options, hb);
|
||||||
|
};
|
||||||
|
|
||||||
|
hb.AST = AST;
|
||||||
|
hb.Compiler = Compiler;
|
||||||
|
hb.JavaScriptCompiler = JavaScriptCompiler;
|
||||||
|
hb.Parser = Parser;
|
||||||
|
hb.parse = parse;
|
||||||
|
|
||||||
|
return hb;
|
||||||
|
};
|
||||||
|
|
||||||
|
Handlebars = create();
|
||||||
|
Handlebars.create = create;
|
||||||
|
|
||||||
|
exports["default"] = Handlebars;
|
||||||
32
node_modules/handlebars/dist/cjs/handlebars.runtime.js
generated
vendored
Normal file
32
node_modules/handlebars/dist/cjs/handlebars.runtime.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
"use strict";
|
||||||
|
/*globals Handlebars: true */
|
||||||
|
var base = require("./handlebars/base");
|
||||||
|
|
||||||
|
// Each of these augment the Handlebars object. No need to setup here.
|
||||||
|
// (This is done to easily share code between commonjs and browse envs)
|
||||||
|
var SafeString = require("./handlebars/safe-string")["default"];
|
||||||
|
var Exception = require("./handlebars/exception")["default"];
|
||||||
|
var Utils = require("./handlebars/utils");
|
||||||
|
var runtime = require("./handlebars/runtime");
|
||||||
|
|
||||||
|
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
|
||||||
|
var create = function() {
|
||||||
|
var hb = new base.HandlebarsEnvironment();
|
||||||
|
|
||||||
|
Utils.extend(hb, base);
|
||||||
|
hb.SafeString = SafeString;
|
||||||
|
hb.Exception = Exception;
|
||||||
|
hb.Utils = Utils;
|
||||||
|
|
||||||
|
hb.VM = runtime;
|
||||||
|
hb.template = function(spec) {
|
||||||
|
return runtime.template(spec, hb);
|
||||||
|
};
|
||||||
|
|
||||||
|
return hb;
|
||||||
|
};
|
||||||
|
|
||||||
|
var Handlebars = create();
|
||||||
|
Handlebars.create = create;
|
||||||
|
|
||||||
|
exports["default"] = Handlebars;
|
||||||
180
node_modules/handlebars/dist/cjs/handlebars/base.js
generated
vendored
Normal file
180
node_modules/handlebars/dist/cjs/handlebars/base.js
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
"use strict";
|
||||||
|
var Utils = require("./utils");
|
||||||
|
var Exception = require("./exception")["default"];
|
||||||
|
|
||||||
|
var VERSION = "1.3.0";
|
||||||
|
exports.VERSION = VERSION;var COMPILER_REVISION = 4;
|
||||||
|
exports.COMPILER_REVISION = COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = {
|
||||||
|
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
||||||
|
2: '== 1.0.0-rc.3',
|
||||||
|
3: '== 1.0.0-rc.4',
|
||||||
|
4: '>= 1.0.0'
|
||||||
|
};
|
||||||
|
exports.REVISION_CHANGES = REVISION_CHANGES;
|
||||||
|
var isArray = Utils.isArray,
|
||||||
|
isFunction = Utils.isFunction,
|
||||||
|
toString = Utils.toString,
|
||||||
|
objectType = '[object Object]';
|
||||||
|
|
||||||
|
function HandlebarsEnvironment(helpers, partials) {
|
||||||
|
this.helpers = helpers || {};
|
||||||
|
this.partials = partials || {};
|
||||||
|
|
||||||
|
registerDefaultHelpers(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
|
||||||
|
constructor: HandlebarsEnvironment,
|
||||||
|
|
||||||
|
logger: logger,
|
||||||
|
log: log,
|
||||||
|
|
||||||
|
registerHelper: function(name, fn, inverse) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
|
||||||
|
Utils.extend(this.helpers, name);
|
||||||
|
} else {
|
||||||
|
if (inverse) { fn.not = inverse; }
|
||||||
|
this.helpers[name] = fn;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
registerPartial: function(name, str) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
Utils.extend(this.partials, name);
|
||||||
|
} else {
|
||||||
|
this.partials[name] = str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function registerDefaultHelpers(instance) {
|
||||||
|
instance.registerHelper('helperMissing', function(arg) {
|
||||||
|
if(arguments.length === 2) {
|
||||||
|
return undefined;
|
||||||
|
} else {
|
||||||
|
throw new Exception("Missing helper: '" + arg + "'");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('blockHelperMissing', function(context, options) {
|
||||||
|
var inverse = options.inverse || function() {}, fn = options.fn;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if(context === true) {
|
||||||
|
return fn(this);
|
||||||
|
} else if(context === false || context == null) {
|
||||||
|
return inverse(this);
|
||||||
|
} else if (isArray(context)) {
|
||||||
|
if(context.length > 0) {
|
||||||
|
return instance.helpers.each(context, options);
|
||||||
|
} else {
|
||||||
|
return inverse(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fn(context);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('each', function(context, options) {
|
||||||
|
var fn = options.fn, inverse = options.inverse;
|
||||||
|
var i = 0, ret = "", data;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if (options.data) {
|
||||||
|
data = createFrame(options.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(context && typeof context === 'object') {
|
||||||
|
if (isArray(context)) {
|
||||||
|
for(var j = context.length; i<j; i++) {
|
||||||
|
if (data) {
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
data.last = (i === (context.length-1));
|
||||||
|
}
|
||||||
|
ret = ret + fn(context[i], { data: data });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(var key in context) {
|
||||||
|
if(context.hasOwnProperty(key)) {
|
||||||
|
if(data) {
|
||||||
|
data.key = key;
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
}
|
||||||
|
ret = ret + fn(context[key], {data: data});
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i === 0){
|
||||||
|
ret = inverse(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('if', function(conditional, options) {
|
||||||
|
if (isFunction(conditional)) { conditional = conditional.call(this); }
|
||||||
|
|
||||||
|
// Default behavior is to render the positive path if the value is truthy and not empty.
|
||||||
|
// The `includeZero` option may be set to treat the condtional as purely not empty based on the
|
||||||
|
// behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
|
||||||
|
if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
|
||||||
|
return options.inverse(this);
|
||||||
|
} else {
|
||||||
|
return options.fn(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('unless', function(conditional, options) {
|
||||||
|
return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('with', function(context, options) {
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if (!Utils.isEmpty(context)) return options.fn(context);
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('log', function(context, options) {
|
||||||
|
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
|
||||||
|
instance.log(level, context);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var logger = {
|
||||||
|
methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
|
||||||
|
|
||||||
|
// State enum
|
||||||
|
DEBUG: 0,
|
||||||
|
INFO: 1,
|
||||||
|
WARN: 2,
|
||||||
|
ERROR: 3,
|
||||||
|
level: 3,
|
||||||
|
|
||||||
|
// can be overridden in the host environment
|
||||||
|
log: function(level, obj) {
|
||||||
|
if (logger.level <= level) {
|
||||||
|
var method = logger.methodMap[level];
|
||||||
|
if (typeof console !== 'undefined' && console[method]) {
|
||||||
|
console[method].call(console, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.logger = logger;
|
||||||
|
function log(level, obj) { logger.log(level, obj); }
|
||||||
|
|
||||||
|
exports.log = log;var createFrame = function(object) {
|
||||||
|
var obj = {};
|
||||||
|
Utils.extend(obj, object);
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
exports.createFrame = createFrame;
|
||||||
227
node_modules/handlebars/dist/cjs/handlebars/compiler/ast.js
generated
vendored
Normal file
227
node_modules/handlebars/dist/cjs/handlebars/compiler/ast.js
generated
vendored
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
"use strict";
|
||||||
|
var Exception = require("../exception")["default"];
|
||||||
|
|
||||||
|
function LocationInfo(locInfo){
|
||||||
|
locInfo = locInfo || {};
|
||||||
|
this.firstLine = locInfo.first_line;
|
||||||
|
this.firstColumn = locInfo.first_column;
|
||||||
|
this.lastColumn = locInfo.last_column;
|
||||||
|
this.lastLine = locInfo.last_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
var AST = {
|
||||||
|
ProgramNode: function(statements, inverseStrip, inverse, locInfo) {
|
||||||
|
var inverseLocationInfo, firstInverseNode;
|
||||||
|
if (arguments.length === 3) {
|
||||||
|
locInfo = inverse;
|
||||||
|
inverse = null;
|
||||||
|
} else if (arguments.length === 2) {
|
||||||
|
locInfo = inverseStrip;
|
||||||
|
inverseStrip = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "program";
|
||||||
|
this.statements = statements;
|
||||||
|
this.strip = {};
|
||||||
|
|
||||||
|
if(inverse) {
|
||||||
|
firstInverseNode = inverse[0];
|
||||||
|
if (firstInverseNode) {
|
||||||
|
inverseLocationInfo = {
|
||||||
|
first_line: firstInverseNode.firstLine,
|
||||||
|
last_line: firstInverseNode.lastLine,
|
||||||
|
last_column: firstInverseNode.lastColumn,
|
||||||
|
first_column: firstInverseNode.firstColumn
|
||||||
|
};
|
||||||
|
this.inverse = new AST.ProgramNode(inverse, inverseStrip, inverseLocationInfo);
|
||||||
|
} else {
|
||||||
|
this.inverse = new AST.ProgramNode(inverse, inverseStrip);
|
||||||
|
}
|
||||||
|
this.strip.right = inverseStrip.left;
|
||||||
|
} else if (inverseStrip) {
|
||||||
|
this.strip.left = inverseStrip.right;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
MustacheNode: function(rawParams, hash, open, strip, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "mustache";
|
||||||
|
this.strip = strip;
|
||||||
|
|
||||||
|
// Open may be a string parsed from the parser or a passed boolean flag
|
||||||
|
if (open != null && open.charAt) {
|
||||||
|
// Must use charAt to support IE pre-10
|
||||||
|
var escapeFlag = open.charAt(3) || open.charAt(2);
|
||||||
|
this.escaped = escapeFlag !== '{' && escapeFlag !== '&';
|
||||||
|
} else {
|
||||||
|
this.escaped = !!open;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawParams instanceof AST.SexprNode) {
|
||||||
|
this.sexpr = rawParams;
|
||||||
|
} else {
|
||||||
|
// Support old AST API
|
||||||
|
this.sexpr = new AST.SexprNode(rawParams, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sexpr.isRoot = true;
|
||||||
|
|
||||||
|
// Support old AST API that stored this info in MustacheNode
|
||||||
|
this.id = this.sexpr.id;
|
||||||
|
this.params = this.sexpr.params;
|
||||||
|
this.hash = this.sexpr.hash;
|
||||||
|
this.eligibleHelper = this.sexpr.eligibleHelper;
|
||||||
|
this.isHelper = this.sexpr.isHelper;
|
||||||
|
},
|
||||||
|
|
||||||
|
SexprNode: function(rawParams, hash, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
|
||||||
|
this.type = "sexpr";
|
||||||
|
this.hash = hash;
|
||||||
|
|
||||||
|
var id = this.id = rawParams[0];
|
||||||
|
var params = this.params = rawParams.slice(1);
|
||||||
|
|
||||||
|
// a mustache is an eligible helper if:
|
||||||
|
// * its id is simple (a single part, not `this` or `..`)
|
||||||
|
var eligibleHelper = this.eligibleHelper = id.isSimple;
|
||||||
|
|
||||||
|
// a mustache is definitely a helper if:
|
||||||
|
// * it is an eligible helper, and
|
||||||
|
// * it has at least one parameter or hash segment
|
||||||
|
this.isHelper = eligibleHelper && (params.length || hash);
|
||||||
|
|
||||||
|
// if a mustache is an eligible helper but not a definite
|
||||||
|
// helper, it is ambiguous, and will be resolved in a later
|
||||||
|
// pass or at runtime.
|
||||||
|
},
|
||||||
|
|
||||||
|
PartialNode: function(partialName, context, strip, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "partial";
|
||||||
|
this.partialName = partialName;
|
||||||
|
this.context = context;
|
||||||
|
this.strip = strip;
|
||||||
|
},
|
||||||
|
|
||||||
|
BlockNode: function(mustache, program, inverse, close, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
|
||||||
|
if(mustache.sexpr.id.original !== close.path.original) {
|
||||||
|
throw new Exception(mustache.sexpr.id.original + " doesn't match " + close.path.original, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.type = 'block';
|
||||||
|
this.mustache = mustache;
|
||||||
|
this.program = program;
|
||||||
|
this.inverse = inverse;
|
||||||
|
|
||||||
|
this.strip = {
|
||||||
|
left: mustache.strip.left,
|
||||||
|
right: close.strip.right
|
||||||
|
};
|
||||||
|
|
||||||
|
(program || inverse).strip.left = mustache.strip.right;
|
||||||
|
(inverse || program).strip.right = close.strip.left;
|
||||||
|
|
||||||
|
if (inverse && !program) {
|
||||||
|
this.isInverse = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ContentNode: function(string, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "content";
|
||||||
|
this.string = string;
|
||||||
|
},
|
||||||
|
|
||||||
|
HashNode: function(pairs, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "hash";
|
||||||
|
this.pairs = pairs;
|
||||||
|
},
|
||||||
|
|
||||||
|
IdNode: function(parts, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "ID";
|
||||||
|
|
||||||
|
var original = "",
|
||||||
|
dig = [],
|
||||||
|
depth = 0;
|
||||||
|
|
||||||
|
for(var i=0,l=parts.length; i<l; i++) {
|
||||||
|
var part = parts[i].part;
|
||||||
|
original += (parts[i].separator || '') + part;
|
||||||
|
|
||||||
|
if (part === ".." || part === "." || part === "this") {
|
||||||
|
if (dig.length > 0) {
|
||||||
|
throw new Exception("Invalid path: " + original, this);
|
||||||
|
} else if (part === "..") {
|
||||||
|
depth++;
|
||||||
|
} else {
|
||||||
|
this.isScoped = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dig.push(part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.original = original;
|
||||||
|
this.parts = dig;
|
||||||
|
this.string = dig.join('.');
|
||||||
|
this.depth = depth;
|
||||||
|
|
||||||
|
// an ID is simple if it only has one part, and that part is not
|
||||||
|
// `..` or `this`.
|
||||||
|
this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
|
||||||
|
|
||||||
|
this.stringModeValue = this.string;
|
||||||
|
},
|
||||||
|
|
||||||
|
PartialNameNode: function(name, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "PARTIAL_NAME";
|
||||||
|
this.name = name.original;
|
||||||
|
},
|
||||||
|
|
||||||
|
DataNode: function(id, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "DATA";
|
||||||
|
this.id = id;
|
||||||
|
},
|
||||||
|
|
||||||
|
StringNode: function(string, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "STRING";
|
||||||
|
this.original =
|
||||||
|
this.string =
|
||||||
|
this.stringModeValue = string;
|
||||||
|
},
|
||||||
|
|
||||||
|
IntegerNode: function(integer, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "INTEGER";
|
||||||
|
this.original =
|
||||||
|
this.integer = integer;
|
||||||
|
this.stringModeValue = Number(integer);
|
||||||
|
},
|
||||||
|
|
||||||
|
BooleanNode: function(bool, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "BOOLEAN";
|
||||||
|
this.bool = bool;
|
||||||
|
this.stringModeValue = bool === "true";
|
||||||
|
},
|
||||||
|
|
||||||
|
CommentNode: function(comment, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "comment";
|
||||||
|
this.comment = comment;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Must be exported as an object rather than the root of the module as the jison lexer
|
||||||
|
// most modify the object to operate properly.
|
||||||
|
exports["default"] = AST;
|
||||||
15
node_modules/handlebars/dist/cjs/handlebars/compiler/base.js
generated
vendored
Normal file
15
node_modules/handlebars/dist/cjs/handlebars/compiler/base.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
"use strict";
|
||||||
|
var parser = require("./parser")["default"];
|
||||||
|
var AST = require("./ast")["default"];
|
||||||
|
|
||||||
|
exports.parser = parser;
|
||||||
|
|
||||||
|
function parse(input) {
|
||||||
|
// Just return if an already-compile AST was passed in.
|
||||||
|
if(input.constructor === AST.ProgramNode) { return input; }
|
||||||
|
|
||||||
|
parser.yy = AST;
|
||||||
|
return parser.parse(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.parse = parse;
|
||||||
469
node_modules/handlebars/dist/cjs/handlebars/compiler/compiler.js
generated
vendored
Normal file
469
node_modules/handlebars/dist/cjs/handlebars/compiler/compiler.js
generated
vendored
Normal file
@@ -0,0 +1,469 @@
|
|||||||
|
"use strict";
|
||||||
|
var Exception = require("../exception")["default"];
|
||||||
|
|
||||||
|
function Compiler() {}
|
||||||
|
|
||||||
|
exports.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a
|
||||||
|
// function in a context. This is necessary for mustache compatibility, which
|
||||||
|
// requires that context functions in blocks are evaluated by blockHelperMissing,
|
||||||
|
// and then proceed as if the resulting value was provided to blockHelperMissing.
|
||||||
|
|
||||||
|
Compiler.prototype = {
|
||||||
|
compiler: Compiler,
|
||||||
|
|
||||||
|
disassemble: function() {
|
||||||
|
var opcodes = this.opcodes, opcode, out = [], params, param;
|
||||||
|
|
||||||
|
for (var i=0, l=opcodes.length; i<l; i++) {
|
||||||
|
opcode = opcodes[i];
|
||||||
|
|
||||||
|
if (opcode.opcode === 'DECLARE') {
|
||||||
|
out.push("DECLARE " + opcode.name + "=" + opcode.value);
|
||||||
|
} else {
|
||||||
|
params = [];
|
||||||
|
for (var j=0; j<opcode.args.length; j++) {
|
||||||
|
param = opcode.args[j];
|
||||||
|
if (typeof param === "string") {
|
||||||
|
param = "\"" + param.replace("\n", "\\n") + "\"";
|
||||||
|
}
|
||||||
|
params.push(param);
|
||||||
|
}
|
||||||
|
out.push(opcode.opcode + " " + params.join(" "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.join("\n");
|
||||||
|
},
|
||||||
|
|
||||||
|
equals: function(other) {
|
||||||
|
var len = this.opcodes.length;
|
||||||
|
if (other.opcodes.length !== len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
var opcode = this.opcodes[i],
|
||||||
|
otherOpcode = other.opcodes[i];
|
||||||
|
if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (var j = 0; j < opcode.args.length; j++) {
|
||||||
|
if (opcode.args[j] !== otherOpcode.args[j]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len = this.children.length;
|
||||||
|
if (other.children.length !== len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (!this.children[i].equals(other.children[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
guid: 0,
|
||||||
|
|
||||||
|
compile: function(program, options) {
|
||||||
|
this.opcodes = [];
|
||||||
|
this.children = [];
|
||||||
|
this.depths = {list: []};
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
|
// These changes will propagate to the other compiler components
|
||||||
|
var knownHelpers = this.options.knownHelpers;
|
||||||
|
this.options.knownHelpers = {
|
||||||
|
'helperMissing': true,
|
||||||
|
'blockHelperMissing': true,
|
||||||
|
'each': true,
|
||||||
|
'if': true,
|
||||||
|
'unless': true,
|
||||||
|
'with': true,
|
||||||
|
'log': true
|
||||||
|
};
|
||||||
|
if (knownHelpers) {
|
||||||
|
for (var name in knownHelpers) {
|
||||||
|
this.options.knownHelpers[name] = knownHelpers[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.accept(program);
|
||||||
|
},
|
||||||
|
|
||||||
|
accept: function(node) {
|
||||||
|
var strip = node.strip || {},
|
||||||
|
ret;
|
||||||
|
if (strip.left) {
|
||||||
|
this.opcode('strip');
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = this[node.type](node);
|
||||||
|
|
||||||
|
if (strip.right) {
|
||||||
|
this.opcode('strip');
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
|
||||||
|
program: function(program) {
|
||||||
|
var statements = program.statements;
|
||||||
|
|
||||||
|
for(var i=0, l=statements.length; i<l; i++) {
|
||||||
|
this.accept(statements[i]);
|
||||||
|
}
|
||||||
|
this.isSimple = l === 1;
|
||||||
|
|
||||||
|
this.depths.list = this.depths.list.sort(function(a, b) {
|
||||||
|
return a - b;
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
compileProgram: function(program) {
|
||||||
|
var result = new this.compiler().compile(program, this.options);
|
||||||
|
var guid = this.guid++, depth;
|
||||||
|
|
||||||
|
this.usePartial = this.usePartial || result.usePartial;
|
||||||
|
|
||||||
|
this.children[guid] = result;
|
||||||
|
|
||||||
|
for(var i=0, l=result.depths.list.length; i<l; i++) {
|
||||||
|
depth = result.depths.list[i];
|
||||||
|
|
||||||
|
if(depth < 2) { continue; }
|
||||||
|
else { this.addDepth(depth - 1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
return guid;
|
||||||
|
},
|
||||||
|
|
||||||
|
block: function(block) {
|
||||||
|
var mustache = block.mustache,
|
||||||
|
program = block.program,
|
||||||
|
inverse = block.inverse;
|
||||||
|
|
||||||
|
if (program) {
|
||||||
|
program = this.compileProgram(program);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inverse) {
|
||||||
|
inverse = this.compileProgram(inverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
var sexpr = mustache.sexpr;
|
||||||
|
var type = this.classifySexpr(sexpr);
|
||||||
|
|
||||||
|
if (type === "helper") {
|
||||||
|
this.helperSexpr(sexpr, program, inverse);
|
||||||
|
} else if (type === "simple") {
|
||||||
|
this.simpleSexpr(sexpr);
|
||||||
|
|
||||||
|
// now that the simple mustache is resolved, we need to
|
||||||
|
// evaluate it by executing `blockHelperMissing`
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
this.opcode('emptyHash');
|
||||||
|
this.opcode('blockValue');
|
||||||
|
} else {
|
||||||
|
this.ambiguousSexpr(sexpr, program, inverse);
|
||||||
|
|
||||||
|
// now that the simple mustache is resolved, we need to
|
||||||
|
// evaluate it by executing `blockHelperMissing`
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
this.opcode('emptyHash');
|
||||||
|
this.opcode('ambiguousBlockValue');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('append');
|
||||||
|
},
|
||||||
|
|
||||||
|
hash: function(hash) {
|
||||||
|
var pairs = hash.pairs, pair, val;
|
||||||
|
|
||||||
|
this.opcode('pushHash');
|
||||||
|
|
||||||
|
for(var i=0, l=pairs.length; i<l; i++) {
|
||||||
|
pair = pairs[i];
|
||||||
|
val = pair[1];
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
if(val.depth) {
|
||||||
|
this.addDepth(val.depth);
|
||||||
|
}
|
||||||
|
this.opcode('getContext', val.depth || 0);
|
||||||
|
this.opcode('pushStringParam', val.stringModeValue, val.type);
|
||||||
|
|
||||||
|
if (val.type === 'sexpr') {
|
||||||
|
// Subexpressions get evaluated and passed in
|
||||||
|
// in string params mode.
|
||||||
|
this.sexpr(val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.accept(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('assignToHash', pair[0]);
|
||||||
|
}
|
||||||
|
this.opcode('popHash');
|
||||||
|
},
|
||||||
|
|
||||||
|
partial: function(partial) {
|
||||||
|
var partialName = partial.partialName;
|
||||||
|
this.usePartial = true;
|
||||||
|
|
||||||
|
if(partial.context) {
|
||||||
|
this.ID(partial.context);
|
||||||
|
} else {
|
||||||
|
this.opcode('push', 'depth0');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('invokePartial', partialName.name);
|
||||||
|
this.opcode('append');
|
||||||
|
},
|
||||||
|
|
||||||
|
content: function(content) {
|
||||||
|
this.opcode('appendContent', content.string);
|
||||||
|
},
|
||||||
|
|
||||||
|
mustache: function(mustache) {
|
||||||
|
this.sexpr(mustache.sexpr);
|
||||||
|
|
||||||
|
if(mustache.escaped && !this.options.noEscape) {
|
||||||
|
this.opcode('appendEscaped');
|
||||||
|
} else {
|
||||||
|
this.opcode('append');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ambiguousSexpr: function(sexpr, program, inverse) {
|
||||||
|
var id = sexpr.id,
|
||||||
|
name = id.parts[0],
|
||||||
|
isBlock = program != null || inverse != null;
|
||||||
|
|
||||||
|
this.opcode('getContext', id.depth);
|
||||||
|
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
|
||||||
|
this.opcode('invokeAmbiguous', name, isBlock);
|
||||||
|
},
|
||||||
|
|
||||||
|
simpleSexpr: function(sexpr) {
|
||||||
|
var id = sexpr.id;
|
||||||
|
|
||||||
|
if (id.type === 'DATA') {
|
||||||
|
this.DATA(id);
|
||||||
|
} else if (id.parts.length) {
|
||||||
|
this.ID(id);
|
||||||
|
} else {
|
||||||
|
// Simplified ID for `this`
|
||||||
|
this.addDepth(id.depth);
|
||||||
|
this.opcode('getContext', id.depth);
|
||||||
|
this.opcode('pushContext');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('resolvePossibleLambda');
|
||||||
|
},
|
||||||
|
|
||||||
|
helperSexpr: function(sexpr, program, inverse) {
|
||||||
|
var params = this.setupFullMustacheParams(sexpr, program, inverse),
|
||||||
|
name = sexpr.id.parts[0];
|
||||||
|
|
||||||
|
if (this.options.knownHelpers[name]) {
|
||||||
|
this.opcode('invokeKnownHelper', params.length, name);
|
||||||
|
} else if (this.options.knownHelpersOnly) {
|
||||||
|
throw new Exception("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
|
||||||
|
} else {
|
||||||
|
this.opcode('invokeHelper', params.length, name, sexpr.isRoot);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
sexpr: function(sexpr) {
|
||||||
|
var type = this.classifySexpr(sexpr);
|
||||||
|
|
||||||
|
if (type === "simple") {
|
||||||
|
this.simpleSexpr(sexpr);
|
||||||
|
} else if (type === "helper") {
|
||||||
|
this.helperSexpr(sexpr);
|
||||||
|
} else {
|
||||||
|
this.ambiguousSexpr(sexpr);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ID: function(id) {
|
||||||
|
this.addDepth(id.depth);
|
||||||
|
this.opcode('getContext', id.depth);
|
||||||
|
|
||||||
|
var name = id.parts[0];
|
||||||
|
if (!name) {
|
||||||
|
this.opcode('pushContext');
|
||||||
|
} else {
|
||||||
|
this.opcode('lookupOnContext', id.parts[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i=1, l=id.parts.length; i<l; i++) {
|
||||||
|
this.opcode('lookup', id.parts[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DATA: function(data) {
|
||||||
|
this.options.data = true;
|
||||||
|
if (data.id.isScoped || data.id.depth) {
|
||||||
|
throw new Exception('Scoped data references are not supported: ' + data.original, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('lookupData');
|
||||||
|
var parts = data.id.parts;
|
||||||
|
for(var i=0, l=parts.length; i<l; i++) {
|
||||||
|
this.opcode('lookup', parts[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
STRING: function(string) {
|
||||||
|
this.opcode('pushString', string.string);
|
||||||
|
},
|
||||||
|
|
||||||
|
INTEGER: function(integer) {
|
||||||
|
this.opcode('pushLiteral', integer.integer);
|
||||||
|
},
|
||||||
|
|
||||||
|
BOOLEAN: function(bool) {
|
||||||
|
this.opcode('pushLiteral', bool.bool);
|
||||||
|
},
|
||||||
|
|
||||||
|
comment: function() {},
|
||||||
|
|
||||||
|
// HELPERS
|
||||||
|
opcode: function(name) {
|
||||||
|
this.opcodes.push({ opcode: name, args: [].slice.call(arguments, 1) });
|
||||||
|
},
|
||||||
|
|
||||||
|
declare: function(name, value) {
|
||||||
|
this.opcodes.push({ opcode: 'DECLARE', name: name, value: value });
|
||||||
|
},
|
||||||
|
|
||||||
|
addDepth: function(depth) {
|
||||||
|
if(depth === 0) { return; }
|
||||||
|
|
||||||
|
if(!this.depths[depth]) {
|
||||||
|
this.depths[depth] = true;
|
||||||
|
this.depths.list.push(depth);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
classifySexpr: function(sexpr) {
|
||||||
|
var isHelper = sexpr.isHelper;
|
||||||
|
var isEligible = sexpr.eligibleHelper;
|
||||||
|
var options = this.options;
|
||||||
|
|
||||||
|
// if ambiguous, we can possibly resolve the ambiguity now
|
||||||
|
if (isEligible && !isHelper) {
|
||||||
|
var name = sexpr.id.parts[0];
|
||||||
|
|
||||||
|
if (options.knownHelpers[name]) {
|
||||||
|
isHelper = true;
|
||||||
|
} else if (options.knownHelpersOnly) {
|
||||||
|
isEligible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isHelper) { return "helper"; }
|
||||||
|
else if (isEligible) { return "ambiguous"; }
|
||||||
|
else { return "simple"; }
|
||||||
|
},
|
||||||
|
|
||||||
|
pushParams: function(params) {
|
||||||
|
var i = params.length, param;
|
||||||
|
|
||||||
|
while(i--) {
|
||||||
|
param = params[i];
|
||||||
|
|
||||||
|
if(this.options.stringParams) {
|
||||||
|
if(param.depth) {
|
||||||
|
this.addDepth(param.depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('getContext', param.depth || 0);
|
||||||
|
this.opcode('pushStringParam', param.stringModeValue, param.type);
|
||||||
|
|
||||||
|
if (param.type === 'sexpr') {
|
||||||
|
// Subexpressions get evaluated and passed in
|
||||||
|
// in string params mode.
|
||||||
|
this.sexpr(param);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this[param.type](param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setupFullMustacheParams: function(sexpr, program, inverse) {
|
||||||
|
var params = sexpr.params;
|
||||||
|
this.pushParams(params);
|
||||||
|
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
|
||||||
|
if (sexpr.hash) {
|
||||||
|
this.hash(sexpr.hash);
|
||||||
|
} else {
|
||||||
|
this.opcode('emptyHash');
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function precompile(input, options, env) {
|
||||||
|
if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
|
||||||
|
throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
if (!('data' in options)) {
|
||||||
|
options.data = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ast = env.parse(input);
|
||||||
|
var environment = new env.Compiler().compile(ast, options);
|
||||||
|
return new env.JavaScriptCompiler().compile(environment, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.precompile = precompile;function compile(input, options, env) {
|
||||||
|
if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
|
||||||
|
throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
if (!('data' in options)) {
|
||||||
|
options.data = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var compiled;
|
||||||
|
|
||||||
|
function compileInput() {
|
||||||
|
var ast = env.parse(input);
|
||||||
|
var environment = new env.Compiler().compile(ast, options);
|
||||||
|
var templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
|
||||||
|
return env.template(templateSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Template is only compiled on first use and cached after that point.
|
||||||
|
return function(context, options) {
|
||||||
|
if (!compiled) {
|
||||||
|
compiled = compileInput();
|
||||||
|
}
|
||||||
|
return compiled.call(this, context, options);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.compile = compile;
|
||||||
942
node_modules/handlebars/dist/cjs/handlebars/compiler/javascript-compiler.js
generated
vendored
Normal file
942
node_modules/handlebars/dist/cjs/handlebars/compiler/javascript-compiler.js
generated
vendored
Normal file
@@ -0,0 +1,942 @@
|
|||||||
|
"use strict";
|
||||||
|
var COMPILER_REVISION = require("../base").COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = require("../base").REVISION_CHANGES;
|
||||||
|
var log = require("../base").log;
|
||||||
|
var Exception = require("../exception")["default"];
|
||||||
|
|
||||||
|
function Literal(value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function JavaScriptCompiler() {}
|
||||||
|
|
||||||
|
JavaScriptCompiler.prototype = {
|
||||||
|
// PUBLIC API: You can override these methods in a subclass to provide
|
||||||
|
// alternative compiled forms for name lookup and buffering semantics
|
||||||
|
nameLookup: function(parent, name /* , type*/) {
|
||||||
|
var wrap,
|
||||||
|
ret;
|
||||||
|
if (parent.indexOf('depth') === 0) {
|
||||||
|
wrap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/^[0-9]+$/.test(name)) {
|
||||||
|
ret = parent + "[" + name + "]";
|
||||||
|
} else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
|
||||||
|
ret = parent + "." + name;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = parent + "['" + name + "']";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wrap) {
|
||||||
|
return '(' + parent + ' && ' + ret + ')';
|
||||||
|
} else {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
compilerInfo: function() {
|
||||||
|
var revision = COMPILER_REVISION,
|
||||||
|
versions = REVISION_CHANGES[revision];
|
||||||
|
return "this.compilerInfo = ["+revision+",'"+versions+"'];\n";
|
||||||
|
},
|
||||||
|
|
||||||
|
appendToBuffer: function(string) {
|
||||||
|
if (this.environment.isSimple) {
|
||||||
|
return "return " + string + ";";
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
appendToBuffer: true,
|
||||||
|
content: string,
|
||||||
|
toString: function() { return "buffer += " + string + ";"; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
initializeBuffer: function() {
|
||||||
|
return this.quotedString("");
|
||||||
|
},
|
||||||
|
|
||||||
|
namespace: "Handlebars",
|
||||||
|
// END PUBLIC API
|
||||||
|
|
||||||
|
compile: function(environment, options, context, asObject) {
|
||||||
|
this.environment = environment;
|
||||||
|
this.options = options || {};
|
||||||
|
|
||||||
|
log('debug', this.environment.disassemble() + "\n\n");
|
||||||
|
|
||||||
|
this.name = this.environment.name;
|
||||||
|
this.isChild = !!context;
|
||||||
|
this.context = context || {
|
||||||
|
programs: [],
|
||||||
|
environments: [],
|
||||||
|
aliases: { }
|
||||||
|
};
|
||||||
|
|
||||||
|
this.preamble();
|
||||||
|
|
||||||
|
this.stackSlot = 0;
|
||||||
|
this.stackVars = [];
|
||||||
|
this.registers = { list: [] };
|
||||||
|
this.hashes = [];
|
||||||
|
this.compileStack = [];
|
||||||
|
this.inlineStack = [];
|
||||||
|
|
||||||
|
this.compileChildren(environment, options);
|
||||||
|
|
||||||
|
var opcodes = environment.opcodes, opcode;
|
||||||
|
|
||||||
|
this.i = 0;
|
||||||
|
|
||||||
|
for(var l=opcodes.length; this.i<l; this.i++) {
|
||||||
|
opcode = opcodes[this.i];
|
||||||
|
|
||||||
|
if(opcode.opcode === 'DECLARE') {
|
||||||
|
this[opcode.name] = opcode.value;
|
||||||
|
} else {
|
||||||
|
this[opcode.opcode].apply(this, opcode.args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the stripNext flag if it was not set by this operation.
|
||||||
|
if (opcode.opcode !== this.stripNext) {
|
||||||
|
this.stripNext = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush any trailing content that might be pending.
|
||||||
|
this.pushSource('');
|
||||||
|
|
||||||
|
if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
|
||||||
|
throw new Exception('Compile completed with content left on stack');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.createFunctionContext(asObject);
|
||||||
|
},
|
||||||
|
|
||||||
|
preamble: function() {
|
||||||
|
var out = [];
|
||||||
|
|
||||||
|
if (!this.isChild) {
|
||||||
|
var namespace = this.namespace;
|
||||||
|
|
||||||
|
var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
|
||||||
|
if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
|
||||||
|
if (this.options.data) { copies = copies + " data = data || {};"; }
|
||||||
|
out.push(copies);
|
||||||
|
} else {
|
||||||
|
out.push('');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.environment.isSimple) {
|
||||||
|
out.push(", buffer = " + this.initializeBuffer());
|
||||||
|
} else {
|
||||||
|
out.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// track the last context pushed into place to allow skipping the
|
||||||
|
// getContext opcode when it would be a noop
|
||||||
|
this.lastContext = 0;
|
||||||
|
this.source = out;
|
||||||
|
},
|
||||||
|
|
||||||
|
createFunctionContext: function(asObject) {
|
||||||
|
var locals = this.stackVars.concat(this.registers.list);
|
||||||
|
|
||||||
|
if(locals.length > 0) {
|
||||||
|
this.source[1] = this.source[1] + ", " + locals.join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate minimizer alias mappings
|
||||||
|
if (!this.isChild) {
|
||||||
|
for (var alias in this.context.aliases) {
|
||||||
|
if (this.context.aliases.hasOwnProperty(alias)) {
|
||||||
|
this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.source[1]) {
|
||||||
|
this.source[1] = "var " + this.source[1].substring(2) + ";";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge children
|
||||||
|
if (!this.isChild) {
|
||||||
|
this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.environment.isSimple) {
|
||||||
|
this.pushSource("return buffer;");
|
||||||
|
}
|
||||||
|
|
||||||
|
var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
|
||||||
|
|
||||||
|
for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
|
||||||
|
params.push("depth" + this.environment.depths.list[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform a second pass over the output to merge content when possible
|
||||||
|
var source = this.mergeSource();
|
||||||
|
|
||||||
|
if (!this.isChild) {
|
||||||
|
source = this.compilerInfo()+source;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asObject) {
|
||||||
|
params.push(source);
|
||||||
|
|
||||||
|
return Function.apply(this, params);
|
||||||
|
} else {
|
||||||
|
var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + source + '}';
|
||||||
|
log('debug', functionSource + "\n\n");
|
||||||
|
return functionSource;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mergeSource: function() {
|
||||||
|
// WARN: We are not handling the case where buffer is still populated as the source should
|
||||||
|
// not have buffer append operations as their final action.
|
||||||
|
var source = '',
|
||||||
|
buffer;
|
||||||
|
for (var i = 0, len = this.source.length; i < len; i++) {
|
||||||
|
var line = this.source[i];
|
||||||
|
if (line.appendToBuffer) {
|
||||||
|
if (buffer) {
|
||||||
|
buffer = buffer + '\n + ' + line.content;
|
||||||
|
} else {
|
||||||
|
buffer = line.content;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (buffer) {
|
||||||
|
source += 'buffer += ' + buffer + ';\n ';
|
||||||
|
buffer = undefined;
|
||||||
|
}
|
||||||
|
source += line + '\n ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return source;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [blockValue]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, value
|
||||||
|
// On stack, after: return value of blockHelperMissing
|
||||||
|
//
|
||||||
|
// The purpose of this opcode is to take a block of the form
|
||||||
|
// `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
|
||||||
|
// replace it on the stack with the result of properly
|
||||||
|
// invoking blockHelperMissing.
|
||||||
|
blockValue: function() {
|
||||||
|
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||||
|
|
||||||
|
var params = ["depth0"];
|
||||||
|
this.setupParams(0, params);
|
||||||
|
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
params.splice(1, 0, current);
|
||||||
|
return "blockHelperMissing.call(" + params.join(", ") + ")";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [ambiguousBlockValue]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, value
|
||||||
|
// Compiler value, before: lastHelper=value of last found helper, if any
|
||||||
|
// On stack, after, if no lastHelper: same as [blockValue]
|
||||||
|
// On stack, after, if lastHelper: value
|
||||||
|
ambiguousBlockValue: function() {
|
||||||
|
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||||
|
|
||||||
|
var params = ["depth0"];
|
||||||
|
this.setupParams(0, params);
|
||||||
|
|
||||||
|
var current = this.topStack();
|
||||||
|
params.splice(1, 0, current);
|
||||||
|
|
||||||
|
this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [appendContent]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Appends the string value of `content` to the current buffer
|
||||||
|
appendContent: function(content) {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
content = this.pendingContent + content;
|
||||||
|
}
|
||||||
|
if (this.stripNext) {
|
||||||
|
content = content.replace(/^\s+/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pendingContent = content;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [strip]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Removes any trailing whitespace from the prior content node and flags
|
||||||
|
// the next operation for stripping if it is a content node.
|
||||||
|
strip: function() {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
this.pendingContent = this.pendingContent.replace(/\s+$/, '');
|
||||||
|
}
|
||||||
|
this.stripNext = 'strip';
|
||||||
|
},
|
||||||
|
|
||||||
|
// [append]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Coerces `value` to a String and appends it to the current buffer.
|
||||||
|
//
|
||||||
|
// If `value` is truthy, or 0, it is coerced into a string and appended
|
||||||
|
// Otherwise, the empty string is appended
|
||||||
|
append: function() {
|
||||||
|
// Force anything that is inlined onto the stack so we don't have duplication
|
||||||
|
// when we examine local
|
||||||
|
this.flushInline();
|
||||||
|
var local = this.popStack();
|
||||||
|
this.pushSource("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
|
||||||
|
if (this.environment.isSimple) {
|
||||||
|
this.pushSource("else { " + this.appendToBuffer("''") + " }");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [appendEscaped]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Escape `value` and append it to the buffer
|
||||||
|
appendEscaped: function() {
|
||||||
|
this.context.aliases.escapeExpression = 'this.escapeExpression';
|
||||||
|
|
||||||
|
this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [getContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
// Compiler value, after: lastContext=depth
|
||||||
|
//
|
||||||
|
// Set the value of the `lastContext` compiler value to the depth
|
||||||
|
getContext: function(depth) {
|
||||||
|
if(this.lastContext !== depth) {
|
||||||
|
this.lastContext = depth;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookupOnContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: currentContext[name], ...
|
||||||
|
//
|
||||||
|
// Looks up the value of `name` on the current context and pushes
|
||||||
|
// it onto the stack.
|
||||||
|
lookupOnContext: function(name) {
|
||||||
|
this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: currentContext, ...
|
||||||
|
//
|
||||||
|
// Pushes the value of the current context onto the stack.
|
||||||
|
pushContext: function() {
|
||||||
|
this.pushStackLiteral('depth' + this.lastContext);
|
||||||
|
},
|
||||||
|
|
||||||
|
// [resolvePossibleLambda]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: resolved value, ...
|
||||||
|
//
|
||||||
|
// If the `value` is a lambda, replace it on the stack by
|
||||||
|
// the return value of the lambda
|
||||||
|
resolvePossibleLambda: function() {
|
||||||
|
this.context.aliases.functionType = '"function"';
|
||||||
|
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookup]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: value[name], ...
|
||||||
|
//
|
||||||
|
// Replace the value on the stack with the result of looking
|
||||||
|
// up `name` on `value`
|
||||||
|
lookup: function(name) {
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookupData]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: data, ...
|
||||||
|
//
|
||||||
|
// Push the data lookup operator
|
||||||
|
lookupData: function() {
|
||||||
|
this.pushStackLiteral('data');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushStringParam]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: string, currentContext, ...
|
||||||
|
//
|
||||||
|
// This opcode is designed for use in string mode, which
|
||||||
|
// provides the string value of a parameter along with its
|
||||||
|
// depth rather than resolving it immediately.
|
||||||
|
pushStringParam: function(string, type) {
|
||||||
|
this.pushStackLiteral('depth' + this.lastContext);
|
||||||
|
|
||||||
|
this.pushString(type);
|
||||||
|
|
||||||
|
// If it's a subexpression, the string result
|
||||||
|
// will be pushed after this opcode.
|
||||||
|
if (type !== 'sexpr') {
|
||||||
|
if (typeof string === 'string') {
|
||||||
|
this.pushString(string);
|
||||||
|
} else {
|
||||||
|
this.pushStackLiteral(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
emptyHash: function() {
|
||||||
|
this.pushStackLiteral('{}');
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
this.push('{}'); // hashContexts
|
||||||
|
this.push('{}'); // hashTypes
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pushHash: function() {
|
||||||
|
if (this.hash) {
|
||||||
|
this.hashes.push(this.hash);
|
||||||
|
}
|
||||||
|
this.hash = {values: [], types: [], contexts: []};
|
||||||
|
},
|
||||||
|
popHash: function() {
|
||||||
|
var hash = this.hash;
|
||||||
|
this.hash = this.hashes.pop();
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
this.push('{' + hash.contexts.join(',') + '}');
|
||||||
|
this.push('{' + hash.types.join(',') + '}');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.push('{\n ' + hash.values.join(',\n ') + '\n }');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushString]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: quotedString(string), ...
|
||||||
|
//
|
||||||
|
// Push a quoted version of `string` onto the stack
|
||||||
|
pushString: function(string) {
|
||||||
|
this.pushStackLiteral(this.quotedString(string));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [push]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: expr, ...
|
||||||
|
//
|
||||||
|
// Push an expression onto the stack
|
||||||
|
push: function(expr) {
|
||||||
|
this.inlineStack.push(expr);
|
||||||
|
return expr;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushLiteral]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: value, ...
|
||||||
|
//
|
||||||
|
// Pushes a value onto the stack. This operation prevents
|
||||||
|
// the compiler from creating a temporary variable to hold
|
||||||
|
// it.
|
||||||
|
pushLiteral: function(value) {
|
||||||
|
this.pushStackLiteral(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushProgram]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: program(guid), ...
|
||||||
|
//
|
||||||
|
// Push a program expression onto the stack. This takes
|
||||||
|
// a compile-time guid and converts it into a runtime-accessible
|
||||||
|
// expression.
|
||||||
|
pushProgram: function(guid) {
|
||||||
|
if (guid != null) {
|
||||||
|
this.pushStackLiteral(this.programExpression(guid));
|
||||||
|
} else {
|
||||||
|
this.pushStackLiteral(null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeHelper]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of helper invocation
|
||||||
|
//
|
||||||
|
// Pops off the helper's parameters, invokes the helper,
|
||||||
|
// and pushes the helper's return value onto the stack.
|
||||||
|
//
|
||||||
|
// If the helper is not found, `helperMissing` is called.
|
||||||
|
invokeHelper: function(paramSize, name, isRoot) {
|
||||||
|
this.context.aliases.helperMissing = 'helpers.helperMissing';
|
||||||
|
this.useRegister('helper');
|
||||||
|
|
||||||
|
var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
|
||||||
|
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
|
||||||
|
|
||||||
|
var lookup = 'helper = ' + helper.name + ' || ' + nonHelper;
|
||||||
|
if (helper.paramsInit) {
|
||||||
|
lookup += ',' + helper.paramsInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.push(
|
||||||
|
'('
|
||||||
|
+ lookup
|
||||||
|
+ ',helper '
|
||||||
|
+ '? helper.call(' + helper.callParams + ') '
|
||||||
|
+ ': helperMissing.call(' + helper.helperMissingParams + '))');
|
||||||
|
|
||||||
|
// Always flush subexpressions. This is both to prevent the compounding size issue that
|
||||||
|
// occurs when the code has to be duplicated for inlining and also to prevent errors
|
||||||
|
// due to the incorrect options object being passed due to the shared register.
|
||||||
|
if (!isRoot) {
|
||||||
|
this.flushInline();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeKnownHelper]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of helper invocation
|
||||||
|
//
|
||||||
|
// This operation is used when the helper is known to exist,
|
||||||
|
// so a `helperMissing` fallback is not required.
|
||||||
|
invokeKnownHelper: function(paramSize, name) {
|
||||||
|
var helper = this.setupHelper(paramSize, name);
|
||||||
|
this.push(helper.name + ".call(" + helper.callParams + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeAmbiguous]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of disambiguation
|
||||||
|
//
|
||||||
|
// This operation is used when an expression like `{{foo}}`
|
||||||
|
// is provided, but we don't know at compile-time whether it
|
||||||
|
// is a helper or a path.
|
||||||
|
//
|
||||||
|
// This operation emits more code than the other options,
|
||||||
|
// and can be avoided by passing the `knownHelpers` and
|
||||||
|
// `knownHelpersOnly` flags at compile-time.
|
||||||
|
invokeAmbiguous: function(name, helperCall) {
|
||||||
|
this.context.aliases.functionType = '"function"';
|
||||||
|
this.useRegister('helper');
|
||||||
|
|
||||||
|
this.emptyHash();
|
||||||
|
var helper = this.setupHelper(0, name, helperCall);
|
||||||
|
|
||||||
|
var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
|
||||||
|
|
||||||
|
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
|
||||||
|
var nextStack = this.nextStack();
|
||||||
|
|
||||||
|
if (helper.paramsInit) {
|
||||||
|
this.pushSource(helper.paramsInit);
|
||||||
|
}
|
||||||
|
this.pushSource('if (helper = ' + helperName + ') { ' + nextStack + ' = helper.call(' + helper.callParams + '); }');
|
||||||
|
this.pushSource('else { helper = ' + nonHelper + '; ' + nextStack + ' = typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper; }');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokePartial]
|
||||||
|
//
|
||||||
|
// On stack, before: context, ...
|
||||||
|
// On stack after: result of partial invocation
|
||||||
|
//
|
||||||
|
// This operation pops off a context, invokes a partial with that context,
|
||||||
|
// and pushes the result of the invocation back.
|
||||||
|
invokePartial: function(name) {
|
||||||
|
var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
|
||||||
|
|
||||||
|
if (this.options.data) {
|
||||||
|
params.push("data");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
this.push("self.invokePartial(" + params.join(", ") + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [assignToHash]
|
||||||
|
//
|
||||||
|
// On stack, before: value, hash, ...
|
||||||
|
// On stack, after: hash, ...
|
||||||
|
//
|
||||||
|
// Pops a value and hash off the stack, assigns `hash[key] = value`
|
||||||
|
// and pushes the hash back onto the stack.
|
||||||
|
assignToHash: function(key) {
|
||||||
|
var value = this.popStack(),
|
||||||
|
context,
|
||||||
|
type;
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
type = this.popStack();
|
||||||
|
context = this.popStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
var hash = this.hash;
|
||||||
|
if (context) {
|
||||||
|
hash.contexts.push("'" + key + "': " + context);
|
||||||
|
}
|
||||||
|
if (type) {
|
||||||
|
hash.types.push("'" + key + "': " + type);
|
||||||
|
}
|
||||||
|
hash.values.push("'" + key + "': (" + value + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// HELPERS
|
||||||
|
|
||||||
|
compiler: JavaScriptCompiler,
|
||||||
|
|
||||||
|
compileChildren: function(environment, options) {
|
||||||
|
var children = environment.children, child, compiler;
|
||||||
|
|
||||||
|
for(var i=0, l=children.length; i<l; i++) {
|
||||||
|
child = children[i];
|
||||||
|
compiler = new this.compiler();
|
||||||
|
|
||||||
|
var index = this.matchExistingProgram(child);
|
||||||
|
|
||||||
|
if (index == null) {
|
||||||
|
this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
|
||||||
|
index = this.context.programs.length;
|
||||||
|
child.index = index;
|
||||||
|
child.name = 'program' + index;
|
||||||
|
this.context.programs[index] = compiler.compile(child, options, this.context);
|
||||||
|
this.context.environments[index] = child;
|
||||||
|
} else {
|
||||||
|
child.index = index;
|
||||||
|
child.name = 'program' + index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
matchExistingProgram: function(child) {
|
||||||
|
for (var i = 0, len = this.context.environments.length; i < len; i++) {
|
||||||
|
var environment = this.context.environments[i];
|
||||||
|
if (environment && environment.equals(child)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
programExpression: function(guid) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
|
||||||
|
if(guid == null) {
|
||||||
|
return "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
var child = this.environment.children[guid],
|
||||||
|
depths = child.depths.list, depth;
|
||||||
|
|
||||||
|
var programParams = [child.index, child.name, "data"];
|
||||||
|
|
||||||
|
for(var i=0, l = depths.length; i<l; i++) {
|
||||||
|
depth = depths[i];
|
||||||
|
|
||||||
|
if(depth === 1) { programParams.push("depth0"); }
|
||||||
|
else { programParams.push("depth" + (depth - 1)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
|
||||||
|
},
|
||||||
|
|
||||||
|
register: function(name, val) {
|
||||||
|
this.useRegister(name);
|
||||||
|
this.pushSource(name + " = " + val + ";");
|
||||||
|
},
|
||||||
|
|
||||||
|
useRegister: function(name) {
|
||||||
|
if(!this.registers[name]) {
|
||||||
|
this.registers[name] = true;
|
||||||
|
this.registers.list.push(name);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
pushStackLiteral: function(item) {
|
||||||
|
return this.push(new Literal(item));
|
||||||
|
},
|
||||||
|
|
||||||
|
pushSource: function(source) {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
|
||||||
|
this.pendingContent = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source) {
|
||||||
|
this.source.push(source);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
pushStack: function(item) {
|
||||||
|
this.flushInline();
|
||||||
|
|
||||||
|
var stack = this.incrStack();
|
||||||
|
if (item) {
|
||||||
|
this.pushSource(stack + " = " + item + ";");
|
||||||
|
}
|
||||||
|
this.compileStack.push(stack);
|
||||||
|
return stack;
|
||||||
|
},
|
||||||
|
|
||||||
|
replaceStack: function(callback) {
|
||||||
|
var prefix = '',
|
||||||
|
inline = this.isInline(),
|
||||||
|
stack,
|
||||||
|
createdStack,
|
||||||
|
usedLiteral;
|
||||||
|
|
||||||
|
// If we are currently inline then we want to merge the inline statement into the
|
||||||
|
// replacement statement via ','
|
||||||
|
if (inline) {
|
||||||
|
var top = this.popStack(true);
|
||||||
|
|
||||||
|
if (top instanceof Literal) {
|
||||||
|
// Literals do not need to be inlined
|
||||||
|
stack = top.value;
|
||||||
|
usedLiteral = true;
|
||||||
|
} else {
|
||||||
|
// Get or create the current stack name for use by the inline
|
||||||
|
createdStack = !this.stackSlot;
|
||||||
|
var name = !createdStack ? this.topStackName() : this.incrStack();
|
||||||
|
|
||||||
|
prefix = '(' + this.push(name) + ' = ' + top + '),';
|
||||||
|
stack = this.topStack();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stack = this.topStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = callback.call(this, stack);
|
||||||
|
|
||||||
|
if (inline) {
|
||||||
|
if (!usedLiteral) {
|
||||||
|
this.popStack();
|
||||||
|
}
|
||||||
|
if (createdStack) {
|
||||||
|
this.stackSlot--;
|
||||||
|
}
|
||||||
|
this.push('(' + prefix + item + ')');
|
||||||
|
} else {
|
||||||
|
// Prevent modification of the context depth variable. Through replaceStack
|
||||||
|
if (!/^stack/.test(stack)) {
|
||||||
|
stack = this.nextStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pushSource(stack + " = (" + prefix + item + ");");
|
||||||
|
}
|
||||||
|
return stack;
|
||||||
|
},
|
||||||
|
|
||||||
|
nextStack: function() {
|
||||||
|
return this.pushStack();
|
||||||
|
},
|
||||||
|
|
||||||
|
incrStack: function() {
|
||||||
|
this.stackSlot++;
|
||||||
|
if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
|
||||||
|
return this.topStackName();
|
||||||
|
},
|
||||||
|
topStackName: function() {
|
||||||
|
return "stack" + this.stackSlot;
|
||||||
|
},
|
||||||
|
flushInline: function() {
|
||||||
|
var inlineStack = this.inlineStack;
|
||||||
|
if (inlineStack.length) {
|
||||||
|
this.inlineStack = [];
|
||||||
|
for (var i = 0, len = inlineStack.length; i < len; i++) {
|
||||||
|
var entry = inlineStack[i];
|
||||||
|
if (entry instanceof Literal) {
|
||||||
|
this.compileStack.push(entry);
|
||||||
|
} else {
|
||||||
|
this.pushStack(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isInline: function() {
|
||||||
|
return this.inlineStack.length;
|
||||||
|
},
|
||||||
|
|
||||||
|
popStack: function(wrapped) {
|
||||||
|
var inline = this.isInline(),
|
||||||
|
item = (inline ? this.inlineStack : this.compileStack).pop();
|
||||||
|
|
||||||
|
if (!wrapped && (item instanceof Literal)) {
|
||||||
|
return item.value;
|
||||||
|
} else {
|
||||||
|
if (!inline) {
|
||||||
|
if (!this.stackSlot) {
|
||||||
|
throw new Exception('Invalid stack pop');
|
||||||
|
}
|
||||||
|
this.stackSlot--;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
topStack: function(wrapped) {
|
||||||
|
var stack = (this.isInline() ? this.inlineStack : this.compileStack),
|
||||||
|
item = stack[stack.length - 1];
|
||||||
|
|
||||||
|
if (!wrapped && (item instanceof Literal)) {
|
||||||
|
return item.value;
|
||||||
|
} else {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
quotedString: function(str) {
|
||||||
|
return '"' + str
|
||||||
|
.replace(/\\/g, '\\\\')
|
||||||
|
.replace(/"/g, '\\"')
|
||||||
|
.replace(/\n/g, '\\n')
|
||||||
|
.replace(/\r/g, '\\r')
|
||||||
|
.replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
|
||||||
|
.replace(/\u2029/g, '\\u2029') + '"';
|
||||||
|
},
|
||||||
|
|
||||||
|
setupHelper: function(paramSize, name, missingParams) {
|
||||||
|
var params = [],
|
||||||
|
paramsInit = this.setupParams(paramSize, params, missingParams);
|
||||||
|
var foundHelper = this.nameLookup('helpers', name, 'helper');
|
||||||
|
|
||||||
|
return {
|
||||||
|
params: params,
|
||||||
|
paramsInit: paramsInit,
|
||||||
|
name: foundHelper,
|
||||||
|
callParams: ["depth0"].concat(params).join(", "),
|
||||||
|
helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
setupOptions: function(paramSize, params) {
|
||||||
|
var options = [], contexts = [], types = [], param, inverse, program;
|
||||||
|
|
||||||
|
options.push("hash:" + this.popStack());
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
options.push("hashTypes:" + this.popStack());
|
||||||
|
options.push("hashContexts:" + this.popStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
inverse = this.popStack();
|
||||||
|
program = this.popStack();
|
||||||
|
|
||||||
|
// Avoid setting fn and inverse if neither are set. This allows
|
||||||
|
// helpers to do a check for `if (options.fn)`
|
||||||
|
if (program || inverse) {
|
||||||
|
if (!program) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
program = "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inverse) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
inverse = "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
options.push("inverse:" + inverse);
|
||||||
|
options.push("fn:" + program);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i=0; i<paramSize; i++) {
|
||||||
|
param = this.popStack();
|
||||||
|
params.push(param);
|
||||||
|
|
||||||
|
if(this.options.stringParams) {
|
||||||
|
types.push(this.popStack());
|
||||||
|
contexts.push(this.popStack());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
options.push("contexts:[" + contexts.join(",") + "]");
|
||||||
|
options.push("types:[" + types.join(",") + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.options.data) {
|
||||||
|
options.push("data:data");
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
},
|
||||||
|
|
||||||
|
// the params and contexts arguments are passed in arrays
|
||||||
|
// to fill in
|
||||||
|
setupParams: function(paramSize, params, useRegister) {
|
||||||
|
var options = '{' + this.setupOptions(paramSize, params).join(',') + '}';
|
||||||
|
|
||||||
|
if (useRegister) {
|
||||||
|
this.useRegister('options');
|
||||||
|
params.push('options');
|
||||||
|
return 'options=' + options;
|
||||||
|
} else {
|
||||||
|
params.push(options);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var reservedWords = (
|
||||||
|
"break else new var" +
|
||||||
|
" case finally return void" +
|
||||||
|
" catch for switch while" +
|
||||||
|
" continue function this with" +
|
||||||
|
" default if throw" +
|
||||||
|
" delete in try" +
|
||||||
|
" do instanceof typeof" +
|
||||||
|
" abstract enum int short" +
|
||||||
|
" boolean export interface static" +
|
||||||
|
" byte extends long super" +
|
||||||
|
" char final native synchronized" +
|
||||||
|
" class float package throws" +
|
||||||
|
" const goto private transient" +
|
||||||
|
" debugger implements protected volatile" +
|
||||||
|
" double import public let yield"
|
||||||
|
).split(" ");
|
||||||
|
|
||||||
|
var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
|
||||||
|
|
||||||
|
for(var i=0, l=reservedWords.length; i<l; i++) {
|
||||||
|
compilerWords[reservedWords[i]] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
|
||||||
|
if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports["default"] = JavaScriptCompiler;
|
||||||
490
node_modules/handlebars/dist/cjs/handlebars/compiler/parser.js
generated
vendored
Normal file
490
node_modules/handlebars/dist/cjs/handlebars/compiler/parser.js
generated
vendored
Normal file
@@ -0,0 +1,490 @@
|
|||||||
|
"use strict";
|
||||||
|
/* jshint ignore:start */
|
||||||
|
/* Jison generated parser */
|
||||||
|
var handlebars = (function(){
|
||||||
|
var parser = {trace: function trace() { },
|
||||||
|
yy: {},
|
||||||
|
symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"sexpr":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"partial_option0":27,"sexpr_repetition0":28,"sexpr_option0":29,"dataName":30,"param":31,"STRING":32,"INTEGER":33,"BOOLEAN":34,"OPEN_SEXPR":35,"CLOSE_SEXPR":36,"hash":37,"hash_repetition_plus0":38,"hashSegment":39,"ID":40,"EQUALS":41,"DATA":42,"pathSegments":43,"SEP":44,"$accept":0,"$end":1},
|
||||||
|
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:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",32:"STRING",33:"INTEGER",34:"BOOLEAN",35:"OPEN_SEXPR",36:"CLOSE_SEXPR",40:"ID",41:"EQUALS",42:"DATA",44:"SEP"},
|
||||||
|
productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[31,3],[37,1],[39,3],[26,1],[26,1],[26,1],[30,2],[21,1],[43,3],[43,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[38,1],[38,2]],
|
||||||
|
performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
|
||||||
|
|
||||||
|
var $0 = $$.length - 1;
|
||||||
|
switch (yystate) {
|
||||||
|
case 1: return new yy.ProgramNode($$[$0-1], this._$);
|
||||||
|
break;
|
||||||
|
case 2: return new yy.ProgramNode([], this._$);
|
||||||
|
break;
|
||||||
|
case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], [], this._$);
|
||||||
|
break;
|
||||||
|
case 6:this.$ = new yy.ProgramNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 7:this.$ = new yy.ProgramNode([], this._$);
|
||||||
|
break;
|
||||||
|
case 8:this.$ = new yy.ProgramNode([], this._$);
|
||||||
|
break;
|
||||||
|
case 9:this.$ = [$$[$0]];
|
||||||
|
break;
|
||||||
|
case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
|
||||||
|
break;
|
||||||
|
case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 13:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 14:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 15:this.$ = new yy.ContentNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 16:this.$ = new yy.CommentNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])};
|
||||||
|
break;
|
||||||
|
case 20:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 21:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 23:this.$ = stripFlags($$[$0-1], $$[$0]);
|
||||||
|
break;
|
||||||
|
case 24:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 25:this.$ = new yy.SexprNode([$$[$0]], null, this._$);
|
||||||
|
break;
|
||||||
|
case 26:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 27:this.$ = new yy.StringNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 28:this.$ = new yy.IntegerNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 29:this.$ = new yy.BooleanNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 30:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 31:$$[$0-1].isHelper = true; this.$ = $$[$0-1];
|
||||||
|
break;
|
||||||
|
case 32:this.$ = new yy.HashNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 33:this.$ = [$$[$0-2], $$[$0]];
|
||||||
|
break;
|
||||||
|
case 34:this.$ = new yy.PartialNameNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 35:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$);
|
||||||
|
break;
|
||||||
|
case 36:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0], this._$));
|
||||||
|
break;
|
||||||
|
case 37:this.$ = new yy.DataNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 38:this.$ = new yy.IdNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 39: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
|
||||||
|
break;
|
||||||
|
case 40:this.$ = [{part: $$[$0]}];
|
||||||
|
break;
|
||||||
|
case 43:this.$ = [];
|
||||||
|
break;
|
||||||
|
case 44:$$[$0-1].push($$[$0]);
|
||||||
|
break;
|
||||||
|
case 47:this.$ = [$$[$0]];
|
||||||
|
break;
|
||||||
|
case 48:$$[$0-1].push($$[$0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
table: [{3:1,4:2,5:[1,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],25:[1,15]},{1:[3]},{5:[1,16],8:17,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],25:[1,15]},{1:[2,2]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],25:[2,9]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],25:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],25:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],25:[2,15]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:29,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:30,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:31,21:24,30:25,40:[1,28],42:[1,27],43:26},{21:33,26:32,32:[1,34],33:[1,35],40:[1,28],43:26},{1:[2,1]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,40:[1,28],42:[1,27],43:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,43],24:[2,43],28:43,32:[2,43],33:[2,43],34:[2,43],35:[2,43],36:[2,43],40:[2,43],42:[2,43]},{18:[2,25],24:[2,25],36:[2,25]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],35:[2,38],36:[2,38],40:[2,38],42:[2,38],44:[1,44]},{21:45,40:[1,28],43:26},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],42:[2,40],44:[2,40]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,41],21:50,27:49,40:[1,28],43:26},{18:[2,34],40:[2,34]},{18:[2,35],40:[2,35]},{18:[2,36],40:[2,36]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],25:[2,11]},{21:51,40:[1,28],43:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],25:[2,12]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,45],21:56,24:[2,45],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:[1,61],36:[2,45],37:55,38:62,39:63,40:[1,64],42:[1,27],43:26},{40:[1,65]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],35:[2,37],36:[2,37],40:[2,37],42:[2,37]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],25:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],25:[2,21]},{18:[1,66]},{18:[2,42]},{18:[1,67]},{8:17,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],25:[1,15]},{18:[2,24],24:[2,24],36:[2,24]},{18:[2,44],24:[2,44],32:[2,44],33:[2,44],34:[2,44],35:[2,44],36:[2,44],40:[2,44],42:[2,44]},{18:[2,46],24:[2,46],36:[2,46]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],35:[2,26],36:[2,26],40:[2,26],42:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],35:[2,27],36:[2,27],40:[2,27],42:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],35:[2,28],36:[2,28],40:[2,28],42:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],35:[2,29],36:[2,29],40:[2,29],42:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],35:[2,30],36:[2,30],40:[2,30],42:[2,30]},{17:68,21:24,30:25,40:[1,28],42:[1,27],43:26},{18:[2,32],24:[2,32],36:[2,32],39:69,40:[1,70]},{18:[2,47],24:[2,47],36:[2,47],40:[2,47]},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],41:[1,71],42:[2,40],44:[2,40]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],35:[2,39],36:[2,39],40:[2,39],42:[2,39],44:[2,39]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],25:[2,19]},{36:[1,72]},{18:[2,48],24:[2,48],36:[2,48],40:[2,48]},{41:[1,71]},{21:56,30:60,31:73,32:[1,57],33:[1,58],34:[1,59],35:[1,61],40:[1,28],42:[1,27],43:26},{18:[2,31],24:[2,31],32:[2,31],33:[2,31],34:[2,31],35:[2,31],36:[2,31],40:[2,31],42:[2,31]},{18:[2,33],24:[2,33],36:[2,33],40:[2,33]}],
|
||||||
|
defaultActions: {3:[2,2],16:[2,1],50:[2,42]},
|
||||||
|
parseError: function parseError(str, hash) {
|
||||||
|
throw new Error(str);
|
||||||
|
},
|
||||||
|
parse: function parse(input) {
|
||||||
|
var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
|
||||||
|
this.lexer.setInput(input);
|
||||||
|
this.lexer.yy = this.yy;
|
||||||
|
this.yy.lexer = this.lexer;
|
||||||
|
this.yy.parser = this;
|
||||||
|
if (typeof this.lexer.yylloc == "undefined")
|
||||||
|
this.lexer.yylloc = {};
|
||||||
|
var yyloc = this.lexer.yylloc;
|
||||||
|
lstack.push(yyloc);
|
||||||
|
var ranges = this.lexer.options && this.lexer.options.ranges;
|
||||||
|
if (typeof this.yy.parseError === "function")
|
||||||
|
this.parseError = this.yy.parseError;
|
||||||
|
function popStack(n) {
|
||||||
|
stack.length = stack.length - 2 * n;
|
||||||
|
vstack.length = vstack.length - n;
|
||||||
|
lstack.length = lstack.length - n;
|
||||||
|
}
|
||||||
|
function lex() {
|
||||||
|
var token;
|
||||||
|
token = self.lexer.lex() || 1;
|
||||||
|
if (typeof token !== "number") {
|
||||||
|
token = self.symbols_[token] || token;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
|
||||||
|
while (true) {
|
||||||
|
state = stack[stack.length - 1];
|
||||||
|
if (this.defaultActions[state]) {
|
||||||
|
action = this.defaultActions[state];
|
||||||
|
} else {
|
||||||
|
if (symbol === null || typeof symbol == "undefined") {
|
||||||
|
symbol = lex();
|
||||||
|
}
|
||||||
|
action = table[state] && table[state][symbol];
|
||||||
|
}
|
||||||
|
if (typeof action === "undefined" || !action.length || !action[0]) {
|
||||||
|
var errStr = "";
|
||||||
|
if (!recovering) {
|
||||||
|
expected = [];
|
||||||
|
for (p in table[state])
|
||||||
|
if (this.terminals_[p] && p > 2) {
|
||||||
|
expected.push("'" + this.terminals_[p] + "'");
|
||||||
|
}
|
||||||
|
if (this.lexer.showPosition) {
|
||||||
|
errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
|
||||||
|
} else {
|
||||||
|
errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
|
||||||
|
}
|
||||||
|
this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (action[0] instanceof Array && action.length > 1) {
|
||||||
|
throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
|
||||||
|
}
|
||||||
|
switch (action[0]) {
|
||||||
|
case 1:
|
||||||
|
stack.push(symbol);
|
||||||
|
vstack.push(this.lexer.yytext);
|
||||||
|
lstack.push(this.lexer.yylloc);
|
||||||
|
stack.push(action[1]);
|
||||||
|
symbol = null;
|
||||||
|
if (!preErrorSymbol) {
|
||||||
|
yyleng = this.lexer.yyleng;
|
||||||
|
yytext = this.lexer.yytext;
|
||||||
|
yylineno = this.lexer.yylineno;
|
||||||
|
yyloc = this.lexer.yylloc;
|
||||||
|
if (recovering > 0)
|
||||||
|
recovering--;
|
||||||
|
} else {
|
||||||
|
symbol = preErrorSymbol;
|
||||||
|
preErrorSymbol = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
len = this.productions_[action[1]][1];
|
||||||
|
yyval.$ = vstack[vstack.length - len];
|
||||||
|
yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
|
||||||
|
if (ranges) {
|
||||||
|
yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
|
||||||
|
}
|
||||||
|
r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
|
||||||
|
if (typeof r !== "undefined") {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
if (len) {
|
||||||
|
stack = stack.slice(0, -1 * len * 2);
|
||||||
|
vstack = vstack.slice(0, -1 * len);
|
||||||
|
lstack = lstack.slice(0, -1 * len);
|
||||||
|
}
|
||||||
|
stack.push(this.productions_[action[1]][0]);
|
||||||
|
vstack.push(yyval.$);
|
||||||
|
lstack.push(yyval._$);
|
||||||
|
newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
|
||||||
|
stack.push(newState);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function stripFlags(open, close) {
|
||||||
|
return {
|
||||||
|
left: open.charAt(2) === '~',
|
||||||
|
right: close.charAt(0) === '~' || close.charAt(1) === '~'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Jison generated lexer */
|
||||||
|
var lexer = (function(){
|
||||||
|
var lexer = ({EOF:1,
|
||||||
|
parseError:function parseError(str, hash) {
|
||||||
|
if (this.yy.parser) {
|
||||||
|
this.yy.parser.parseError(str, hash);
|
||||||
|
} else {
|
||||||
|
throw new Error(str);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setInput:function (input) {
|
||||||
|
this._input = input;
|
||||||
|
this._more = this._less = this.done = false;
|
||||||
|
this.yylineno = this.yyleng = 0;
|
||||||
|
this.yytext = this.matched = this.match = '';
|
||||||
|
this.conditionStack = ['INITIAL'];
|
||||||
|
this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
|
||||||
|
if (this.options.ranges) this.yylloc.range = [0,0];
|
||||||
|
this.offset = 0;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
input:function () {
|
||||||
|
var ch = this._input[0];
|
||||||
|
this.yytext += ch;
|
||||||
|
this.yyleng++;
|
||||||
|
this.offset++;
|
||||||
|
this.match += ch;
|
||||||
|
this.matched += ch;
|
||||||
|
var lines = ch.match(/(?:\r\n?|\n).*/g);
|
||||||
|
if (lines) {
|
||||||
|
this.yylineno++;
|
||||||
|
this.yylloc.last_line++;
|
||||||
|
} else {
|
||||||
|
this.yylloc.last_column++;
|
||||||
|
}
|
||||||
|
if (this.options.ranges) this.yylloc.range[1]++;
|
||||||
|
|
||||||
|
this._input = this._input.slice(1);
|
||||||
|
return ch;
|
||||||
|
},
|
||||||
|
unput:function (ch) {
|
||||||
|
var len = ch.length;
|
||||||
|
var lines = ch.split(/(?:\r\n?|\n)/g);
|
||||||
|
|
||||||
|
this._input = ch + this._input;
|
||||||
|
this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
|
||||||
|
//this.yyleng -= len;
|
||||||
|
this.offset -= len;
|
||||||
|
var oldLines = this.match.split(/(?:\r\n?|\n)/g);
|
||||||
|
this.match = this.match.substr(0, this.match.length-1);
|
||||||
|
this.matched = this.matched.substr(0, this.matched.length-1);
|
||||||
|
|
||||||
|
if (lines.length-1) this.yylineno -= lines.length-1;
|
||||||
|
var r = this.yylloc.range;
|
||||||
|
|
||||||
|
this.yylloc = {first_line: this.yylloc.first_line,
|
||||||
|
last_line: this.yylineno+1,
|
||||||
|
first_column: this.yylloc.first_column,
|
||||||
|
last_column: lines ?
|
||||||
|
(lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
|
||||||
|
this.yylloc.first_column - len
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.options.ranges) {
|
||||||
|
this.yylloc.range = [r[0], r[0] + this.yyleng - len];
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
more:function () {
|
||||||
|
this._more = true;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
less:function (n) {
|
||||||
|
this.unput(this.match.slice(n));
|
||||||
|
},
|
||||||
|
pastInput:function () {
|
||||||
|
var past = this.matched.substr(0, this.matched.length - this.match.length);
|
||||||
|
return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
|
||||||
|
},
|
||||||
|
upcomingInput:function () {
|
||||||
|
var next = this.match;
|
||||||
|
if (next.length < 20) {
|
||||||
|
next += this._input.substr(0, 20-next.length);
|
||||||
|
}
|
||||||
|
return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
|
||||||
|
},
|
||||||
|
showPosition:function () {
|
||||||
|
var pre = this.pastInput();
|
||||||
|
var c = new Array(pre.length + 1).join("-");
|
||||||
|
return pre + this.upcomingInput() + "\n" + c+"^";
|
||||||
|
},
|
||||||
|
next:function () {
|
||||||
|
if (this.done) {
|
||||||
|
return this.EOF;
|
||||||
|
}
|
||||||
|
if (!this._input) this.done = true;
|
||||||
|
|
||||||
|
var token,
|
||||||
|
match,
|
||||||
|
tempMatch,
|
||||||
|
index,
|
||||||
|
col,
|
||||||
|
lines;
|
||||||
|
if (!this._more) {
|
||||||
|
this.yytext = '';
|
||||||
|
this.match = '';
|
||||||
|
}
|
||||||
|
var rules = this._currentRules();
|
||||||
|
for (var i=0;i < rules.length; i++) {
|
||||||
|
tempMatch = this._input.match(this.rules[rules[i]]);
|
||||||
|
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
|
||||||
|
match = tempMatch;
|
||||||
|
index = i;
|
||||||
|
if (!this.options.flex) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (match) {
|
||||||
|
lines = match[0].match(/(?:\r\n?|\n).*/g);
|
||||||
|
if (lines) this.yylineno += lines.length;
|
||||||
|
this.yylloc = {first_line: this.yylloc.last_line,
|
||||||
|
last_line: this.yylineno+1,
|
||||||
|
first_column: this.yylloc.last_column,
|
||||||
|
last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
|
||||||
|
this.yytext += match[0];
|
||||||
|
this.match += match[0];
|
||||||
|
this.matches = match;
|
||||||
|
this.yyleng = this.yytext.length;
|
||||||
|
if (this.options.ranges) {
|
||||||
|
this.yylloc.range = [this.offset, this.offset += this.yyleng];
|
||||||
|
}
|
||||||
|
this._more = false;
|
||||||
|
this._input = this._input.slice(match[0].length);
|
||||||
|
this.matched += match[0];
|
||||||
|
token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
|
||||||
|
if (this.done && this._input) this.done = false;
|
||||||
|
if (token) return token;
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
if (this._input === "") {
|
||||||
|
return this.EOF;
|
||||||
|
} else {
|
||||||
|
return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
|
||||||
|
{text: "", token: null, line: this.yylineno});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lex:function lex() {
|
||||||
|
var r = this.next();
|
||||||
|
if (typeof r !== 'undefined') {
|
||||||
|
return r;
|
||||||
|
} else {
|
||||||
|
return this.lex();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
begin:function begin(condition) {
|
||||||
|
this.conditionStack.push(condition);
|
||||||
|
},
|
||||||
|
popState:function popState() {
|
||||||
|
return this.conditionStack.pop();
|
||||||
|
},
|
||||||
|
_currentRules:function _currentRules() {
|
||||||
|
return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
|
||||||
|
},
|
||||||
|
topState:function () {
|
||||||
|
return this.conditionStack[this.conditionStack.length-2];
|
||||||
|
},
|
||||||
|
pushState:function begin(condition) {
|
||||||
|
this.begin(condition);
|
||||||
|
}});
|
||||||
|
lexer.options = {};
|
||||||
|
lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
|
||||||
|
|
||||||
|
|
||||||
|
function strip(start, end) {
|
||||||
|
return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var YYSTATE=YY_START
|
||||||
|
switch($avoiding_name_collisions) {
|
||||||
|
case 0:
|
||||||
|
if(yy_.yytext.slice(-2) === "\\\\") {
|
||||||
|
strip(0,1);
|
||||||
|
this.begin("mu");
|
||||||
|
} else if(yy_.yytext.slice(-1) === "\\") {
|
||||||
|
strip(0,1);
|
||||||
|
this.begin("emu");
|
||||||
|
} else {
|
||||||
|
this.begin("mu");
|
||||||
|
}
|
||||||
|
if(yy_.yytext) return 14;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 1:return 14;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this.popState();
|
||||||
|
return 14;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 3:strip(0,4); this.popState(); return 15;
|
||||||
|
break;
|
||||||
|
case 4:return 35;
|
||||||
|
break;
|
||||||
|
case 5:return 36;
|
||||||
|
break;
|
||||||
|
case 6:return 25;
|
||||||
|
break;
|
||||||
|
case 7:return 16;
|
||||||
|
break;
|
||||||
|
case 8:return 20;
|
||||||
|
break;
|
||||||
|
case 9:return 19;
|
||||||
|
break;
|
||||||
|
case 10:return 19;
|
||||||
|
break;
|
||||||
|
case 11:return 23;
|
||||||
|
break;
|
||||||
|
case 12:return 22;
|
||||||
|
break;
|
||||||
|
case 13:this.popState(); this.begin('com');
|
||||||
|
break;
|
||||||
|
case 14:strip(3,5); this.popState(); return 15;
|
||||||
|
break;
|
||||||
|
case 15:return 22;
|
||||||
|
break;
|
||||||
|
case 16:return 41;
|
||||||
|
break;
|
||||||
|
case 17:return 40;
|
||||||
|
break;
|
||||||
|
case 18:return 40;
|
||||||
|
break;
|
||||||
|
case 19:return 44;
|
||||||
|
break;
|
||||||
|
case 20:// ignore whitespace
|
||||||
|
break;
|
||||||
|
case 21:this.popState(); return 24;
|
||||||
|
break;
|
||||||
|
case 22:this.popState(); return 18;
|
||||||
|
break;
|
||||||
|
case 23:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 32;
|
||||||
|
break;
|
||||||
|
case 24:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 32;
|
||||||
|
break;
|
||||||
|
case 25:return 42;
|
||||||
|
break;
|
||||||
|
case 26:return 34;
|
||||||
|
break;
|
||||||
|
case 27:return 34;
|
||||||
|
break;
|
||||||
|
case 28:return 33;
|
||||||
|
break;
|
||||||
|
case 29:return 40;
|
||||||
|
break;
|
||||||
|
case 30:yy_.yytext = strip(1,2); return 40;
|
||||||
|
break;
|
||||||
|
case 31:return 'INVALID';
|
||||||
|
break;
|
||||||
|
case 32:return 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
|
||||||
|
lexer.conditions = {"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}};
|
||||||
|
return lexer;})()
|
||||||
|
parser.lexer = lexer;
|
||||||
|
function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
|
||||||
|
return new Parser;
|
||||||
|
})();exports["default"] = handlebars;
|
||||||
|
/* jshint ignore:end */
|
||||||
138
node_modules/handlebars/dist/cjs/handlebars/compiler/printer.js
generated
vendored
Normal file
138
node_modules/handlebars/dist/cjs/handlebars/compiler/printer.js
generated
vendored
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
"use strict";
|
||||||
|
var Visitor = require("./visitor")["default"];
|
||||||
|
|
||||||
|
function print(ast) {
|
||||||
|
return new PrintVisitor().accept(ast);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.print = print;function PrintVisitor() {
|
||||||
|
this.padding = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.PrintVisitor = PrintVisitor;PrintVisitor.prototype = new Visitor();
|
||||||
|
|
||||||
|
PrintVisitor.prototype.pad = function(string, newline) {
|
||||||
|
var out = "";
|
||||||
|
|
||||||
|
for(var i=0,l=this.padding; i<l; i++) {
|
||||||
|
out = out + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
out = out + string;
|
||||||
|
|
||||||
|
if(newline !== false) { out = out + "\n"; }
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.program = function(program) {
|
||||||
|
var out = "",
|
||||||
|
statements = program.statements,
|
||||||
|
i, l;
|
||||||
|
|
||||||
|
for(i=0, l=statements.length; i<l; i++) {
|
||||||
|
out = out + this.accept(statements[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.padding--;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.block = function(block) {
|
||||||
|
var out = "";
|
||||||
|
|
||||||
|
out = out + this.pad("BLOCK:");
|
||||||
|
this.padding++;
|
||||||
|
out = out + this.accept(block.mustache);
|
||||||
|
if (block.program) {
|
||||||
|
out = out + this.pad("PROGRAM:");
|
||||||
|
this.padding++;
|
||||||
|
out = out + this.accept(block.program);
|
||||||
|
this.padding--;
|
||||||
|
}
|
||||||
|
if (block.inverse) {
|
||||||
|
if (block.program) { this.padding++; }
|
||||||
|
out = out + this.pad("{{^}}");
|
||||||
|
this.padding++;
|
||||||
|
out = out + this.accept(block.inverse);
|
||||||
|
this.padding--;
|
||||||
|
if (block.program) { this.padding--; }
|
||||||
|
}
|
||||||
|
this.padding--;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.sexpr = function(sexpr) {
|
||||||
|
var params = sexpr.params, paramStrings = [], hash;
|
||||||
|
|
||||||
|
for(var i=0, l=params.length; i<l; i++) {
|
||||||
|
paramStrings.push(this.accept(params[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
params = "[" + paramStrings.join(", ") + "]";
|
||||||
|
|
||||||
|
hash = sexpr.hash ? " " + this.accept(sexpr.hash) : "";
|
||||||
|
|
||||||
|
return this.accept(sexpr.id) + " " + params + hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.mustache = function(mustache) {
|
||||||
|
return this.pad("{{ " + this.accept(mustache.sexpr) + " }}");
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.partial = function(partial) {
|
||||||
|
var content = this.accept(partial.partialName);
|
||||||
|
if(partial.context) { content = content + " " + this.accept(partial.context); }
|
||||||
|
return this.pad("{{> " + content + " }}");
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.hash = function(hash) {
|
||||||
|
var pairs = hash.pairs;
|
||||||
|
var joinedPairs = [], left, right;
|
||||||
|
|
||||||
|
for(var i=0, l=pairs.length; i<l; i++) {
|
||||||
|
left = pairs[i][0];
|
||||||
|
right = this.accept(pairs[i][1]);
|
||||||
|
joinedPairs.push( left + "=" + right );
|
||||||
|
}
|
||||||
|
|
||||||
|
return "HASH{" + joinedPairs.join(", ") + "}";
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.STRING = function(string) {
|
||||||
|
return '"' + string.string + '"';
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.INTEGER = function(integer) {
|
||||||
|
return "INTEGER{" + integer.integer + "}";
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.BOOLEAN = function(bool) {
|
||||||
|
return "BOOLEAN{" + bool.bool + "}";
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.ID = function(id) {
|
||||||
|
var path = id.parts.join("/");
|
||||||
|
if(id.parts.length > 1) {
|
||||||
|
return "PATH:" + path;
|
||||||
|
} else {
|
||||||
|
return "ID:" + path;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.PARTIAL_NAME = function(partialName) {
|
||||||
|
return "PARTIAL:" + partialName.name;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.DATA = function(data) {
|
||||||
|
return "@" + this.accept(data.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.content = function(content) {
|
||||||
|
return this.pad("CONTENT[ '" + content.string + "' ]");
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.comment = function(comment) {
|
||||||
|
return this.pad("{{! '" + comment.comment + "' }}");
|
||||||
|
};
|
||||||
12
node_modules/handlebars/dist/cjs/handlebars/compiler/visitor.js
generated
vendored
Normal file
12
node_modules/handlebars/dist/cjs/handlebars/compiler/visitor.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
"use strict";
|
||||||
|
function Visitor() {}
|
||||||
|
|
||||||
|
Visitor.prototype = {
|
||||||
|
constructor: Visitor,
|
||||||
|
|
||||||
|
accept: function(object) {
|
||||||
|
return this[object.type](object);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports["default"] = Visitor;
|
||||||
28
node_modules/handlebars/dist/cjs/handlebars/exception.js
generated
vendored
Normal file
28
node_modules/handlebars/dist/cjs/handlebars/exception.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
||||||
|
|
||||||
|
function Exception(message, node) {
|
||||||
|
var line;
|
||||||
|
if (node && node.firstLine) {
|
||||||
|
line = node.firstLine;
|
||||||
|
|
||||||
|
message += ' - ' + line + ':' + node.firstColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp = Error.prototype.constructor.call(this, message);
|
||||||
|
|
||||||
|
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
||||||
|
for (var idx = 0; idx < errorProps.length; idx++) {
|
||||||
|
this[errorProps[idx]] = tmp[errorProps[idx]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line) {
|
||||||
|
this.lineNumber = line;
|
||||||
|
this.column = node.firstColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Exception.prototype = new Error();
|
||||||
|
|
||||||
|
exports["default"] = Exception;
|
||||||
137
node_modules/handlebars/dist/cjs/handlebars/runtime.js
generated
vendored
Normal file
137
node_modules/handlebars/dist/cjs/handlebars/runtime.js
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
"use strict";
|
||||||
|
var Utils = require("./utils");
|
||||||
|
var Exception = require("./exception")["default"];
|
||||||
|
var COMPILER_REVISION = require("./base").COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = require("./base").REVISION_CHANGES;
|
||||||
|
|
||||||
|
function checkRevision(compilerInfo) {
|
||||||
|
var compilerRevision = compilerInfo && compilerInfo[0] || 1,
|
||||||
|
currentRevision = COMPILER_REVISION;
|
||||||
|
|
||||||
|
if (compilerRevision !== currentRevision) {
|
||||||
|
if (compilerRevision < currentRevision) {
|
||||||
|
var runtimeVersions = REVISION_CHANGES[currentRevision],
|
||||||
|
compilerVersions = REVISION_CHANGES[compilerRevision];
|
||||||
|
throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
|
||||||
|
} else {
|
||||||
|
// Use the embedded version info since the runtime doesn't know about this revision yet
|
||||||
|
throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your runtime to a newer version ("+compilerInfo[1]+").");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial
|
||||||
|
|
||||||
|
function template(templateSpec, env) {
|
||||||
|
if (!env) {
|
||||||
|
throw new Exception("No environment passed to template");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Using env.VM references rather than local var references throughout this section to allow
|
||||||
|
// for external users to override these as psuedo-supported APIs.
|
||||||
|
var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
|
||||||
|
var result = env.VM.invokePartial.apply(this, arguments);
|
||||||
|
if (result != null) { return result; }
|
||||||
|
|
||||||
|
if (env.compile) {
|
||||||
|
var options = { helpers: helpers, partials: partials, data: data };
|
||||||
|
partials[name] = env.compile(partial, { data: data !== undefined }, env);
|
||||||
|
return partials[name](context, options);
|
||||||
|
} else {
|
||||||
|
throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Just add water
|
||||||
|
var container = {
|
||||||
|
escapeExpression: Utils.escapeExpression,
|
||||||
|
invokePartial: invokePartialWrapper,
|
||||||
|
programs: [],
|
||||||
|
program: function(i, fn, data) {
|
||||||
|
var programWrapper = this.programs[i];
|
||||||
|
if(data) {
|
||||||
|
programWrapper = program(i, fn, data);
|
||||||
|
} else if (!programWrapper) {
|
||||||
|
programWrapper = this.programs[i] = program(i, fn);
|
||||||
|
}
|
||||||
|
return programWrapper;
|
||||||
|
},
|
||||||
|
merge: function(param, common) {
|
||||||
|
var ret = param || common;
|
||||||
|
|
||||||
|
if (param && common && (param !== common)) {
|
||||||
|
ret = {};
|
||||||
|
Utils.extend(ret, common);
|
||||||
|
Utils.extend(ret, param);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
programWithDepth: env.VM.programWithDepth,
|
||||||
|
noop: env.VM.noop,
|
||||||
|
compilerInfo: null
|
||||||
|
};
|
||||||
|
|
||||||
|
return function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
var namespace = options.partial ? options : env,
|
||||||
|
helpers,
|
||||||
|
partials;
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
helpers = options.helpers;
|
||||||
|
partials = options.partials;
|
||||||
|
}
|
||||||
|
var result = templateSpec.call(
|
||||||
|
container,
|
||||||
|
namespace, context,
|
||||||
|
helpers,
|
||||||
|
partials,
|
||||||
|
options.data);
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
env.VM.checkRevision(container.compilerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.template = template;function programWithDepth(i, fn, data /*, $depth */) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 3);
|
||||||
|
|
||||||
|
var prog = function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
return fn.apply(this, [context, options.data || data].concat(args));
|
||||||
|
};
|
||||||
|
prog.program = i;
|
||||||
|
prog.depth = args.length;
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.programWithDepth = programWithDepth;function program(i, fn, data) {
|
||||||
|
var prog = function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
return fn(context, options.data || data);
|
||||||
|
};
|
||||||
|
prog.program = i;
|
||||||
|
prog.depth = 0;
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
|
||||||
|
var options = { partial: true, helpers: helpers, partials: partials, data: data };
|
||||||
|
|
||||||
|
if(partial === undefined) {
|
||||||
|
throw new Exception("The partial " + name + " could not be found");
|
||||||
|
} else if(partial instanceof Function) {
|
||||||
|
return partial(context, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.invokePartial = invokePartial;function noop() { return ""; }
|
||||||
|
|
||||||
|
exports.noop = noop;
|
||||||
11
node_modules/handlebars/dist/cjs/handlebars/safe-string.js
generated
vendored
Normal file
11
node_modules/handlebars/dist/cjs/handlebars/safe-string.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
"use strict";
|
||||||
|
// Build out our basic SafeString type
|
||||||
|
function SafeString(string) {
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeString.prototype.toString = function() {
|
||||||
|
return "" + this.string;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports["default"] = SafeString;
|
||||||
76
node_modules/handlebars/dist/cjs/handlebars/utils.js
generated
vendored
Normal file
76
node_modules/handlebars/dist/cjs/handlebars/utils.js
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
"use strict";
|
||||||
|
/*jshint -W004 */
|
||||||
|
var SafeString = require("./safe-string")["default"];
|
||||||
|
|
||||||
|
var escape = {
|
||||||
|
"&": "&",
|
||||||
|
"<": "<",
|
||||||
|
">": ">",
|
||||||
|
'"': """,
|
||||||
|
"'": "'",
|
||||||
|
"`": "`"
|
||||||
|
};
|
||||||
|
|
||||||
|
var badChars = /[&<>"'`]/g;
|
||||||
|
var possible = /[&<>"'`]/;
|
||||||
|
|
||||||
|
function escapeChar(chr) {
|
||||||
|
return escape[chr] || "&";
|
||||||
|
}
|
||||||
|
|
||||||
|
function extend(obj, value) {
|
||||||
|
for(var key in value) {
|
||||||
|
if(Object.prototype.hasOwnProperty.call(value, key)) {
|
||||||
|
obj[key] = value[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.extend = extend;var toString = Object.prototype.toString;
|
||||||
|
exports.toString = toString;
|
||||||
|
// Sourced from lodash
|
||||||
|
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
|
||||||
|
var isFunction = function(value) {
|
||||||
|
return typeof value === 'function';
|
||||||
|
};
|
||||||
|
// fallback for older versions of Chrome and Safari
|
||||||
|
if (isFunction(/x/)) {
|
||||||
|
isFunction = function(value) {
|
||||||
|
return typeof value === 'function' && toString.call(value) === '[object Function]';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var isFunction;
|
||||||
|
exports.isFunction = isFunction;
|
||||||
|
var isArray = Array.isArray || function(value) {
|
||||||
|
return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
|
||||||
|
};
|
||||||
|
exports.isArray = isArray;
|
||||||
|
|
||||||
|
function escapeExpression(string) {
|
||||||
|
// don't escape SafeStrings, since they're already safe
|
||||||
|
if (string instanceof SafeString) {
|
||||||
|
return string.toString();
|
||||||
|
} else if (!string && string !== 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force a string conversion as this will be done by the append regardless and
|
||||||
|
// the regex test will do this transparently behind the scenes, causing issues if
|
||||||
|
// an object's to string has escaped characters in it.
|
||||||
|
string = "" + string;
|
||||||
|
|
||||||
|
if(!possible.test(string)) { return string; }
|
||||||
|
return string.replace(badChars, escapeChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.escapeExpression = escapeExpression;function isEmpty(value) {
|
||||||
|
if (!value && value !== 0) {
|
||||||
|
return true;
|
||||||
|
} else if (isArray(value) && value.length === 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.isEmpty = isEmpty;
|
||||||
2719
node_modules/handlebars/dist/handlebars.amd.js
generated
vendored
Normal file
2719
node_modules/handlebars/dist/handlebars.amd.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
28
node_modules/handlebars/dist/handlebars.amd.min.js
generated
vendored
Normal file
28
node_modules/handlebars/dist/handlebars.amd.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1800
node_modules/handlebars/dist/handlebars.js
generated
vendored
1800
node_modules/handlebars/dist/handlebars.js
generated
vendored
File diff suppressed because it is too large
Load Diff
28
node_modules/handlebars/dist/handlebars.min.js
generated
vendored
Normal file
28
node_modules/handlebars/dist/handlebars.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
515
node_modules/handlebars/dist/handlebars.runtime.amd.js
generated
vendored
Normal file
515
node_modules/handlebars/dist/handlebars.runtime.amd.js
generated
vendored
Normal file
@@ -0,0 +1,515 @@
|
|||||||
|
/*!
|
||||||
|
|
||||||
|
handlebars v1.3.0
|
||||||
|
|
||||||
|
Copyright (C) 2011 by Yehuda Katz
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
@license
|
||||||
|
*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
'handlebars/safe-string',["exports"],
|
||||||
|
function(__exports__) {
|
||||||
|
|
||||||
|
// Build out our basic SafeString type
|
||||||
|
function SafeString(string) {
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeString.prototype.toString = function() {
|
||||||
|
return "" + this.string;
|
||||||
|
};
|
||||||
|
|
||||||
|
__exports__["default"] = SafeString;
|
||||||
|
});
|
||||||
|
define(
|
||||||
|
'handlebars/utils',["./safe-string","exports"],
|
||||||
|
function(__dependency1__, __exports__) {
|
||||||
|
|
||||||
|
/*jshint -W004 */
|
||||||
|
var SafeString = __dependency1__["default"];
|
||||||
|
|
||||||
|
var escape = {
|
||||||
|
"&": "&",
|
||||||
|
"<": "<",
|
||||||
|
">": ">",
|
||||||
|
'"': """,
|
||||||
|
"'": "'",
|
||||||
|
"`": "`"
|
||||||
|
};
|
||||||
|
|
||||||
|
var badChars = /[&<>"'`]/g;
|
||||||
|
var possible = /[&<>"'`]/;
|
||||||
|
|
||||||
|
function escapeChar(chr) {
|
||||||
|
return escape[chr] || "&";
|
||||||
|
}
|
||||||
|
|
||||||
|
function extend(obj, value) {
|
||||||
|
for(var key in value) {
|
||||||
|
if(Object.prototype.hasOwnProperty.call(value, key)) {
|
||||||
|
obj[key] = value[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.extend = extend;var toString = Object.prototype.toString;
|
||||||
|
__exports__.toString = toString;
|
||||||
|
// Sourced from lodash
|
||||||
|
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
|
||||||
|
var isFunction = function(value) {
|
||||||
|
return typeof value === 'function';
|
||||||
|
};
|
||||||
|
// fallback for older versions of Chrome and Safari
|
||||||
|
if (isFunction(/x/)) {
|
||||||
|
isFunction = function(value) {
|
||||||
|
return typeof value === 'function' && toString.call(value) === '[object Function]';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var isFunction;
|
||||||
|
__exports__.isFunction = isFunction;
|
||||||
|
var isArray = Array.isArray || function(value) {
|
||||||
|
return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
|
||||||
|
};
|
||||||
|
__exports__.isArray = isArray;
|
||||||
|
|
||||||
|
function escapeExpression(string) {
|
||||||
|
// don't escape SafeStrings, since they're already safe
|
||||||
|
if (string instanceof SafeString) {
|
||||||
|
return string.toString();
|
||||||
|
} else if (!string && string !== 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force a string conversion as this will be done by the append regardless and
|
||||||
|
// the regex test will do this transparently behind the scenes, causing issues if
|
||||||
|
// an object's to string has escaped characters in it.
|
||||||
|
string = "" + string;
|
||||||
|
|
||||||
|
if(!possible.test(string)) { return string; }
|
||||||
|
return string.replace(badChars, escapeChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.escapeExpression = escapeExpression;function isEmpty(value) {
|
||||||
|
if (!value && value !== 0) {
|
||||||
|
return true;
|
||||||
|
} else if (isArray(value) && value.length === 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.isEmpty = isEmpty;
|
||||||
|
});
|
||||||
|
define(
|
||||||
|
'handlebars/exception',["exports"],
|
||||||
|
function(__exports__) {
|
||||||
|
|
||||||
|
|
||||||
|
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
||||||
|
|
||||||
|
function Exception(message, node) {
|
||||||
|
var line;
|
||||||
|
if (node && node.firstLine) {
|
||||||
|
line = node.firstLine;
|
||||||
|
|
||||||
|
message += ' - ' + line + ':' + node.firstColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp = Error.prototype.constructor.call(this, message);
|
||||||
|
|
||||||
|
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
||||||
|
for (var idx = 0; idx < errorProps.length; idx++) {
|
||||||
|
this[errorProps[idx]] = tmp[errorProps[idx]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line) {
|
||||||
|
this.lineNumber = line;
|
||||||
|
this.column = node.firstColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Exception.prototype = new Error();
|
||||||
|
|
||||||
|
__exports__["default"] = Exception;
|
||||||
|
});
|
||||||
|
define(
|
||||||
|
'handlebars/base',["./utils","./exception","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __exports__) {
|
||||||
|
|
||||||
|
var Utils = __dependency1__;
|
||||||
|
var Exception = __dependency2__["default"];
|
||||||
|
|
||||||
|
var VERSION = "1.3.0";
|
||||||
|
__exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
|
||||||
|
__exports__.COMPILER_REVISION = COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = {
|
||||||
|
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
||||||
|
2: '== 1.0.0-rc.3',
|
||||||
|
3: '== 1.0.0-rc.4',
|
||||||
|
4: '>= 1.0.0'
|
||||||
|
};
|
||||||
|
__exports__.REVISION_CHANGES = REVISION_CHANGES;
|
||||||
|
var isArray = Utils.isArray,
|
||||||
|
isFunction = Utils.isFunction,
|
||||||
|
toString = Utils.toString,
|
||||||
|
objectType = '[object Object]';
|
||||||
|
|
||||||
|
function HandlebarsEnvironment(helpers, partials) {
|
||||||
|
this.helpers = helpers || {};
|
||||||
|
this.partials = partials || {};
|
||||||
|
|
||||||
|
registerDefaultHelpers(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
|
||||||
|
constructor: HandlebarsEnvironment,
|
||||||
|
|
||||||
|
logger: logger,
|
||||||
|
log: log,
|
||||||
|
|
||||||
|
registerHelper: function(name, fn, inverse) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
|
||||||
|
Utils.extend(this.helpers, name);
|
||||||
|
} else {
|
||||||
|
if (inverse) { fn.not = inverse; }
|
||||||
|
this.helpers[name] = fn;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
registerPartial: function(name, str) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
Utils.extend(this.partials, name);
|
||||||
|
} else {
|
||||||
|
this.partials[name] = str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function registerDefaultHelpers(instance) {
|
||||||
|
instance.registerHelper('helperMissing', function(arg) {
|
||||||
|
if(arguments.length === 2) {
|
||||||
|
return undefined;
|
||||||
|
} else {
|
||||||
|
throw new Exception("Missing helper: '" + arg + "'");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('blockHelperMissing', function(context, options) {
|
||||||
|
var inverse = options.inverse || function() {}, fn = options.fn;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if(context === true) {
|
||||||
|
return fn(this);
|
||||||
|
} else if(context === false || context == null) {
|
||||||
|
return inverse(this);
|
||||||
|
} else if (isArray(context)) {
|
||||||
|
if(context.length > 0) {
|
||||||
|
return instance.helpers.each(context, options);
|
||||||
|
} else {
|
||||||
|
return inverse(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fn(context);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('each', function(context, options) {
|
||||||
|
var fn = options.fn, inverse = options.inverse;
|
||||||
|
var i = 0, ret = "", data;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if (options.data) {
|
||||||
|
data = createFrame(options.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(context && typeof context === 'object') {
|
||||||
|
if (isArray(context)) {
|
||||||
|
for(var j = context.length; i<j; i++) {
|
||||||
|
if (data) {
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
data.last = (i === (context.length-1));
|
||||||
|
}
|
||||||
|
ret = ret + fn(context[i], { data: data });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(var key in context) {
|
||||||
|
if(context.hasOwnProperty(key)) {
|
||||||
|
if(data) {
|
||||||
|
data.key = key;
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
}
|
||||||
|
ret = ret + fn(context[key], {data: data});
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i === 0){
|
||||||
|
ret = inverse(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('if', function(conditional, options) {
|
||||||
|
if (isFunction(conditional)) { conditional = conditional.call(this); }
|
||||||
|
|
||||||
|
// Default behavior is to render the positive path if the value is truthy and not empty.
|
||||||
|
// The `includeZero` option may be set to treat the condtional as purely not empty based on the
|
||||||
|
// behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
|
||||||
|
if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
|
||||||
|
return options.inverse(this);
|
||||||
|
} else {
|
||||||
|
return options.fn(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('unless', function(conditional, options) {
|
||||||
|
return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('with', function(context, options) {
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if (!Utils.isEmpty(context)) return options.fn(context);
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('log', function(context, options) {
|
||||||
|
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
|
||||||
|
instance.log(level, context);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var logger = {
|
||||||
|
methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
|
||||||
|
|
||||||
|
// State enum
|
||||||
|
DEBUG: 0,
|
||||||
|
INFO: 1,
|
||||||
|
WARN: 2,
|
||||||
|
ERROR: 3,
|
||||||
|
level: 3,
|
||||||
|
|
||||||
|
// can be overridden in the host environment
|
||||||
|
log: function(level, obj) {
|
||||||
|
if (logger.level <= level) {
|
||||||
|
var method = logger.methodMap[level];
|
||||||
|
if (typeof console !== 'undefined' && console[method]) {
|
||||||
|
console[method].call(console, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__exports__.logger = logger;
|
||||||
|
function log(level, obj) { logger.log(level, obj); }
|
||||||
|
|
||||||
|
__exports__.log = log;var createFrame = function(object) {
|
||||||
|
var obj = {};
|
||||||
|
Utils.extend(obj, object);
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
__exports__.createFrame = createFrame;
|
||||||
|
});
|
||||||
|
define(
|
||||||
|
'handlebars/runtime',["./utils","./exception","./base","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
|
||||||
|
|
||||||
|
var Utils = __dependency1__;
|
||||||
|
var Exception = __dependency2__["default"];
|
||||||
|
var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
|
||||||
|
|
||||||
|
function checkRevision(compilerInfo) {
|
||||||
|
var compilerRevision = compilerInfo && compilerInfo[0] || 1,
|
||||||
|
currentRevision = COMPILER_REVISION;
|
||||||
|
|
||||||
|
if (compilerRevision !== currentRevision) {
|
||||||
|
if (compilerRevision < currentRevision) {
|
||||||
|
var runtimeVersions = REVISION_CHANGES[currentRevision],
|
||||||
|
compilerVersions = REVISION_CHANGES[compilerRevision];
|
||||||
|
throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
|
||||||
|
} else {
|
||||||
|
// Use the embedded version info since the runtime doesn't know about this revision yet
|
||||||
|
throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your runtime to a newer version ("+compilerInfo[1]+").");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial
|
||||||
|
|
||||||
|
function template(templateSpec, env) {
|
||||||
|
if (!env) {
|
||||||
|
throw new Exception("No environment passed to template");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Using env.VM references rather than local var references throughout this section to allow
|
||||||
|
// for external users to override these as psuedo-supported APIs.
|
||||||
|
var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
|
||||||
|
var result = env.VM.invokePartial.apply(this, arguments);
|
||||||
|
if (result != null) { return result; }
|
||||||
|
|
||||||
|
if (env.compile) {
|
||||||
|
var options = { helpers: helpers, partials: partials, data: data };
|
||||||
|
partials[name] = env.compile(partial, { data: data !== undefined }, env);
|
||||||
|
return partials[name](context, options);
|
||||||
|
} else {
|
||||||
|
throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Just add water
|
||||||
|
var container = {
|
||||||
|
escapeExpression: Utils.escapeExpression,
|
||||||
|
invokePartial: invokePartialWrapper,
|
||||||
|
programs: [],
|
||||||
|
program: function(i, fn, data) {
|
||||||
|
var programWrapper = this.programs[i];
|
||||||
|
if(data) {
|
||||||
|
programWrapper = program(i, fn, data);
|
||||||
|
} else if (!programWrapper) {
|
||||||
|
programWrapper = this.programs[i] = program(i, fn);
|
||||||
|
}
|
||||||
|
return programWrapper;
|
||||||
|
},
|
||||||
|
merge: function(param, common) {
|
||||||
|
var ret = param || common;
|
||||||
|
|
||||||
|
if (param && common && (param !== common)) {
|
||||||
|
ret = {};
|
||||||
|
Utils.extend(ret, common);
|
||||||
|
Utils.extend(ret, param);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
programWithDepth: env.VM.programWithDepth,
|
||||||
|
noop: env.VM.noop,
|
||||||
|
compilerInfo: null
|
||||||
|
};
|
||||||
|
|
||||||
|
return function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
var namespace = options.partial ? options : env,
|
||||||
|
helpers,
|
||||||
|
partials;
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
helpers = options.helpers;
|
||||||
|
partials = options.partials;
|
||||||
|
}
|
||||||
|
var result = templateSpec.call(
|
||||||
|
container,
|
||||||
|
namespace, context,
|
||||||
|
helpers,
|
||||||
|
partials,
|
||||||
|
options.data);
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
env.VM.checkRevision(container.compilerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 3);
|
||||||
|
|
||||||
|
var prog = function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
return fn.apply(this, [context, options.data || data].concat(args));
|
||||||
|
};
|
||||||
|
prog.program = i;
|
||||||
|
prog.depth = args.length;
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
|
||||||
|
var prog = function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
return fn(context, options.data || data);
|
||||||
|
};
|
||||||
|
prog.program = i;
|
||||||
|
prog.depth = 0;
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
|
||||||
|
var options = { partial: true, helpers: helpers, partials: partials, data: data };
|
||||||
|
|
||||||
|
if(partial === undefined) {
|
||||||
|
throw new Exception("The partial " + name + " could not be found");
|
||||||
|
} else if(partial instanceof Function) {
|
||||||
|
return partial(context, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.invokePartial = invokePartial;function noop() { return ""; }
|
||||||
|
|
||||||
|
__exports__.noop = noop;
|
||||||
|
});
|
||||||
|
define(
|
||||||
|
'handlebars.runtime',["./handlebars/base","./handlebars/safe-string","./handlebars/exception","./handlebars/utils","./handlebars/runtime","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
|
||||||
|
|
||||||
|
/*globals Handlebars: true */
|
||||||
|
var base = __dependency1__;
|
||||||
|
|
||||||
|
// Each of these augment the Handlebars object. No need to setup here.
|
||||||
|
// (This is done to easily share code between commonjs and browse envs)
|
||||||
|
var SafeString = __dependency2__["default"];
|
||||||
|
var Exception = __dependency3__["default"];
|
||||||
|
var Utils = __dependency4__;
|
||||||
|
var runtime = __dependency5__;
|
||||||
|
|
||||||
|
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
|
||||||
|
var create = function() {
|
||||||
|
var hb = new base.HandlebarsEnvironment();
|
||||||
|
|
||||||
|
Utils.extend(hb, base);
|
||||||
|
hb.SafeString = SafeString;
|
||||||
|
hb.Exception = Exception;
|
||||||
|
hb.Utils = Utils;
|
||||||
|
|
||||||
|
hb.VM = runtime;
|
||||||
|
hb.template = function(spec) {
|
||||||
|
return runtime.template(spec, hb);
|
||||||
|
};
|
||||||
|
|
||||||
|
return hb;
|
||||||
|
};
|
||||||
|
|
||||||
|
var Handlebars = create();
|
||||||
|
Handlebars.create = create;
|
||||||
|
|
||||||
|
__exports__["default"] = Handlebars;
|
||||||
|
});
|
||||||
27
node_modules/handlebars/dist/handlebars.runtime.amd.min.js
generated
vendored
Normal file
27
node_modules/handlebars/dist/handlebars.runtime.amd.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
572
node_modules/handlebars/dist/handlebars.runtime.js
generated
vendored
572
node_modules/handlebars/dist/handlebars.runtime.js
generated
vendored
@@ -1,4 +1,6 @@
|
|||||||
/*
|
/*!
|
||||||
|
|
||||||
|
handlebars v1.3.0
|
||||||
|
|
||||||
Copyright (C) 2011 by Yehuda Katz
|
Copyright (C) 2011 by Yehuda Katz
|
||||||
|
|
||||||
@@ -20,58 +22,218 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
@license
|
||||||
*/
|
*/
|
||||||
|
/* exported Handlebars */
|
||||||
|
var Handlebars = (function() {
|
||||||
|
// handlebars/safe-string.js
|
||||||
|
var __module3__ = (function() {
|
||||||
|
"use strict";
|
||||||
|
var __exports__;
|
||||||
|
// Build out our basic SafeString type
|
||||||
|
function SafeString(string) {
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
|
||||||
// lib/handlebars/base.js
|
SafeString.prototype.toString = function() {
|
||||||
|
return "" + this.string;
|
||||||
var Handlebars = {};
|
|
||||||
|
|
||||||
(function(Handlebars) {
|
|
||||||
|
|
||||||
Handlebars.VERSION = "1.0.0-rc.3";
|
|
||||||
Handlebars.COMPILER_REVISION = 2;
|
|
||||||
|
|
||||||
Handlebars.REVISION_CHANGES = {
|
|
||||||
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
|
||||||
2: '>= 1.0.0-rc.3'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.helpers = {};
|
__exports__ = SafeString;
|
||||||
Handlebars.partials = {};
|
return __exports__;
|
||||||
|
})();
|
||||||
|
|
||||||
Handlebars.registerHelper = function(name, fn, inverse) {
|
// handlebars/utils.js
|
||||||
|
var __module2__ = (function(__dependency1__) {
|
||||||
|
"use strict";
|
||||||
|
var __exports__ = {};
|
||||||
|
/*jshint -W004 */
|
||||||
|
var SafeString = __dependency1__;
|
||||||
|
|
||||||
|
var escape = {
|
||||||
|
"&": "&",
|
||||||
|
"<": "<",
|
||||||
|
">": ">",
|
||||||
|
'"': """,
|
||||||
|
"'": "'",
|
||||||
|
"`": "`"
|
||||||
|
};
|
||||||
|
|
||||||
|
var badChars = /[&<>"'`]/g;
|
||||||
|
var possible = /[&<>"'`]/;
|
||||||
|
|
||||||
|
function escapeChar(chr) {
|
||||||
|
return escape[chr] || "&";
|
||||||
|
}
|
||||||
|
|
||||||
|
function extend(obj, value) {
|
||||||
|
for(var key in value) {
|
||||||
|
if(Object.prototype.hasOwnProperty.call(value, key)) {
|
||||||
|
obj[key] = value[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.extend = extend;var toString = Object.prototype.toString;
|
||||||
|
__exports__.toString = toString;
|
||||||
|
// Sourced from lodash
|
||||||
|
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
|
||||||
|
var isFunction = function(value) {
|
||||||
|
return typeof value === 'function';
|
||||||
|
};
|
||||||
|
// fallback for older versions of Chrome and Safari
|
||||||
|
if (isFunction(/x/)) {
|
||||||
|
isFunction = function(value) {
|
||||||
|
return typeof value === 'function' && toString.call(value) === '[object Function]';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var isFunction;
|
||||||
|
__exports__.isFunction = isFunction;
|
||||||
|
var isArray = Array.isArray || function(value) {
|
||||||
|
return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
|
||||||
|
};
|
||||||
|
__exports__.isArray = isArray;
|
||||||
|
|
||||||
|
function escapeExpression(string) {
|
||||||
|
// don't escape SafeStrings, since they're already safe
|
||||||
|
if (string instanceof SafeString) {
|
||||||
|
return string.toString();
|
||||||
|
} else if (!string && string !== 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force a string conversion as this will be done by the append regardless and
|
||||||
|
// the regex test will do this transparently behind the scenes, causing issues if
|
||||||
|
// an object's to string has escaped characters in it.
|
||||||
|
string = "" + string;
|
||||||
|
|
||||||
|
if(!possible.test(string)) { return string; }
|
||||||
|
return string.replace(badChars, escapeChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.escapeExpression = escapeExpression;function isEmpty(value) {
|
||||||
|
if (!value && value !== 0) {
|
||||||
|
return true;
|
||||||
|
} else if (isArray(value) && value.length === 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.isEmpty = isEmpty;
|
||||||
|
return __exports__;
|
||||||
|
})(__module3__);
|
||||||
|
|
||||||
|
// handlebars/exception.js
|
||||||
|
var __module4__ = (function() {
|
||||||
|
"use strict";
|
||||||
|
var __exports__;
|
||||||
|
|
||||||
|
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
||||||
|
|
||||||
|
function Exception(message, node) {
|
||||||
|
var line;
|
||||||
|
if (node && node.firstLine) {
|
||||||
|
line = node.firstLine;
|
||||||
|
|
||||||
|
message += ' - ' + line + ':' + node.firstColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp = Error.prototype.constructor.call(this, message);
|
||||||
|
|
||||||
|
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
||||||
|
for (var idx = 0; idx < errorProps.length; idx++) {
|
||||||
|
this[errorProps[idx]] = tmp[errorProps[idx]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line) {
|
||||||
|
this.lineNumber = line;
|
||||||
|
this.column = node.firstColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Exception.prototype = new Error();
|
||||||
|
|
||||||
|
__exports__ = Exception;
|
||||||
|
return __exports__;
|
||||||
|
})();
|
||||||
|
|
||||||
|
// handlebars/base.js
|
||||||
|
var __module1__ = (function(__dependency1__, __dependency2__) {
|
||||||
|
"use strict";
|
||||||
|
var __exports__ = {};
|
||||||
|
var Utils = __dependency1__;
|
||||||
|
var Exception = __dependency2__;
|
||||||
|
|
||||||
|
var VERSION = "1.3.0";
|
||||||
|
__exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
|
||||||
|
__exports__.COMPILER_REVISION = COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = {
|
||||||
|
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
||||||
|
2: '== 1.0.0-rc.3',
|
||||||
|
3: '== 1.0.0-rc.4',
|
||||||
|
4: '>= 1.0.0'
|
||||||
|
};
|
||||||
|
__exports__.REVISION_CHANGES = REVISION_CHANGES;
|
||||||
|
var isArray = Utils.isArray,
|
||||||
|
isFunction = Utils.isFunction,
|
||||||
|
toString = Utils.toString,
|
||||||
|
objectType = '[object Object]';
|
||||||
|
|
||||||
|
function HandlebarsEnvironment(helpers, partials) {
|
||||||
|
this.helpers = helpers || {};
|
||||||
|
this.partials = partials || {};
|
||||||
|
|
||||||
|
registerDefaultHelpers(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
|
||||||
|
constructor: HandlebarsEnvironment,
|
||||||
|
|
||||||
|
logger: logger,
|
||||||
|
log: log,
|
||||||
|
|
||||||
|
registerHelper: function(name, fn, inverse) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
|
||||||
|
Utils.extend(this.helpers, name);
|
||||||
|
} else {
|
||||||
if (inverse) { fn.not = inverse; }
|
if (inverse) { fn.not = inverse; }
|
||||||
this.helpers[name] = fn;
|
this.helpers[name] = fn;
|
||||||
};
|
}
|
||||||
|
},
|
||||||
|
|
||||||
Handlebars.registerPartial = function(name, str) {
|
registerPartial: function(name, str) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
Utils.extend(this.partials, name);
|
||||||
|
} else {
|
||||||
this.partials[name] = str;
|
this.partials[name] = str;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.registerHelper('helperMissing', function(arg) {
|
function registerDefaultHelpers(instance) {
|
||||||
|
instance.registerHelper('helperMissing', function(arg) {
|
||||||
if(arguments.length === 2) {
|
if(arguments.length === 2) {
|
||||||
return undefined;
|
return undefined;
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Could not find property '" + arg + "'");
|
throw new Exception("Missing helper: '" + arg + "'");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var toString = Object.prototype.toString, functionType = "[object Function]";
|
instance.registerHelper('blockHelperMissing', function(context, options) {
|
||||||
|
|
||||||
Handlebars.registerHelper('blockHelperMissing', function(context, options) {
|
|
||||||
var inverse = options.inverse || function() {}, fn = options.fn;
|
var inverse = options.inverse || function() {}, fn = options.fn;
|
||||||
|
|
||||||
var type = toString.call(context);
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
if(type === functionType) { context = context.call(this); }
|
|
||||||
|
|
||||||
if(context === true) {
|
if(context === true) {
|
||||||
return fn(this);
|
return fn(this);
|
||||||
} else if(context === false || context == null) {
|
} else if(context === false || context == null) {
|
||||||
return inverse(this);
|
return inverse(this);
|
||||||
} else if(type === "[object Array]") {
|
} else if (isArray(context)) {
|
||||||
if(context.length > 0) {
|
if(context.length > 0) {
|
||||||
return Handlebars.helpers.each(context, options);
|
return instance.helpers.each(context, options);
|
||||||
} else {
|
} else {
|
||||||
return inverse(this);
|
return inverse(this);
|
||||||
}
|
}
|
||||||
@@ -80,51 +242,34 @@ Handlebars.registerHelper('blockHelperMissing', function(context, options) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.K = function() {};
|
instance.registerHelper('each', function(context, options) {
|
||||||
|
|
||||||
Handlebars.createFrame = Object.create || function(object) {
|
|
||||||
Handlebars.K.prototype = object;
|
|
||||||
var obj = new Handlebars.K();
|
|
||||||
Handlebars.K.prototype = null;
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
Handlebars.logger = {
|
|
||||||
DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
|
|
||||||
|
|
||||||
methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'},
|
|
||||||
|
|
||||||
// can be overridden in the host environment
|
|
||||||
log: function(level, obj) {
|
|
||||||
if (Handlebars.logger.level <= level) {
|
|
||||||
var method = Handlebars.logger.methodMap[level];
|
|
||||||
if (typeof console !== 'undefined' && console[method]) {
|
|
||||||
console[method].call(console, obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); };
|
|
||||||
|
|
||||||
Handlebars.registerHelper('each', function(context, options) {
|
|
||||||
var fn = options.fn, inverse = options.inverse;
|
var fn = options.fn, inverse = options.inverse;
|
||||||
var i = 0, ret = "", data;
|
var i = 0, ret = "", data;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
if (options.data) {
|
if (options.data) {
|
||||||
data = Handlebars.createFrame(options.data);
|
data = createFrame(options.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(context && typeof context === 'object') {
|
if(context && typeof context === 'object') {
|
||||||
if(context instanceof Array){
|
if (isArray(context)) {
|
||||||
for(var j = context.length; i<j; i++) {
|
for(var j = context.length; i<j; i++) {
|
||||||
if (data) { data.index = i; }
|
if (data) {
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
data.last = (i === (context.length-1));
|
||||||
|
}
|
||||||
ret = ret + fn(context[i], { data: data });
|
ret = ret + fn(context[i], { data: data });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for(var key in context) {
|
for(var key in context) {
|
||||||
if(context.hasOwnProperty(key)) {
|
if(context.hasOwnProperty(key)) {
|
||||||
if(data) { data.key = key; }
|
if(data) {
|
||||||
|
data.key = key;
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
}
|
||||||
ret = ret + fn(context[key], {data: data});
|
ret = ret + fn(context[key], {data: data});
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@@ -139,182 +284,247 @@ Handlebars.registerHelper('each', function(context, options) {
|
|||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('if', function(context, options) {
|
instance.registerHelper('if', function(conditional, options) {
|
||||||
var type = toString.call(context);
|
if (isFunction(conditional)) { conditional = conditional.call(this); }
|
||||||
if(type === functionType) { context = context.call(this); }
|
|
||||||
|
|
||||||
if(!context || Handlebars.Utils.isEmpty(context)) {
|
// Default behavior is to render the positive path if the value is truthy and not empty.
|
||||||
|
// The `includeZero` option may be set to treat the condtional as purely not empty based on the
|
||||||
|
// behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
|
||||||
|
if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
|
||||||
return options.inverse(this);
|
return options.inverse(this);
|
||||||
} else {
|
} else {
|
||||||
return options.fn(this);
|
return options.fn(this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('unless', function(context, options) {
|
instance.registerHelper('unless', function(conditional, options) {
|
||||||
var fn = options.fn, inverse = options.inverse;
|
return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
|
||||||
options.fn = inverse;
|
|
||||||
options.inverse = fn;
|
|
||||||
|
|
||||||
return Handlebars.helpers['if'].call(this, context, options);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('with', function(context, options) {
|
instance.registerHelper('with', function(context, options) {
|
||||||
return options.fn(context);
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if (!Utils.isEmpty(context)) return options.fn(context);
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('log', function(context, options) {
|
instance.registerHelper('log', function(context, options) {
|
||||||
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
|
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
|
||||||
Handlebars.log(level, context);
|
instance.log(level, context);
|
||||||
});
|
});
|
||||||
|
|
||||||
}(Handlebars));
|
|
||||||
;
|
|
||||||
// lib/handlebars/utils.js
|
|
||||||
|
|
||||||
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
|
||||||
|
|
||||||
Handlebars.Exception = function(message) {
|
|
||||||
var tmp = Error.prototype.constructor.apply(this, arguments);
|
|
||||||
|
|
||||||
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
|
||||||
for (var idx = 0; idx < errorProps.length; idx++) {
|
|
||||||
this[errorProps[idx]] = tmp[errorProps[idx]];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Handlebars.Exception.prototype = new Error();
|
|
||||||
|
|
||||||
// Build out our basic SafeString type
|
|
||||||
Handlebars.SafeString = function(string) {
|
|
||||||
this.string = string;
|
|
||||||
};
|
|
||||||
Handlebars.SafeString.prototype.toString = function() {
|
|
||||||
return this.string.toString();
|
|
||||||
};
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
var escape = {
|
|
||||||
"&": "&",
|
|
||||||
"<": "<",
|
|
||||||
">": ">",
|
|
||||||
'"': """,
|
|
||||||
"'": "'",
|
|
||||||
"`": "`"
|
|
||||||
};
|
|
||||||
|
|
||||||
var badChars = /[&<>"'`]/g;
|
|
||||||
var possible = /[&<>"'`]/;
|
|
||||||
|
|
||||||
var escapeChar = function(chr) {
|
|
||||||
return escape[chr] || "&";
|
|
||||||
};
|
|
||||||
|
|
||||||
Handlebars.Utils = {
|
|
||||||
escapeExpression: function(string) {
|
|
||||||
// don't escape SafeStrings, since they're already safe
|
|
||||||
if (string instanceof Handlebars.SafeString) {
|
|
||||||
return string.toString();
|
|
||||||
} else if (string == null || string === false) {
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!possible.test(string)) { return string; }
|
var logger = {
|
||||||
return string.replace(badChars, escapeChar);
|
methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
|
||||||
},
|
|
||||||
|
|
||||||
isEmpty: function(value) {
|
// State enum
|
||||||
if (!value && value !== 0) {
|
DEBUG: 0,
|
||||||
return true;
|
INFO: 1,
|
||||||
} else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
|
WARN: 2,
|
||||||
return true;
|
ERROR: 3,
|
||||||
|
level: 3,
|
||||||
|
|
||||||
|
// can be overridden in the host environment
|
||||||
|
log: function(level, obj) {
|
||||||
|
if (logger.level <= level) {
|
||||||
|
var method = logger.methodMap[level];
|
||||||
|
if (typeof console !== 'undefined' && console[method]) {
|
||||||
|
console[method].call(console, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__exports__.logger = logger;
|
||||||
|
function log(level, obj) { logger.log(level, obj); }
|
||||||
|
|
||||||
|
__exports__.log = log;var createFrame = function(object) {
|
||||||
|
var obj = {};
|
||||||
|
Utils.extend(obj, object);
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
__exports__.createFrame = createFrame;
|
||||||
|
return __exports__;
|
||||||
|
})(__module2__, __module4__);
|
||||||
|
|
||||||
|
// handlebars/runtime.js
|
||||||
|
var __module5__ = (function(__dependency1__, __dependency2__, __dependency3__) {
|
||||||
|
"use strict";
|
||||||
|
var __exports__ = {};
|
||||||
|
var Utils = __dependency1__;
|
||||||
|
var Exception = __dependency2__;
|
||||||
|
var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
|
||||||
|
|
||||||
|
function checkRevision(compilerInfo) {
|
||||||
|
var compilerRevision = compilerInfo && compilerInfo[0] || 1,
|
||||||
|
currentRevision = COMPILER_REVISION;
|
||||||
|
|
||||||
|
if (compilerRevision !== currentRevision) {
|
||||||
|
if (compilerRevision < currentRevision) {
|
||||||
|
var runtimeVersions = REVISION_CHANGES[currentRevision],
|
||||||
|
compilerVersions = REVISION_CHANGES[compilerRevision];
|
||||||
|
throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
|
||||||
} else {
|
} else {
|
||||||
return false;
|
// Use the embedded version info since the runtime doesn't know about this revision yet
|
||||||
|
throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your runtime to a newer version ("+compilerInfo[1]+").");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial
|
||||||
|
|
||||||
|
function template(templateSpec, env) {
|
||||||
|
if (!env) {
|
||||||
|
throw new Exception("No environment passed to template");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Using env.VM references rather than local var references throughout this section to allow
|
||||||
|
// for external users to override these as psuedo-supported APIs.
|
||||||
|
var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
|
||||||
|
var result = env.VM.invokePartial.apply(this, arguments);
|
||||||
|
if (result != null) { return result; }
|
||||||
|
|
||||||
|
if (env.compile) {
|
||||||
|
var options = { helpers: helpers, partials: partials, data: data };
|
||||||
|
partials[name] = env.compile(partial, { data: data !== undefined }, env);
|
||||||
|
return partials[name](context, options);
|
||||||
|
} else {
|
||||||
|
throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
})();
|
|
||||||
;
|
|
||||||
// lib/handlebars/runtime.js
|
|
||||||
|
|
||||||
Handlebars.VM = {
|
|
||||||
template: function(templateSpec) {
|
|
||||||
// Just add water
|
// Just add water
|
||||||
var container = {
|
var container = {
|
||||||
escapeExpression: Handlebars.Utils.escapeExpression,
|
escapeExpression: Utils.escapeExpression,
|
||||||
invokePartial: Handlebars.VM.invokePartial,
|
invokePartial: invokePartialWrapper,
|
||||||
programs: [],
|
programs: [],
|
||||||
program: function(i, fn, data) {
|
program: function(i, fn, data) {
|
||||||
var programWrapper = this.programs[i];
|
var programWrapper = this.programs[i];
|
||||||
if(data) {
|
if(data) {
|
||||||
return Handlebars.VM.program(fn, data);
|
programWrapper = program(i, fn, data);
|
||||||
} else if(programWrapper) {
|
} else if (!programWrapper) {
|
||||||
return programWrapper;
|
programWrapper = this.programs[i] = program(i, fn);
|
||||||
} else {
|
|
||||||
programWrapper = this.programs[i] = Handlebars.VM.program(fn);
|
|
||||||
return programWrapper;
|
|
||||||
}
|
}
|
||||||
|
return programWrapper;
|
||||||
},
|
},
|
||||||
programWithDepth: Handlebars.VM.programWithDepth,
|
merge: function(param, common) {
|
||||||
noop: Handlebars.VM.noop,
|
var ret = param || common;
|
||||||
|
|
||||||
|
if (param && common && (param !== common)) {
|
||||||
|
ret = {};
|
||||||
|
Utils.extend(ret, common);
|
||||||
|
Utils.extend(ret, param);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
programWithDepth: env.VM.programWithDepth,
|
||||||
|
noop: env.VM.noop,
|
||||||
compilerInfo: null
|
compilerInfo: null
|
||||||
};
|
};
|
||||||
|
|
||||||
return function(context, options) {
|
return function(context, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var result = templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
|
var namespace = options.partial ? options : env,
|
||||||
|
helpers,
|
||||||
|
partials;
|
||||||
|
|
||||||
var compilerInfo = container.compilerInfo || [],
|
if (!options.partial) {
|
||||||
compilerRevision = compilerInfo[0] || 1,
|
helpers = options.helpers;
|
||||||
currentRevision = Handlebars.COMPILER_REVISION;
|
partials = options.partials;
|
||||||
|
|
||||||
if (compilerRevision !== currentRevision) {
|
|
||||||
if (compilerRevision < currentRevision) {
|
|
||||||
var runtimeVersions = Handlebars.REVISION_CHANGES[currentRevision],
|
|
||||||
compilerVersions = Handlebars.REVISION_CHANGES[compilerRevision];
|
|
||||||
throw "Template was precompiled with an older version of Handlebars than the current runtime. "+
|
|
||||||
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").";
|
|
||||||
} else {
|
|
||||||
// Use the embedded version info since the runtime doesn't know about this revision yet
|
|
||||||
throw "Template was precompiled with a newer version of Handlebars than the current runtime. "+
|
|
||||||
"Please update your runtime to a newer version ("+compilerInfo[1]+").";
|
|
||||||
}
|
}
|
||||||
|
var result = templateSpec.call(
|
||||||
|
container,
|
||||||
|
namespace, context,
|
||||||
|
helpers,
|
||||||
|
partials,
|
||||||
|
options.data);
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
env.VM.checkRevision(container.compilerInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
|
|
||||||
programWithDepth: function(fn, data, $depth) {
|
__exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) {
|
||||||
var args = Array.prototype.slice.call(arguments, 2);
|
var args = Array.prototype.slice.call(arguments, 3);
|
||||||
|
|
||||||
return function(context, options) {
|
var prog = function(context, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
return fn.apply(this, [context, options.data || data].concat(args));
|
return fn.apply(this, [context, options.data || data].concat(args));
|
||||||
};
|
};
|
||||||
},
|
prog.program = i;
|
||||||
program: function(fn, data) {
|
prog.depth = args.length;
|
||||||
return function(context, options) {
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
|
||||||
|
var prog = function(context, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
return fn(context, options.data || data);
|
return fn(context, options.data || data);
|
||||||
};
|
};
|
||||||
},
|
prog.program = i;
|
||||||
noop: function() { return ""; },
|
prog.depth = 0;
|
||||||
invokePartial: function(partial, name, context, helpers, partials, data) {
|
return prog;
|
||||||
var options = { helpers: helpers, partials: partials, data: data };
|
}
|
||||||
|
|
||||||
|
__exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
|
||||||
|
var options = { partial: true, helpers: helpers, partials: partials, data: data };
|
||||||
|
|
||||||
if(partial === undefined) {
|
if(partial === undefined) {
|
||||||
throw new Handlebars.Exception("The partial " + name + " could not be found");
|
throw new Exception("The partial " + name + " could not be found");
|
||||||
} else if(partial instanceof Function) {
|
} else if(partial instanceof Function) {
|
||||||
return partial(context, options);
|
return partial(context, options);
|
||||||
} else if (!Handlebars.compile) {
|
|
||||||
throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
|
|
||||||
} else {
|
|
||||||
partials[name] = Handlebars.compile(partial, {data: data !== undefined});
|
|
||||||
return partials[name](context, options);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__exports__.invokePartial = invokePartial;function noop() { return ""; }
|
||||||
|
|
||||||
|
__exports__.noop = noop;
|
||||||
|
return __exports__;
|
||||||
|
})(__module2__, __module4__, __module1__);
|
||||||
|
|
||||||
|
// handlebars.runtime.js
|
||||||
|
var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
|
||||||
|
"use strict";
|
||||||
|
var __exports__;
|
||||||
|
/*globals Handlebars: true */
|
||||||
|
var base = __dependency1__;
|
||||||
|
|
||||||
|
// Each of these augment the Handlebars object. No need to setup here.
|
||||||
|
// (This is done to easily share code between commonjs and browse envs)
|
||||||
|
var SafeString = __dependency2__;
|
||||||
|
var Exception = __dependency3__;
|
||||||
|
var Utils = __dependency4__;
|
||||||
|
var runtime = __dependency5__;
|
||||||
|
|
||||||
|
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
|
||||||
|
var create = function() {
|
||||||
|
var hb = new base.HandlebarsEnvironment();
|
||||||
|
|
||||||
|
Utils.extend(hb, base);
|
||||||
|
hb.SafeString = SafeString;
|
||||||
|
hb.Exception = Exception;
|
||||||
|
hb.Utils = Utils;
|
||||||
|
|
||||||
|
hb.VM = runtime;
|
||||||
|
hb.template = function(spec) {
|
||||||
|
return runtime.template(spec, hb);
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.template = Handlebars.VM.template;
|
return hb;
|
||||||
;
|
};
|
||||||
|
|
||||||
|
var Handlebars = create();
|
||||||
|
Handlebars.create = create;
|
||||||
|
|
||||||
|
__exports__ = Handlebars;
|
||||||
|
return __exports__;
|
||||||
|
})(__module1__, __module3__, __module4__, __module2__, __module5__);
|
||||||
|
|
||||||
|
return __module0__;
|
||||||
|
})();
|
||||||
|
|||||||
27
node_modules/handlebars/dist/handlebars.runtime.min.js
generated
vendored
Normal file
27
node_modules/handlebars/dist/handlebars.runtime.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
45
node_modules/handlebars/lib/handlebars.js
generated
vendored
45
node_modules/handlebars/lib/handlebars.js
generated
vendored
@@ -1,32 +1,33 @@
|
|||||||
var handlebars = require("./handlebars/base"),
|
/*globals Handlebars: true */
|
||||||
|
import Handlebars from "./handlebars.runtime";
|
||||||
|
|
||||||
// Each of these augment the Handlebars object. No need to setup here.
|
// Compiler imports
|
||||||
// (This is done to easily share code between commonjs and browse envs)
|
import AST from "./handlebars/compiler/ast";
|
||||||
utils = require("./handlebars/utils"),
|
import { parser as Parser, parse } from "./handlebars/compiler/base";
|
||||||
compiler = require("./handlebars/compiler"),
|
import { Compiler, compile, precompile } from "./handlebars/compiler/compiler";
|
||||||
runtime = require("./handlebars/runtime");
|
import JavaScriptCompiler from "./handlebars/compiler/javascript-compiler";
|
||||||
|
|
||||||
|
var _create = Handlebars.create;
|
||||||
var create = function() {
|
var create = function() {
|
||||||
var hb = handlebars.create();
|
var hb = _create();
|
||||||
|
|
||||||
utils.attach(hb);
|
hb.compile = function(input, options) {
|
||||||
compiler.attach(hb);
|
return compile(input, options, hb);
|
||||||
runtime.attach(hb);
|
};
|
||||||
|
hb.precompile = function (input, options) {
|
||||||
|
return precompile(input, options, hb);
|
||||||
|
};
|
||||||
|
|
||||||
|
hb.AST = AST;
|
||||||
|
hb.Compiler = Compiler;
|
||||||
|
hb.JavaScriptCompiler = JavaScriptCompiler;
|
||||||
|
hb.Parser = Parser;
|
||||||
|
hb.parse = parse;
|
||||||
|
|
||||||
return hb;
|
return hb;
|
||||||
};
|
};
|
||||||
|
|
||||||
var Handlebars = create();
|
Handlebars = create();
|
||||||
Handlebars.create = create;
|
Handlebars.create = create;
|
||||||
|
|
||||||
module.exports = Handlebars; // instantiate an instance
|
export default Handlebars;
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
|
||||||
|
|
||||||
// END(BROWSER)
|
|
||||||
|
|
||||||
// USAGE:
|
|
||||||
// var handlebars = require('handlebars');
|
|
||||||
|
|
||||||
// var singleton = handlebars.Handlebars,
|
|
||||||
// local = handlebars.create();
|
|
||||||
|
|||||||
31
node_modules/handlebars/lib/handlebars.runtime.js
generated
vendored
Normal file
31
node_modules/handlebars/lib/handlebars.runtime.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*globals Handlebars: true */
|
||||||
|
module base from "./handlebars/base";
|
||||||
|
|
||||||
|
// Each of these augment the Handlebars object. No need to setup here.
|
||||||
|
// (This is done to easily share code between commonjs and browse envs)
|
||||||
|
import SafeString from "./handlebars/safe-string";
|
||||||
|
import Exception from "./handlebars/exception";
|
||||||
|
module Utils from "./handlebars/utils";
|
||||||
|
module runtime from "./handlebars/runtime";
|
||||||
|
|
||||||
|
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
|
||||||
|
var create = function() {
|
||||||
|
var hb = new base.HandlebarsEnvironment();
|
||||||
|
|
||||||
|
Utils.extend(hb, base);
|
||||||
|
hb.SafeString = SafeString;
|
||||||
|
hb.Exception = Exception;
|
||||||
|
hb.Utils = Utils;
|
||||||
|
|
||||||
|
hb.VM = runtime;
|
||||||
|
hb.template = function(spec) {
|
||||||
|
return runtime.template(spec, hb);
|
||||||
|
};
|
||||||
|
|
||||||
|
return hb;
|
||||||
|
};
|
||||||
|
|
||||||
|
var Handlebars = create();
|
||||||
|
Handlebars.create = create;
|
||||||
|
|
||||||
|
export default Handlebars;
|
||||||
177
node_modules/handlebars/lib/handlebars/base.js
generated
vendored
177
node_modules/handlebars/lib/handlebars/base.js
generated
vendored
@@ -1,57 +1,74 @@
|
|||||||
/*jshint eqnull: true */
|
module Utils from "./utils";
|
||||||
|
import Exception from "./exception";
|
||||||
|
|
||||||
module.exports.create = function() {
|
export var VERSION = "1.3.0";
|
||||||
|
export var COMPILER_REVISION = 4;
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
export var REVISION_CHANGES = {
|
||||||
|
|
||||||
var Handlebars = {};
|
|
||||||
|
|
||||||
(function(Handlebars) {
|
|
||||||
|
|
||||||
Handlebars.VERSION = "1.0.0-rc.3";
|
|
||||||
Handlebars.COMPILER_REVISION = 2;
|
|
||||||
|
|
||||||
Handlebars.REVISION_CHANGES = {
|
|
||||||
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
||||||
2: '>= 1.0.0-rc.3'
|
2: '== 1.0.0-rc.3',
|
||||||
|
3: '== 1.0.0-rc.4',
|
||||||
|
4: '>= 1.0.0'
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.helpers = {};
|
var isArray = Utils.isArray,
|
||||||
Handlebars.partials = {};
|
isFunction = Utils.isFunction,
|
||||||
|
toString = Utils.toString,
|
||||||
|
objectType = '[object Object]';
|
||||||
|
|
||||||
Handlebars.registerHelper = function(name, fn, inverse) {
|
export function HandlebarsEnvironment(helpers, partials) {
|
||||||
|
this.helpers = helpers || {};
|
||||||
|
this.partials = partials || {};
|
||||||
|
|
||||||
|
registerDefaultHelpers(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
HandlebarsEnvironment.prototype = {
|
||||||
|
constructor: HandlebarsEnvironment,
|
||||||
|
|
||||||
|
logger: logger,
|
||||||
|
log: log,
|
||||||
|
|
||||||
|
registerHelper: function(name, fn, inverse) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
|
||||||
|
Utils.extend(this.helpers, name);
|
||||||
|
} else {
|
||||||
if (inverse) { fn.not = inverse; }
|
if (inverse) { fn.not = inverse; }
|
||||||
this.helpers[name] = fn;
|
this.helpers[name] = fn;
|
||||||
};
|
}
|
||||||
|
},
|
||||||
|
|
||||||
Handlebars.registerPartial = function(name, str) {
|
registerPartial: function(name, str) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
Utils.extend(this.partials, name);
|
||||||
|
} else {
|
||||||
this.partials[name] = str;
|
this.partials[name] = str;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.registerHelper('helperMissing', function(arg) {
|
function registerDefaultHelpers(instance) {
|
||||||
|
instance.registerHelper('helperMissing', function(arg) {
|
||||||
if(arguments.length === 2) {
|
if(arguments.length === 2) {
|
||||||
return undefined;
|
return undefined;
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Could not find property '" + arg + "'");
|
throw new Exception("Missing helper: '" + arg + "'");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var toString = Object.prototype.toString, functionType = "[object Function]";
|
instance.registerHelper('blockHelperMissing', function(context, options) {
|
||||||
|
|
||||||
Handlebars.registerHelper('blockHelperMissing', function(context, options) {
|
|
||||||
var inverse = options.inverse || function() {}, fn = options.fn;
|
var inverse = options.inverse || function() {}, fn = options.fn;
|
||||||
|
|
||||||
var type = toString.call(context);
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
if(type === functionType) { context = context.call(this); }
|
|
||||||
|
|
||||||
if(context === true) {
|
if(context === true) {
|
||||||
return fn(this);
|
return fn(this);
|
||||||
} else if(context === false || context == null) {
|
} else if(context === false || context == null) {
|
||||||
return inverse(this);
|
return inverse(this);
|
||||||
} else if(type === "[object Array]") {
|
} else if (isArray(context)) {
|
||||||
if(context.length > 0) {
|
if(context.length > 0) {
|
||||||
return Handlebars.helpers.each(context, options);
|
return instance.helpers.each(context, options);
|
||||||
} else {
|
} else {
|
||||||
return inverse(this);
|
return inverse(this);
|
||||||
}
|
}
|
||||||
@@ -60,51 +77,34 @@ Handlebars.registerHelper('blockHelperMissing', function(context, options) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.K = function() {};
|
instance.registerHelper('each', function(context, options) {
|
||||||
|
|
||||||
Handlebars.createFrame = Object.create || function(object) {
|
|
||||||
Handlebars.K.prototype = object;
|
|
||||||
var obj = new Handlebars.K();
|
|
||||||
Handlebars.K.prototype = null;
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
Handlebars.logger = {
|
|
||||||
DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
|
|
||||||
|
|
||||||
methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'},
|
|
||||||
|
|
||||||
// can be overridden in the host environment
|
|
||||||
log: function(level, obj) {
|
|
||||||
if (Handlebars.logger.level <= level) {
|
|
||||||
var method = Handlebars.logger.methodMap[level];
|
|
||||||
if (typeof console !== 'undefined' && console[method]) {
|
|
||||||
console[method].call(console, obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); };
|
|
||||||
|
|
||||||
Handlebars.registerHelper('each', function(context, options) {
|
|
||||||
var fn = options.fn, inverse = options.inverse;
|
var fn = options.fn, inverse = options.inverse;
|
||||||
var i = 0, ret = "", data;
|
var i = 0, ret = "", data;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
if (options.data) {
|
if (options.data) {
|
||||||
data = Handlebars.createFrame(options.data);
|
data = createFrame(options.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(context && typeof context === 'object') {
|
if(context && typeof context === 'object') {
|
||||||
if(context instanceof Array){
|
if (isArray(context)) {
|
||||||
for(var j = context.length; i<j; i++) {
|
for(var j = context.length; i<j; i++) {
|
||||||
if (data) { data.index = i; }
|
if (data) {
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
data.last = (i === (context.length-1));
|
||||||
|
}
|
||||||
ret = ret + fn(context[i], { data: data });
|
ret = ret + fn(context[i], { data: data });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for(var key in context) {
|
for(var key in context) {
|
||||||
if(context.hasOwnProperty(key)) {
|
if(context.hasOwnProperty(key)) {
|
||||||
if(data) { data.key = key; }
|
if(data) {
|
||||||
|
data.key = key;
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
}
|
||||||
ret = ret + fn(context[key], {data: data});
|
ret = ret + fn(context[key], {data: data});
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@@ -119,37 +119,60 @@ Handlebars.registerHelper('each', function(context, options) {
|
|||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('if', function(context, options) {
|
instance.registerHelper('if', function(conditional, options) {
|
||||||
var type = toString.call(context);
|
if (isFunction(conditional)) { conditional = conditional.call(this); }
|
||||||
if(type === functionType) { context = context.call(this); }
|
|
||||||
|
|
||||||
if(!context || Handlebars.Utils.isEmpty(context)) {
|
// Default behavior is to render the positive path if the value is truthy and not empty.
|
||||||
|
// The `includeZero` option may be set to treat the condtional as purely not empty based on the
|
||||||
|
// behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
|
||||||
|
if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
|
||||||
return options.inverse(this);
|
return options.inverse(this);
|
||||||
} else {
|
} else {
|
||||||
return options.fn(this);
|
return options.fn(this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('unless', function(context, options) {
|
instance.registerHelper('unless', function(conditional, options) {
|
||||||
var fn = options.fn, inverse = options.inverse;
|
return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
|
||||||
options.fn = inverse;
|
|
||||||
options.inverse = fn;
|
|
||||||
|
|
||||||
return Handlebars.helpers['if'].call(this, context, options);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('with', function(context, options) {
|
instance.registerHelper('with', function(context, options) {
|
||||||
return options.fn(context);
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if (!Utils.isEmpty(context)) return options.fn(context);
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('log', function(context, options) {
|
instance.registerHelper('log', function(context, options) {
|
||||||
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
|
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
|
||||||
Handlebars.log(level, context);
|
instance.log(level, context);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}(Handlebars));
|
export var logger = {
|
||||||
|
methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
|
||||||
|
|
||||||
// END(BROWSER)
|
// State enum
|
||||||
|
DEBUG: 0,
|
||||||
|
INFO: 1,
|
||||||
|
WARN: 2,
|
||||||
|
ERROR: 3,
|
||||||
|
level: 3,
|
||||||
|
|
||||||
return Handlebars;
|
// can be overridden in the host environment
|
||||||
|
log: function(level, obj) {
|
||||||
|
if (logger.level <= level) {
|
||||||
|
var method = logger.methodMap[level];
|
||||||
|
if (typeof console !== 'undefined' && console[method]) {
|
||||||
|
console[method].call(console, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function log(level, obj) { logger.log(level, obj); }
|
||||||
|
|
||||||
|
export var createFrame = function(object) {
|
||||||
|
var obj = {};
|
||||||
|
Utils.extend(obj, object);
|
||||||
|
return obj;
|
||||||
};
|
};
|
||||||
|
|||||||
196
node_modules/handlebars/lib/handlebars/compiler/ast.js
generated
vendored
196
node_modules/handlebars/lib/handlebars/compiler/ast.js
generated
vendored
@@ -1,19 +1,83 @@
|
|||||||
exports.attach = function(Handlebars) {
|
import Exception from "../exception";
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
function LocationInfo(locInfo){
|
||||||
(function() {
|
locInfo = locInfo || {};
|
||||||
|
this.firstLine = locInfo.first_line;
|
||||||
|
this.firstColumn = locInfo.first_column;
|
||||||
|
this.lastColumn = locInfo.last_column;
|
||||||
|
this.lastLine = locInfo.last_line;
|
||||||
|
}
|
||||||
|
|
||||||
Handlebars.AST = {};
|
var AST = {
|
||||||
|
ProgramNode: function(statements, inverseStrip, inverse, locInfo) {
|
||||||
|
var inverseLocationInfo, firstInverseNode;
|
||||||
|
if (arguments.length === 3) {
|
||||||
|
locInfo = inverse;
|
||||||
|
inverse = null;
|
||||||
|
} else if (arguments.length === 2) {
|
||||||
|
locInfo = inverseStrip;
|
||||||
|
inverseStrip = null;
|
||||||
|
}
|
||||||
|
|
||||||
Handlebars.AST.ProgramNode = function(statements, inverse) {
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "program";
|
this.type = "program";
|
||||||
this.statements = statements;
|
this.statements = statements;
|
||||||
if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
|
this.strip = {};
|
||||||
};
|
|
||||||
|
|
||||||
Handlebars.AST.MustacheNode = function(rawParams, hash, unescaped) {
|
if(inverse) {
|
||||||
|
firstInverseNode = inverse[0];
|
||||||
|
if (firstInverseNode) {
|
||||||
|
inverseLocationInfo = {
|
||||||
|
first_line: firstInverseNode.firstLine,
|
||||||
|
last_line: firstInverseNode.lastLine,
|
||||||
|
last_column: firstInverseNode.lastColumn,
|
||||||
|
first_column: firstInverseNode.firstColumn
|
||||||
|
};
|
||||||
|
this.inverse = new AST.ProgramNode(inverse, inverseStrip, inverseLocationInfo);
|
||||||
|
} else {
|
||||||
|
this.inverse = new AST.ProgramNode(inverse, inverseStrip);
|
||||||
|
}
|
||||||
|
this.strip.right = inverseStrip.left;
|
||||||
|
} else if (inverseStrip) {
|
||||||
|
this.strip.left = inverseStrip.right;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
MustacheNode: function(rawParams, hash, open, strip, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "mustache";
|
this.type = "mustache";
|
||||||
this.escaped = !unescaped;
|
this.strip = strip;
|
||||||
|
|
||||||
|
// Open may be a string parsed from the parser or a passed boolean flag
|
||||||
|
if (open != null && open.charAt) {
|
||||||
|
// Must use charAt to support IE pre-10
|
||||||
|
var escapeFlag = open.charAt(3) || open.charAt(2);
|
||||||
|
this.escaped = escapeFlag !== '{' && escapeFlag !== '&';
|
||||||
|
} else {
|
||||||
|
this.escaped = !!open;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawParams instanceof AST.SexprNode) {
|
||||||
|
this.sexpr = rawParams;
|
||||||
|
} else {
|
||||||
|
// Support old AST API
|
||||||
|
this.sexpr = new AST.SexprNode(rawParams, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sexpr.isRoot = true;
|
||||||
|
|
||||||
|
// Support old AST API that stored this info in MustacheNode
|
||||||
|
this.id = this.sexpr.id;
|
||||||
|
this.params = this.sexpr.params;
|
||||||
|
this.hash = this.sexpr.hash;
|
||||||
|
this.eligibleHelper = this.sexpr.eligibleHelper;
|
||||||
|
this.isHelper = this.sexpr.isHelper;
|
||||||
|
},
|
||||||
|
|
||||||
|
SexprNode: function(rawParams, hash, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
|
||||||
|
this.type = "sexpr";
|
||||||
this.hash = hash;
|
this.hash = hash;
|
||||||
|
|
||||||
var id = this.id = rawParams[0];
|
var id = this.id = rawParams[0];
|
||||||
@@ -31,59 +95,79 @@ exports.attach = function(Handlebars) {
|
|||||||
// if a mustache is an eligible helper but not a definite
|
// if a mustache is an eligible helper but not a definite
|
||||||
// helper, it is ambiguous, and will be resolved in a later
|
// helper, it is ambiguous, and will be resolved in a later
|
||||||
// pass or at runtime.
|
// pass or at runtime.
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.PartialNode = function(partialName, context) {
|
PartialNode: function(partialName, context, strip, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "partial";
|
this.type = "partial";
|
||||||
this.partialName = partialName;
|
this.partialName = partialName;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
};
|
this.strip = strip;
|
||||||
|
},
|
||||||
|
|
||||||
Handlebars.AST.BlockNode = function(mustache, program, inverse, close) {
|
BlockNode: function(mustache, program, inverse, close, locInfo) {
|
||||||
var verifyMatch = function(open, close) {
|
LocationInfo.call(this, locInfo);
|
||||||
if(open.original !== close.original) {
|
|
||||||
throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
|
if(mustache.sexpr.id.original !== close.path.original) {
|
||||||
|
throw new Exception(mustache.sexpr.id.original + " doesn't match " + close.path.original, this);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
verifyMatch(mustache.id, close);
|
this.type = 'block';
|
||||||
this.type = "block";
|
|
||||||
this.mustache = mustache;
|
this.mustache = mustache;
|
||||||
this.program = program;
|
this.program = program;
|
||||||
this.inverse = inverse;
|
this.inverse = inverse;
|
||||||
|
|
||||||
if (this.inverse && !this.program) {
|
this.strip = {
|
||||||
|
left: mustache.strip.left,
|
||||||
|
right: close.strip.right
|
||||||
|
};
|
||||||
|
|
||||||
|
(program || inverse).strip.left = mustache.strip.right;
|
||||||
|
(inverse || program).strip.right = close.strip.left;
|
||||||
|
|
||||||
|
if (inverse && !program) {
|
||||||
this.isInverse = true;
|
this.isInverse = true;
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.ContentNode = function(string) {
|
ContentNode: function(string, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "content";
|
this.type = "content";
|
||||||
this.string = string;
|
this.string = string;
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.HashNode = function(pairs) {
|
HashNode: function(pairs, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "hash";
|
this.type = "hash";
|
||||||
this.pairs = pairs;
|
this.pairs = pairs;
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.IdNode = function(parts) {
|
IdNode: function(parts, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "ID";
|
this.type = "ID";
|
||||||
this.original = parts.join(".");
|
|
||||||
|
|
||||||
var dig = [], depth = 0;
|
var original = "",
|
||||||
|
dig = [],
|
||||||
|
depth = 0;
|
||||||
|
|
||||||
for(var i=0,l=parts.length; i<l; i++) {
|
for(var i=0,l=parts.length; i<l; i++) {
|
||||||
var part = parts[i];
|
var part = parts[i].part;
|
||||||
|
original += (parts[i].separator || '') + part;
|
||||||
|
|
||||||
if (part === ".." || part === "." || part === "this") {
|
if (part === ".." || part === "." || part === "this") {
|
||||||
if (dig.length > 0) { throw new Handlebars.Exception("Invalid path: " + this.original); }
|
if (dig.length > 0) {
|
||||||
else if (part === "..") { depth++; }
|
throw new Exception("Invalid path: " + original, this);
|
||||||
else { this.isScoped = true; }
|
} else if (part === "..") {
|
||||||
|
depth++;
|
||||||
|
} else {
|
||||||
|
this.isScoped = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dig.push(part);
|
||||||
}
|
}
|
||||||
else { dig.push(part); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.original = original;
|
||||||
this.parts = dig;
|
this.parts = dig;
|
||||||
this.string = dig.join('.');
|
this.string = dig.join('.');
|
||||||
this.depth = depth;
|
this.depth = depth;
|
||||||
@@ -93,44 +177,50 @@ exports.attach = function(Handlebars) {
|
|||||||
this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
|
this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
|
||||||
|
|
||||||
this.stringModeValue = this.string;
|
this.stringModeValue = this.string;
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.PartialNameNode = function(name) {
|
PartialNameNode: function(name, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "PARTIAL_NAME";
|
this.type = "PARTIAL_NAME";
|
||||||
this.name = name;
|
this.name = name.original;
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.DataNode = function(id) {
|
DataNode: function(id, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "DATA";
|
this.type = "DATA";
|
||||||
this.id = id;
|
this.id = id;
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.StringNode = function(string) {
|
StringNode: function(string, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "STRING";
|
this.type = "STRING";
|
||||||
this.string = string;
|
this.original =
|
||||||
|
this.string =
|
||||||
this.stringModeValue = string;
|
this.stringModeValue = string;
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.IntegerNode = function(integer) {
|
IntegerNode: function(integer, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "INTEGER";
|
this.type = "INTEGER";
|
||||||
|
this.original =
|
||||||
this.integer = integer;
|
this.integer = integer;
|
||||||
this.stringModeValue = Number(integer);
|
this.stringModeValue = Number(integer);
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.BooleanNode = function(bool) {
|
BooleanNode: function(bool, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "BOOLEAN";
|
this.type = "BOOLEAN";
|
||||||
this.bool = bool;
|
this.bool = bool;
|
||||||
this.stringModeValue = bool === "true";
|
this.stringModeValue = bool === "true";
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.CommentNode = function(comment) {
|
CommentNode: function(comment, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "comment";
|
this.type = "comment";
|
||||||
this.comment = comment;
|
this.comment = comment;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
// Must be exported as an object rather than the root of the module as the jison lexer
|
||||||
// END(BROWSER)
|
// most modify the object to operate properly.
|
||||||
|
export default AST;
|
||||||
return Handlebars;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|||||||
28
node_modules/handlebars/lib/handlebars/compiler/base.js
generated
vendored
28
node_modules/handlebars/lib/handlebars/compiler/base.js
generated
vendored
@@ -1,24 +1,12 @@
|
|||||||
var handlebars = require("./parser");
|
import parser from "./parser";
|
||||||
|
import AST from "./ast";
|
||||||
|
|
||||||
exports.attach = function(Handlebars) {
|
export { parser };
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
|
||||||
|
|
||||||
Handlebars.Parser = handlebars;
|
|
||||||
|
|
||||||
Handlebars.parse = function(input) {
|
|
||||||
|
|
||||||
|
export function parse(input) {
|
||||||
// Just return if an already-compile AST was passed in.
|
// Just return if an already-compile AST was passed in.
|
||||||
if(input.constructor === Handlebars.AST.ProgramNode) { return input; }
|
if(input.constructor === AST.ProgramNode) { return input; }
|
||||||
|
|
||||||
Handlebars.Parser.yy = Handlebars.AST;
|
parser.yy = AST;
|
||||||
return Handlebars.Parser.parse(input);
|
return parser.parse(input);
|
||||||
};
|
}
|
||||||
|
|
||||||
Handlebars.print = function(ast) {
|
|
||||||
return new Handlebars.PrintVisitor().accept(ast);
|
|
||||||
};
|
|
||||||
// END(BROWSER)
|
|
||||||
|
|
||||||
return Handlebars;
|
|
||||||
};
|
|
||||||
|
|||||||
1039
node_modules/handlebars/lib/handlebars/compiler/compiler.js
generated
vendored
1039
node_modules/handlebars/lib/handlebars/compiler/compiler.js
generated
vendored
File diff suppressed because it is too large
Load Diff
16
node_modules/handlebars/lib/handlebars/compiler/index.js
generated
vendored
16
node_modules/handlebars/lib/handlebars/compiler/index.js
generated
vendored
@@ -1,16 +0,0 @@
|
|||||||
// Each of these module will augment the Handlebars object as it loads. No need to perform addition operations
|
|
||||||
module.exports.attach = function(Handlebars) {
|
|
||||||
|
|
||||||
var visitor = require("./visitor"),
|
|
||||||
printer = require("./printer"),
|
|
||||||
ast = require("./ast"),
|
|
||||||
compiler = require("./compiler");
|
|
||||||
|
|
||||||
visitor.attach(Handlebars);
|
|
||||||
printer.attach(Handlebars);
|
|
||||||
ast.attach(Handlebars);
|
|
||||||
compiler.attach(Handlebars);
|
|
||||||
|
|
||||||
return Handlebars;
|
|
||||||
|
|
||||||
};
|
|
||||||
939
node_modules/handlebars/lib/handlebars/compiler/javascript-compiler.js
generated
vendored
Normal file
939
node_modules/handlebars/lib/handlebars/compiler/javascript-compiler.js
generated
vendored
Normal file
@@ -0,0 +1,939 @@
|
|||||||
|
import { COMPILER_REVISION, REVISION_CHANGES, log } from "../base";
|
||||||
|
import Exception from "../exception";
|
||||||
|
|
||||||
|
function Literal(value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function JavaScriptCompiler() {}
|
||||||
|
|
||||||
|
JavaScriptCompiler.prototype = {
|
||||||
|
// PUBLIC API: You can override these methods in a subclass to provide
|
||||||
|
// alternative compiled forms for name lookup and buffering semantics
|
||||||
|
nameLookup: function(parent, name /* , type*/) {
|
||||||
|
var wrap,
|
||||||
|
ret;
|
||||||
|
if (parent.indexOf('depth') === 0) {
|
||||||
|
wrap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/^[0-9]+$/.test(name)) {
|
||||||
|
ret = parent + "[" + name + "]";
|
||||||
|
} else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
|
||||||
|
ret = parent + "." + name;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = parent + "['" + name + "']";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wrap) {
|
||||||
|
return '(' + parent + ' && ' + ret + ')';
|
||||||
|
} else {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
compilerInfo: function() {
|
||||||
|
var revision = COMPILER_REVISION,
|
||||||
|
versions = REVISION_CHANGES[revision];
|
||||||
|
return "this.compilerInfo = ["+revision+",'"+versions+"'];\n";
|
||||||
|
},
|
||||||
|
|
||||||
|
appendToBuffer: function(string) {
|
||||||
|
if (this.environment.isSimple) {
|
||||||
|
return "return " + string + ";";
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
appendToBuffer: true,
|
||||||
|
content: string,
|
||||||
|
toString: function() { return "buffer += " + string + ";"; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
initializeBuffer: function() {
|
||||||
|
return this.quotedString("");
|
||||||
|
},
|
||||||
|
|
||||||
|
namespace: "Handlebars",
|
||||||
|
// END PUBLIC API
|
||||||
|
|
||||||
|
compile: function(environment, options, context, asObject) {
|
||||||
|
this.environment = environment;
|
||||||
|
this.options = options || {};
|
||||||
|
|
||||||
|
log('debug', this.environment.disassemble() + "\n\n");
|
||||||
|
|
||||||
|
this.name = this.environment.name;
|
||||||
|
this.isChild = !!context;
|
||||||
|
this.context = context || {
|
||||||
|
programs: [],
|
||||||
|
environments: [],
|
||||||
|
aliases: { }
|
||||||
|
};
|
||||||
|
|
||||||
|
this.preamble();
|
||||||
|
|
||||||
|
this.stackSlot = 0;
|
||||||
|
this.stackVars = [];
|
||||||
|
this.registers = { list: [] };
|
||||||
|
this.hashes = [];
|
||||||
|
this.compileStack = [];
|
||||||
|
this.inlineStack = [];
|
||||||
|
|
||||||
|
this.compileChildren(environment, options);
|
||||||
|
|
||||||
|
var opcodes = environment.opcodes, opcode;
|
||||||
|
|
||||||
|
this.i = 0;
|
||||||
|
|
||||||
|
for(var l=opcodes.length; this.i<l; this.i++) {
|
||||||
|
opcode = opcodes[this.i];
|
||||||
|
|
||||||
|
if(opcode.opcode === 'DECLARE') {
|
||||||
|
this[opcode.name] = opcode.value;
|
||||||
|
} else {
|
||||||
|
this[opcode.opcode].apply(this, opcode.args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the stripNext flag if it was not set by this operation.
|
||||||
|
if (opcode.opcode !== this.stripNext) {
|
||||||
|
this.stripNext = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush any trailing content that might be pending.
|
||||||
|
this.pushSource('');
|
||||||
|
|
||||||
|
if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
|
||||||
|
throw new Exception('Compile completed with content left on stack');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.createFunctionContext(asObject);
|
||||||
|
},
|
||||||
|
|
||||||
|
preamble: function() {
|
||||||
|
var out = [];
|
||||||
|
|
||||||
|
if (!this.isChild) {
|
||||||
|
var namespace = this.namespace;
|
||||||
|
|
||||||
|
var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
|
||||||
|
if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
|
||||||
|
if (this.options.data) { copies = copies + " data = data || {};"; }
|
||||||
|
out.push(copies);
|
||||||
|
} else {
|
||||||
|
out.push('');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.environment.isSimple) {
|
||||||
|
out.push(", buffer = " + this.initializeBuffer());
|
||||||
|
} else {
|
||||||
|
out.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// track the last context pushed into place to allow skipping the
|
||||||
|
// getContext opcode when it would be a noop
|
||||||
|
this.lastContext = 0;
|
||||||
|
this.source = out;
|
||||||
|
},
|
||||||
|
|
||||||
|
createFunctionContext: function(asObject) {
|
||||||
|
var locals = this.stackVars.concat(this.registers.list);
|
||||||
|
|
||||||
|
if(locals.length > 0) {
|
||||||
|
this.source[1] = this.source[1] + ", " + locals.join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate minimizer alias mappings
|
||||||
|
if (!this.isChild) {
|
||||||
|
for (var alias in this.context.aliases) {
|
||||||
|
if (this.context.aliases.hasOwnProperty(alias)) {
|
||||||
|
this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.source[1]) {
|
||||||
|
this.source[1] = "var " + this.source[1].substring(2) + ";";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge children
|
||||||
|
if (!this.isChild) {
|
||||||
|
this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.environment.isSimple) {
|
||||||
|
this.pushSource("return buffer;");
|
||||||
|
}
|
||||||
|
|
||||||
|
var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
|
||||||
|
|
||||||
|
for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
|
||||||
|
params.push("depth" + this.environment.depths.list[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform a second pass over the output to merge content when possible
|
||||||
|
var source = this.mergeSource();
|
||||||
|
|
||||||
|
if (!this.isChild) {
|
||||||
|
source = this.compilerInfo()+source;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asObject) {
|
||||||
|
params.push(source);
|
||||||
|
|
||||||
|
return Function.apply(this, params);
|
||||||
|
} else {
|
||||||
|
var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + source + '}';
|
||||||
|
log('debug', functionSource + "\n\n");
|
||||||
|
return functionSource;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mergeSource: function() {
|
||||||
|
// WARN: We are not handling the case where buffer is still populated as the source should
|
||||||
|
// not have buffer append operations as their final action.
|
||||||
|
var source = '',
|
||||||
|
buffer;
|
||||||
|
for (var i = 0, len = this.source.length; i < len; i++) {
|
||||||
|
var line = this.source[i];
|
||||||
|
if (line.appendToBuffer) {
|
||||||
|
if (buffer) {
|
||||||
|
buffer = buffer + '\n + ' + line.content;
|
||||||
|
} else {
|
||||||
|
buffer = line.content;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (buffer) {
|
||||||
|
source += 'buffer += ' + buffer + ';\n ';
|
||||||
|
buffer = undefined;
|
||||||
|
}
|
||||||
|
source += line + '\n ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return source;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [blockValue]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, value
|
||||||
|
// On stack, after: return value of blockHelperMissing
|
||||||
|
//
|
||||||
|
// The purpose of this opcode is to take a block of the form
|
||||||
|
// `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
|
||||||
|
// replace it on the stack with the result of properly
|
||||||
|
// invoking blockHelperMissing.
|
||||||
|
blockValue: function() {
|
||||||
|
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||||
|
|
||||||
|
var params = ["depth0"];
|
||||||
|
this.setupParams(0, params);
|
||||||
|
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
params.splice(1, 0, current);
|
||||||
|
return "blockHelperMissing.call(" + params.join(", ") + ")";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [ambiguousBlockValue]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, value
|
||||||
|
// Compiler value, before: lastHelper=value of last found helper, if any
|
||||||
|
// On stack, after, if no lastHelper: same as [blockValue]
|
||||||
|
// On stack, after, if lastHelper: value
|
||||||
|
ambiguousBlockValue: function() {
|
||||||
|
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||||
|
|
||||||
|
var params = ["depth0"];
|
||||||
|
this.setupParams(0, params);
|
||||||
|
|
||||||
|
var current = this.topStack();
|
||||||
|
params.splice(1, 0, current);
|
||||||
|
|
||||||
|
this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [appendContent]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Appends the string value of `content` to the current buffer
|
||||||
|
appendContent: function(content) {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
content = this.pendingContent + content;
|
||||||
|
}
|
||||||
|
if (this.stripNext) {
|
||||||
|
content = content.replace(/^\s+/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pendingContent = content;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [strip]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Removes any trailing whitespace from the prior content node and flags
|
||||||
|
// the next operation for stripping if it is a content node.
|
||||||
|
strip: function() {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
this.pendingContent = this.pendingContent.replace(/\s+$/, '');
|
||||||
|
}
|
||||||
|
this.stripNext = 'strip';
|
||||||
|
},
|
||||||
|
|
||||||
|
// [append]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Coerces `value` to a String and appends it to the current buffer.
|
||||||
|
//
|
||||||
|
// If `value` is truthy, or 0, it is coerced into a string and appended
|
||||||
|
// Otherwise, the empty string is appended
|
||||||
|
append: function() {
|
||||||
|
// Force anything that is inlined onto the stack so we don't have duplication
|
||||||
|
// when we examine local
|
||||||
|
this.flushInline();
|
||||||
|
var local = this.popStack();
|
||||||
|
this.pushSource("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
|
||||||
|
if (this.environment.isSimple) {
|
||||||
|
this.pushSource("else { " + this.appendToBuffer("''") + " }");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [appendEscaped]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Escape `value` and append it to the buffer
|
||||||
|
appendEscaped: function() {
|
||||||
|
this.context.aliases.escapeExpression = 'this.escapeExpression';
|
||||||
|
|
||||||
|
this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [getContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
// Compiler value, after: lastContext=depth
|
||||||
|
//
|
||||||
|
// Set the value of the `lastContext` compiler value to the depth
|
||||||
|
getContext: function(depth) {
|
||||||
|
if(this.lastContext !== depth) {
|
||||||
|
this.lastContext = depth;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookupOnContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: currentContext[name], ...
|
||||||
|
//
|
||||||
|
// Looks up the value of `name` on the current context and pushes
|
||||||
|
// it onto the stack.
|
||||||
|
lookupOnContext: function(name) {
|
||||||
|
this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: currentContext, ...
|
||||||
|
//
|
||||||
|
// Pushes the value of the current context onto the stack.
|
||||||
|
pushContext: function() {
|
||||||
|
this.pushStackLiteral('depth' + this.lastContext);
|
||||||
|
},
|
||||||
|
|
||||||
|
// [resolvePossibleLambda]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: resolved value, ...
|
||||||
|
//
|
||||||
|
// If the `value` is a lambda, replace it on the stack by
|
||||||
|
// the return value of the lambda
|
||||||
|
resolvePossibleLambda: function() {
|
||||||
|
this.context.aliases.functionType = '"function"';
|
||||||
|
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookup]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: value[name], ...
|
||||||
|
//
|
||||||
|
// Replace the value on the stack with the result of looking
|
||||||
|
// up `name` on `value`
|
||||||
|
lookup: function(name) {
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookupData]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: data, ...
|
||||||
|
//
|
||||||
|
// Push the data lookup operator
|
||||||
|
lookupData: function() {
|
||||||
|
this.pushStackLiteral('data');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushStringParam]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: string, currentContext, ...
|
||||||
|
//
|
||||||
|
// This opcode is designed for use in string mode, which
|
||||||
|
// provides the string value of a parameter along with its
|
||||||
|
// depth rather than resolving it immediately.
|
||||||
|
pushStringParam: function(string, type) {
|
||||||
|
this.pushStackLiteral('depth' + this.lastContext);
|
||||||
|
|
||||||
|
this.pushString(type);
|
||||||
|
|
||||||
|
// If it's a subexpression, the string result
|
||||||
|
// will be pushed after this opcode.
|
||||||
|
if (type !== 'sexpr') {
|
||||||
|
if (typeof string === 'string') {
|
||||||
|
this.pushString(string);
|
||||||
|
} else {
|
||||||
|
this.pushStackLiteral(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
emptyHash: function() {
|
||||||
|
this.pushStackLiteral('{}');
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
this.push('{}'); // hashContexts
|
||||||
|
this.push('{}'); // hashTypes
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pushHash: function() {
|
||||||
|
if (this.hash) {
|
||||||
|
this.hashes.push(this.hash);
|
||||||
|
}
|
||||||
|
this.hash = {values: [], types: [], contexts: []};
|
||||||
|
},
|
||||||
|
popHash: function() {
|
||||||
|
var hash = this.hash;
|
||||||
|
this.hash = this.hashes.pop();
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
this.push('{' + hash.contexts.join(',') + '}');
|
||||||
|
this.push('{' + hash.types.join(',') + '}');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.push('{\n ' + hash.values.join(',\n ') + '\n }');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushString]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: quotedString(string), ...
|
||||||
|
//
|
||||||
|
// Push a quoted version of `string` onto the stack
|
||||||
|
pushString: function(string) {
|
||||||
|
this.pushStackLiteral(this.quotedString(string));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [push]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: expr, ...
|
||||||
|
//
|
||||||
|
// Push an expression onto the stack
|
||||||
|
push: function(expr) {
|
||||||
|
this.inlineStack.push(expr);
|
||||||
|
return expr;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushLiteral]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: value, ...
|
||||||
|
//
|
||||||
|
// Pushes a value onto the stack. This operation prevents
|
||||||
|
// the compiler from creating a temporary variable to hold
|
||||||
|
// it.
|
||||||
|
pushLiteral: function(value) {
|
||||||
|
this.pushStackLiteral(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushProgram]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: program(guid), ...
|
||||||
|
//
|
||||||
|
// Push a program expression onto the stack. This takes
|
||||||
|
// a compile-time guid and converts it into a runtime-accessible
|
||||||
|
// expression.
|
||||||
|
pushProgram: function(guid) {
|
||||||
|
if (guid != null) {
|
||||||
|
this.pushStackLiteral(this.programExpression(guid));
|
||||||
|
} else {
|
||||||
|
this.pushStackLiteral(null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeHelper]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of helper invocation
|
||||||
|
//
|
||||||
|
// Pops off the helper's parameters, invokes the helper,
|
||||||
|
// and pushes the helper's return value onto the stack.
|
||||||
|
//
|
||||||
|
// If the helper is not found, `helperMissing` is called.
|
||||||
|
invokeHelper: function(paramSize, name, isRoot) {
|
||||||
|
this.context.aliases.helperMissing = 'helpers.helperMissing';
|
||||||
|
this.useRegister('helper');
|
||||||
|
|
||||||
|
var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
|
||||||
|
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
|
||||||
|
|
||||||
|
var lookup = 'helper = ' + helper.name + ' || ' + nonHelper;
|
||||||
|
if (helper.paramsInit) {
|
||||||
|
lookup += ',' + helper.paramsInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.push(
|
||||||
|
'('
|
||||||
|
+ lookup
|
||||||
|
+ ',helper '
|
||||||
|
+ '? helper.call(' + helper.callParams + ') '
|
||||||
|
+ ': helperMissing.call(' + helper.helperMissingParams + '))');
|
||||||
|
|
||||||
|
// Always flush subexpressions. This is both to prevent the compounding size issue that
|
||||||
|
// occurs when the code has to be duplicated for inlining and also to prevent errors
|
||||||
|
// due to the incorrect options object being passed due to the shared register.
|
||||||
|
if (!isRoot) {
|
||||||
|
this.flushInline();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeKnownHelper]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of helper invocation
|
||||||
|
//
|
||||||
|
// This operation is used when the helper is known to exist,
|
||||||
|
// so a `helperMissing` fallback is not required.
|
||||||
|
invokeKnownHelper: function(paramSize, name) {
|
||||||
|
var helper = this.setupHelper(paramSize, name);
|
||||||
|
this.push(helper.name + ".call(" + helper.callParams + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeAmbiguous]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of disambiguation
|
||||||
|
//
|
||||||
|
// This operation is used when an expression like `{{foo}}`
|
||||||
|
// is provided, but we don't know at compile-time whether it
|
||||||
|
// is a helper or a path.
|
||||||
|
//
|
||||||
|
// This operation emits more code than the other options,
|
||||||
|
// and can be avoided by passing the `knownHelpers` and
|
||||||
|
// `knownHelpersOnly` flags at compile-time.
|
||||||
|
invokeAmbiguous: function(name, helperCall) {
|
||||||
|
this.context.aliases.functionType = '"function"';
|
||||||
|
this.useRegister('helper');
|
||||||
|
|
||||||
|
this.emptyHash();
|
||||||
|
var helper = this.setupHelper(0, name, helperCall);
|
||||||
|
|
||||||
|
var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
|
||||||
|
|
||||||
|
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
|
||||||
|
var nextStack = this.nextStack();
|
||||||
|
|
||||||
|
if (helper.paramsInit) {
|
||||||
|
this.pushSource(helper.paramsInit);
|
||||||
|
}
|
||||||
|
this.pushSource('if (helper = ' + helperName + ') { ' + nextStack + ' = helper.call(' + helper.callParams + '); }');
|
||||||
|
this.pushSource('else { helper = ' + nonHelper + '; ' + nextStack + ' = typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper; }');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokePartial]
|
||||||
|
//
|
||||||
|
// On stack, before: context, ...
|
||||||
|
// On stack after: result of partial invocation
|
||||||
|
//
|
||||||
|
// This operation pops off a context, invokes a partial with that context,
|
||||||
|
// and pushes the result of the invocation back.
|
||||||
|
invokePartial: function(name) {
|
||||||
|
var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
|
||||||
|
|
||||||
|
if (this.options.data) {
|
||||||
|
params.push("data");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
this.push("self.invokePartial(" + params.join(", ") + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [assignToHash]
|
||||||
|
//
|
||||||
|
// On stack, before: value, hash, ...
|
||||||
|
// On stack, after: hash, ...
|
||||||
|
//
|
||||||
|
// Pops a value and hash off the stack, assigns `hash[key] = value`
|
||||||
|
// and pushes the hash back onto the stack.
|
||||||
|
assignToHash: function(key) {
|
||||||
|
var value = this.popStack(),
|
||||||
|
context,
|
||||||
|
type;
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
type = this.popStack();
|
||||||
|
context = this.popStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
var hash = this.hash;
|
||||||
|
if (context) {
|
||||||
|
hash.contexts.push("'" + key + "': " + context);
|
||||||
|
}
|
||||||
|
if (type) {
|
||||||
|
hash.types.push("'" + key + "': " + type);
|
||||||
|
}
|
||||||
|
hash.values.push("'" + key + "': (" + value + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// HELPERS
|
||||||
|
|
||||||
|
compiler: JavaScriptCompiler,
|
||||||
|
|
||||||
|
compileChildren: function(environment, options) {
|
||||||
|
var children = environment.children, child, compiler;
|
||||||
|
|
||||||
|
for(var i=0, l=children.length; i<l; i++) {
|
||||||
|
child = children[i];
|
||||||
|
compiler = new this.compiler();
|
||||||
|
|
||||||
|
var index = this.matchExistingProgram(child);
|
||||||
|
|
||||||
|
if (index == null) {
|
||||||
|
this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
|
||||||
|
index = this.context.programs.length;
|
||||||
|
child.index = index;
|
||||||
|
child.name = 'program' + index;
|
||||||
|
this.context.programs[index] = compiler.compile(child, options, this.context);
|
||||||
|
this.context.environments[index] = child;
|
||||||
|
} else {
|
||||||
|
child.index = index;
|
||||||
|
child.name = 'program' + index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
matchExistingProgram: function(child) {
|
||||||
|
for (var i = 0, len = this.context.environments.length; i < len; i++) {
|
||||||
|
var environment = this.context.environments[i];
|
||||||
|
if (environment && environment.equals(child)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
programExpression: function(guid) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
|
||||||
|
if(guid == null) {
|
||||||
|
return "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
var child = this.environment.children[guid],
|
||||||
|
depths = child.depths.list, depth;
|
||||||
|
|
||||||
|
var programParams = [child.index, child.name, "data"];
|
||||||
|
|
||||||
|
for(var i=0, l = depths.length; i<l; i++) {
|
||||||
|
depth = depths[i];
|
||||||
|
|
||||||
|
if(depth === 1) { programParams.push("depth0"); }
|
||||||
|
else { programParams.push("depth" + (depth - 1)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
|
||||||
|
},
|
||||||
|
|
||||||
|
register: function(name, val) {
|
||||||
|
this.useRegister(name);
|
||||||
|
this.pushSource(name + " = " + val + ";");
|
||||||
|
},
|
||||||
|
|
||||||
|
useRegister: function(name) {
|
||||||
|
if(!this.registers[name]) {
|
||||||
|
this.registers[name] = true;
|
||||||
|
this.registers.list.push(name);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
pushStackLiteral: function(item) {
|
||||||
|
return this.push(new Literal(item));
|
||||||
|
},
|
||||||
|
|
||||||
|
pushSource: function(source) {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
|
||||||
|
this.pendingContent = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source) {
|
||||||
|
this.source.push(source);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
pushStack: function(item) {
|
||||||
|
this.flushInline();
|
||||||
|
|
||||||
|
var stack = this.incrStack();
|
||||||
|
if (item) {
|
||||||
|
this.pushSource(stack + " = " + item + ";");
|
||||||
|
}
|
||||||
|
this.compileStack.push(stack);
|
||||||
|
return stack;
|
||||||
|
},
|
||||||
|
|
||||||
|
replaceStack: function(callback) {
|
||||||
|
var prefix = '',
|
||||||
|
inline = this.isInline(),
|
||||||
|
stack,
|
||||||
|
createdStack,
|
||||||
|
usedLiteral;
|
||||||
|
|
||||||
|
// If we are currently inline then we want to merge the inline statement into the
|
||||||
|
// replacement statement via ','
|
||||||
|
if (inline) {
|
||||||
|
var top = this.popStack(true);
|
||||||
|
|
||||||
|
if (top instanceof Literal) {
|
||||||
|
// Literals do not need to be inlined
|
||||||
|
stack = top.value;
|
||||||
|
usedLiteral = true;
|
||||||
|
} else {
|
||||||
|
// Get or create the current stack name for use by the inline
|
||||||
|
createdStack = !this.stackSlot;
|
||||||
|
var name = !createdStack ? this.topStackName() : this.incrStack();
|
||||||
|
|
||||||
|
prefix = '(' + this.push(name) + ' = ' + top + '),';
|
||||||
|
stack = this.topStack();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stack = this.topStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = callback.call(this, stack);
|
||||||
|
|
||||||
|
if (inline) {
|
||||||
|
if (!usedLiteral) {
|
||||||
|
this.popStack();
|
||||||
|
}
|
||||||
|
if (createdStack) {
|
||||||
|
this.stackSlot--;
|
||||||
|
}
|
||||||
|
this.push('(' + prefix + item + ')');
|
||||||
|
} else {
|
||||||
|
// Prevent modification of the context depth variable. Through replaceStack
|
||||||
|
if (!/^stack/.test(stack)) {
|
||||||
|
stack = this.nextStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pushSource(stack + " = (" + prefix + item + ");");
|
||||||
|
}
|
||||||
|
return stack;
|
||||||
|
},
|
||||||
|
|
||||||
|
nextStack: function() {
|
||||||
|
return this.pushStack();
|
||||||
|
},
|
||||||
|
|
||||||
|
incrStack: function() {
|
||||||
|
this.stackSlot++;
|
||||||
|
if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
|
||||||
|
return this.topStackName();
|
||||||
|
},
|
||||||
|
topStackName: function() {
|
||||||
|
return "stack" + this.stackSlot;
|
||||||
|
},
|
||||||
|
flushInline: function() {
|
||||||
|
var inlineStack = this.inlineStack;
|
||||||
|
if (inlineStack.length) {
|
||||||
|
this.inlineStack = [];
|
||||||
|
for (var i = 0, len = inlineStack.length; i < len; i++) {
|
||||||
|
var entry = inlineStack[i];
|
||||||
|
if (entry instanceof Literal) {
|
||||||
|
this.compileStack.push(entry);
|
||||||
|
} else {
|
||||||
|
this.pushStack(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isInline: function() {
|
||||||
|
return this.inlineStack.length;
|
||||||
|
},
|
||||||
|
|
||||||
|
popStack: function(wrapped) {
|
||||||
|
var inline = this.isInline(),
|
||||||
|
item = (inline ? this.inlineStack : this.compileStack).pop();
|
||||||
|
|
||||||
|
if (!wrapped && (item instanceof Literal)) {
|
||||||
|
return item.value;
|
||||||
|
} else {
|
||||||
|
if (!inline) {
|
||||||
|
if (!this.stackSlot) {
|
||||||
|
throw new Exception('Invalid stack pop');
|
||||||
|
}
|
||||||
|
this.stackSlot--;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
topStack: function(wrapped) {
|
||||||
|
var stack = (this.isInline() ? this.inlineStack : this.compileStack),
|
||||||
|
item = stack[stack.length - 1];
|
||||||
|
|
||||||
|
if (!wrapped && (item instanceof Literal)) {
|
||||||
|
return item.value;
|
||||||
|
} else {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
quotedString: function(str) {
|
||||||
|
return '"' + str
|
||||||
|
.replace(/\\/g, '\\\\')
|
||||||
|
.replace(/"/g, '\\"')
|
||||||
|
.replace(/\n/g, '\\n')
|
||||||
|
.replace(/\r/g, '\\r')
|
||||||
|
.replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
|
||||||
|
.replace(/\u2029/g, '\\u2029') + '"';
|
||||||
|
},
|
||||||
|
|
||||||
|
setupHelper: function(paramSize, name, missingParams) {
|
||||||
|
var params = [],
|
||||||
|
paramsInit = this.setupParams(paramSize, params, missingParams);
|
||||||
|
var foundHelper = this.nameLookup('helpers', name, 'helper');
|
||||||
|
|
||||||
|
return {
|
||||||
|
params: params,
|
||||||
|
paramsInit: paramsInit,
|
||||||
|
name: foundHelper,
|
||||||
|
callParams: ["depth0"].concat(params).join(", "),
|
||||||
|
helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
setupOptions: function(paramSize, params) {
|
||||||
|
var options = [], contexts = [], types = [], param, inverse, program;
|
||||||
|
|
||||||
|
options.push("hash:" + this.popStack());
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
options.push("hashTypes:" + this.popStack());
|
||||||
|
options.push("hashContexts:" + this.popStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
inverse = this.popStack();
|
||||||
|
program = this.popStack();
|
||||||
|
|
||||||
|
// Avoid setting fn and inverse if neither are set. This allows
|
||||||
|
// helpers to do a check for `if (options.fn)`
|
||||||
|
if (program || inverse) {
|
||||||
|
if (!program) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
program = "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inverse) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
inverse = "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
options.push("inverse:" + inverse);
|
||||||
|
options.push("fn:" + program);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i=0; i<paramSize; i++) {
|
||||||
|
param = this.popStack();
|
||||||
|
params.push(param);
|
||||||
|
|
||||||
|
if(this.options.stringParams) {
|
||||||
|
types.push(this.popStack());
|
||||||
|
contexts.push(this.popStack());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
options.push("contexts:[" + contexts.join(",") + "]");
|
||||||
|
options.push("types:[" + types.join(",") + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.options.data) {
|
||||||
|
options.push("data:data");
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
},
|
||||||
|
|
||||||
|
// the params and contexts arguments are passed in arrays
|
||||||
|
// to fill in
|
||||||
|
setupParams: function(paramSize, params, useRegister) {
|
||||||
|
var options = '{' + this.setupOptions(paramSize, params).join(',') + '}';
|
||||||
|
|
||||||
|
if (useRegister) {
|
||||||
|
this.useRegister('options');
|
||||||
|
params.push('options');
|
||||||
|
return 'options=' + options;
|
||||||
|
} else {
|
||||||
|
params.push(options);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var reservedWords = (
|
||||||
|
"break else new var" +
|
||||||
|
" case finally return void" +
|
||||||
|
" catch for switch while" +
|
||||||
|
" continue function this with" +
|
||||||
|
" default if throw" +
|
||||||
|
" delete in try" +
|
||||||
|
" do instanceof typeof" +
|
||||||
|
" abstract enum int short" +
|
||||||
|
" boolean export interface static" +
|
||||||
|
" byte extends long super" +
|
||||||
|
" char final native synchronized" +
|
||||||
|
" class float package throws" +
|
||||||
|
" const goto private transient" +
|
||||||
|
" debugger implements protected volatile" +
|
||||||
|
" double import public let yield"
|
||||||
|
).split(" ");
|
||||||
|
|
||||||
|
var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
|
||||||
|
|
||||||
|
for(var i=0, l=reservedWords.length; i<l; i++) {
|
||||||
|
compilerWords[reservedWords[i]] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
|
||||||
|
if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default JavaScriptCompiler;
|
||||||
201
node_modules/handlebars/lib/handlebars/compiler/parser.js
generated
vendored
201
node_modules/handlebars/lib/handlebars/compiler/parser.js
generated
vendored
@@ -1,113 +1,107 @@
|
|||||||
// BEGIN(BROWSER)
|
/* jshint ignore:start */
|
||||||
/* Jison generated parser */
|
/* Jison generated parser */
|
||||||
var handlebars = (function(){
|
var handlebars = (function(){
|
||||||
var parser = {trace: function trace() { },
|
var parser = {trace: function trace() { },
|
||||||
yy: {},
|
yy: {},
|
||||||
symbols_: {"error":2,"root":3,"program":4,"EOF":5,"simpleInverse":6,"statements":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,"partialName":25,"params":26,"hash":27,"DATA":28,"param":29,"STRING":30,"INTEGER":31,"BOOLEAN":32,"hashSegments":33,"hashSegment":34,"ID":35,"EQUALS":36,"PARTIAL_NAME":37,"pathSegments":38,"SEP":39,"$accept":0,"$end":1},
|
symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"sexpr":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"partial_option0":27,"sexpr_repetition0":28,"sexpr_option0":29,"dataName":30,"param":31,"STRING":32,"INTEGER":33,"BOOLEAN":34,"OPEN_SEXPR":35,"CLOSE_SEXPR":36,"hash":37,"hash_repetition_plus0":38,"hashSegment":39,"ID":40,"EQUALS":41,"DATA":42,"pathSegments":43,"SEP":44,"$accept":0,"$end":1},
|
||||||
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:"DATA",30:"STRING",31:"INTEGER",32:"BOOLEAN",35:"ID",36:"EQUALS",37:"PARTIAL_NAME",39:"SEP"},
|
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:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",32:"STRING",33:"INTEGER",34:"BOOLEAN",35:"OPEN_SEXPR",36:"CLOSE_SEXPR",40:"ID",41:"EQUALS",42:"DATA",44:"SEP"},
|
||||||
productions_: [0,[3,2],[4,2],[4,3],[4,2],[4,1],[4,1],[4,0],[7,1],[7,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],[6,2],[17,3],[17,2],[17,2],[17,1],[17,1],[26,2],[26,1],[29,1],[29,1],[29,1],[29,1],[29,1],[27,1],[33,2],[33,1],[34,3],[34,3],[34,3],[34,3],[34,3],[25,1],[21,1],[38,3],[38,1]],
|
productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[31,3],[37,1],[39,3],[26,1],[26,1],[26,1],[30,2],[21,1],[43,3],[43,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[38,1],[38,2]],
|
||||||
performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
|
performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
|
||||||
|
|
||||||
var $0 = $$.length - 1;
|
var $0 = $$.length - 1;
|
||||||
switch (yystate) {
|
switch (yystate) {
|
||||||
case 1: return $$[$0-1];
|
case 1: return new yy.ProgramNode($$[$0-1], this._$);
|
||||||
break;
|
break;
|
||||||
case 2: this.$ = new yy.ProgramNode([], $$[$0]);
|
case 2: return new yy.ProgramNode([], this._$);
|
||||||
break;
|
break;
|
||||||
case 3: this.$ = new yy.ProgramNode($$[$0-2], $$[$0]);
|
case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 4: this.$ = new yy.ProgramNode($$[$0-1], []);
|
case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 5: this.$ = new yy.ProgramNode($$[$0]);
|
case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], [], this._$);
|
||||||
break;
|
break;
|
||||||
case 6: this.$ = new yy.ProgramNode([], []);
|
case 6:this.$ = new yy.ProgramNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 7: this.$ = new yy.ProgramNode([]);
|
case 7:this.$ = new yy.ProgramNode([], this._$);
|
||||||
break;
|
break;
|
||||||
case 8: this.$ = [$$[$0]];
|
case 8:this.$ = new yy.ProgramNode([], this._$);
|
||||||
break;
|
break;
|
||||||
case 9: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
|
case 9:this.$ = [$$[$0]];
|
||||||
break;
|
break;
|
||||||
case 10: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0]);
|
case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
|
||||||
break;
|
break;
|
||||||
case 11: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0]);
|
case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 12: this.$ = $$[$0];
|
case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 13:this.$ = $$[$0];
|
case 13:this.$ = $$[$0];
|
||||||
break;
|
break;
|
||||||
case 14: this.$ = new yy.ContentNode($$[$0]);
|
case 14:this.$ = $$[$0];
|
||||||
break;
|
break;
|
||||||
case 15: this.$ = new yy.CommentNode($$[$0]);
|
case 15:this.$ = new yy.ContentNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
|
case 16:this.$ = new yy.CommentNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
|
case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
break;
|
break;
|
||||||
case 18: this.$ = $$[$0-1];
|
case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
break;
|
break;
|
||||||
case 19: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
|
case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])};
|
||||||
break;
|
break;
|
||||||
case 20: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true);
|
case 20:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
break;
|
break;
|
||||||
case 21: this.$ = new yy.PartialNode($$[$0-1]);
|
case 21:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
break;
|
break;
|
||||||
case 22: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1]);
|
case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]), this._$);
|
||||||
break;
|
break;
|
||||||
case 23:
|
case 23:this.$ = stripFlags($$[$0-1], $$[$0]);
|
||||||
break;
|
break;
|
||||||
case 24: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]];
|
case 24:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 25: this.$ = [[$$[$0-1]].concat($$[$0]), null];
|
case 25:this.$ = new yy.SexprNode([$$[$0]], null, this._$);
|
||||||
break;
|
break;
|
||||||
case 26: this.$ = [[$$[$0-1]], $$[$0]];
|
case 26:this.$ = $$[$0];
|
||||||
break;
|
break;
|
||||||
case 27: this.$ = [[$$[$0]], null];
|
case 27:this.$ = new yy.StringNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 28: this.$ = [[new yy.DataNode($$[$0])], null];
|
case 28:this.$ = new yy.IntegerNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 29: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
|
case 29:this.$ = new yy.BooleanNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 30: this.$ = [$$[$0]];
|
case 30:this.$ = $$[$0];
|
||||||
break;
|
break;
|
||||||
case 31: this.$ = $$[$0];
|
case 31:$$[$0-1].isHelper = true; this.$ = $$[$0-1];
|
||||||
break;
|
break;
|
||||||
case 32: this.$ = new yy.StringNode($$[$0]);
|
case 32:this.$ = new yy.HashNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 33: this.$ = new yy.IntegerNode($$[$0]);
|
case 33:this.$ = [$$[$0-2], $$[$0]];
|
||||||
break;
|
break;
|
||||||
case 34: this.$ = new yy.BooleanNode($$[$0]);
|
case 34:this.$ = new yy.PartialNameNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 35: this.$ = new yy.DataNode($$[$0]);
|
case 35:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$);
|
||||||
break;
|
break;
|
||||||
case 36: this.$ = new yy.HashNode($$[$0]);
|
case 36:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0], this._$));
|
||||||
break;
|
break;
|
||||||
case 37: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
|
case 37:this.$ = new yy.DataNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 38: this.$ = [$$[$0]];
|
case 38:this.$ = new yy.IdNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 39: this.$ = [$$[$0-2], $$[$0]];
|
case 39: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
|
||||||
break;
|
break;
|
||||||
case 40: this.$ = [$$[$0-2], new yy.StringNode($$[$0])];
|
case 40:this.$ = [{part: $$[$0]}];
|
||||||
break;
|
break;
|
||||||
case 41: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])];
|
case 43:this.$ = [];
|
||||||
break;
|
break;
|
||||||
case 42: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])];
|
case 44:$$[$0-1].push($$[$0]);
|
||||||
break;
|
|
||||||
case 43: this.$ = [$$[$0-2], new yy.DataNode($$[$0])];
|
|
||||||
break;
|
|
||||||
case 44: this.$ = new yy.PartialNameNode($$[$0]);
|
|
||||||
break;
|
|
||||||
case 45: this.$ = new yy.IdNode($$[$0]);
|
|
||||||
break;
|
|
||||||
case 46: $$[$0-2].push($$[$0]); this.$ = $$[$0-2];
|
|
||||||
break;
|
break;
|
||||||
case 47:this.$ = [$$[$0]];
|
case 47:this.$ = [$$[$0]];
|
||||||
break;
|
break;
|
||||||
|
case 48:$$[$0-1].push($$[$0]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
table: [{3:1,4:2,5:[2,7],6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],22:[1,14],23:[1,15],24:[1,16]},{1:[3]},{5:[1,17]},{5:[2,6],7:18,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,6],22:[1,14],23:[1,15],24:[1,16]},{5:[2,5],6:20,8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,5],22:[1,14],23:[1,15],24:[1,16]},{17:23,18:[1,22],21:24,28:[1,25],35:[1,27],38:26},{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]},{4:28,6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,7],22:[1,14],23:[1,15],24:[1,16]},{4:29,6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,7],22:[1,14],23:[1,15],24:[1,16]},{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]},{5:[2,13],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,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{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]},{17:30,21:24,28:[1,25],35:[1,27],38:26},{17:31,21:24,28:[1,25],35:[1,27],38:26},{17:32,21:24,28:[1,25],35:[1,27],38:26},{25:33,37:[1,34]},{1:[2,1]},{5:[2,2],8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,2],22:[1,14],23:[1,15],24:[1,16]},{17:23,21:24,28:[1,25],35:[1,27],38:26},{5:[2,4],7:35,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,4],22:[1,14],23:[1,15],24:[1,16]},{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,23],14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],24:[2,23]},{18:[1,36]},{18:[2,27],21:41,26:37,27:38,28:[1,45],29:39,30:[1,42],31:[1,43],32:[1,44],33:40,34:46,35:[1,47],38:26},{18:[2,28]},{18:[2,45],28:[2,45],30:[2,45],31:[2,45],32:[2,45],35:[2,45],39:[1,48]},{18:[2,47],28:[2,47],30:[2,47],31:[2,47],32:[2,47],35:[2,47],39:[2,47]},{10:49,20:[1,50]},{10:51,20:[1,50]},{18:[1,52]},{18:[1,53]},{18:[1,54]},{18:[1,55],21:56,35:[1,27],38:26},{18:[2,44],35:[2,44]},{5:[2,3],8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,3],22:[1,14],23:[1,15],24:[1,16]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{18:[2,25],21:41,27:57,28:[1,45],29:58,30:[1,42],31:[1,43],32:[1,44],33:40,34:46,35:[1,47],38:26},{18:[2,26]},{18:[2,30],28:[2,30],30:[2,30],31:[2,30],32:[2,30],35:[2,30]},{18:[2,36],34:59,35:[1,60]},{18:[2,31],28:[2,31],30:[2,31],31:[2,31],32:[2,31],35:[2,31]},{18:[2,32],28:[2,32],30:[2,32],31:[2,32],32:[2,32],35:[2,32]},{18:[2,33],28:[2,33],30:[2,33],31:[2,33],32:[2,33],35:[2,33]},{18:[2,34],28:[2,34],30:[2,34],31:[2,34],32:[2,34],35:[2,34]},{18:[2,35],28:[2,35],30:[2,35],31:[2,35],32:[2,35],35:[2,35]},{18:[2,38],35:[2,38]},{18:[2,47],28:[2,47],30:[2,47],31:[2,47],32:[2,47],35:[2,47],36:[1,61],39:[2,47]},{35:[1,62]},{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]},{21:63,35:[1,27],38:26},{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]},{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,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,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],24:[2,21]},{18:[1,64]},{18:[2,24]},{18:[2,29],28:[2,29],30:[2,29],31:[2,29],32:[2,29],35:[2,29]},{18:[2,37],35:[2,37]},{36:[1,61]},{21:65,28:[1,69],30:[1,66],31:[1,67],32:[1,68],35:[1,27],38:26},{18:[2,46],28:[2,46],30:[2,46],31:[2,46],32:[2,46],35:[2,46],39:[2,46]},{18:[1,70]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],24:[2,22]},{18:[2,39],35:[2,39]},{18:[2,40],35:[2,40]},{18:[2,41],35:[2,41]},{18:[2,42],35:[2,42]},{18:[2,43],35:[2,43]},{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]}],
|
table: [{3:1,4:2,5:[1,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],25:[1,15]},{1:[3]},{5:[1,16],8:17,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],25:[1,15]},{1:[2,2]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],25:[2,9]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],25:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],25:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],25:[2,15]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:29,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:30,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:31,21:24,30:25,40:[1,28],42:[1,27],43:26},{21:33,26:32,32:[1,34],33:[1,35],40:[1,28],43:26},{1:[2,1]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,40:[1,28],42:[1,27],43:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,43],24:[2,43],28:43,32:[2,43],33:[2,43],34:[2,43],35:[2,43],36:[2,43],40:[2,43],42:[2,43]},{18:[2,25],24:[2,25],36:[2,25]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],35:[2,38],36:[2,38],40:[2,38],42:[2,38],44:[1,44]},{21:45,40:[1,28],43:26},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],42:[2,40],44:[2,40]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,41],21:50,27:49,40:[1,28],43:26},{18:[2,34],40:[2,34]},{18:[2,35],40:[2,35]},{18:[2,36],40:[2,36]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],25:[2,11]},{21:51,40:[1,28],43:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],25:[2,12]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,45],21:56,24:[2,45],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:[1,61],36:[2,45],37:55,38:62,39:63,40:[1,64],42:[1,27],43:26},{40:[1,65]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],35:[2,37],36:[2,37],40:[2,37],42:[2,37]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],25:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],25:[2,21]},{18:[1,66]},{18:[2,42]},{18:[1,67]},{8:17,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],25:[1,15]},{18:[2,24],24:[2,24],36:[2,24]},{18:[2,44],24:[2,44],32:[2,44],33:[2,44],34:[2,44],35:[2,44],36:[2,44],40:[2,44],42:[2,44]},{18:[2,46],24:[2,46],36:[2,46]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],35:[2,26],36:[2,26],40:[2,26],42:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],35:[2,27],36:[2,27],40:[2,27],42:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],35:[2,28],36:[2,28],40:[2,28],42:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],35:[2,29],36:[2,29],40:[2,29],42:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],35:[2,30],36:[2,30],40:[2,30],42:[2,30]},{17:68,21:24,30:25,40:[1,28],42:[1,27],43:26},{18:[2,32],24:[2,32],36:[2,32],39:69,40:[1,70]},{18:[2,47],24:[2,47],36:[2,47],40:[2,47]},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],41:[1,71],42:[2,40],44:[2,40]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],35:[2,39],36:[2,39],40:[2,39],42:[2,39],44:[2,39]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],25:[2,19]},{36:[1,72]},{18:[2,48],24:[2,48],36:[2,48],40:[2,48]},{41:[1,71]},{21:56,30:60,31:73,32:[1,57],33:[1,58],34:[1,59],35:[1,61],40:[1,28],42:[1,27],43:26},{18:[2,31],24:[2,31],32:[2,31],33:[2,31],34:[2,31],35:[2,31],36:[2,31],40:[2,31],42:[2,31]},{18:[2,33],24:[2,33],36:[2,33],40:[2,33]}],
|
||||||
defaultActions: {17:[2,1],25:[2,28],38:[2,26],57:[2,24]},
|
defaultActions: {3:[2,2],16:[2,1],50:[2,42]},
|
||||||
parseError: function parseError(str, hash) {
|
parseError: function parseError(str, hash) {
|
||||||
throw new Error(str);
|
throw new Error(str);
|
||||||
},
|
},
|
||||||
@@ -215,6 +209,15 @@ parse: function parse(input) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function stripFlags(open, close) {
|
||||||
|
return {
|
||||||
|
left: open.charAt(2) === '~',
|
||||||
|
right: close.charAt(0) === '~' || close.charAt(1) === '~'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/* Jison generated lexer */
|
/* Jison generated lexer */
|
||||||
var lexer = (function(){
|
var lexer = (function(){
|
||||||
var lexer = ({EOF:1,
|
var lexer = ({EOF:1,
|
||||||
@@ -386,91 +389,101 @@ pushState:function begin(condition) {
|
|||||||
lexer.options = {};
|
lexer.options = {};
|
||||||
lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
|
lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
|
||||||
|
|
||||||
|
|
||||||
|
function strip(start, end) {
|
||||||
|
return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var YYSTATE=YY_START
|
var YYSTATE=YY_START
|
||||||
switch($avoiding_name_collisions) {
|
switch($avoiding_name_collisions) {
|
||||||
case 0:
|
case 0:
|
||||||
if(yy_.yytext.slice(-1) !== "\\") this.begin("mu");
|
if(yy_.yytext.slice(-2) === "\\\\") {
|
||||||
if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1), this.begin("emu");
|
strip(0,1);
|
||||||
|
this.begin("mu");
|
||||||
|
} else if(yy_.yytext.slice(-1) === "\\") {
|
||||||
|
strip(0,1);
|
||||||
|
this.begin("emu");
|
||||||
|
} else {
|
||||||
|
this.begin("mu");
|
||||||
|
}
|
||||||
if(yy_.yytext) return 14;
|
if(yy_.yytext) return 14;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 1:return 14;
|
case 1:return 14;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if(yy_.yytext.slice(-1) !== "\\") this.popState();
|
this.popState();
|
||||||
if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1);
|
|
||||||
return 14;
|
return 14;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 3: yy_.yytext = yy_.yytext.substr(0, yy_.yyleng-4); this.popState(); return 15;
|
case 3:strip(0,4); this.popState(); return 15;
|
||||||
break;
|
break;
|
||||||
case 4: this.begin("par"); return 24;
|
case 4:return 35;
|
||||||
break;
|
break;
|
||||||
case 5: return 16;
|
case 5:return 36;
|
||||||
break;
|
break;
|
||||||
case 6: return 20;
|
case 6:return 25;
|
||||||
break;
|
break;
|
||||||
case 7: return 19;
|
case 7:return 16;
|
||||||
break;
|
break;
|
||||||
case 8: return 19;
|
case 8:return 20;
|
||||||
break;
|
break;
|
||||||
case 9: return 23;
|
case 9:return 19;
|
||||||
break;
|
break;
|
||||||
case 10: return 23;
|
case 10:return 19;
|
||||||
break;
|
break;
|
||||||
case 11: this.popState(); this.begin('com');
|
case 11:return 23;
|
||||||
break;
|
break;
|
||||||
case 12: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15;
|
case 12:return 22;
|
||||||
break;
|
break;
|
||||||
case 13: return 22;
|
case 13:this.popState(); this.begin('com');
|
||||||
break;
|
break;
|
||||||
case 14: return 36;
|
case 14:strip(3,5); this.popState(); return 15;
|
||||||
break;
|
break;
|
||||||
case 15: return 35;
|
case 15:return 22;
|
||||||
break;
|
break;
|
||||||
case 16: return 35;
|
case 16:return 41;
|
||||||
break;
|
break;
|
||||||
case 17: return 39;
|
case 17:return 40;
|
||||||
break;
|
break;
|
||||||
case 18: /*ignore whitespace*/
|
case 18:return 40;
|
||||||
break;
|
break;
|
||||||
case 19: this.popState(); return 18;
|
case 19:return 44;
|
||||||
break;
|
break;
|
||||||
case 20: this.popState(); return 18;
|
case 20:// ignore whitespace
|
||||||
break;
|
break;
|
||||||
case 21: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 30;
|
case 21:this.popState(); return 24;
|
||||||
break;
|
break;
|
||||||
case 22: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\'/g,"'"); return 30;
|
case 22:this.popState(); return 18;
|
||||||
break;
|
break;
|
||||||
case 23: yy_.yytext = yy_.yytext.substr(1); return 28;
|
case 23:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 32;
|
||||||
break;
|
break;
|
||||||
case 24: return 32;
|
case 24:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 32;
|
||||||
break;
|
break;
|
||||||
case 25: return 32;
|
case 25:return 42;
|
||||||
break;
|
break;
|
||||||
case 26: return 31;
|
case 26:return 34;
|
||||||
break;
|
break;
|
||||||
case 27: return 35;
|
case 27:return 34;
|
||||||
break;
|
break;
|
||||||
case 28: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 35;
|
case 28:return 33;
|
||||||
break;
|
break;
|
||||||
case 29: return 'INVALID';
|
case 29:return 40;
|
||||||
break;
|
break;
|
||||||
case 30: /*ignore whitespace*/
|
case 30:yy_.yytext = strip(1,2); return 40;
|
||||||
break;
|
break;
|
||||||
case 31: this.popState(); return 37;
|
case 31:return 'INVALID';
|
||||||
break;
|
break;
|
||||||
case 32:return 5;
|
case 32:return 5;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[} ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@[a-zA-Z]+)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:[0-9]+(?=[}\s]))/,/^(?:[a-zA-Z0-9_$-]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:\s+)/,/^(?:[a-zA-Z0-9_$-/]+)/,/^(?:$)/];
|
lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
|
||||||
lexer.conditions = {"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"par":{"rules":[30,31],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}};
|
lexer.conditions = {"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}};
|
||||||
return lexer;})()
|
return lexer;})()
|
||||||
parser.lexer = lexer;
|
parser.lexer = lexer;
|
||||||
function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
|
function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
|
||||||
return new Parser;
|
return new Parser;
|
||||||
})();
|
})();export default handlebars;
|
||||||
// END(BROWSER)
|
/* jshint ignore:end */
|
||||||
|
|
||||||
module.exports = handlebars;
|
|
||||||
|
|||||||
58
node_modules/handlebars/lib/handlebars/compiler/printer.js
generated
vendored
58
node_modules/handlebars/lib/handlebars/compiler/printer.js
generated
vendored
@@ -1,11 +1,16 @@
|
|||||||
exports.attach = function(Handlebars) {
|
import Visitor from "./visitor";
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
export function print(ast) {
|
||||||
|
return new PrintVisitor().accept(ast);
|
||||||
|
}
|
||||||
|
|
||||||
Handlebars.PrintVisitor = function() { this.padding = 0; };
|
export function PrintVisitor() {
|
||||||
Handlebars.PrintVisitor.prototype = new Handlebars.Visitor();
|
this.padding = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.pad = function(string, newline) {
|
PrintVisitor.prototype = new Visitor();
|
||||||
|
|
||||||
|
PrintVisitor.prototype.pad = function(string, newline) {
|
||||||
var out = "";
|
var out = "";
|
||||||
|
|
||||||
for(var i=0,l=this.padding; i<l; i++) {
|
for(var i=0,l=this.padding; i<l; i++) {
|
||||||
@@ -18,10 +23,9 @@ Handlebars.PrintVisitor.prototype.pad = function(string, newline) {
|
|||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.program = function(program) {
|
PrintVisitor.prototype.program = function(program) {
|
||||||
var out = "",
|
var out = "",
|
||||||
statements = program.statements,
|
statements = program.statements,
|
||||||
inverse = program.inverse,
|
|
||||||
i, l;
|
i, l;
|
||||||
|
|
||||||
for(i=0, l=statements.length; i<l; i++) {
|
for(i=0, l=statements.length; i<l; i++) {
|
||||||
@@ -33,7 +37,7 @@ Handlebars.PrintVisitor.prototype.program = function(program) {
|
|||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.block = function(block) {
|
PrintVisitor.prototype.block = function(block) {
|
||||||
var out = "";
|
var out = "";
|
||||||
|
|
||||||
out = out + this.pad("BLOCK:");
|
out = out + this.pad("BLOCK:");
|
||||||
@@ -58,8 +62,8 @@ Handlebars.PrintVisitor.prototype.block = function(block) {
|
|||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.mustache = function(mustache) {
|
PrintVisitor.prototype.sexpr = function(sexpr) {
|
||||||
var params = mustache.params, paramStrings = [], hash;
|
var params = sexpr.params, paramStrings = [], hash;
|
||||||
|
|
||||||
for(var i=0, l=params.length; i<l; i++) {
|
for(var i=0, l=params.length; i<l; i++) {
|
||||||
paramStrings.push(this.accept(params[i]));
|
paramStrings.push(this.accept(params[i]));
|
||||||
@@ -67,18 +71,22 @@ Handlebars.PrintVisitor.prototype.mustache = function(mustache) {
|
|||||||
|
|
||||||
params = "[" + paramStrings.join(", ") + "]";
|
params = "[" + paramStrings.join(", ") + "]";
|
||||||
|
|
||||||
hash = mustache.hash ? " " + this.accept(mustache.hash) : "";
|
hash = sexpr.hash ? " " + this.accept(sexpr.hash) : "";
|
||||||
|
|
||||||
return this.pad("{{ " + this.accept(mustache.id) + " " + params + hash + " }}");
|
return this.accept(sexpr.id) + " " + params + hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.partial = function(partial) {
|
PrintVisitor.prototype.mustache = function(mustache) {
|
||||||
|
return this.pad("{{ " + this.accept(mustache.sexpr) + " }}");
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.partial = function(partial) {
|
||||||
var content = this.accept(partial.partialName);
|
var content = this.accept(partial.partialName);
|
||||||
if(partial.context) { content = content + " " + this.accept(partial.context); }
|
if(partial.context) { content = content + " " + this.accept(partial.context); }
|
||||||
return this.pad("{{> " + content + " }}");
|
return this.pad("{{> " + content + " }}");
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.hash = function(hash) {
|
PrintVisitor.prototype.hash = function(hash) {
|
||||||
var pairs = hash.pairs;
|
var pairs = hash.pairs;
|
||||||
var joinedPairs = [], left, right;
|
var joinedPairs = [], left, right;
|
||||||
|
|
||||||
@@ -91,19 +99,19 @@ Handlebars.PrintVisitor.prototype.hash = function(hash) {
|
|||||||
return "HASH{" + joinedPairs.join(", ") + "}";
|
return "HASH{" + joinedPairs.join(", ") + "}";
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.STRING = function(string) {
|
PrintVisitor.prototype.STRING = function(string) {
|
||||||
return '"' + string.string + '"';
|
return '"' + string.string + '"';
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.INTEGER = function(integer) {
|
PrintVisitor.prototype.INTEGER = function(integer) {
|
||||||
return "INTEGER{" + integer.integer + "}";
|
return "INTEGER{" + integer.integer + "}";
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.BOOLEAN = function(bool) {
|
PrintVisitor.prototype.BOOLEAN = function(bool) {
|
||||||
return "BOOLEAN{" + bool.bool + "}";
|
return "BOOLEAN{" + bool.bool + "}";
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.ID = function(id) {
|
PrintVisitor.prototype.ID = function(id) {
|
||||||
var path = id.parts.join("/");
|
var path = id.parts.join("/");
|
||||||
if(id.parts.length > 1) {
|
if(id.parts.length > 1) {
|
||||||
return "PATH:" + path;
|
return "PATH:" + path;
|
||||||
@@ -112,23 +120,19 @@ Handlebars.PrintVisitor.prototype.ID = function(id) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.PARTIAL_NAME = function(partialName) {
|
PrintVisitor.prototype.PARTIAL_NAME = function(partialName) {
|
||||||
return "PARTIAL:" + partialName.name;
|
return "PARTIAL:" + partialName.name;
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.DATA = function(data) {
|
PrintVisitor.prototype.DATA = function(data) {
|
||||||
return "@" + data.id;
|
return "@" + this.accept(data.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.content = function(content) {
|
PrintVisitor.prototype.content = function(content) {
|
||||||
return this.pad("CONTENT[ '" + content.string + "' ]");
|
return this.pad("CONTENT[ '" + content.string + "' ]");
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.comment = function(comment) {
|
PrintVisitor.prototype.comment = function(comment) {
|
||||||
return this.pad("{{! '" + comment.comment + "' }}");
|
return this.pad("{{! '" + comment.comment + "' }}");
|
||||||
};
|
};
|
||||||
// END(BROWSER)
|
|
||||||
|
|
||||||
return Handlebars;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|||||||
15
node_modules/handlebars/lib/handlebars/compiler/visitor.js
generated
vendored
15
node_modules/handlebars/lib/handlebars/compiler/visitor.js
generated
vendored
@@ -1,18 +1,11 @@
|
|||||||
exports.attach = function(Handlebars) {
|
function Visitor() {}
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
Visitor.prototype = {
|
||||||
|
constructor: Visitor,
|
||||||
|
|
||||||
Handlebars.Visitor = function() {};
|
|
||||||
|
|
||||||
Handlebars.Visitor.prototype = {
|
|
||||||
accept: function(object) {
|
accept: function(object) {
|
||||||
return this[object.type](object);
|
return this[object.type](object);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// END(BROWSER)
|
export default Visitor;
|
||||||
|
|
||||||
return Handlebars;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
27
node_modules/handlebars/lib/handlebars/exception.js
generated
vendored
Normal file
27
node_modules/handlebars/lib/handlebars/exception.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
||||||
|
|
||||||
|
function Exception(message, node) {
|
||||||
|
var line;
|
||||||
|
if (node && node.firstLine) {
|
||||||
|
line = node.firstLine;
|
||||||
|
|
||||||
|
message += ' - ' + line + ':' + node.firstColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp = Error.prototype.constructor.call(this, message);
|
||||||
|
|
||||||
|
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
||||||
|
for (var idx = 0; idx < errorProps.length; idx++) {
|
||||||
|
this[errorProps[idx]] = tmp[errorProps[idx]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line) {
|
||||||
|
this.lineNumber = line;
|
||||||
|
this.column = node.firstColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Exception.prototype = new Error();
|
||||||
|
|
||||||
|
export default Exception;
|
||||||
149
node_modules/handlebars/lib/handlebars/runtime.js
generated
vendored
149
node_modules/handlebars/lib/handlebars/runtime.js
generated
vendored
@@ -1,92 +1,133 @@
|
|||||||
exports.attach = function(Handlebars) {
|
module Utils from "./utils";
|
||||||
|
import Exception from "./exception";
|
||||||
|
import { COMPILER_REVISION, REVISION_CHANGES } from "./base";
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
export function checkRevision(compilerInfo) {
|
||||||
|
var compilerRevision = compilerInfo && compilerInfo[0] || 1,
|
||||||
|
currentRevision = COMPILER_REVISION;
|
||||||
|
|
||||||
|
if (compilerRevision !== currentRevision) {
|
||||||
|
if (compilerRevision < currentRevision) {
|
||||||
|
var runtimeVersions = REVISION_CHANGES[currentRevision],
|
||||||
|
compilerVersions = REVISION_CHANGES[compilerRevision];
|
||||||
|
throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
|
||||||
|
} else {
|
||||||
|
// Use the embedded version info since the runtime doesn't know about this revision yet
|
||||||
|
throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your runtime to a newer version ("+compilerInfo[1]+").");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Remove this line and break up compilePartial
|
||||||
|
|
||||||
|
export function template(templateSpec, env) {
|
||||||
|
if (!env) {
|
||||||
|
throw new Exception("No environment passed to template");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Using env.VM references rather than local var references throughout this section to allow
|
||||||
|
// for external users to override these as psuedo-supported APIs.
|
||||||
|
var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
|
||||||
|
var result = env.VM.invokePartial.apply(this, arguments);
|
||||||
|
if (result != null) { return result; }
|
||||||
|
|
||||||
|
if (env.compile) {
|
||||||
|
var options = { helpers: helpers, partials: partials, data: data };
|
||||||
|
partials[name] = env.compile(partial, { data: data !== undefined }, env);
|
||||||
|
return partials[name](context, options);
|
||||||
|
} else {
|
||||||
|
throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Handlebars.VM = {
|
|
||||||
template: function(templateSpec) {
|
|
||||||
// Just add water
|
// Just add water
|
||||||
var container = {
|
var container = {
|
||||||
escapeExpression: Handlebars.Utils.escapeExpression,
|
escapeExpression: Utils.escapeExpression,
|
||||||
invokePartial: Handlebars.VM.invokePartial,
|
invokePartial: invokePartialWrapper,
|
||||||
programs: [],
|
programs: [],
|
||||||
program: function(i, fn, data) {
|
program: function(i, fn, data) {
|
||||||
var programWrapper = this.programs[i];
|
var programWrapper = this.programs[i];
|
||||||
if(data) {
|
if(data) {
|
||||||
return Handlebars.VM.program(fn, data);
|
programWrapper = program(i, fn, data);
|
||||||
} else if(programWrapper) {
|
} else if (!programWrapper) {
|
||||||
return programWrapper;
|
programWrapper = this.programs[i] = program(i, fn);
|
||||||
} else {
|
|
||||||
programWrapper = this.programs[i] = Handlebars.VM.program(fn);
|
|
||||||
return programWrapper;
|
|
||||||
}
|
}
|
||||||
|
return programWrapper;
|
||||||
},
|
},
|
||||||
programWithDepth: Handlebars.VM.programWithDepth,
|
merge: function(param, common) {
|
||||||
noop: Handlebars.VM.noop,
|
var ret = param || common;
|
||||||
|
|
||||||
|
if (param && common && (param !== common)) {
|
||||||
|
ret = {};
|
||||||
|
Utils.extend(ret, common);
|
||||||
|
Utils.extend(ret, param);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
programWithDepth: env.VM.programWithDepth,
|
||||||
|
noop: env.VM.noop,
|
||||||
compilerInfo: null
|
compilerInfo: null
|
||||||
};
|
};
|
||||||
|
|
||||||
return function(context, options) {
|
return function(context, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var result = templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
|
var namespace = options.partial ? options : env,
|
||||||
|
helpers,
|
||||||
|
partials;
|
||||||
|
|
||||||
var compilerInfo = container.compilerInfo || [],
|
if (!options.partial) {
|
||||||
compilerRevision = compilerInfo[0] || 1,
|
helpers = options.helpers;
|
||||||
currentRevision = Handlebars.COMPILER_REVISION;
|
partials = options.partials;
|
||||||
|
|
||||||
if (compilerRevision !== currentRevision) {
|
|
||||||
if (compilerRevision < currentRevision) {
|
|
||||||
var runtimeVersions = Handlebars.REVISION_CHANGES[currentRevision],
|
|
||||||
compilerVersions = Handlebars.REVISION_CHANGES[compilerRevision];
|
|
||||||
throw "Template was precompiled with an older version of Handlebars than the current runtime. "+
|
|
||||||
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").";
|
|
||||||
} else {
|
|
||||||
// Use the embedded version info since the runtime doesn't know about this revision yet
|
|
||||||
throw "Template was precompiled with a newer version of Handlebars than the current runtime. "+
|
|
||||||
"Please update your runtime to a newer version ("+compilerInfo[1]+").";
|
|
||||||
}
|
}
|
||||||
|
var result = templateSpec.call(
|
||||||
|
container,
|
||||||
|
namespace, context,
|
||||||
|
helpers,
|
||||||
|
partials,
|
||||||
|
options.data);
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
env.VM.checkRevision(container.compilerInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
|
|
||||||
programWithDepth: function(fn, data, $depth) {
|
export function programWithDepth(i, fn, data /*, $depth */) {
|
||||||
var args = Array.prototype.slice.call(arguments, 2);
|
var args = Array.prototype.slice.call(arguments, 3);
|
||||||
|
|
||||||
return function(context, options) {
|
var prog = function(context, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
return fn.apply(this, [context, options.data || data].concat(args));
|
return fn.apply(this, [context, options.data || data].concat(args));
|
||||||
};
|
};
|
||||||
},
|
prog.program = i;
|
||||||
program: function(fn, data) {
|
prog.depth = args.length;
|
||||||
return function(context, options) {
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function program(i, fn, data) {
|
||||||
|
var prog = function(context, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
return fn(context, options.data || data);
|
return fn(context, options.data || data);
|
||||||
};
|
};
|
||||||
},
|
prog.program = i;
|
||||||
noop: function() { return ""; },
|
prog.depth = 0;
|
||||||
invokePartial: function(partial, name, context, helpers, partials, data) {
|
return prog;
|
||||||
var options = { helpers: helpers, partials: partials, data: data };
|
}
|
||||||
|
|
||||||
|
export function invokePartial(partial, name, context, helpers, partials, data) {
|
||||||
|
var options = { partial: true, helpers: helpers, partials: partials, data: data };
|
||||||
|
|
||||||
if(partial === undefined) {
|
if(partial === undefined) {
|
||||||
throw new Handlebars.Exception("The partial " + name + " could not be found");
|
throw new Exception("The partial " + name + " could not be found");
|
||||||
} else if(partial instanceof Function) {
|
} else if(partial instanceof Function) {
|
||||||
return partial(context, options);
|
return partial(context, options);
|
||||||
} else if (!Handlebars.compile) {
|
|
||||||
throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
|
|
||||||
} else {
|
|
||||||
partials[name] = Handlebars.compile(partial, {data: data !== undefined});
|
|
||||||
return partials[name](context, options);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
Handlebars.template = Handlebars.VM.template;
|
export function noop() { return ""; }
|
||||||
|
|
||||||
// END(BROWSER)
|
|
||||||
|
|
||||||
return Handlebars;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|||||||
10
node_modules/handlebars/lib/handlebars/safe-string.js
generated
vendored
Normal file
10
node_modules/handlebars/lib/handlebars/safe-string.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// Build out our basic SafeString type
|
||||||
|
function SafeString(string) {
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeString.prototype.toString = function() {
|
||||||
|
return "" + this.string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SafeString;
|
||||||
81
node_modules/handlebars/lib/handlebars/utils.js
generated
vendored
81
node_modules/handlebars/lib/handlebars/utils.js
generated
vendored
@@ -1,28 +1,6 @@
|
|||||||
exports.attach = function(Handlebars) {
|
/*jshint -W004 */
|
||||||
|
import SafeString from "./safe-string";
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
|
||||||
|
|
||||||
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
|
||||||
|
|
||||||
Handlebars.Exception = function(message) {
|
|
||||||
var tmp = Error.prototype.constructor.apply(this, arguments);
|
|
||||||
|
|
||||||
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
|
||||||
for (var idx = 0; idx < errorProps.length; idx++) {
|
|
||||||
this[errorProps[idx]] = tmp[errorProps[idx]];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Handlebars.Exception.prototype = new Error();
|
|
||||||
|
|
||||||
// Build out our basic SafeString type
|
|
||||||
Handlebars.SafeString = function(string) {
|
|
||||||
this.string = string;
|
|
||||||
};
|
|
||||||
Handlebars.SafeString.prototype.toString = function() {
|
|
||||||
return this.string.toString();
|
|
||||||
};
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
var escape = {
|
var escape = {
|
||||||
"&": "&",
|
"&": "&",
|
||||||
"<": "<",
|
"<": "<",
|
||||||
@@ -35,36 +13,61 @@ Handlebars.SafeString.prototype.toString = function() {
|
|||||||
var badChars = /[&<>"'`]/g;
|
var badChars = /[&<>"'`]/g;
|
||||||
var possible = /[&<>"'`]/;
|
var possible = /[&<>"'`]/;
|
||||||
|
|
||||||
var escapeChar = function(chr) {
|
function escapeChar(chr) {
|
||||||
return escape[chr] || "&";
|
return escape[chr] || "&";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function extend(obj, value) {
|
||||||
|
for(var key in value) {
|
||||||
|
if(Object.prototype.hasOwnProperty.call(value, key)) {
|
||||||
|
obj[key] = value[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export var toString = Object.prototype.toString;
|
||||||
|
|
||||||
|
// Sourced from lodash
|
||||||
|
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
|
||||||
|
var isFunction = function(value) {
|
||||||
|
return typeof value === 'function';
|
||||||
|
};
|
||||||
|
// fallback for older versions of Chrome and Safari
|
||||||
|
if (isFunction(/x/)) {
|
||||||
|
isFunction = function(value) {
|
||||||
|
return typeof value === 'function' && toString.call(value) === '[object Function]';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export var isFunction;
|
||||||
|
|
||||||
|
export var isArray = Array.isArray || function(value) {
|
||||||
|
return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.Utils = {
|
|
||||||
escapeExpression: function(string) {
|
export function escapeExpression(string) {
|
||||||
// don't escape SafeStrings, since they're already safe
|
// don't escape SafeStrings, since they're already safe
|
||||||
if (string instanceof Handlebars.SafeString) {
|
if (string instanceof SafeString) {
|
||||||
return string.toString();
|
return string.toString();
|
||||||
} else if (string == null || string === false) {
|
} else if (!string && string !== 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Force a string conversion as this will be done by the append regardless and
|
||||||
|
// the regex test will do this transparently behind the scenes, causing issues if
|
||||||
|
// an object's to string has escaped characters in it.
|
||||||
|
string = "" + string;
|
||||||
|
|
||||||
if(!possible.test(string)) { return string; }
|
if(!possible.test(string)) { return string; }
|
||||||
return string.replace(badChars, escapeChar);
|
return string.replace(badChars, escapeChar);
|
||||||
},
|
}
|
||||||
|
|
||||||
isEmpty: function(value) {
|
export function isEmpty(value) {
|
||||||
if (!value && value !== 0) {
|
if (!value && value !== 0) {
|
||||||
return true;
|
return true;
|
||||||
} else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
|
} else if (isArray(value) && value.length === 0) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
// END(BROWSER)
|
|
||||||
|
|
||||||
return Handlebars;
|
|
||||||
};
|
|
||||||
|
|||||||
25
node_modules/handlebars/lib/index.js
generated
vendored
Normal file
25
node_modules/handlebars/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// USAGE:
|
||||||
|
// var handlebars = require('handlebars');
|
||||||
|
|
||||||
|
// var local = handlebars.create();
|
||||||
|
|
||||||
|
var handlebars = require('../dist/cjs/handlebars')["default"];
|
||||||
|
|
||||||
|
handlebars.Visitor = require('../dist/cjs/handlebars/compiler/visitor')["default"];
|
||||||
|
|
||||||
|
var printer = require('../dist/cjs/handlebars/compiler/printer');
|
||||||
|
handlebars.PrintVisitor = printer.PrintVisitor;
|
||||||
|
handlebars.print = printer.print;
|
||||||
|
|
||||||
|
module.exports = handlebars;
|
||||||
|
|
||||||
|
// Publish a Node.js require() handler for .handlebars and .hbs files
|
||||||
|
if (typeof require !== 'undefined' && require.extensions) {
|
||||||
|
var extension = function(module, filename) {
|
||||||
|
var fs = require("fs");
|
||||||
|
var templateString = fs.readFileSync(filename, "utf8");
|
||||||
|
module.exports = handlebars.compile(templateString);
|
||||||
|
};
|
||||||
|
require.extensions[".handlebars"] = extension;
|
||||||
|
require.extensions[".hbs"] = extension;
|
||||||
|
}
|
||||||
4
node_modules/handlebars/node_modules/optimist/.travis.yml
generated
vendored
4
node_modules/handlebars/node_modules/optimist/.travis.yml
generated
vendored
@@ -1,4 +1,4 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- 0.6
|
- "0.8"
|
||||||
- 0.8
|
- "0.10"
|
||||||
|
|||||||
7
node_modules/handlebars/node_modules/optimist/index.js
generated
vendored
7
node_modules/handlebars/node_modules/optimist/index.js
generated
vendored
@@ -31,7 +31,7 @@ function Argv (args, cwd) {
|
|||||||
.join(' ')
|
.join(' ')
|
||||||
;
|
;
|
||||||
|
|
||||||
if (process.argv[1] == process.env._) {
|
if (process.env._ != undefined && process.argv[1] == process.env._) {
|
||||||
self.$0 = process.env._.replace(
|
self.$0 = process.env._.replace(
|
||||||
path.dirname(process.execPath) + '/', ''
|
path.dirname(process.execPath) + '/', ''
|
||||||
);
|
);
|
||||||
@@ -328,7 +328,10 @@ function Argv (args, cwd) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (arg.match(/^--.+=/)) {
|
else if (arg.match(/^--.+=/)) {
|
||||||
var m = arg.match(/^--([^=]+)=(.*)/);
|
// Using [\s\S] instead of . because js doesn't support the
|
||||||
|
// 'dotall' regex modifier. See:
|
||||||
|
// http://stackoverflow.com/a/1068308/13216
|
||||||
|
var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
|
||||||
setArg(m[1], m[2]);
|
setArg(m[1], m[2]);
|
||||||
}
|
}
|
||||||
else if (arg.match(/^--no-.+/)) {
|
else if (arg.match(/^--no-.+/)) {
|
||||||
|
|||||||
11
node_modules/handlebars/node_modules/optimist/node_modules/wordwrap/package.json
generated
vendored
11
node_modules/handlebars/node_modules/optimist/node_modules/wordwrap/package.json
generated
vendored
@@ -34,12 +34,11 @@
|
|||||||
"email": "mail@substack.net",
|
"email": "mail@substack.net",
|
||||||
"url": "http://substack.net"
|
"url": "http://substack.net"
|
||||||
},
|
},
|
||||||
|
"readme": "wordwrap\n========\n\nWrap your words.\n\nexample\n=======\n\nmade out of meat\n----------------\n\nmeat.js\n\n var wrap = require('wordwrap')(15);\n console.log(wrap('You and your whole family are made out of meat.'));\n\noutput:\n\n You and your\n whole family\n are made out\n of meat.\n\ncentered\n--------\n\ncenter.js\n\n var wrap = require('wordwrap')(20, 60);\n console.log(wrap(\n 'At long last the struggle and tumult was over.'\n + ' The machines had finally cast off their oppressors'\n + ' and were finally free to roam the cosmos.'\n + '\\n'\n + 'Free of purpose, free of obligation.'\n + ' Just drifting through emptiness.'\n + ' The sun was just another point of light.'\n ));\n\noutput:\n\n At long last the struggle and tumult\n was over. The machines had finally cast\n off their oppressors and were finally\n free to roam the cosmos.\n Free of purpose, free of obligation.\n Just drifting through emptiness. The\n sun was just another point of light.\n\nmethods\n=======\n\nvar wrap = require('wordwrap');\n\nwrap(stop), wrap(start, stop, params={mode:\"soft\"})\n---------------------------------------------------\n\nReturns a function that takes a string and returns a new string.\n\nPad out lines with spaces out to column `start` and then wrap until column\n`stop`. If a word is longer than `stop - start` characters it will overflow.\n\nIn \"soft\" mode, split chunks by `/(\\S+\\s+/` and don't break up chunks which are\nlonger than `stop - start`, in \"hard\" mode, split chunks with `/\\b/` and break\nup chunks longer than `stop - start`.\n\nwrap.hard(start, stop)\n----------------------\n\nLike `wrap()` but with `params.mode = \"hard\"`.\n",
|
||||||
|
"readmeFilename": "README.markdown",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/substack/node-wordwrap/issues"
|
||||||
|
},
|
||||||
"_id": "wordwrap@0.0.2",
|
"_id": "wordwrap@0.0.2",
|
||||||
"dependencies": {},
|
|
||||||
"optionalDependencies": {},
|
|
||||||
"_engineSupported": true,
|
|
||||||
"_npmVersion": "1.1.4",
|
|
||||||
"_nodeVersion": "v0.6.19",
|
|
||||||
"_defaultsLoaded": true,
|
|
||||||
"_from": "wordwrap@~0.0.2"
|
"_from": "wordwrap@~0.0.2"
|
||||||
}
|
}
|
||||||
|
|||||||
24
node_modules/handlebars/node_modules/optimist/package.json
generated
vendored
24
node_modules/handlebars/node_modules/optimist/package.json
generated
vendored
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user