mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-02 08:07:50 +00:00
Compare commits
3856 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d52119597 | ||
|
|
b75041173c | ||
|
|
23eba0a029 | ||
|
|
566781cab2 | ||
|
|
0ea1fc5602 | ||
|
|
2ce9e09e8b | ||
|
|
6cab7ceb0f | ||
|
|
8ae7d8aa07 | ||
|
|
ce6ccef2d0 | ||
|
|
2c6d880542 | ||
|
|
bf89287c56 | ||
|
|
df176dfe8a | ||
|
|
141a32d388 | ||
|
|
37786b76ed | ||
|
|
02b920f259 | ||
|
|
31e25f88a0 | ||
|
|
231c8a468e | ||
|
|
ae346f564f | ||
|
|
fcc0608cf2 | ||
|
|
641cd63462 | ||
|
|
0b907a3efa | ||
|
|
ce180cf2bf | ||
|
|
d97276404c | ||
|
|
d5a9b4344b | ||
|
|
e317fdfa3d | ||
|
|
150ea2639a | ||
|
|
a551348b40 | ||
|
|
3429b5d661 | ||
|
|
c8314b215b | ||
|
|
5929f7d23b | ||
|
|
85a7df3d27 | ||
|
|
e6c5a0e848 | ||
|
|
92dee72b10 | ||
|
|
4d6e57a5e6 | ||
|
|
936a1c2764 | ||
|
|
a08a3c6096 | ||
|
|
82be40eace | ||
|
|
20ba0bd1dc | ||
|
|
75ce6b82e8 | ||
|
|
9749ac56ba | ||
|
|
746f9bb778 | ||
|
|
f2dae588aa | ||
|
|
9f3f0a76aa | ||
|
|
30f28a51ca | ||
|
|
3e22344782 | ||
|
|
0b20d89d62 | ||
|
|
80d892c744 | ||
|
|
53326bef33 | ||
|
|
f05a5a3abb | ||
|
|
8581be4977 | ||
|
|
0e8277ba9e | ||
|
|
3cc2f83912 | ||
|
|
177034a498 | ||
|
|
f4d06e5183 | ||
|
|
637a6b5f7e | ||
|
|
75445b8b98 | ||
|
|
f96de55ac7 | ||
|
|
c4d4af3b5a | ||
|
|
5dfee44340 | ||
|
|
99f5857d84 | ||
|
|
520f7c6812 | ||
|
|
63d493aa1f | ||
|
|
38ab42f855 | ||
|
|
bc3771f3af | ||
|
|
9d90af409b | ||
|
|
20183bbd57 | ||
|
|
1d8efe1cf8 | ||
|
|
23354d413f | ||
|
|
715f03f5f1 | ||
|
|
ff6bbaed19 | ||
|
|
f82cbbab1c | ||
|
|
5a1b526b6c | ||
|
|
1ef92c87fb | ||
|
|
0aef515522 | ||
|
|
9b5c97666a | ||
|
|
a55d822f9a | ||
|
|
5b2bde6e0d | ||
|
|
020c5b27dc | ||
|
|
65457208e5 | ||
|
|
6eb1b98975 | ||
|
|
a927bab6b3 | ||
|
|
48e3e3e8cb | ||
|
|
b5d095401d | ||
|
|
b3e58d4794 | ||
|
|
79b064320e | ||
|
|
335b8326ee | ||
|
|
e777020e44 | ||
|
|
745d97ebe1 | ||
|
|
bb06d98a43 | ||
|
|
3500b0016c | ||
|
|
7ec916b777 | ||
|
|
3c71f79929 | ||
|
|
a83e70104c | ||
|
|
85af554bac | ||
|
|
885722afde | ||
|
|
b2f094da01 | ||
|
|
1e85ec6758 | ||
|
|
c8974aac3e | ||
|
|
ad318c04e5 | ||
|
|
db73e48206 | ||
|
|
d13972e0b8 | ||
|
|
df74b2bfcb | ||
|
|
b94b75726d | ||
|
|
9a2d38acff | ||
|
|
537f8f401e | ||
|
|
04f1a799dc | ||
|
|
74adb2f540 | ||
|
|
a129a2509f | ||
|
|
cc0b8e9d10 | ||
|
|
af8fcf234f | ||
|
|
e0dc2daf54 | ||
|
|
c066e655dc | ||
|
|
2698e6f0ea | ||
|
|
63902bde9c | ||
|
|
c876004fb2 | ||
|
|
633f37bfb6 | ||
|
|
d70bc74dc8 | ||
|
|
d7a4524e70 | ||
|
|
fe1e27fd40 | ||
|
|
8a7a099073 | ||
|
|
1b53b5f9eb | ||
|
|
8b758ee25a | ||
|
|
81c24a8478 | ||
|
|
a6f3e0b6af | ||
|
|
6e9e8127b6 | ||
|
|
63d43275d3 | ||
|
|
cb2bf7f8fa | ||
|
|
1fae760ccd | ||
|
|
4195c4c4bf | ||
|
|
13e7a1ed93 | ||
|
|
ea4357ca98 | ||
|
|
5e8255d24d | ||
|
|
003d6ec43f | ||
|
|
9749ff7c67 | ||
|
|
c88589e0e5 | ||
|
|
32ef1bb7a5 | ||
|
|
206c65904f | ||
|
|
219d4688e4 | ||
|
|
adc687f0a0 | ||
|
|
88e59c9a5a | ||
|
|
71a89a575f | ||
|
|
e3dc8dfcf4 | ||
|
|
2dd77d5bc7 | ||
|
|
0192226bb3 | ||
|
|
faf2658da2 | ||
|
|
9a1c00d2dc | ||
|
|
4a8695caff | ||
|
|
b28016bfeb | ||
|
|
4758a9e66d | ||
|
|
97bd1ef4ec | ||
|
|
2adac8bdae | ||
|
|
3c56914822 | ||
|
|
c5cc907838 | ||
|
|
0907aabacd | ||
|
|
f4290bda7f | ||
|
|
4bdb82a7a2 | ||
|
|
6a696dde3a | ||
|
|
8481684a82 | ||
|
|
03aa8b3356 | ||
|
|
64bfed2640 | ||
|
|
2edcc89303 | ||
|
|
18313f2e90 | ||
|
|
0ff96418bd | ||
|
|
1480abf0e8 | ||
|
|
e7ba75d533 | ||
|
|
044291d940 | ||
|
|
ad62efcb9e | ||
|
|
0dc59d9481 | ||
|
|
11ab3034b1 | ||
|
|
c594bda77f | ||
|
|
8218b74fb3 | ||
|
|
3d0beb1a2e | ||
|
|
515cfd48d8 | ||
|
|
1448bab5b3 | ||
|
|
2884f8acb8 | ||
|
|
075cae4efb | ||
|
|
d2b98323dd | ||
|
|
b1a81a85b1 | ||
|
|
668384649a | ||
|
|
a7252b1a7f | ||
|
|
a4e58e4d55 | ||
|
|
4241e01364 | ||
|
|
d7d7952138 | ||
|
|
9cc2253339 | ||
|
|
6831802590 | ||
|
|
9d79cc7e87 | ||
|
|
763b003a11 | ||
|
|
d560e2a558 | ||
|
|
f914f080b1 | ||
|
|
600a4e86e1 | ||
|
|
e7b4ada65f | ||
|
|
95f31be096 | ||
|
|
ad6db7eaae | ||
|
|
d7a99c6618 | ||
|
|
f20d8f5cc0 | ||
|
|
8930e6b393 | ||
|
|
f26886acb0 | ||
|
|
820ab8d486 | ||
|
|
8e425fb358 | ||
|
|
6006f499ac | ||
|
|
3caa740fc4 | ||
|
|
007ea9ea20 | ||
|
|
5d248d261d | ||
|
|
26908cba64 | ||
|
|
18d118746e | ||
|
|
9a633f5f2e | ||
|
|
5aa44e98d5 | ||
|
|
33916fa975 | ||
|
|
eab18df403 | ||
|
|
002caceb05 | ||
|
|
c250aa804a | ||
|
|
94ca50883f | ||
|
|
462c482873 | ||
|
|
e28e04a990 | ||
|
|
6438385d64 | ||
|
|
bfb08ce003 | ||
|
|
3590a06f40 | ||
|
|
23ca6c5e10 | ||
|
|
1aea5bcd50 | ||
|
|
82c5d8ed28 | ||
|
|
5dcd58a75f | ||
|
|
dc605a4ee1 | ||
|
|
fec940ab8b | ||
|
|
05fd7cecf4 | ||
|
|
2f52730b48 | ||
|
|
4c1819c7dd | ||
|
|
c58c0df30e | ||
|
|
c5902b3144 | ||
|
|
519eb424e7 | ||
|
|
03478afea4 | ||
|
|
306ef8addf | ||
|
|
d4659b261d | ||
|
|
69ce41807a | ||
|
|
cc81da5aa4 | ||
|
|
eee714f52b | ||
|
|
c976b637d8 | ||
|
|
ea93515d53 | ||
|
|
652499bdcf | ||
|
|
819862199a | ||
|
|
6c1bc1d7bb | ||
|
|
36ebe76e0a | ||
|
|
8f8d35dec7 | ||
|
|
ac1e436339 | ||
|
|
78d4812b0e | ||
|
|
6a1b7626e3 | ||
|
|
b6ccb4c96f | ||
|
|
9712ac550c | ||
|
|
5b173766c6 | ||
|
|
b535c4f321 | ||
|
|
56c5ebcb71 | ||
|
|
028234ba86 | ||
|
|
f063b4d231 | ||
|
|
508f27cc32 | ||
|
|
d4783170e5 | ||
|
|
51e459b386 | ||
|
|
1253d254af | ||
|
|
5e70574396 | ||
|
|
b5dce2f74b | ||
|
|
6113da3e68 | ||
|
|
faf6406289 | ||
|
|
7c443431d9 | ||
|
|
0f201e3fd8 | ||
|
|
bf96c30187 | ||
|
|
eb1b7b914a | ||
|
|
135bc2de52 | ||
|
|
ab2269717d | ||
|
|
b5a42cfa75 | ||
|
|
6693416d0a | ||
|
|
9cdf013933 | ||
|
|
1dfaa30520 | ||
|
|
d898fcee75 | ||
|
|
1e647a2058 | ||
|
|
10e379d862 | ||
|
|
ee456493c4 | ||
|
|
69e9c7d0be | ||
|
|
adce718d63 | ||
|
|
3a94a65f12 | ||
|
|
bbe30db1b7 | ||
|
|
68f3c43805 | ||
|
|
3c99ecda60 | ||
|
|
b1366696c4 | ||
|
|
534aeb4065 | ||
|
|
cc77a36dd9 | ||
|
|
5991068fdf | ||
|
|
913778d5ab | ||
|
|
9a8345d4f9 | ||
|
|
ba9bd3bc76 | ||
|
|
aad0070b77 | ||
|
|
d192e69811 | ||
|
|
ec8d919b93 | ||
|
|
4ce4f1d758 | ||
|
|
3aa40d4df6 | ||
|
|
ec1be41b62 | ||
|
|
c15d81545a | ||
|
|
1af8b9d16a | ||
|
|
d860cf834d | ||
|
|
63d5a3acbc | ||
|
|
132aacee89 | ||
|
|
973038da6a | ||
|
|
584da3c39b | ||
|
|
73c4829255 | ||
|
|
68942f7ec4 | ||
|
|
e914b83a1b | ||
|
|
2268376360 | ||
|
|
6bb3b9a684 | ||
|
|
9f213c119c | ||
|
|
f081e2b799 | ||
|
|
a024152c12 | ||
|
|
42d23dbc70 | ||
|
|
74786e8a25 | ||
|
|
eeb4ede60d | ||
|
|
f2eee8896c | ||
|
|
bf4a70d91c | ||
|
|
a35ab3937a | ||
|
|
5ef9a4be8a | ||
|
|
d76d7582fe | ||
|
|
44006142c7 | ||
|
|
6840b2cfe5 | ||
|
|
5613f60403 | ||
|
|
76d3959f1a | ||
|
|
b681759000 | ||
|
|
d6336c4302 | ||
|
|
35b161450a | ||
|
|
861aaf06c6 | ||
|
|
a910884e7d | ||
|
|
0e7bef9014 | ||
|
|
d942189bc6 | ||
|
|
eb16051b1e | ||
|
|
7749a7e41d | ||
|
|
dc4cef17d4 | ||
|
|
89ed40e4a4 | ||
|
|
10ee74d872 | ||
|
|
474ae1e91c | ||
|
|
0dc70ca5f3 | ||
|
|
633b1663ca | ||
|
|
153fe61b4b | ||
|
|
9734fd0353 | ||
|
|
6209c120c0 | ||
|
|
3516881e7a | ||
|
|
15398555b3 | ||
|
|
cb132fcbf4 | ||
|
|
f42f46c7d6 | ||
|
|
f1046f1cf1 | ||
|
|
4a62287139 | ||
|
|
69cd56357f | ||
|
|
b66a886682 | ||
|
|
249504b7d6 | ||
|
|
fa0086404d | ||
|
|
f243ebba91 | ||
|
|
540afb193b | ||
|
|
8294acdf1c | ||
|
|
7733d02938 | ||
|
|
9b6342e7fa | ||
|
|
22c09cb31b | ||
|
|
21e79cb54a | ||
|
|
b8cc829f4a | ||
|
|
ace0dacf15 | ||
|
|
5ca13098e3 | ||
|
|
07b13eedec | ||
|
|
d9168ed9ec | ||
|
|
fb4e2c167c | ||
|
|
10ee3585f6 | ||
|
|
5d4ba820dd | ||
|
|
a51e00e69f | ||
|
|
4dfa963851 | ||
|
|
f2d4f6ccf6 | ||
|
|
182cb8ab25 | ||
|
|
ece341d868 | ||
|
|
d72e8c2687 | ||
|
|
b0ff6f4c7b | ||
|
|
6ec5249492 | ||
|
|
c44cd76c5a | ||
|
|
37f711d72a | ||
|
|
fcf18fb965 | ||
|
|
2efd6250fb | ||
|
|
1b4bd8523d | ||
|
|
60c44910df | ||
|
|
faf67fae03 | ||
|
|
e95f547950 | ||
|
|
96b663b783 | ||
|
|
ce44f7e4b0 | ||
|
|
16a9c7d492 | ||
|
|
fc369c3448 | ||
|
|
b1a33edf0f | ||
|
|
3b805f1a24 | ||
|
|
954b4d8075 | ||
|
|
d073e2a881 | ||
|
|
044dd2af94 | ||
|
|
ee489fa8c0 | ||
|
|
035ed5f49b | ||
|
|
7dcd690f61 | ||
|
|
1c9290aded | ||
|
|
0b922b1ed1 | ||
|
|
34eec362e5 | ||
|
|
b829383864 | ||
|
|
3960235428 | ||
|
|
e91a662491 | ||
|
|
ba4da24984 | ||
|
|
70378432b7 | ||
|
|
6b63009b14 | ||
|
|
dd45fea732 | ||
|
|
ee09425cfb | ||
|
|
af02a1e024 | ||
|
|
2a86f0776c | ||
|
|
c6f73d9df8 | ||
|
|
5ab79f292b | ||
|
|
82c7a22d27 | ||
|
|
35fa977981 | ||
|
|
ecbc46a91d | ||
|
|
d2f6416e45 | ||
|
|
97a885a05c | ||
|
|
aa1edd6b94 | ||
|
|
083e401717 | ||
|
|
bdeca2edce | ||
|
|
c84e14db46 | ||
|
|
919c5bd0b3 | ||
|
|
af8a8f1e3f | ||
|
|
41d08e123f | ||
|
|
67d9656e35 | ||
|
|
1a58a70494 | ||
|
|
a477b2efd1 | ||
|
|
59c4546b8c | ||
|
|
ed1a75ef4c | ||
|
|
0cd942f152 | ||
|
|
fe7f082083 | ||
|
|
849fd71f76 | ||
|
|
4e3a72388d | ||
|
|
29e3d9eff5 | ||
|
|
64280f4285 | ||
|
|
98c6eaac3b | ||
|
|
22d965c66c | ||
|
|
2eb932ebc1 | ||
|
|
2ee0634db3 | ||
|
|
db3b6a1252 | ||
|
|
24810aeca3 | ||
|
|
c888319f22 | ||
|
|
13ee78a9c9 | ||
|
|
acaa07cf7c | ||
|
|
1a3c9939e8 | ||
|
|
56afe21022 | ||
|
|
b58bfa82e6 | ||
|
|
a6257b5901 | ||
|
|
16ad7e53ff | ||
|
|
3e4e4f2664 | ||
|
|
dc0c4fe8fb | ||
|
|
0c050bb266 | ||
|
|
47a5b227cc | ||
|
|
ed61d0c591 | ||
|
|
8ff856ecf8 | ||
|
|
93a607bea0 | ||
|
|
7bec7ba49d | ||
|
|
4c8f3bd392 | ||
|
|
74ba9eb159 | ||
|
|
d28ca4eda7 | ||
|
|
9563b5a7df | ||
|
|
d3a049c6e0 | ||
|
|
a52a3eb42f | ||
|
|
c54b21a754 | ||
|
|
cc8995cd5c | ||
|
|
2e222fbae2 | ||
|
|
cdf3b15336 | ||
|
|
a9a95de02d | ||
|
|
d4bcd4ab0c | ||
|
|
3b2ed06864 | ||
|
|
ab210b3988 | ||
|
|
70617be903 | ||
|
|
f039d5bbcb | ||
|
|
e0adb3cf9a | ||
|
|
4dd6e07b8d | ||
|
|
d69b7951e0 | ||
|
|
d915ece2e7 | ||
|
|
f1be3df112 | ||
|
|
29b7ca4c25 | ||
|
|
f478d916aa | ||
|
|
d2e50b09db | ||
|
|
23c2dd33f2 | ||
|
|
ce0c3c935c | ||
|
|
bdbafb7a2a | ||
|
|
edffe2a6fc | ||
|
|
cd69a53406 | ||
|
|
439ffa5849 | ||
|
|
4518c30cbe | ||
|
|
6683809447 | ||
|
|
cccd43a16b | ||
|
|
91d44147bb | ||
|
|
777311bbf5 | ||
|
|
9ded5dc78d | ||
|
|
5b81c4573c | ||
|
|
32b2e9f6cf | ||
|
|
a6dba44561 | ||
|
|
03fc317a3f | ||
|
|
00a8130201 | ||
|
|
74fc15cccd | ||
|
|
1d4d919f6d | ||
|
|
1826cc8870 | ||
|
|
8a6dab03c4 | ||
|
|
dffad444c3 | ||
|
|
d6f1b164f7 | ||
|
|
4011f054d6 | ||
|
|
14e9978359 | ||
|
|
98535638a2 | ||
|
|
8861c04e77 | ||
|
|
42b6f320d8 | ||
|
|
31b4a9197f | ||
|
|
f06c9d5b9b | ||
|
|
130fafd7c2 | ||
|
|
e76f79cd56 | ||
|
|
ba21718cb9 | ||
|
|
6dfb2997cb | ||
|
|
ae9ac3b439 | ||
|
|
d70b5a9886 | ||
|
|
fb2a20201c | ||
|
|
d1761558b4 | ||
|
|
5bd0a53edd | ||
|
|
53ea73238a | ||
|
|
28560cb887 | ||
|
|
0bcd12aa4e | ||
|
|
a7dfdebed6 | ||
|
|
aca07530aa | ||
|
|
c0110c6bab | ||
|
|
0ef9e0fa75 | ||
|
|
ba0751917d | ||
|
|
e3c1bfbcba | ||
|
|
5aaa0a7b5f | ||
|
|
2ca75970c0 | ||
|
|
d9c92288be | ||
|
|
e4f231502a | ||
|
|
04a61e6fd6 | ||
|
|
dc5c7d2ee8 | ||
|
|
87ac6812a3 | ||
|
|
8d4d2d62c1 | ||
|
|
68fc036b7a | ||
|
|
f053c4d532 | ||
|
|
06e4a2dbde | ||
|
|
9e0ecab0c1 | ||
|
|
996e61a383 | ||
|
|
309aa4a3f3 | ||
|
|
0906fbf995 | ||
|
|
2348ec40ee | ||
|
|
c6852f4b96 | ||
|
|
8b01139738 | ||
|
|
5ea3717152 | ||
|
|
d01a673adb | ||
|
|
571ec44c33 | ||
|
|
e5a3c12026 | ||
|
|
bb2f1aa4be | ||
|
|
59070bcd5b | ||
|
|
2f52dd88a9 | ||
|
|
79fec3ac40 | ||
|
|
6247bbf4b1 | ||
|
|
11de155432 | ||
|
|
bfe833c132 | ||
|
|
1fd1da72f4 | ||
|
|
f4c994d182 | ||
|
|
d81a6e6e89 | ||
|
|
fab5daacf8 | ||
|
|
b714c6b746 | ||
|
|
af1355a94e | ||
|
|
ebc08fd6f5 | ||
|
|
30b1445195 | ||
|
|
0d1c7a1414 | ||
|
|
7e8e7757f4 | ||
|
|
42eb180b6c | ||
|
|
dff35bc9b7 | ||
|
|
6a87ed2853 | ||
|
|
1266d49c65 | ||
|
|
c8b130b232 | ||
|
|
67a6b0f383 | ||
|
|
e7c176f904 | ||
|
|
4cc8363b5f | ||
|
|
93193d7e76 | ||
|
|
d68321ac27 | ||
|
|
b2e8359d31 | ||
|
|
a302ca3d6c | ||
|
|
670358f235 | ||
|
|
10e329f762 | ||
|
|
6a3c1bdb99 | ||
|
|
90923c965b | ||
|
|
d555241d03 | ||
|
|
3d2b6b7620 | ||
|
|
0b943b418c | ||
|
|
db12aaad11 | ||
|
|
860aa65d10 | ||
|
|
2e5e279a14 | ||
|
|
df87b9ff56 | ||
|
|
6c06ff3ca0 | ||
|
|
40d6e9c841 | ||
|
|
6a4f06f325 | ||
|
|
f7d306cb02 | ||
|
|
34bc182c22 | ||
|
|
3f8dd7e658 | ||
|
|
46341fea96 | ||
|
|
4319cdbba1 | ||
|
|
3453236830 | ||
|
|
fa2058ec77 | ||
|
|
7f823fe2a8 | ||
|
|
58e14705b5 | ||
|
|
99b7613206 | ||
|
|
545e614c04 | ||
|
|
5ea04a388d | ||
|
|
8922372f4b | ||
|
|
ceaa2c1619 | ||
|
|
4e73daab79 | ||
|
|
5b29d987c8 | ||
|
|
1cd53c051d | ||
|
|
5460d0030f | ||
|
|
d14a0ce592 | ||
|
|
a4000a3286 | ||
|
|
85fd650f5c | ||
|
|
b19033a375 | ||
|
|
33e19ce9f6 | ||
|
|
d21218fd57 | ||
|
|
9f2279c675 | ||
|
|
06bfbfaff4 | ||
|
|
562834e0d0 | ||
|
|
bdf2285f14 | ||
|
|
1780682a8d | ||
|
|
9b48bd27dd | ||
|
|
0b1e2a6107 | ||
|
|
c78edf3fff | ||
|
|
6fcd99c6da | ||
|
|
b42f3a5400 | ||
|
|
bb543920a6 | ||
|
|
0845758023 | ||
|
|
816f81260a | ||
|
|
a9583f4440 | ||
|
|
4e52c9cc65 | ||
|
|
8299dded0b | ||
|
|
5d83cafc50 | ||
|
|
9819e60aae | ||
|
|
1182eb4a9f | ||
|
|
48a0986c14 | ||
|
|
6c2f7046d1 | ||
|
|
9735bffae5 | ||
|
|
56a11910db | ||
|
|
70b00dc4e3 | ||
|
|
56c1bf01a4 | ||
|
|
022b295aaa | ||
|
|
fd977895ab | ||
|
|
ad1f3ddbad | ||
|
|
c8b159e38c | ||
|
|
7405e3c12a | ||
|
|
1b8ca164c9 | ||
|
|
74cdaa9fcb | ||
|
|
0ba331485a | ||
|
|
f5b3c0affc | ||
|
|
316ae0c785 | ||
|
|
c2d2fa2579 | ||
|
|
d683eb2dd1 | ||
|
|
470d35e96c | ||
|
|
7464d82243 | ||
|
|
c61fed32db | ||
|
|
c4cdec5531 | ||
|
|
3ad9d38063 | ||
|
|
f8b95abf0c | ||
|
|
579794666a | ||
|
|
2ef25b6338 | ||
|
|
faddd94518 | ||
|
|
cd5f9b8bd4 | ||
|
|
94fd20e864 | ||
|
|
3558eef66b | ||
|
|
ee66e2154d | ||
|
|
5500a86f0b | ||
|
|
9b1c1774cd | ||
|
|
a8e31469c5 | ||
|
|
b70bafaf51 | ||
|
|
d393349b4d | ||
|
|
0904724694 | ||
|
|
eff4825000 | ||
|
|
091c00229a | ||
|
|
126f0d6036 | ||
|
|
f99bc6d8f9 | ||
|
|
3da0117838 | ||
|
|
3d8cf6a90b | ||
|
|
ac44663f04 | ||
|
|
57113b21ed | ||
|
|
57d5ace61c | ||
|
|
f4da80e7c6 | ||
|
|
df3ca5c7c8 | ||
|
|
4b676df37f | ||
|
|
5dc04266ea | ||
|
|
dbcfe3f5d2 | ||
|
|
fdbec5b0d2 | ||
|
|
3ea129b4f8 | ||
|
|
48a7e40520 | ||
|
|
08b956cf88 | ||
|
|
93b1e1f5ac | ||
|
|
bdecf6baf5 | ||
|
|
4528311d77 | ||
|
|
0bc1761dae | ||
|
|
f690b0edf6 | ||
|
|
10851772af | ||
|
|
66e7b28195 | ||
|
|
76021fb582 | ||
|
|
db50adbd9f | ||
|
|
5c7cc146a1 | ||
|
|
fa3b384c6f | ||
|
|
3f9a878b03 | ||
|
|
ab3b972185 | ||
|
|
fb9118a044 | ||
|
|
5cce5b6707 | ||
|
|
3256c9b3f5 | ||
|
|
8b43b2b69d | ||
|
|
02a862684d | ||
|
|
c15f5b5106 | ||
|
|
0f06d51065 | ||
|
|
8abfa419e8 | ||
|
|
c3c90ab78b | ||
|
|
666be21f59 | ||
|
|
0fe8197100 | ||
|
|
d8a7a7792a | ||
|
|
82b9a0c949 | ||
|
|
a3083d2990 | ||
|
|
3c62914304 | ||
|
|
a094768469 | ||
|
|
3965f063d3 | ||
|
|
2b7c295bf1 | ||
|
|
2fd297c1e1 | ||
|
|
263c04aeb2 | ||
|
|
8f2b5e195e | ||
|
|
7e3dd2b8cc | ||
|
|
49c027537e | ||
|
|
a1a6095295 | ||
|
|
5f7dcc9b78 | ||
|
|
1705bf4f3c | ||
|
|
8612946bf5 | ||
|
|
7cf40576dd | ||
|
|
239f35d830 | ||
|
|
05ff42b767 | ||
|
|
7bab4817f2 | ||
|
|
0d87b7d720 | ||
|
|
6b72adbeee | ||
|
|
db97ae46e5 | ||
|
|
fc6c084693 | ||
|
|
9e01cc5705 | ||
|
|
f9ce45c058 | ||
|
|
056ff4b6ea | ||
|
|
52653f73b9 | ||
|
|
a06207b814 | ||
|
|
3b3ef411a4 | ||
|
|
6418f78fdb | ||
|
|
5d4187bf03 | ||
|
|
cfffad73eb | ||
|
|
ef7db87b82 | ||
|
|
212eea9cf5 | ||
|
|
da792cc272 | ||
|
|
2ae2142b35 | ||
|
|
a00f5f308a | ||
|
|
81cfde12f3 | ||
|
|
1a53d38dae | ||
|
|
b834fdbc5e | ||
|
|
1cb2db03ed | ||
|
|
57bca50ed0 | ||
|
|
94386583e2 | ||
|
|
b1ab63d549 | ||
|
|
ad56bdd354 | ||
|
|
65e30c13e2 | ||
|
|
0c54fac651 | ||
|
|
9660c22a9f | ||
|
|
31e8df4a59 | ||
|
|
8e6ecaf8d4 | ||
|
|
4d69a0ce29 | ||
|
|
1b842f86ca | ||
|
|
a2330fb630 | ||
|
|
30f0232d71 | ||
|
|
404e658a5d | ||
|
|
f5682397c2 | ||
|
|
4896810258 | ||
|
|
dd0de8b6e1 | ||
|
|
2a9f9f7ebd | ||
|
|
2f3afd3637 | ||
|
|
f0a2c88fdc | ||
|
|
c3a5b12cd3 | ||
|
|
d7b0e66270 | ||
|
|
1871ed5441 | ||
|
|
5ea6948127 | ||
|
|
9bd77d36f1 | ||
|
|
3ffa6cd1ac | ||
|
|
ad87df3168 | ||
|
|
8bd0d32fd2 | ||
|
|
f182675a6e | ||
|
|
56ce89e04f | ||
|
|
062ec036f8 | ||
|
|
8089242b2f | ||
|
|
8efa1a0032 | ||
|
|
7ce8304ce6 | ||
|
|
233adab647 | ||
|
|
475c86d100 | ||
|
|
f754654dae | ||
|
|
53ce20c0df | ||
|
|
ad91e3a344 | ||
|
|
4f2b33f80f | ||
|
|
2b24d42f8d | ||
|
|
ab70f306cd | ||
|
|
4fb83fe0a5 | ||
|
|
9c6ef34270 | ||
|
|
481eb8e5dc | ||
|
|
7cf65b899b | ||
|
|
dd70fcb9bc | ||
|
|
6dd8c05533 | ||
|
|
0b900d94f7 | ||
|
|
cf724c43cb | ||
|
|
cdf5ac4fc4 | ||
|
|
b768ce4ca4 | ||
|
|
0115503af9 | ||
|
|
08dd30c5bf | ||
|
|
72270013c8 | ||
|
|
a2a59cbeae | ||
|
|
20a38d2dbe | ||
|
|
9aade0a2da | ||
|
|
9af1d1af52 | ||
|
|
8bb69cd6da | ||
|
|
84a84a1687 | ||
|
|
462c43434b | ||
|
|
b830691611 | ||
|
|
204f1747cf | ||
|
|
13c9d80a3b | ||
|
|
64f45b061b | ||
|
|
c1202fd127 | ||
|
|
2060f3f59a | ||
|
|
1fb92df2e7 | ||
|
|
848301bf70 | ||
|
|
08b5b71fcb | ||
|
|
5414d4a9e4 | ||
|
|
b930bd7326 | ||
|
|
d1d1be49ba | ||
|
|
6ad7963347 | ||
|
|
2dcda2487a | ||
|
|
55911eac7a | ||
|
|
176b109ae7 | ||
|
|
0f12d43a59 | ||
|
|
6dfc2aca4b | ||
|
|
f5a34d5191 | ||
|
|
bc3a7f70e4 | ||
|
|
dcabee8d5e | ||
|
|
d7e290dc68 | ||
|
|
2e2341c8b2 | ||
|
|
0ee717342b | ||
|
|
9f372b3146 | ||
|
|
dd92e36feb | ||
|
|
c25738c62c | ||
|
|
c264e98e6e | ||
|
|
f2780bcbc2 | ||
|
|
050b703fc0 | ||
|
|
eed09f64f7 | ||
|
|
28c4ad1501 | ||
|
|
28d1dad629 | ||
|
|
b5f0672888 | ||
|
|
71fc4faae7 | ||
|
|
8bff1e8bc4 | ||
|
|
af67dd6610 | ||
|
|
c46c700f7c | ||
|
|
2a2de2efdc | ||
|
|
f384c42de5 | ||
|
|
bf1c54e5a3 | ||
|
|
d8f2cc50df | ||
|
|
06c25ba998 | ||
|
|
58654a3f3a | ||
|
|
32521cd1b6 | ||
|
|
e072fe6ea9 | ||
|
|
b5897fdb62 | ||
|
|
55df525f1b | ||
|
|
e6dde68924 | ||
|
|
b3e2305dea | ||
|
|
ec3e3ed1fd | ||
|
|
30fc97eef6 | ||
|
|
5939692616 | ||
|
|
9ce3176b59 | ||
|
|
497d35b03b | ||
|
|
6a1191de31 | ||
|
|
6c3a17de71 | ||
|
|
22cf82e44b | ||
|
|
10c7e49273 | ||
|
|
4900eae751 | ||
|
|
5334c599f0 | ||
|
|
ad10a1eba5 | ||
|
|
3ca626f2a9 | ||
|
|
e7ad40d8f4 | ||
|
|
d38ab1145a | ||
|
|
f31360e1a4 | ||
|
|
059fead736 | ||
|
|
4e8360c030 | ||
|
|
fbd80746a5 | ||
|
|
072a5de1c5 | ||
|
|
5c3c5a5521 | ||
|
|
461b294bc7 | ||
|
|
71de0f2d08 | ||
|
|
2ffdc4f2ef | ||
|
|
dc9b320c4a | ||
|
|
a6a93148b4 | ||
|
|
f7dc3b9ce4 | ||
|
|
12ad5d53c9 | ||
|
|
54dc1e2e15 | ||
|
|
073f715f17 | ||
|
|
7ff50893dc | ||
|
|
d128082b23 | ||
|
|
1b8f89c3f1 | ||
|
|
8eb138e0b3 | ||
|
|
8256579310 | ||
|
|
41f1fb8d95 | ||
|
|
277d91afce | ||
|
|
aaa840ebef | ||
|
|
29ffdadabb | ||
|
|
e5f19fe037 | ||
|
|
5791d71e9f | ||
|
|
104a7022fb | ||
|
|
6210b613be | ||
|
|
2ba9380616 | ||
|
|
59042bc2e2 | ||
|
|
ccfd8e51ea | ||
|
|
1aafb6c2c1 | ||
|
|
7976aa4b28 | ||
|
|
1b4e175c0c | ||
|
|
3ef955c139 | ||
|
|
51990ed0e5 | ||
|
|
138523bab3 | ||
|
|
995ec2b104 | ||
|
|
d13f8749d4 | ||
|
|
0350443810 | ||
|
|
c5841dccbb | ||
|
|
a0c50f9ef5 | ||
|
|
120020b4db | ||
|
|
676747467a | ||
|
|
e2d13541dc | ||
|
|
057cbc76b3 | ||
|
|
48035187d2 | ||
|
|
f05f60f929 | ||
|
|
3ab19e81ac | ||
|
|
532be6cd87 | ||
|
|
21a492fa43 | ||
|
|
edf83823f1 | ||
|
|
8d6f7de046 | ||
|
|
a7de4f3663 | ||
|
|
e538f16315 | ||
|
|
3f8b3e2baa | ||
|
|
a90ecde389 | ||
|
|
1ad65bb66b | ||
|
|
d85bb3bce1 | ||
|
|
8cd4732321 | ||
|
|
6957b02c27 | ||
|
|
adcadf08d1 | ||
|
|
3b36145257 | ||
|
|
c3e5eaf8da | ||
|
|
fd176107ae | ||
|
|
ad203e1461 | ||
|
|
1fe9ba5879 | ||
|
|
678321bb2f | ||
|
|
967ce824f7 | ||
|
|
336e5e0ff7 | ||
|
|
7a94f472c7 | ||
|
|
70b41a2a6e | ||
|
|
216e7f3b10 | ||
|
|
0717da6e37 | ||
|
|
3f64316e00 | ||
|
|
172eaf84b5 | ||
|
|
0c20889a17 | ||
|
|
62523d537b | ||
|
|
6643252019 | ||
|
|
13022a6bb0 | ||
|
|
fc018691e5 | ||
|
|
56666c4bf4 | ||
|
|
379da81f85 | ||
|
|
9ce6d4b72a | ||
|
|
be46c31c74 | ||
|
|
cd4029dc61 | ||
|
|
d2aa55a3bd | ||
|
|
838be0846d | ||
|
|
9414cb97b5 | ||
|
|
d6883a077a | ||
|
|
aa60b8399b | ||
|
|
cbe504df77 | ||
|
|
e0efcc1f25 | ||
|
|
c6e536a768 | ||
|
|
77ba53bda7 | ||
|
|
c2c6f1493a | ||
|
|
debaed6e5e | ||
|
|
0d6279617b | ||
|
|
3435314400 | ||
|
|
f248a8383b | ||
|
|
5458b007d1 | ||
|
|
6735291c99 | ||
|
|
6ad7a20c07 | ||
|
|
3191825ecc | ||
|
|
baee6b9738 | ||
|
|
c4a7f899db | ||
|
|
c01623ba56 | ||
|
|
81d0d5c59f | ||
|
|
cc4fdfd852 | ||
|
|
ba7be29153 | ||
|
|
4eae95b88d | ||
|
|
06d8281f16 | ||
|
|
87c21ba75e | ||
|
|
7f88a7c9bb | ||
|
|
38c57a662c | ||
|
|
36f5ddc543 | ||
|
|
8b873b6b1b | ||
|
|
68bd881ca8 | ||
|
|
c3e717a3ef | ||
|
|
d9be6f8a9a | ||
|
|
3bfb9d65f4 | ||
|
|
9ad26f943f | ||
|
|
c5112cb24e | ||
|
|
c17e1f9e75 | ||
|
|
b48b454909 | ||
|
|
6b59a924e8 | ||
|
|
87879a6784 | ||
|
|
fca5fda9da | ||
|
|
691d566482 | ||
|
|
61578f4dca | ||
|
|
9f4a7fc0da | ||
|
|
200a5d84c7 | ||
|
|
309a2ad0a3 | ||
|
|
e696331e2a | ||
|
|
c3126e24ce | ||
|
|
bde931f2f5 | ||
|
|
58b3e9f201 | ||
|
|
1423dcb619 | ||
|
|
df3540b0f9 | ||
|
|
921209580a | ||
|
|
d4e058a844 | ||
|
|
8f9eed154e | ||
|
|
1416655d53 | ||
|
|
9a147218ce | ||
|
|
34b575da03 | ||
|
|
54d22a23b5 | ||
|
|
ee10e17ce7 | ||
|
|
8ff97468cc | ||
|
|
6f898c6c97 | ||
|
|
cfeb8d053f | ||
|
|
d317171a45 | ||
|
|
9b0aadccf8 | ||
|
|
d6850ab358 | ||
|
|
c139a0d9ed | ||
|
|
67b0c4cddd | ||
|
|
ce36bf6134 | ||
|
|
e2dd65a403 | ||
|
|
a2595d5107 | ||
|
|
6dc0cf0c44 | ||
|
|
faac630001 | ||
|
|
0deacc7229 | ||
|
|
c849fe1496 | ||
|
|
4238e84ec4 | ||
|
|
df4e306c64 | ||
|
|
916c728d70 | ||
|
|
476d85915b | ||
|
|
e54b8ead72 | ||
|
|
d2444d2992 | ||
|
|
48acda2c3c | ||
|
|
264f7b1d30 | ||
|
|
fc44d54607 | ||
|
|
afc3698578 | ||
|
|
c3cd94b695 | ||
|
|
ea219f683e | ||
|
|
faf6584652 | ||
|
|
4dc41749fb | ||
|
|
2aa94301a8 | ||
|
|
d2870b6df7 | ||
|
|
5cbc44610c | ||
|
|
9032cc0ecc | ||
|
|
e48b314ad0 | ||
|
|
6fdaf905c4 | ||
|
|
79b706fb5c | ||
|
|
eaee188244 | ||
|
|
a6ac62d628 | ||
|
|
7a7f12504b | ||
|
|
55c83d17e1 | ||
|
|
8009c1b7eb | ||
|
|
1580453f4b | ||
|
|
9cc8f5dd07 | ||
|
|
7e326b8431 | ||
|
|
8bddb47fab | ||
|
|
b1b462d22b | ||
|
|
d5847faaba | ||
|
|
4c9f3aee74 | ||
|
|
ff4e0cb1c2 | ||
|
|
c159da1fbc | ||
|
|
d5e55f9dbd | ||
|
|
642ed4061a | ||
|
|
5178c3e67f | ||
|
|
e402347d73 | ||
|
|
3004c58798 | ||
|
|
15a44fe650 | ||
|
|
e37a96a94a | ||
|
|
e475a3b64c | ||
|
|
663ebd25ea | ||
|
|
e6bec0de72 | ||
|
|
f513effd47 | ||
|
|
dd05e898cc | ||
|
|
49a88e75e6 | ||
|
|
14a99471f4 | ||
|
|
bdbc181e38 | ||
|
|
133b1151bd | ||
|
|
653aab2358 | ||
|
|
13669313d4 | ||
|
|
e84d79ccf3 | ||
|
|
34077f9624 | ||
|
|
28ba64a4db | ||
|
|
0eefd3e140 | ||
|
|
20bbfc5917 | ||
|
|
9d6832224e | ||
|
|
2cf17b19dc | ||
|
|
390cf2114a | ||
|
|
8bff019b5d | ||
|
|
7d221f3be9 | ||
|
|
b8628b9772 | ||
|
|
cda4d9e1b2 | ||
|
|
f5d7a4d41e | ||
|
|
94486302f5 | ||
|
|
4f4a7409f6 | ||
|
|
60f57f9e4b | ||
|
|
2f98cd9eb0 | ||
|
|
f77586f13d | ||
|
|
fa82091989 | ||
|
|
66e9c68da4 | ||
|
|
c97c2fee37 | ||
|
|
fd03500786 | ||
|
|
83d5c31a0c | ||
|
|
7f19c10da9 | ||
|
|
c10ea527a0 | ||
|
|
5a54c1520a | ||
|
|
3f2732be7b | ||
|
|
d504b1f90f | ||
|
|
210dac058d | ||
|
|
ccb3012e5a | ||
|
|
c94f2e6f07 | ||
|
|
e31d7178b4 | ||
|
|
b3a4b8085c | ||
|
|
b56d7ab9c3 | ||
|
|
c63e270921 | ||
|
|
cffbae3a13 | ||
|
|
d2d03228ee | ||
|
|
30458fa536 | ||
|
|
0e60831f46 | ||
|
|
69238bf8e8 | ||
|
|
db483df9a6 | ||
|
|
1dc95f5d3a | ||
|
|
37caef10b1 | ||
|
|
381ecd8f70 | ||
|
|
f2a829362b | ||
|
|
fe2e994f2d | ||
|
|
95ba6bf040 | ||
|
|
6f937e8958 | ||
|
|
12f04650de | ||
|
|
f7330cce14 | ||
|
|
ba56f95da8 | ||
|
|
46704724e3 | ||
|
|
caadd5bb32 | ||
|
|
faa221f162 | ||
|
|
a814d5438a | ||
|
|
ab43c4cf2a | ||
|
|
d781e2dfb8 | ||
|
|
968ef1560f | ||
|
|
1631ceedb3 | ||
|
|
884c2af17d | ||
|
|
51ab030541 | ||
|
|
2a1e063641 | ||
|
|
62b3120ffd | ||
|
|
ea17b3d7c9 | ||
|
|
f3e98fc71c | ||
|
|
5034e11f22 | ||
|
|
560473d70b | ||
|
|
10e53509bd | ||
|
|
27afb02482 | ||
|
|
07fd0989ea | ||
|
|
d7c38aea50 | ||
|
|
20d57e27c9 | ||
|
|
4606c8092f | ||
|
|
30f256aad2 | ||
|
|
1b9dbd0e62 | ||
|
|
225c8871f9 | ||
|
|
d0333134d5 | ||
|
|
b24b8315d3 | ||
|
|
4ddc3b518b | ||
|
|
479a7e441d | ||
|
|
af5ae8d656 | ||
|
|
1365882de4 | ||
|
|
7854cd1f94 | ||
|
|
12a1a14527 | ||
|
|
a71cc552c9 | ||
|
|
e42d091502 | ||
|
|
d89d5befa0 | ||
|
|
92e5ae29c9 | ||
|
|
65aeb97e3e | ||
|
|
08a9ef1072 | ||
|
|
9c3f297e97 | ||
|
|
2554871c64 | ||
|
|
404edebdff | ||
|
|
2f2030babf | ||
|
|
b560b35175 | ||
|
|
3063b19e1d | ||
|
|
a17fb54c37 | ||
|
|
c1b8a8594d | ||
|
|
0a7fc6c48c | ||
|
|
79d59ff9ca | ||
|
|
c7d3c78e72 | ||
|
|
d56322a032 | ||
|
|
aac3c4d5c7 | ||
|
|
9ba1ddc2dd | ||
|
|
61eeaa0496 | ||
|
|
d3b6f9975c | ||
|
|
5200c8d659 | ||
|
|
e2c6f57859 | ||
|
|
b084210705 | ||
|
|
6622922468 | ||
|
|
caf31eb6d3 | ||
|
|
464691f129 | ||
|
|
afcf539e6e | ||
|
|
bf2c1a2df2 | ||
|
|
7400064cd5 | ||
|
|
7eb3754807 | ||
|
|
a9cc2fdb54 | ||
|
|
212282e77c | ||
|
|
1e8a820108 | ||
|
|
0117341b7e | ||
|
|
d21eac8b18 | ||
|
|
af4edc3b76 | ||
|
|
8a959896bf | ||
|
|
ba5107e801 | ||
|
|
d7de4a3579 | ||
|
|
175b14860e | ||
|
|
72fcb4ebda | ||
|
|
3a221f9b6e | ||
|
|
1241fb54f3 | ||
|
|
b291dcadc6 | ||
|
|
4105b19f75 | ||
|
|
b7b8ad7760 | ||
|
|
8465e3061a | ||
|
|
6b09cd61d2 | ||
|
|
aac609cc38 | ||
|
|
0b1d16f9db | ||
|
|
7374f6dc4f | ||
|
|
9577d80fc2 | ||
|
|
c550e27d21 | ||
|
|
423730da76 | ||
|
|
78a4c6f525 | ||
|
|
0d3ac21ae0 | ||
|
|
2cae3245aa | ||
|
|
e143a0ec6b | ||
|
|
35ce087f3b | ||
|
|
e787bc8ae4 | ||
|
|
4937052475 | ||
|
|
739eb67bec | ||
|
|
a3049b6f94 | ||
|
|
2f1346fefa | ||
|
|
f116db3108 | ||
|
|
87a8780cca | ||
|
|
d2de62283b | ||
|
|
11c16139c2 | ||
|
|
1c91ec69ba | ||
|
|
73429e7779 | ||
|
|
fe5aff0c72 | ||
|
|
c36d29a896 | ||
|
|
e3b5395905 | ||
|
|
3a25ecbbc9 | ||
|
|
7d63970293 | ||
|
|
ee267d23ba | ||
|
|
e0e4eed26b | ||
|
|
5b280bd60d | ||
|
|
2f9cc91b64 | ||
|
|
36bcced355 | ||
|
|
9a9b17d38d | ||
|
|
e2cd275ac5 | ||
|
|
61eb5d906c | ||
|
|
a113dc0861 | ||
|
|
6a164a235d | ||
|
|
c1eaa90c2b | ||
|
|
00e00eb7b5 | ||
|
|
0d2db28908 | ||
|
|
20202b793b | ||
|
|
62e84e73ae | ||
|
|
73f6fd49d0 | ||
|
|
4f9da35b76 | ||
|
|
cc7b413a2a | ||
|
|
fcf29f357d | ||
|
|
4fd1eae84f | ||
|
|
1c770a3c66 | ||
|
|
e152f54903 | ||
|
|
5d3a9d817a | ||
|
|
e884916275 | ||
|
|
5b7b16416b | ||
|
|
04b93aeaf2 | ||
|
|
39bdd37615 | ||
|
|
4ccb3810c2 | ||
|
|
1065ebb0aa | ||
|
|
74c08de530 | ||
|
|
b195fdbf60 | ||
|
|
f68efe6674 | ||
|
|
ed309182bf | ||
|
|
50c6b276f9 | ||
|
|
4c1a8f358a | ||
|
|
05ff79f347 | ||
|
|
3ae328898d | ||
|
|
7d35c43def | ||
|
|
d4f857b739 | ||
|
|
b6bc844b4d | ||
|
|
d06a477371 | ||
|
|
c128c029f3 | ||
|
|
a58ad5006f | ||
|
|
3c5655fc3d | ||
|
|
6ab04866ec | ||
|
|
1f07f9d127 | ||
|
|
e5ccfc4446 | ||
|
|
ec89382e35 | ||
|
|
4a7873ef77 | ||
|
|
ff2fd45ff0 | ||
|
|
e8cfeec0cf | ||
|
|
c72171d1da | ||
|
|
885b56000b | ||
|
|
3d1ee9dcf0 | ||
|
|
5d2133a483 | ||
|
|
52bb56ba43 | ||
|
|
d2edf11726 | ||
|
|
9a152c23bb | ||
|
|
8572445f57 | ||
|
|
9940d73167 | ||
|
|
8b8a9ae854 | ||
|
|
036bf92223 | ||
|
|
410969743f | ||
|
|
14da67121c | ||
|
|
681d3e09ba | ||
|
|
0ce130efa7 | ||
|
|
d14d7ade85 | ||
|
|
7b4fd28ef1 | ||
|
|
b2280b2d72 | ||
|
|
b41826c332 | ||
|
|
3d93ed9059 | ||
|
|
35a0756e5a | ||
|
|
10419366f9 | ||
|
|
8373d31013 | ||
|
|
0c89a8f145 | ||
|
|
257ac4d37e | ||
|
|
653aee8b07 | ||
|
|
88726aff8c | ||
|
|
baabdb4ac2 | ||
|
|
6277510557 | ||
|
|
e9ab17fcb1 | ||
|
|
2f9ba719d4 | ||
|
|
e259f300b1 | ||
|
|
fcc357ddd1 | ||
|
|
e613198af7 | ||
|
|
e3c1214971 | ||
|
|
1c3f9f7fbf | ||
|
|
f4a1573586 | ||
|
|
95db668c3c | ||
|
|
691e21fa78 | ||
|
|
c555681c8b | ||
|
|
ae7ef24196 | ||
|
|
f935b141f1 | ||
|
|
a893d43d16 | ||
|
|
7cb47c8494 | ||
|
|
5ef4c763b6 | ||
|
|
459b5bd89c | ||
|
|
c5237a926d | ||
|
|
2e5052a7fa | ||
|
|
cd8d9bf07c | ||
|
|
7da022ebb4 | ||
|
|
67f9c7e0f0 | ||
|
|
1812d557b6 | ||
|
|
34cde430a5 | ||
|
|
12a6b58614 | ||
|
|
cb81fccfaf | ||
|
|
1ce0fffd25 | ||
|
|
0c1c4b08c7 | ||
|
|
c875b61003 | ||
|
|
f4b34c8ca5 | ||
|
|
a6b4b5e30c | ||
|
|
64fb8f0c53 | ||
|
|
78a312f61c | ||
|
|
2c6c4426e8 | ||
|
|
a9df0601a6 | ||
|
|
4345f353a0 | ||
|
|
96b525658e | ||
|
|
9525952573 | ||
|
|
76828a87ee | ||
|
|
789eb59904 | ||
|
|
c0265f8fd9 | ||
|
|
891ebb8ff6 | ||
|
|
1111c20d54 | ||
|
|
387176e83d | ||
|
|
80a38b285d | ||
|
|
aa0c02a243 | ||
|
|
3c5932af75 | ||
|
|
f40a7d47f5 | ||
|
|
f85543c7ff | ||
|
|
36d2ff7c3b | ||
|
|
7ba673ed89 | ||
|
|
a0cba79df2 | ||
|
|
c91e8d7aa7 | ||
|
|
e85b0a81ba | ||
|
|
bfc40498bd | ||
|
|
41ac7062f8 | ||
|
|
71c19b566b | ||
|
|
0de72f3abb | ||
|
|
ce3c78d30b | ||
|
|
7152308c25 | ||
|
|
cd838d4902 | ||
|
|
f7799eee59 | ||
|
|
247718bc6c | ||
|
|
6b5521fbf7 | ||
|
|
13e00379ae | ||
|
|
347663716c | ||
|
|
69415ea966 | ||
|
|
6c71e3c583 | ||
|
|
06861ceb55 | ||
|
|
6e286473ab | ||
|
|
6091219aaf | ||
|
|
76cee1287a | ||
|
|
ff138c6d47 | ||
|
|
a89f8b8098 | ||
|
|
f4009a9944 | ||
|
|
16b479d21e | ||
|
|
0f8c20c3ab | ||
|
|
d5c3b258f3 | ||
|
|
ee4a703407 | ||
|
|
e901208721 | ||
|
|
5deb7371ab | ||
|
|
f999195f47 | ||
|
|
9b920cf813 | ||
|
|
4155e8e0ce | ||
|
|
b583530c66 | ||
|
|
43c13c22a8 | ||
|
|
32167b45ce | ||
|
|
f09ae1e2e3 | ||
|
|
086e1e1a74 | ||
|
|
1020637d79 | ||
|
|
9c30d69d55 | ||
|
|
ff673f053b | ||
|
|
2514987d3e | ||
|
|
e332a916b0 | ||
|
|
5eb7faec29 | ||
|
|
8cfebee922 | ||
|
|
f4a22f8aef | ||
|
|
5fd641e8c7 | ||
|
|
4cde537a7f | ||
|
|
56ee4c1ae5 | ||
|
|
1874ad2ff2 | ||
|
|
907ed641bf | ||
|
|
a23ccd863d | ||
|
|
8d145d7a32 | ||
|
|
4a0419e554 | ||
|
|
f23a458319 | ||
|
|
1e324103cc | ||
|
|
85d8ced299 | ||
|
|
0631b8f052 | ||
|
|
649994464c | ||
|
|
8c618780b7 | ||
|
|
0dc2e8994b | ||
|
|
d25ab4f204 | ||
|
|
ff26080c5c | ||
|
|
95bd2dde19 | ||
|
|
6ad31a5441 | ||
|
|
702a82bb38 | ||
|
|
a5e91385b0 | ||
|
|
4c690b9d4c | ||
|
|
695d6e14d4 | ||
|
|
c19f87134e | ||
|
|
3de50e8dd4 | ||
|
|
fb20dae0a8 | ||
|
|
0f8db11f53 | ||
|
|
e3f94156f1 | ||
|
|
cf468fc4d1 | ||
|
|
849cf30b95 | ||
|
|
d08febc711 | ||
|
|
53bfafb84c | ||
|
|
40809e40c2 | ||
|
|
925197ae09 | ||
|
|
07f72de63d | ||
|
|
f17f62b532 | ||
|
|
b97bbe0572 | ||
|
|
9e4cc7fdbc | ||
|
|
7dcb56ea5c | ||
|
|
a814c6d152 | ||
|
|
cbe3a0fde7 | ||
|
|
7e375370fa | ||
|
|
1d149b100b | ||
|
|
1bce75ed53 | ||
|
|
d8a72fe797 | ||
|
|
5bd8319f99 | ||
|
|
d8221b880b | ||
|
|
1316ce5ca8 | ||
|
|
d5562767a2 | ||
|
|
1a03ee8b9b | ||
|
|
d07e53e9a0 | ||
|
|
04160e6acc | ||
|
|
6f4c7ca171 | ||
|
|
2d397efcf5 | ||
|
|
ba8e59e1bd | ||
|
|
568faa526f | ||
|
|
b761fbaabe | ||
|
|
4a493a96d7 | ||
|
|
601244ba74 | ||
|
|
d606197264 | ||
|
|
1fee10e167 | ||
|
|
674802abe4 | ||
|
|
179422a84b | ||
|
|
5c9e4685db | ||
|
|
c59f8c734a | ||
|
|
d2fa2be5af | ||
|
|
2d3d66e9d1 | ||
|
|
21713801ad | ||
|
|
598e2adebe | ||
|
|
8bbb84fdc7 | ||
|
|
59b7bc7b98 | ||
|
|
55d52be3c2 | ||
|
|
3aa4e45bdb | ||
|
|
534976e64f | ||
|
|
3efa9d2030 | ||
|
|
2c4657355f | ||
|
|
68702ca43f | ||
|
|
54a0de9b52 | ||
|
|
94832f3f81 | ||
|
|
fb00ba9efd | ||
|
|
96736cf1de | ||
|
|
834c55ec6f | ||
|
|
6528a434ce | ||
|
|
a24ee0a331 | ||
|
|
e86144bb06 | ||
|
|
ce7cb16cfe | ||
|
|
754bafc069 | ||
|
|
7eff6fde7c | ||
|
|
626dac600a | ||
|
|
f1b2d4340d | ||
|
|
aea4d73e61 | ||
|
|
3d6c74ead1 | ||
|
|
c606f80fe3 | ||
|
|
250ca36f05 | ||
|
|
4c63be066f | ||
|
|
b559eeb7e6 | ||
|
|
a9742dbdc6 | ||
|
|
5feaade1c7 | ||
|
|
31747dfecd | ||
|
|
eda9484413 | ||
|
|
7e904c1d15 | ||
|
|
5f8527ba04 | ||
|
|
082e95b700 | ||
|
|
aef5c61415 | ||
|
|
68fdac532f | ||
|
|
f718284538 | ||
|
|
966283dd6d | ||
|
|
0f3ec9ad73 | ||
|
|
cb685904ef | ||
|
|
5bf545ee90 | ||
|
|
b018ada5c8 | ||
|
|
976e81be43 | ||
|
|
694cb18256 | ||
|
|
a715a5fa37 | ||
|
|
1e10c9d508 | ||
|
|
2aacfea8ea | ||
|
|
43c2cb4ba8 | ||
|
|
c93f708bc8 | ||
|
|
353416a088 | ||
|
|
93b98abb8d | ||
|
|
5e28e38c98 | ||
|
|
0e828e5b3b | ||
|
|
c331d12678 | ||
|
|
f0817b2461 | ||
|
|
d3f2cd5321 | ||
|
|
7017766591 | ||
|
|
841890c178 | ||
|
|
4f5189b0dd | ||
|
|
250ecd13bd | ||
|
|
34133b094b | ||
|
|
75c3939c88 | ||
|
|
cb44430a3f | ||
|
|
be88b5aba2 | ||
|
|
3d0f7b8e7e | ||
|
|
a53d5dc791 | ||
|
|
7f1164b6a6 | ||
|
|
2174f10db5 | ||
|
|
e3c218092c | ||
|
|
cf73ba2905 | ||
|
|
d653b951e3 | ||
|
|
900c0eafac | ||
|
|
bf6eaaf625 | ||
|
|
32f3d214cb | ||
|
|
cd62b2a209 | ||
|
|
ff25b4cb46 | ||
|
|
5c07dd995e | ||
|
|
f54cc28a43 | ||
|
|
9b1c7bb1e3 | ||
|
|
ffe8a729b7 | ||
|
|
a47f356021 | ||
|
|
7d7a34c733 | ||
|
|
e306959ebe | ||
|
|
ce16c4d37f | ||
|
|
565cc05b48 | ||
|
|
287839e498 | ||
|
|
4be0969098 | ||
|
|
f1008b1abf | ||
|
|
8d8b3c2194 | ||
|
|
6631b57fc0 | ||
|
|
88b4bc3753 | ||
|
|
23a4dde10f | ||
|
|
5a47eb8559 | ||
|
|
81cd990052 | ||
|
|
dd9e7cf665 | ||
|
|
b2f50b5327 | ||
|
|
b21fe4b2fc | ||
|
|
5f23a3143c | ||
|
|
ef136c9d00 | ||
|
|
c7e8b724c7 | ||
|
|
0243e7ba8b | ||
|
|
b3f5375283 | ||
|
|
f90f683be5 | ||
|
|
bd23666b45 | ||
|
|
a620c2ec1a | ||
|
|
a723612141 | ||
|
|
2d7d4212c1 | ||
|
|
52cca034cf | ||
|
|
79ec1f5a02 | ||
|
|
68729a9696 | ||
|
|
93383204b3 | ||
|
|
78f17bd083 | ||
|
|
ea87006150 | ||
|
|
c0027c377b | ||
|
|
77b84c1de0 | ||
|
|
a14e2fedcf | ||
|
|
0341399e54 | ||
|
|
1dcf3585fb | ||
|
|
dbb48cf086 | ||
|
|
064c8adcf2 | ||
|
|
cff83e095a | ||
|
|
ff9aecca48 | ||
|
|
53c529a12c | ||
|
|
78454ba876 | ||
|
|
c3c1702d2b | ||
|
|
bffc777b58 | ||
|
|
fcec6a8fdf | ||
|
|
a842f25f89 | ||
|
|
9f2bea8ac1 | ||
|
|
7f9a2a2d34 | ||
|
|
3225f17f5a | ||
|
|
2f8b1dff27 | ||
|
|
7884f972ea | ||
|
|
bfce264537 | ||
|
|
dee5f4c96a | ||
|
|
6bd83137fb | ||
|
|
6c6c38679a | ||
|
|
ca0c700afa | ||
|
|
cc2e434f3d | ||
|
|
4d337f0bee | ||
|
|
539c10883b | ||
|
|
ae8796a570 | ||
|
|
141227d846 | ||
|
|
bb42b87f4e | ||
|
|
866d9dacb6 | ||
|
|
006e32077c | ||
|
|
0aca1c6c7c | ||
|
|
d906d56505 | ||
|
|
3b9ebf358c | ||
|
|
1c643cda5b | ||
|
|
e5697a8070 | ||
|
|
07f1a13cbf | ||
|
|
4c88f3ad64 | ||
|
|
c099d60393 | ||
|
|
5e0d48b40f | ||
|
|
c4f8e83d02 | ||
|
|
a768c1e6c0 | ||
|
|
540325dc20 | ||
|
|
2e57f76c12 | ||
|
|
e71fd6f8b4 | ||
|
|
c721721fc5 | ||
|
|
0ab5d6a7b8 | ||
|
|
66599e5770 | ||
|
|
d7c7463380 | ||
|
|
491a4468dc | ||
|
|
c85150aaea | ||
|
|
c7ba6d2a82 | ||
|
|
ace64cf50f | ||
|
|
cd6d4f6f47 | ||
|
|
1bdf74951a | ||
|
|
eda2b38f46 | ||
|
|
f14e85d6c4 | ||
|
|
76f668dddd | ||
|
|
ce01d696a0 | ||
|
|
8179a3a349 | ||
|
|
e5c397203e | ||
|
|
60aeba732d | ||
|
|
de70ef1ef6 | ||
|
|
1d02c288b3 | ||
|
|
3776920807 | ||
|
|
7d54cde8eb | ||
|
|
1bab2061bd | ||
|
|
34e30cba0d | ||
|
|
ed600c9077 | ||
|
|
30dc6d2b19 | ||
|
|
77c3b4636e | ||
|
|
25edcbaff9 | ||
|
|
553b8fb2e0 | ||
|
|
461b401e28 | ||
|
|
d2a4611d1e | ||
|
|
65c3dbba2c | ||
|
|
7ef0b5b428 | ||
|
|
89589d7ef5 | ||
|
|
70b782c7e7 | ||
|
|
9732b0a636 | ||
|
|
00acaa56b9 | ||
|
|
1cea2be9c1 | ||
|
|
94381bd899 | ||
|
|
23d935d7ec | ||
|
|
69da13b261 | ||
|
|
a6519e0ff7 | ||
|
|
b701a36e21 | ||
|
|
24a34088d8 | ||
|
|
0eeb092aad | ||
|
|
7d4726d12e | ||
|
|
e13bf164ea | ||
|
|
07434b19ae | ||
|
|
819fa88eb7 | ||
|
|
95976814f5 | ||
|
|
0a2dd2a330 | ||
|
|
65f125d998 | ||
|
|
7a2f6ebfd5 | ||
|
|
5d89fa3f07 | ||
|
|
4a66e28584 | ||
|
|
85990bbeb3 | ||
|
|
e0311e1530 | ||
|
|
6eb4dbf9cd | ||
|
|
a90453461e | ||
|
|
7e04c9a909 | ||
|
|
e51602ccfa | ||
|
|
ca7adb59db | ||
|
|
3a12802a4b | ||
|
|
c770eab3e3 | ||
|
|
079b8e7337 | ||
|
|
2e4593eee7 | ||
|
|
3ca80a7bf3 | ||
|
|
a4c15e5fa5 | ||
|
|
a40748e3aa | ||
|
|
029aac8059 | ||
|
|
2970f66218 | ||
|
|
ef238de7a7 | ||
|
|
af05313dc5 | ||
|
|
df0d1b57a0 | ||
|
|
23cff25ed5 | ||
|
|
c70b13a650 | ||
|
|
a51c6a7670 | ||
|
|
0bdb643e14 | ||
|
|
0cbbbf1287 | ||
|
|
9a00b62d28 | ||
|
|
05dce760d6 | ||
|
|
4eaf91c3dc | ||
|
|
818c3d6140 | ||
|
|
5e19cd0084 | ||
|
|
7b06257955 | ||
|
|
2af21c8003 | ||
|
|
db6f907946 | ||
|
|
125ed8bff2 | ||
|
|
1d0f2e9d31 | ||
|
|
43efc930f4 | ||
|
|
737e18d2de | ||
|
|
445445603f | ||
|
|
5957c94958 | ||
|
|
1c41661712 | ||
|
|
1b2909605e | ||
|
|
c6a13f970f | ||
|
|
f2f57dc5a5 | ||
|
|
c6de1ab56c | ||
|
|
0392e37eed | ||
|
|
f630c4ec6c | ||
|
|
e668642b23 | ||
|
|
c4c0c050af | ||
|
|
b4ff8360ba | ||
|
|
708a2ec703 | ||
|
|
407cb2f7e6 | ||
|
|
0b22e76b85 | ||
|
|
7671187160 | ||
|
|
5695e0e6b6 | ||
|
|
e22b2f00dc | ||
|
|
2a017c3a7c | ||
|
|
ce65c3113a | ||
|
|
65a2ebb8ad | ||
|
|
f0a542b154 | ||
|
|
dfe1c940bc | ||
|
|
3cd8708368 | ||
|
|
e677161e49 | ||
|
|
818c6711d8 | ||
|
|
f60cc76f3e | ||
|
|
685321fdc5 | ||
|
|
303215d42f | ||
|
|
f313752888 | ||
|
|
28b83a486e | ||
|
|
80289bd452 | ||
|
|
054be39feb | ||
|
|
6448e049d1 | ||
|
|
8e1f7c8d6f | ||
|
|
c4e31e7a58 | ||
|
|
0860d9712e | ||
|
|
1a17cbd26b | ||
|
|
c2b1d3b551 | ||
|
|
d4fac798fc | ||
|
|
b009b23245 | ||
|
|
f276f1e2f5 | ||
|
|
154e57748f | ||
|
|
6854fee73e | ||
|
|
24240bfba4 | ||
|
|
40e32daabe | ||
|
|
008cbc8972 | ||
|
|
8a1d2b614a | ||
|
|
b79d03d9a4 | ||
|
|
83fb9f84ed | ||
|
|
c634830b9f | ||
|
|
24edd68833 | ||
|
|
6913798250 | ||
|
|
131bd2c2cd | ||
|
|
55ae55c803 | ||
|
|
63f0eea70c | ||
|
|
38aeef0760 | ||
|
|
88d5f5d76c | ||
|
|
486ba5fe0a | ||
|
|
76f85389ae | ||
|
|
3d311496e0 | ||
|
|
fdbfe0f84b | ||
|
|
8a25592904 | ||
|
|
7edf024c71 | ||
|
|
ee4d9890e7 | ||
|
|
9cc06a94ec | ||
|
|
dd6dc1d334 | ||
|
|
fb2bafb49e | ||
|
|
bc3b8e73fe | ||
|
|
4d48441102 | ||
|
|
c0fa980f70 | ||
|
|
bb3bac9933 | ||
|
|
1ac5fa544b | ||
|
|
91bb4d4b00 | ||
|
|
aecdd0fdd5 | ||
|
|
2e5f3cd25c | ||
|
|
8558c55284 | ||
|
|
b16b49aea4 | ||
|
|
09678eeef4 | ||
|
|
fad43842a4 | ||
|
|
4b448a877c | ||
|
|
f090af2292 | ||
|
|
7faaac94dd | ||
|
|
dae0b25717 | ||
|
|
de3d9dca72 | ||
|
|
a91abb3e8d | ||
|
|
dabea8b972 | ||
|
|
dedffb3560 | ||
|
|
5eb2306e9a | ||
|
|
8a2e06a713 | ||
|
|
23b495aee8 | ||
|
|
b9d314e64c | ||
|
|
5a4826e660 | ||
|
|
20bf67d352 | ||
|
|
8b4f1e1383 | ||
|
|
20297e359d | ||
|
|
de7409fd07 | ||
|
|
8498f12a9d | ||
|
|
e949eb8623 | ||
|
|
201d17bc31 | ||
|
|
143e9bd210 | ||
|
|
9ec874d8a6 | ||
|
|
2543afebf1 | ||
|
|
81a859604c | ||
|
|
d3be4bba37 | ||
|
|
6779c9eb36 | ||
|
|
733da570c8 | ||
|
|
65258d5b6a | ||
|
|
618c8bb5ad | ||
|
|
ba8684dfc7 | ||
|
|
36a1bd9e0f | ||
|
|
fe56c1c6f2 | ||
|
|
86a37e6f8d | ||
|
|
da1aad7b92 | ||
|
|
876621f8af | ||
|
|
8a908b720f | ||
|
|
dadde52c40 | ||
|
|
369dd98cbe | ||
|
|
8cdd6cd131 | ||
|
|
973bc21f37 | ||
|
|
2ba327345d | ||
|
|
138ecc4ee1 | ||
|
|
5b9a8e9bf9 | ||
|
|
e520486892 | ||
|
|
ecb91613e8 | ||
|
|
d4ac76081e | ||
|
|
63727b67ee | ||
|
|
d969dcecbf | ||
|
|
49c9a202e0 | ||
|
|
512c8de526 | ||
|
|
012a929067 | ||
|
|
bec4e8d8e4 | ||
|
|
9f0993f29b | ||
|
|
1b79448ac2 | ||
|
|
6cef7d5060 | ||
|
|
752545ec0e | ||
|
|
adbebf7ecc | ||
|
|
4d57ac0ce1 | ||
|
|
24b77d9dcb | ||
|
|
cc0f431c35 | ||
|
|
1e7927fbff | ||
|
|
129e56e570 | ||
|
|
5beef690ad | ||
|
|
b0383b0978 | ||
|
|
16c6a11b77 | ||
|
|
9117b13576 | ||
|
|
af55978918 | ||
|
|
0446a1b3a8 | ||
|
|
3986dd4c32 | ||
|
|
79afa16a7f | ||
|
|
087ed0aa6a | ||
|
|
44fa3d2d07 | ||
|
|
8654d83a33 | ||
|
|
efb78c823c | ||
|
|
3bb7f0c291 | ||
|
|
62e0db7c9b | ||
|
|
130695fcb3 | ||
|
|
05fa301ecb | ||
|
|
ee90f730b5 | ||
|
|
7b8a23453f | ||
|
|
cb44479420 | ||
|
|
afb3806326 | ||
|
|
d96bfd21b7 | ||
|
|
bbc3100bb3 | ||
|
|
ac1bb2a6bd | ||
|
|
41ef391d15 | ||
|
|
e51aa5899a | ||
|
|
38bb975abd | ||
|
|
a249b315ca | ||
|
|
eba85e1ec3 | ||
|
|
c1c92256ea | ||
|
|
58ce97c0b4 | ||
|
|
ca58bab1f0 | ||
|
|
052c484abd | ||
|
|
7a213c9d6f | ||
|
|
f4de7422b3 | ||
|
|
a3d18d0429 | ||
|
|
77fbffdc4b | ||
|
|
63ea01104b | ||
|
|
cad0f1f396 | ||
|
|
677fb93494 | ||
|
|
55cbb12701 | ||
|
|
14099813f0 | ||
|
|
b1fd4e853c | ||
|
|
c1d3fc1b78 | ||
|
|
829980a941 | ||
|
|
d1e1a90d08 | ||
|
|
d56de091f6 | ||
|
|
87bb926fef | ||
|
|
e983f93859 | ||
|
|
c721acc2fa | ||
|
|
16fd4c83ac | ||
|
|
999dfb84ee | ||
|
|
c6557e5078 | ||
|
|
f7aab02978 | ||
|
|
fdcd67dd6b | ||
|
|
6c611d71dd | ||
|
|
b7e2396269 | ||
|
|
ab62875ab1 | ||
|
|
a499fdbb13 | ||
|
|
bf2f0c38ed | ||
|
|
b14c05ccae | ||
|
|
66e7cd41b7 | ||
|
|
e9a15d9189 | ||
|
|
e4aee13e9e | ||
|
|
551f9fcdf9 | ||
|
|
2ec5e948b4 | ||
|
|
60b7f504e6 | ||
|
|
f99668f551 | ||
|
|
8ade41b270 | ||
|
|
a36a5363b4 | ||
|
|
cb22fb54e8 | ||
|
|
1dcfdfdb65 | ||
|
|
d309eb8fa1 | ||
|
|
16dfdbe314 | ||
|
|
b926ed7b00 | ||
|
|
67a6b88104 | ||
|
|
631699bf80 | ||
|
|
80801bf7d0 | ||
|
|
4850a033fa | ||
|
|
0b4029f7a1 | ||
|
|
c07ef0d92a | ||
|
|
ca48c5ddff | ||
|
|
a20c362983 | ||
|
|
7beb204b9d | ||
|
|
3e4f9451a0 | ||
|
|
6e5846d206 | ||
|
|
5965591934 | ||
|
|
78f8a03da5 | ||
|
|
4d10584233 | ||
|
|
106fa64060 | ||
|
|
95be8b2cf3 | ||
|
|
53d7c6c085 | ||
|
|
e4df75519c | ||
|
|
0438fa6816 | ||
|
|
2dab4ccf85 | ||
|
|
b338e76649 | ||
|
|
c737ab764e | ||
|
|
990e73fce6 | ||
|
|
99fac3ae1c | ||
|
|
ad0bcc7de9 | ||
|
|
8069853dda | ||
|
|
14ed669eba | ||
|
|
9ff5fa4acf | ||
|
|
d026024e8c | ||
|
|
25d1491e6b | ||
|
|
4e1415faf2 | ||
|
|
692f64a78a | ||
|
|
b20b8af5a6 | ||
|
|
d34cf636d8 | ||
|
|
3c72ea40b4 | ||
|
|
f87c7833a3 | ||
|
|
f3931140fe | ||
|
|
8459117c23 | ||
|
|
bbc0c97329 | ||
|
|
1d8b152758 | ||
|
|
1c4652448c | ||
|
|
3a34e606b8 | ||
|
|
ca55748103 | ||
|
|
43fa199cfa | ||
|
|
f288ca23ae | ||
|
|
4026714461 | ||
|
|
39a8652708 | ||
|
|
fb432465ea | ||
|
|
42bccfe1ec | ||
|
|
98566150d2 | ||
|
|
676e1705c1 | ||
|
|
172cc1ffea | ||
|
|
6845a52e92 | ||
|
|
b5dc89f0e6 | ||
|
|
ecaea51fe0 | ||
|
|
77baf08092 | ||
|
|
63ff5a2fe3 | ||
|
|
97662f4b3e | ||
|
|
38869d5035 | ||
|
|
08047d4ab7 | ||
|
|
cf33853e68 | ||
|
|
768e618ed9 | ||
|
|
025ed51f11 | ||
|
|
ab9dae3bf3 | ||
|
|
74da5dfd4b | ||
|
|
aaaf452fdc | ||
|
|
d2b97d8aea | ||
|
|
8b95216493 | ||
|
|
f933fa8c78 | ||
|
|
f955309139 | ||
|
|
9c65a82430 | ||
|
|
7b4dda9c73 | ||
|
|
9ad7d2d977 | ||
|
|
e3b4b2f667 | ||
|
|
60a1374fb4 | ||
|
|
7fcbc3c003 | ||
|
|
40421f4321 | ||
|
|
ad2683b610 | ||
|
|
7d49699e5f | ||
|
|
b34a239096 | ||
|
|
02d1251fe4 | ||
|
|
95e58ebb9f | ||
|
|
1cb2704f1b | ||
|
|
dea71f1aa9 | ||
|
|
aee975b7d8 | ||
|
|
18b6d51644 | ||
|
|
3a5ff851af | ||
|
|
cd929345e6 | ||
|
|
de232dd726 | ||
|
|
8ebe99d4f5 | ||
|
|
32f760a461 | ||
|
|
65eaab5cf4 | ||
|
|
51698944e0 | ||
|
|
64fc924357 | ||
|
|
c61a0cdd22 | ||
|
|
9a1de81fc5 | ||
|
|
3633d3cd73 | ||
|
|
9a0465eb05 | ||
|
|
088e199aa2 | ||
|
|
bc4c043d7e | ||
|
|
764299ea8a | ||
|
|
2abc87a1f2 | ||
|
|
75fa116c88 | ||
|
|
cc7575adab | ||
|
|
efb1a2c8e0 | ||
|
|
c2972fcaa0 | ||
|
|
250fd71e16 | ||
|
|
783c165201 | ||
|
|
326a3c5932 | ||
|
|
0af1a85442 | ||
|
|
10e7bb97ee | ||
|
|
c319bbc5f3 | ||
|
|
9e42f70e5f | ||
|
|
ff47152187 | ||
|
|
94b6ce5ca0 | ||
|
|
8e1020f134 | ||
|
|
be7a0fef41 | ||
|
|
9fe7bb7362 | ||
|
|
5d4b121ac1 | ||
|
|
cb424a5f78 | ||
|
|
88ab9d0756 | ||
|
|
29f4fd40ed | ||
|
|
b7f7ba06b9 | ||
|
|
94f8ac8d1d | ||
|
|
72ab38bd2f | ||
|
|
b3d5466131 | ||
|
|
bafbd8f1b6 | ||
|
|
8c1ce03183 | ||
|
|
97490b272f | ||
|
|
2afbe9514b | ||
|
|
603be609a1 | ||
|
|
4590be7b65 | ||
|
|
097a2f6582 | ||
|
|
f818e5bc51 | ||
|
|
34cf8fc43c | ||
|
|
7712765c3a | ||
|
|
eaf1304eda | ||
|
|
f97f32df0f | ||
|
|
79eecd6db4 | ||
|
|
5a75d8e788 | ||
|
|
42e58fb73a | ||
|
|
dba996b2c4 | ||
|
|
647f0dd34b | ||
|
|
a691a519e8 | ||
|
|
86075973b5 | ||
|
|
97ea15300c | ||
|
|
a150a8fd52 | ||
|
|
ad4e20da52 | ||
|
|
e43ab1e46f | ||
|
|
e32e280cf1 | ||
|
|
c1a07e0943 | ||
|
|
93fe641dbf | ||
|
|
d8194c0886 | ||
|
|
75ce4766d3 | ||
|
|
7eff3bf854 | ||
|
|
af143ae7dc | ||
|
|
a0e9140dde | ||
|
|
33e5d46c87 | ||
|
|
f74b206864 | ||
|
|
f334ebe577 | ||
|
|
9c39394d7f | ||
|
|
8ea0e6977a | ||
|
|
bf006473c0 | ||
|
|
568af27be4 | ||
|
|
bd55f86203 | ||
|
|
d95e577639 | ||
|
|
a904e54122 | ||
|
|
2a97655a8d | ||
|
|
d878718510 | ||
|
|
416227a2a2 | ||
|
|
7d1baa8798 | ||
|
|
fe2ee64ec9 | ||
|
|
96819628d6 | ||
|
|
1b30d7909c | ||
|
|
baf253d44e | ||
|
|
b7a4d50007 | ||
|
|
625b4befb5 | ||
|
|
30678f51bd | ||
|
|
7a4103dd48 | ||
|
|
bca3ff2eac | ||
|
|
28e2934a89 | ||
|
|
0563af682d | ||
|
|
5ccd63250b | ||
|
|
f262a0745d | ||
|
|
c42b63b008 | ||
|
|
e7ffb80877 | ||
|
|
919166212f | ||
|
|
deb124f645 | ||
|
|
86b1ff5125 | ||
|
|
2c8c96149f | ||
|
|
82e4cc9951 | ||
|
|
04df06404f | ||
|
|
f6fcf5fce4 | ||
|
|
ac5e92c879 | ||
|
|
37ccc80ba4 | ||
|
|
8153f97899 | ||
|
|
8dedc6d3dc | ||
|
|
807d75e13a | ||
|
|
feac1786e1 | ||
|
|
09e0f4e36c | ||
|
|
9999332107 | ||
|
|
d4ec7e5357 | ||
|
|
064b3caf08 | ||
|
|
c83d2e9513 | ||
|
|
48ff516215 | ||
|
|
cdccbb59ab | ||
|
|
2fe5a863ac | ||
|
|
7d1fccf474 | ||
|
|
0a8dbc8831 | ||
|
|
177a3c2cbd | ||
|
|
9f22e634f5 | ||
|
|
55a8c7b540 | ||
|
|
76c11fe65a | ||
|
|
b15ed00feb | ||
|
|
fc3ff34c2d | ||
|
|
5faa0f55bc | ||
|
|
77f0731c3e | ||
|
|
ffff623852 | ||
|
|
a6bc40b506 | ||
|
|
a034515019 | ||
|
|
49c8f23bf7 | ||
|
|
29b7a71812 | ||
|
|
8de3283dd1 | ||
|
|
4bbe5b3358 | ||
|
|
3dd3af4a73 | ||
|
|
7e7b129822 | ||
|
|
8bcc1d81d2 | ||
|
|
aa8e92e9a5 | ||
|
|
a8196ec99e | ||
|
|
bd3034819e | ||
|
|
7bb86c4e2a | ||
|
|
94ed21d1cf | ||
|
|
1bb7c31ee4 | ||
|
|
06d12b376c | ||
|
|
e9c8137fd8 | ||
|
|
eaaddf40d2 | ||
|
|
3e0c565019 | ||
|
|
984603112f | ||
|
|
fe29246256 | ||
|
|
84d0664112 | ||
|
|
3d3c59cea6 | ||
|
|
7940428b9b | ||
|
|
2e485b9ac5 | ||
|
|
b76aa926f6 | ||
|
|
58d81546da | ||
|
|
7a480990c6 | ||
|
|
afb10efd83 | ||
|
|
e2f05e137f | ||
|
|
d72ade9c70 | ||
|
|
64650fcdee | ||
|
|
e1acb7df13 | ||
|
|
319a30cf3a | ||
|
|
e631f1b313 | ||
|
|
617f31b47f | ||
|
|
61e9aac92d | ||
|
|
75812804f4 | ||
|
|
b60f36f211 | ||
|
|
e342c878d0 | ||
|
|
c6b3cadf55 | ||
|
|
869a361d09 | ||
|
|
f83119e188 | ||
|
|
578c4b444c | ||
|
|
d63f9be03f | ||
|
|
62fe02415a | ||
|
|
481970c763 | ||
|
|
7c8dc66ba1 | ||
|
|
20ffbf5a82 | ||
|
|
2b6f26b214 | ||
|
|
d743ec2d2b | ||
|
|
dfab332285 | ||
|
|
bbbce8a981 | ||
|
|
0dc4ccb42f | ||
|
|
b46c2c2527 | ||
|
|
3b128f844b | ||
|
|
d38b3d09ba | ||
|
|
d35c5ffa04 | ||
|
|
eb7243233e | ||
|
|
21bf629505 | ||
|
|
702022001d | ||
|
|
d9549ad634 | ||
|
|
daf91dbf95 | ||
|
|
2bc19120d9 | ||
|
|
8ddfa8cd68 | ||
|
|
076d10358e | ||
|
|
5930983641 | ||
|
|
a0c5cb51aa | ||
|
|
8e659745fd | ||
|
|
87297d2a07 | ||
|
|
8f23611f1a | ||
|
|
e2affb0f38 | ||
|
|
26e6041b7a | ||
|
|
81707a45d5 | ||
|
|
805f2b28a9 | ||
|
|
22aa02895e | ||
|
|
6bb89778b2 | ||
|
|
6631b9e78f | ||
|
|
7f7d5b32da | ||
|
|
52def444ab | ||
|
|
7d52ab7c54 | ||
|
|
852b324819 | ||
|
|
e019441ede | ||
|
|
ac8f8d0dd6 | ||
|
|
3fa2e7e12e | ||
|
|
5d099491df | ||
|
|
d7ca0f7734 | ||
|
|
5d31338b02 | ||
|
|
a44b81d240 | ||
|
|
742e499de0 | ||
|
|
eb395d6d2d | ||
|
|
a1383c34b5 | ||
|
|
e538da3959 | ||
|
|
687a072dc8 | ||
|
|
5dc9881241 | ||
|
|
0b3a7e2f0f | ||
|
|
123455a5bb | ||
|
|
34c8d8dd2e | ||
|
|
3f4c92d739 | ||
|
|
eb10245df1 | ||
|
|
2dbfcbb378 | ||
|
|
a717f5c030 | ||
|
|
3a711790c5 | ||
|
|
5d77cb0396 | ||
|
|
9972ea578b | ||
|
|
0bb3762397 | ||
|
|
fbd6e21152 | ||
|
|
bea62537df | ||
|
|
fdbe4c5bd5 | ||
|
|
91e779a52c | ||
|
|
e2c5e92cd3 | ||
|
|
5929676ea2 | ||
|
|
36e180ab91 | ||
|
|
1e8fe22553 | ||
|
|
8e1bd2d8f3 | ||
|
|
239ce262ef | ||
|
|
5be66e98c2 | ||
|
|
cacd072c15 | ||
|
|
14c6a1bf23 | ||
|
|
b27dfd4c77 | ||
|
|
4622e9658d | ||
|
|
f8bda517c3 | ||
|
|
de3d9fdb8b | ||
|
|
c6291bea52 | ||
|
|
a266e3c898 | ||
|
|
f9c34d6808 | ||
|
|
10a91cac2f | ||
|
|
f7e25e9c63 | ||
|
|
5f821a58a3 | ||
|
|
4a2ad4e6f9 | ||
|
|
4a2bbb52c1 | ||
|
|
ed401199bd | ||
|
|
eee3a263f5 | ||
|
|
eca1d9aabd | ||
|
|
33ff9cfbb6 | ||
|
|
de8e6d7174 | ||
|
|
cd9332cddf | ||
|
|
fb4a861c0d | ||
|
|
c30460df4c | ||
|
|
31e86a36f8 | ||
|
|
0b4fe85b33 | ||
|
|
99e7a1705a | ||
|
|
27c6259b53 | ||
|
|
1ecae14bae | ||
|
|
c56a09f318 | ||
|
|
ffec2699ea | ||
|
|
46faf0280c | ||
|
|
3b774ed507 | ||
|
|
9c62bbbc05 | ||
|
|
dc6b1ef47b | ||
|
|
1f8e1d2a29 | ||
|
|
b30a948601 | ||
|
|
e90568e044 | ||
|
|
c74b5ba3a2 | ||
|
|
2085d6afad | ||
|
|
8bfdbd0fed | ||
|
|
cc3dc6aff0 | ||
|
|
d01284d147 | ||
|
|
7b7d5118d6 | ||
|
|
a03a7dcb4a | ||
|
|
dfae413afc | ||
|
|
253642a85e | ||
|
|
ce64c8e7d1 | ||
|
|
d7ae0105c3 | ||
|
|
e7320e7bd3 | ||
|
|
a214565803 | ||
|
|
61f1290bea | ||
|
|
ba5e512d10 | ||
|
|
624e4bca40 | ||
|
|
613237727d | ||
|
|
fd2ddca6f2 | ||
|
|
e114c18031 | ||
|
|
49e22742de | ||
|
|
422d7942ef | ||
|
|
a63e7162bc | ||
|
|
1f973b72b8 | ||
|
|
d3dd97f167 | ||
|
|
f0f17e0041 | ||
|
|
d6fa8bf233 | ||
|
|
ec5e685a1c | ||
|
|
c88b95751c | ||
|
|
72ae25bc53 | ||
|
|
02e5cc1da8 | ||
|
|
3d092df56d | ||
|
|
912d5c700c | ||
|
|
6d3c492518 | ||
|
|
5e29e3f1cb | ||
|
|
0558495760 | ||
|
|
0471dfa2f8 | ||
|
|
7883e6544e | ||
|
|
6da87e4a79 | ||
|
|
bafe4fff93 | ||
|
|
da782398a2 | ||
|
|
4b26b46f6a | ||
|
|
0f1e69a2df | ||
|
|
85f2bd464c | ||
|
|
8a4956b736 | ||
|
|
4a369af4c7 | ||
|
|
9749305ecd | ||
|
|
639178dbdc | ||
|
|
62d038b547 | ||
|
|
9b80e3a33b | ||
|
|
0ea54f0458 | ||
|
|
374c52f71f | ||
|
|
60f63e125a | ||
|
|
7cfa7f3de4 | ||
|
|
92409831c2 | ||
|
|
e04790a628 | ||
|
|
cd7bf40508 | ||
|
|
dc378e9ce7 | ||
|
|
5fcdcec1a8 | ||
|
|
8773704c8b | ||
|
|
291fd1857e | ||
|
|
0aa4aeaddc | ||
|
|
ca81f1b2e8 | ||
|
|
fca3a14410 | ||
|
|
d105e80ed8 | ||
|
|
ce63faa597 | ||
|
|
25c1b63a00 | ||
|
|
548728abba | ||
|
|
2ebdbd565a | ||
|
|
86376616ff | ||
|
|
7c6865f948 | ||
|
|
c2da0070f5 | ||
|
|
bf2a2aed66 | ||
|
|
403ea0a0e1 | ||
|
|
27976cbe1a | ||
|
|
70147396a4 | ||
|
|
d6aed16e7c | ||
|
|
0414bae820 | ||
|
|
620866bc39 | ||
|
|
55f080e33f | ||
|
|
9f2b1b03d7 | ||
|
|
c0a0f3aaf5 | ||
|
|
7726b5c56b | ||
|
|
3daff8ab8a | ||
|
|
428c2097c7 | ||
|
|
7786583ecf | ||
|
|
9b79ea7d30 | ||
|
|
3dc8436362 | ||
|
|
9f1f2a4845 | ||
|
|
40204e8133 | ||
|
|
133b1067c5 | ||
|
|
5c8287203e | ||
|
|
061bbb1914 | ||
|
|
572168ef20 | ||
|
|
1aa27f2da3 | ||
|
|
be76614c90 | ||
|
|
e26d355fb7 | ||
|
|
d8dbcef5dd | ||
|
|
5d6a6590bf | ||
|
|
7dfdfe5b50 | ||
|
|
36fcc460f4 | ||
|
|
24b03d42d6 | ||
|
|
60275d3637 | ||
|
|
9b5b471802 | ||
|
|
1edb96f526 | ||
|
|
f949bdcfe4 | ||
|
|
21a45a940e | ||
|
|
fb61dfd39d | ||
|
|
9b5940505b | ||
|
|
8c07a67fe9 | ||
|
|
0f9687ce62 | ||
|
|
1460e46d1f | ||
|
|
692521c49d | ||
|
|
2f1d8cc196 | ||
|
|
eeabb47fb6 | ||
|
|
e078f584eb | ||
|
|
f86322545a | ||
|
|
720e19a01f | ||
|
|
3560fed86e | ||
|
|
5f8f5a9f85 | ||
|
|
1aae24b831 | ||
|
|
b544b1c3d4 | ||
|
|
f462f87183 | ||
|
|
6ed7ef25b2 | ||
|
|
bc79d09f2d | ||
|
|
5b2becb87f | ||
|
|
cd808fb5a5 | ||
|
|
c8a4e40bcf | ||
|
|
911b6c9679 | ||
|
|
03041f87c3 | ||
|
|
360c53d6ca | ||
|
|
3f1d555c71 | ||
|
|
ae1d72265c | ||
|
|
9570c65d88 | ||
|
|
3e0b04509a | ||
|
|
0884379e0b | ||
|
|
ec16532028 | ||
|
|
c8f13544a8 | ||
|
|
44bfe55413 | ||
|
|
b95c1adc86 | ||
|
|
b3a94c26d9 | ||
|
|
159c7238a8 | ||
|
|
70f40bab1d | ||
|
|
6c1a9dc14b | ||
|
|
816381a6a8 | ||
|
|
dd84bca638 | ||
|
|
a5d2019a39 | ||
|
|
26cee564c9 | ||
|
|
316b8a1375 | ||
|
|
618b25df08 | ||
|
|
8f9c4cd217 | ||
|
|
c6e2e33e87 | ||
|
|
db605ea7ca | ||
|
|
a1507d4844 | ||
|
|
c6340a64fe | ||
|
|
265b440c37 | ||
|
|
ea8e6d978d | ||
|
|
c3f5bc6bfb | ||
|
|
e322f6dbe2 | ||
|
|
83059a013c | ||
|
|
e374392450 | ||
|
|
72d505b2f1 | ||
|
|
a11bff0c7b | ||
|
|
a820ee4c82 | ||
|
|
a18be78bd3 | ||
|
|
83b5806cec | ||
|
|
4d7a1199ea | ||
|
|
d47cac563a | ||
|
|
2969290c63 | ||
|
|
277557cd99 | ||
|
|
21db7d438b | ||
|
|
61ff2da15c | ||
|
|
ad8296a535 | ||
|
|
aec3318f4c | ||
|
|
3297c3a2e2 | ||
|
|
84759de36f | ||
|
|
a562126f2f | ||
|
|
1901134601 | ||
|
|
eecb6986ee | ||
|
|
508cada017 | ||
|
|
2abae2f21a | ||
|
|
82c17dbde2 | ||
|
|
425499b3aa | ||
|
|
96605766bb | ||
|
|
161012b0a7 | ||
|
|
0669a053db | ||
|
|
ab66e77740 | ||
|
|
381cd53551 | ||
|
|
1f0e92a752 | ||
|
|
98b3496717 | ||
|
|
4200e2e4e4 | ||
|
|
e239ae1aba | ||
|
|
2acfc307b7 | ||
|
|
186f1cf714 | ||
|
|
a5cf42b7c8 | ||
|
|
fd7dba8860 | ||
|
|
32d7e365d2 | ||
|
|
1078cc1c91 | ||
|
|
c97fc370cd | ||
|
|
fca8da118e | ||
|
|
dda56405e6 | ||
|
|
f0f23d491c | ||
|
|
44c10d720a | ||
|
|
690e5a7f9c | ||
|
|
e4fdbc3cb4 | ||
|
|
fe2b86ba83 | ||
|
|
8fb9557520 | ||
|
|
25c91b398a | ||
|
|
8a524dd98f | ||
|
|
7371f8927c | ||
|
|
3d4f58d564 | ||
|
|
f0e32c88ec | ||
|
|
5ae3eccaf1 | ||
|
|
093f12254f | ||
|
|
3a8afe2969 | ||
|
|
fff5ae97f2 | ||
|
|
3c626e3ea5 | ||
|
|
26f57141a1 | ||
|
|
419aa9dcba | ||
|
|
3f15456b9c | ||
|
|
f67a2fa865 | ||
|
|
0f6de542bf | ||
|
|
1a529841e0 | ||
|
|
a9bf6a0e3b | ||
|
|
76dcd7d96e | ||
|
|
6aa1361b1a | ||
|
|
f623a4ecef | ||
|
|
aa465a12aa | ||
|
|
81ba623423 | ||
|
|
4f6f6cca0f | ||
|
|
56346f2a52 | ||
|
|
edcd3f5145 | ||
|
|
7acd3d5297 | ||
|
|
1732c16778 | ||
|
|
913d440c61 | ||
|
|
8cdb4d48f2 | ||
|
|
907ac05c00 | ||
|
|
067558529c | ||
|
|
c97e653ba1 | ||
|
|
9a935ba90c | ||
|
|
134ed51517 | ||
|
|
993dd84af9 | ||
|
|
28e3ab73fa | ||
|
|
70a5efa1d6 | ||
|
|
a51a355a53 | ||
|
|
fdd0a33571 | ||
|
|
6547d03b91 | ||
|
|
cc0c2f1b3c | ||
|
|
c80c59c692 | ||
|
|
10de191dd5 | ||
|
|
1626cec089 | ||
|
|
0404776d87 | ||
|
|
4398fca1bd | ||
|
|
e94ca12f9f | ||
|
|
036c2f6a1c | ||
|
|
611304e257 | ||
|
|
cf26447f7c | ||
|
|
e5b8e04dde | ||
|
|
bb201e6ca4 | ||
|
|
bb58d633c0 | ||
|
|
56ff8755d4 | ||
|
|
57fc027f77 | ||
|
|
bdb7c226f1 | ||
|
|
17e32017a7 | ||
|
|
2c772d0f4c | ||
|
|
769ff84a65 | ||
|
|
fd1fbd4843 | ||
|
|
eaa9430e26 | ||
|
|
2e5de88445 | ||
|
|
b4b9910203 | ||
|
|
afeeadd665 | ||
|
|
fcbeb10159 | ||
|
|
65227f601e | ||
|
|
56ae4dcd12 | ||
|
|
2b2c8e6b82 | ||
|
|
49c032315c | ||
|
|
15109f801e | ||
|
|
3de0a16a9d | ||
|
|
bb49b0c16a | ||
|
|
9561414985 | ||
|
|
db7354ab72 | ||
|
|
34396dbbec | ||
|
|
d842a2f62e | ||
|
|
a17c32bed0 | ||
|
|
fab0b91a79 | ||
|
|
88974d552d | ||
|
|
b90a38ce8b | ||
|
|
b3df27c362 | ||
|
|
854ea26ab7 | ||
|
|
e385b3499b | ||
|
|
77d323b38c | ||
|
|
64eeb091b8 | ||
|
|
65f5f8e8e2 | ||
|
|
6b3ee1aaaf | ||
|
|
27ca48c6bb | ||
|
|
2786c776e3 | ||
|
|
23cd5b906b | ||
|
|
0f9d20129d | ||
|
|
4649bd3906 | ||
|
|
3048ac2f6d | ||
|
|
8679377fcf | ||
|
|
db5264af3c | ||
|
|
059fbb9e5d | ||
|
|
01303c1e31 | ||
|
|
a8aaa793a0 | ||
|
|
c5698e82da | ||
|
|
ec12f7a5e7 | ||
|
|
b87fec554f | ||
|
|
740981376d | ||
|
|
8694364aa3 | ||
|
|
f1b1fee6e4 | ||
|
|
915596b23e | ||
|
|
6d65cb77ec | ||
|
|
51e2f8e49b | ||
|
|
0a7fc356b6 | ||
|
|
ff0f05a1c1 | ||
|
|
0ea9362d06 | ||
|
|
9d3932bd82 | ||
|
|
8c787fa7f7 | ||
|
|
2508e71324 | ||
|
|
b2f4f96ef9 | ||
|
|
fdae297fca | ||
|
|
36488fd836 | ||
|
|
ee01c944b4 | ||
|
|
d7f4f392d2 | ||
|
|
1756093618 | ||
|
|
1734c6e6bf | ||
|
|
839f345fa3 | ||
|
|
d69b5385e4 | ||
|
|
eb6b5755e7 | ||
|
|
9c65d9f957 | ||
|
|
cfa187f7d9 | ||
|
|
30d0fbeae6 | ||
|
|
9b21656314 | ||
|
|
b1b06a38af | ||
|
|
d2fffe5b88 | ||
|
|
09d560888e | ||
|
|
fa28326ed6 | ||
|
|
9ea4a6b7b6 | ||
|
|
ffa6fafcc1 | ||
|
|
4be5b80ff6 | ||
|
|
5028b07aaa | ||
|
|
7ce5dcdead | ||
|
|
7d8571b0e1 | ||
|
|
fca2fe2c8a | ||
|
|
75576577e0 | ||
|
|
eafc46f6c4 | ||
|
|
c0c36d3338 | ||
|
|
6a73b0820e | ||
|
|
bcb5eda7d8 | ||
|
|
2c833b5028 | ||
|
|
6821603980 | ||
|
|
8bec45cd58 | ||
|
|
ce0f44fb47 | ||
|
|
c740562dd8 | ||
|
|
63a1c8b63e | ||
|
|
112cdb4842 | ||
|
|
2d5f045c29 | ||
|
|
c43ff29f5d | ||
|
|
4c0e3c4db9 | ||
|
|
7995a57f77 | ||
|
|
0a47378f7f | ||
|
|
8e9a244cdd | ||
|
|
5f1a4ea08d | ||
|
|
034b19d85d | ||
|
|
68cb7ea471 | ||
|
|
d9a3ba0dd1 | ||
|
|
663e1d8336 | ||
|
|
31332f4f53 | ||
|
|
cb7163dd19 | ||
|
|
946029a3f7 | ||
|
|
69cbb6e109 | ||
|
|
6054f6bfe1 | ||
|
|
ae7b9f5fcb | ||
|
|
68dc6b9527 | ||
|
|
292cdfd5a0 | ||
|
|
28e2dee605 | ||
|
|
6d79ab2552 | ||
|
|
da17e424ea | ||
|
|
028c25afd3 | ||
|
|
9c2151dc37 | ||
|
|
9e9bd16b18 | ||
|
|
3f138aec22 | ||
|
|
e9f66e7c89 | ||
|
|
6be64b363c | ||
|
|
51230f21f5 | ||
|
|
e12540ba66 | ||
|
|
a6b1bee2af | ||
|
|
6187cdafe3 | ||
|
|
880f785d04 | ||
|
|
5aedcfd6a7 | ||
|
|
6ff1a2c236 | ||
|
|
317f888383 | ||
|
|
33f1f9abde | ||
|
|
913406b568 | ||
|
|
6a74d102a4 | ||
|
|
e9e36cebcb | ||
|
|
af6bf7a232 | ||
|
|
5720a7a5e3 | ||
|
|
449c946423 | ||
|
|
54a2a0da48 | ||
|
|
e209fedb27 | ||
|
|
12494f3008 | ||
|
|
7f60b46488 | ||
|
|
1c9ecd96d4 | ||
|
|
1f84803b91 | ||
|
|
3f6116f28f | ||
|
|
4ea0eb94d4 | ||
|
|
e222bc631a | ||
|
|
9c07c7fe4f | ||
|
|
35d74e18de | ||
|
|
266be2c25f | ||
|
|
b7cb090144 | ||
|
|
30e257bc2b | ||
|
|
fbd5679fb1 | ||
|
|
9db7234f24 | ||
|
|
220b2dc912 | ||
|
|
83c2420038 | ||
|
|
73913f450b | ||
|
|
bb966e7e6f | ||
|
|
b4adc127a4 | ||
|
|
2bc343b524 | ||
|
|
1f4d6eb0df | ||
|
|
ee936fe1a1 | ||
|
|
f6d9239b37 | ||
|
|
512e5b0240 | ||
|
|
600148f501 | ||
|
|
8791a4f696 | ||
|
|
ef40a8a925 | ||
|
|
2473e87947 | ||
|
|
bbe1dfb53d | ||
|
|
3bc27b1a02 | ||
|
|
ec4c6e140b | ||
|
|
545cc1074c | ||
|
|
9c0f4822bc | ||
|
|
5040ec109b | ||
|
|
25b216d7ef | ||
|
|
e475c847d7 | ||
|
|
e7c55c1ad6 | ||
|
|
cd8fcadd29 | ||
|
|
f78b6b30d9 | ||
|
|
cc6a991464 | ||
|
|
81d487dd89 | ||
|
|
af2795c07f | ||
|
|
178d9fb8d5 | ||
|
|
9bd12eb782 | ||
|
|
ef66650997 | ||
|
|
fcffcdde1b | ||
|
|
7de892ccac | ||
|
|
f90f2e051a | ||
|
|
24f49c8d83 | ||
|
|
a4ebaf15ab | ||
|
|
54a46dccc3 | ||
|
|
9747d5057d | ||
|
|
7f5c97d0be | ||
|
|
1933a76631 | ||
|
|
c20d7f9754 | ||
|
|
6b46dc7e89 | ||
|
|
0c1a26170c | ||
|
|
244ee08d7d | ||
|
|
a3acbca24b | ||
|
|
d77e4ed581 | ||
|
|
b928abb956 | ||
|
|
a46ef8d1a6 | ||
|
|
a5d459749f | ||
|
|
7dfa383968 | ||
|
|
036483d195 | ||
|
|
2c950f74bc | ||
|
|
2c59dcd929 | ||
|
|
658d14f31d | ||
|
|
819f4d2151 | ||
|
|
9b214d75df | ||
|
|
e0891a2d71 | ||
|
|
34a4876761 | ||
|
|
13ead0085d | ||
|
|
9e63270fc5 | ||
|
|
eccab3cd57 | ||
|
|
6446daf1a6 | ||
|
|
821602ef1c | ||
|
|
dc3512de9f | ||
|
|
36e9cb7108 | ||
|
|
42f4531720 | ||
|
|
d1fb379a40 | ||
|
|
e27bdb965c | ||
|
|
54fc6df3da | ||
|
|
9dd8f62c8a | ||
|
|
1db19148e7 | ||
|
|
93a01506e4 | ||
|
|
4767ed790c | ||
|
|
e39211347c | ||
|
|
a8cdbb65fe | ||
|
|
ff74ff4149 | ||
|
|
96e47f3d27 | ||
|
|
be52c181ea | ||
|
|
507f2ec544 | ||
|
|
fe00c628f4 | ||
|
|
e9387d322c | ||
|
|
2e3b135fe9 | ||
|
|
d28cc15be2 | ||
|
|
d15bd23800 | ||
|
|
90fe45c52d | ||
|
|
8f7be71905 | ||
|
|
5d583637c4 | ||
|
|
0efb4285c1 | ||
|
|
6dc543ca18 | ||
|
|
e93e1ddeb9 | ||
|
|
d5459f5996 | ||
|
|
c6420a910d | ||
|
|
f8e67b8e68 | ||
|
|
9ffcd382b4 | ||
|
|
725746badf | ||
|
|
9d5290de91 | ||
|
|
1bb0b58cce | ||
|
|
32f0ebbe61 | ||
|
|
25a1d74627 | ||
|
|
355b2f09bf | ||
|
|
01621f75b6 | ||
|
|
242e8a3bd6 | ||
|
|
010c26e716 | ||
|
|
e7bad10663 | ||
|
|
16242f98ce | ||
|
|
14a447b3d8 | ||
|
|
a2088fa500 | ||
|
|
87af68c092 | ||
|
|
06daad87ca | ||
|
|
0b4b86f6c9 | ||
|
|
10626904af | ||
|
|
90cca8a3eb | ||
|
|
8da0141cac | ||
|
|
39e123aaf4 | ||
|
|
24fd17f072 | ||
|
|
9270cc47b5 | ||
|
|
3721db34ab | ||
|
|
e85ae351c7 | ||
|
|
a56ba245ea | ||
|
|
d162eed4c7 | ||
|
|
43fea34f61 | ||
|
|
f7c960fc0d | ||
|
|
ee1933389a | ||
|
|
fdc9d5f1fd | ||
|
|
bad40b6125 | ||
|
|
d76ce85327 | ||
|
|
d3df072a22 | ||
|
|
4b3009a195 | ||
|
|
b72b0d60cb | ||
|
|
5841e62c66 | ||
|
|
9bd0c01702 | ||
|
|
6d86b3a950 | ||
|
|
5ff9b02c89 | ||
|
|
80934ea232 | ||
|
|
5acfa2bf3a | ||
|
|
4fada52e04 | ||
|
|
e1c8e95e11 | ||
|
|
1dfebad790 | ||
|
|
37ffe63d13 | ||
|
|
cc14c34dc2 | ||
|
|
e0cf4e644b | ||
|
|
aad55fc3db | ||
|
|
ba2b459220 | ||
|
|
086669fbe0 | ||
|
|
4cc3fcb6e8 | ||
|
|
8781053dbe | ||
|
|
bdac8974d8 | ||
|
|
9ae24141a3 | ||
|
|
e773efdc59 | ||
|
|
8f94bd1fbd | ||
|
|
d24d83d52a | ||
|
|
c938017baa | ||
|
|
728eea3ae1 | ||
|
|
88f9c1e539 | ||
|
|
76540c20f3 | ||
|
|
70761cf1d9 | ||
|
|
ace913a97d | ||
|
|
d6e269c7f6 | ||
|
|
ec10550b3a | ||
|
|
86e2374b48 | ||
|
|
d156dacbb9 | ||
|
|
1af5517da0 | ||
|
|
e5d34890a9 | ||
|
|
183b2548cf | ||
|
|
d2de489e3a | ||
|
|
90f8dbd86e | ||
|
|
3508ce19f3 | ||
|
|
00188c9818 | ||
|
|
499232f0e6 | ||
|
|
17471a12d2 | ||
|
|
de4b5eeda7 | ||
|
|
d0a0193707 | ||
|
|
5269a26b69 | ||
|
|
8dc6ad587f | ||
|
|
757339c52d | ||
|
|
6e289339d7 | ||
|
|
3ff0a44a1c | ||
|
|
0562228e9a | ||
|
|
0b6993bb7c | ||
|
|
4a19d90d48 | ||
|
|
038b1bcf7b | ||
|
|
a707c2fe8e | ||
|
|
3bb119f578 | ||
|
|
2a92600fa7 | ||
|
|
e80e1dab4d | ||
|
|
45d59d75ba | ||
|
|
28cd4c3ee9 | ||
|
|
e7c44274b0 | ||
|
|
3b2e0e34ef | ||
|
|
2276df07bd | ||
|
|
758ff03520 | ||
|
|
c3ac172960 | ||
|
|
562b4eb531 | ||
|
|
b1f8e845df | ||
|
|
bda869ea54 | ||
|
|
19cfbf082a | ||
|
|
07078bdd1f | ||
|
|
03657a98e1 | ||
|
|
b3f64abfae | ||
|
|
5d73c8f002 | ||
|
|
ba0882762d | ||
|
|
bb8855b628 | ||
|
|
883d5917f5 | ||
|
|
0275e99fe2 | ||
|
|
5d109077e5 | ||
|
|
540851ab6a | ||
|
|
6b920fa5e6 | ||
|
|
d1498bb9fb | ||
|
|
54eeef173a | ||
|
|
723ddf8cda | ||
|
|
9f12552907 | ||
|
|
a8b6fa413e | ||
|
|
76aae8ce42 | ||
|
|
ad0c287053 | ||
|
|
4a11a3559d | ||
|
|
1faa5a80e4 | ||
|
|
f1d3df1ec0 | ||
|
|
e7c94d3351 | ||
|
|
954f76dcf5 | ||
|
|
43037c0ff9 | ||
|
|
93df901b71 | ||
|
|
e97e645eda | ||
|
|
4a03ba3874 | ||
|
|
7f637e4acc | ||
|
|
8f3eeefafd | ||
|
|
5dc550a0ce | ||
|
|
6fe322da27 | ||
|
|
3cfe7c9a56 | ||
|
|
be7d5917cb | ||
|
|
ca28aa6ebd | ||
|
|
e76360c1b5 | ||
|
|
265ca8ba67 | ||
|
|
b0d942d0ec | ||
|
|
6c25905ae4 | ||
|
|
80a39393fe | ||
|
|
d4aed71abf | ||
|
|
ebb72bb992 | ||
|
|
8ffcd30b4d | ||
|
|
06804c37e2 | ||
|
|
1acca0278c | ||
|
|
639c8d4171 | ||
|
|
d77c9d3fca | ||
|
|
2c7cc2c191 | ||
|
|
d7c74b8004 | ||
|
|
aaa8003418 | ||
|
|
86890b13c6 | ||
|
|
39158b0eb6 | ||
|
|
87f1d55bc2 | ||
|
|
14343b5410 | ||
|
|
ffdac30b3c | ||
|
|
244c8dc391 | ||
|
|
e593344461 | ||
|
|
74c46f6e93 | ||
|
|
bbfd8aa249 | ||
|
|
2705a488ad | ||
|
|
850c253e08 | ||
|
|
80e0e3fcd7 | ||
|
|
2cc2d696f1 | ||
|
|
8a83a6b5be | ||
|
|
002d5338a0 | ||
|
|
743aa472f0 | ||
|
|
ba85d5d351 | ||
|
|
4e2ef908dc | ||
|
|
f5dd05ba8e | ||
|
|
17eda2a4cc | ||
|
|
d219c6e019 | ||
|
|
2dc539747b | ||
|
|
e941de50e8 | ||
|
|
63052257a2 | ||
|
|
ac5d2a714e | ||
|
|
59f78c16b1 | ||
|
|
3f7f8133df | ||
|
|
fef5e1ce2c | ||
|
|
0b97b3864f | ||
|
|
3d1330c85d | ||
|
|
041c0cc322 | ||
|
|
e72712640c | ||
|
|
6830195127 | ||
|
|
f9b5d6644d | ||
|
|
40f9eeda36 | ||
|
|
0fa0b0b1ea | ||
|
|
ff0b23f200 | ||
|
|
5456d4081b | ||
|
|
8948fae780 | ||
|
|
ee4542a699 | ||
|
|
31e4e631f9 | ||
|
|
cbf20b3271 | ||
|
|
a65fd50723 | ||
|
|
63a6aac2d8 | ||
|
|
afde4804c9 | ||
|
|
bc8ec9cd3e | ||
|
|
b63ab18e29 | ||
|
|
e7325f58c3 | ||
|
|
7b35bb8c96 | ||
|
|
e84671ce5d | ||
|
|
b01d50fe05 | ||
|
|
3f163051b1 | ||
|
|
4f1d03e1d4 | ||
|
|
fc39e4a225 | ||
|
|
bf88ad7fc8 | ||
|
|
11ba02067e | ||
|
|
952afa05ce | ||
|
|
3131cc3160 | ||
|
|
792f768479 | ||
|
|
ff312a15dd | ||
|
|
36207c9a98 | ||
|
|
b92105e888 | ||
|
|
35bd7c55d0 | ||
|
|
9f19c302d8 | ||
|
|
87b1ac776f | ||
|
|
41e401b05e | ||
|
|
d88da3589d | ||
|
|
9638c393bb | ||
|
|
9961ddc2a8 | ||
|
|
2d40dfd8d4 | ||
|
|
99c9bdf71d | ||
|
|
4fcd25ec88 | ||
|
|
440218da67 | ||
|
|
fefdb9fc8d | ||
|
|
21a0eff593 | ||
|
|
8825a094ae | ||
|
|
aa49ce5c56 | ||
|
|
1522d3385d | ||
|
|
510c41440a | ||
|
|
aa0c34ba1c | ||
|
|
af87e6ef62 | ||
|
|
30291ce6e6 | ||
|
|
890c2eb564 | ||
|
|
67a269b89c | ||
|
|
4b9ee81a78 | ||
|
|
4343f4d229 | ||
|
|
2162baa6c0 | ||
|
|
7e7f792710 | ||
|
|
1bbd9e24b0 | ||
|
|
6435aaa64f | ||
|
|
999aae0a33 | ||
|
|
ba795639b4 | ||
|
|
4c4b205721 | ||
|
|
b3c550b7c0 | ||
|
|
eb8953e784 | ||
|
|
b88b292d5d | ||
|
|
5f42c3b319 | ||
|
|
5b27ae0371 | ||
|
|
f26b1da1b5 | ||
|
|
7a853e2dcb | ||
|
|
9b22748bd0 | ||
|
|
c1e9dd3373 | ||
|
|
8cbbc47043 | ||
|
|
81b3567133 | ||
|
|
fc6568f390 | ||
|
|
8e30fe2946 | ||
|
|
6c811a3261 | ||
|
|
afbe5aa540 | ||
|
|
324afd2d6c | ||
|
|
58d94ef61e | ||
|
|
39974b0982 | ||
|
|
323d7306e2 | ||
|
|
251e228ce4 | ||
|
|
a99f3f217a | ||
|
|
e2acbee113 | ||
|
|
37b69eddf2 | ||
|
|
f0322e6f2c | ||
|
|
756587d080 | ||
|
|
1ad2c92324 | ||
|
|
e5433adf78 | ||
|
|
ed765f75d8 | ||
|
|
4136f1b377 | ||
|
|
860339b90e | ||
|
|
03254a0c0f | ||
|
|
a76081c979 | ||
|
|
71a207079f | ||
|
|
f6e724c4c5 | ||
|
|
4251b36b25 | ||
|
|
b8f39cbfdf | ||
|
|
088c621862 | ||
|
|
2459a53350 | ||
|
|
7093e9c0d4 | ||
|
|
4bc49978d1 | ||
|
|
96bac9c149 | ||
|
|
8dcc15f4d3 | ||
|
|
8183740c04 | ||
|
|
25e4231d7b | ||
|
|
3ed9e0e905 | ||
|
|
45bec0c440 | ||
|
|
5133e39d45 | ||
|
|
cb3b4e446e | ||
|
|
9829a2f3b4 | ||
|
|
7eadf11145 | ||
|
|
2a2bc44f43 | ||
|
|
9ccfa5cec9 | ||
|
|
02687f3c78 | ||
|
|
7ea7a6cbb1 | ||
|
|
a15a28fe5b | ||
|
|
265dedfae1 | ||
|
|
5ddbb8bc56 | ||
|
|
4101b8e937 | ||
|
|
56b6d50479 | ||
|
|
506f585d78 | ||
|
|
577dfb7220 | ||
|
|
7e4286adde | ||
|
|
1090228628 | ||
|
|
aeea861b73 | ||
|
|
997c43bbdd | ||
|
|
958d4dbd2e | ||
|
|
f2b350eb62 | ||
|
|
a3464780a1 | ||
|
|
fe1eb92196 | ||
|
|
0b2d26ec92 | ||
|
|
8024a25f2b | ||
|
|
d287ecbb34 | ||
|
|
d9c95e7730 | ||
|
|
c3b1af31ce | ||
|
|
465576b5cb | ||
|
|
9ecbcd0075 | ||
|
|
c1f62d72ae | ||
|
|
1b27834c41 | ||
|
|
77804907b6 | ||
|
|
9dfa2609be | ||
|
|
8ffb3ab3c4 | ||
|
|
65e1da34fa | ||
|
|
282110807c | ||
|
|
25e5f43d1c | ||
|
|
ce0441694d | ||
|
|
db29699927 | ||
|
|
9a4e2d7617 | ||
|
|
fbf64585b7 | ||
|
|
6d1c6dfd16 | ||
|
|
e78df4d981 | ||
|
|
a757b4d5dc | ||
|
|
d28036ee91 | ||
|
|
d2ba0d4e7a | ||
|
|
5787436177 | ||
|
|
f5ab24b8d2 | ||
|
|
05c0f32a24 | ||
|
|
7b918f77a9 | ||
|
|
d87929d61c | ||
|
|
a926829c33 | ||
|
|
d58e366c40 | ||
|
|
0fb4f7e1c4 | ||
|
|
6ee606e3e2 | ||
|
|
22d4a7690f | ||
|
|
f3a2f5018a | ||
|
|
d2a7589f7c | ||
|
|
f87b4e04f1 | ||
|
|
b5aa4c1f0c | ||
|
|
0c1eb6d288 | ||
|
|
8a03c5f998 | ||
|
|
60aa50ae45 | ||
|
|
aae6bbbb66 | ||
|
|
5ca903c428 | ||
|
|
e86b07f760 | ||
|
|
d7fea5dc78 | ||
|
|
c1eff5aebb | ||
|
|
f2dc490d6f | ||
|
|
b296e1b340 | ||
|
|
8adb060edb | ||
|
|
c3b984fea7 | ||
|
|
afbb2c338b | ||
|
|
6632241ab5 | ||
|
|
be50df81db | ||
|
|
9763b6e2cf | ||
|
|
812b848daf | ||
|
|
4907a7389f | ||
|
|
17dff36b65 | ||
|
|
904921d8c4 | ||
|
|
ac4c075d32 | ||
|
|
ddde64ece9 | ||
|
|
91c097e88d | ||
|
|
894658a3f5 | ||
|
|
a4454ea5f9 | ||
|
|
8ea8fa3a8a | ||
|
|
7480603295 | ||
|
|
079b749d5d | ||
|
|
4815600e85 | ||
|
|
1c63e2d295 | ||
|
|
cf13eca58c | ||
|
|
3cf4607870 | ||
|
|
23c3ba6ad7 | ||
|
|
17fc3c2317 | ||
|
|
af234cbe54 | ||
|
|
c8517c0ec9 | ||
|
|
20b226454b | ||
|
|
98eccf223a | ||
|
|
0fc2ab4d41 | ||
|
|
641b6efe7f | ||
|
|
4c83435b4b | ||
|
|
9f7319cff4 | ||
|
|
dd9baa1502 | ||
|
|
41b4d0daa1 | ||
|
|
e41b181163 | ||
|
|
288ac115d0 | ||
|
|
6774d46a6f | ||
|
|
607abf89f7 | ||
|
|
27f1e5e2f2 | ||
|
|
a457675ce1 | ||
|
|
82049096e6 | ||
|
|
6c965e0223 | ||
|
|
8b4d952929 | ||
|
|
873cc63f94 | ||
|
|
39fc839ff2 | ||
|
|
4edef4c959 | ||
|
|
1d9ced8037 | ||
|
|
4cb77d1429 | ||
|
|
b52d9d1bdd | ||
|
|
5fe7ca5e70 | ||
|
|
62fb440de2 | ||
|
|
96fbd7c7ba | ||
|
|
c9bec8e636 | ||
|
|
769e03e7f2 | ||
|
|
ab83f2d5e2 | ||
|
|
b60d0cdb17 | ||
|
|
677503dbf1 | ||
|
|
25efa29470 | ||
|
|
21a90f8f8f | ||
|
|
64e8d6ae99 | ||
|
|
16a204335e | ||
|
|
0a53f762fe | ||
|
|
6ba4778c1b | ||
|
|
0404c2266c | ||
|
|
e5e914282f | ||
|
|
9867d4bdc3 | ||
|
|
e4cb7112cf | ||
|
|
2d202e90b7 | ||
|
|
016391e442 | ||
|
|
1eff48a429 | ||
|
|
ce33af6bb5 | ||
|
|
fb9d4303f1 | ||
|
|
4e631c9e8f | ||
|
|
766d67d80d | ||
|
|
e2c2a37221 | ||
|
|
2b23020695 | ||
|
|
8d43c6b1a8 | ||
|
|
7362dd1a7c | ||
|
|
316caf7e8c | ||
|
|
87dc6631ee | ||
|
|
62246d7d43 | ||
|
|
a14be3a42c | ||
|
|
7fdf00d5e9 | ||
|
|
99e02f30fb | ||
|
|
716a5b9b5a | ||
|
|
87f880ca52 | ||
|
|
8ec7b84a78 | ||
|
|
05cf5bc8db | ||
|
|
ac25e21a0c | ||
|
|
cc1e0daaa4 | ||
|
|
f4120a9c8c | ||
|
|
e3b80a5e09 | ||
|
|
ef7cb26b01 | ||
|
|
408a5c168f | ||
|
|
0ad6ac95b2 | ||
|
|
bda4747e9c | ||
|
|
bd8f882c94 | ||
|
|
32b5b5b1c4 | ||
|
|
c1e543c9fe | ||
|
|
3908fa5c57 | ||
|
|
1b347fc185 | ||
|
|
282a5e0b01 | ||
|
|
e9d23cc1ea | ||
|
|
34173fd60f | ||
|
|
d0d3c8ef57 | ||
|
|
11912008dd | ||
|
|
c122007e17 | ||
|
|
69dfa1a175 | ||
|
|
bfea443e55 | ||
|
|
680798c28f | ||
|
|
9f0cc45c45 | ||
|
|
0ac97f467f | ||
|
|
647746ea72 | ||
|
|
7bea30b2e6 | ||
|
|
12bc852c89 | ||
|
|
0d42e84045 | ||
|
|
897b85b607 | ||
|
|
5c55cf0efb | ||
|
|
eccd6463f6 | ||
|
|
4a0897c734 | ||
|
|
c86a16df7f | ||
|
|
2ae0e9d902 | ||
|
|
bba18cd56b | ||
|
|
2f20781e16 | ||
|
|
3bee212876 | ||
|
|
6c8893a550 | ||
|
|
9c52ecc19b | ||
|
|
692c884ca2 | ||
|
|
3ef51d7fae | ||
|
|
73d95de122 | ||
|
|
04a568ac9b | ||
|
|
a45499cf04 | ||
|
|
b847d672ab | ||
|
|
3ffefdf6b5 | ||
|
|
cca4c4be80 | ||
|
|
cb9e044cb3 | ||
|
|
fd25dd83bd | ||
|
|
584bb00cfc | ||
|
|
5b9369d344 | ||
|
|
a64506a0de | ||
|
|
2fc83ef80b | ||
|
|
8bee3ebd65 | ||
|
|
99686fdd73 | ||
|
|
33bc3d6a1e | ||
|
|
90597530a4 | ||
|
|
b2af8da9a2 | ||
|
|
05dbf41fdc | ||
|
|
c56bb56708 | ||
|
|
4def1ea1dc | ||
|
|
0ba05e4de0 | ||
|
|
24fce89155 | ||
|
|
1a3c20f91d | ||
|
|
fe3e78cc1c | ||
|
|
749f49b1a0 | ||
|
|
f14010a09d | ||
|
|
0b48b9c7d4 | ||
|
|
13d62b01d1 | ||
|
|
4e7b71db1d | ||
|
|
069fc1f97b | ||
|
|
8684f75254 | ||
|
|
11cd924ce1 | ||
|
|
e2fd0cfc4e | ||
|
|
5eb3106706 | ||
|
|
1831efbe9d | ||
|
|
38edbadca5 | ||
|
|
6fcd80b979 | ||
|
|
cf5e5dbe55 | ||
|
|
a451861bf1 | ||
|
|
7313dd74a6 | ||
|
|
32b9de05f2 | ||
|
|
c79bed22f8 | ||
|
|
cdeb50132d | ||
|
|
090fb09955 | ||
|
|
54b862bd79 | ||
|
|
e37e1c109a | ||
|
|
939123785b | ||
|
|
221b347bd9 | ||
|
|
af9bf3e852 | ||
|
|
ed8746df77 | ||
|
|
bb187db49d | ||
|
|
081e72b3ea | ||
|
|
6188c38053 | ||
|
|
12b0186f5a | ||
|
|
9bccc9c53c | ||
|
|
351b2b320e | ||
|
|
94258feb09 | ||
|
|
8b0f033a78 | ||
|
|
f58f255fc8 | ||
|
|
e3eabcf648 | ||
|
|
9aa506cbd7 | ||
|
|
d8cff7b90f | ||
|
|
07e7bca9eb | ||
|
|
e1f442be90 | ||
|
|
c5d579e0e3 | ||
|
|
5271c2e08f | ||
|
|
9010a7ddbc | ||
|
|
bb95fb7d07 | ||
|
|
2edb11376d | ||
|
|
e7f5ebf912 | ||
|
|
da9758c2f3 | ||
|
|
3e11d58d73 | ||
|
|
6b35c097d6 | ||
|
|
619ba13265 | ||
|
|
529c5b8abf | ||
|
|
3a5ed6e800 | ||
|
|
52cddc015b | ||
|
|
4a01f4f65f | ||
|
|
f9768cb5a3 | ||
|
|
221e0e550c | ||
|
|
d2d1d42d0f | ||
|
|
faf018a097 | ||
|
|
a2a71a107e | ||
|
|
fc9c937e67 | ||
|
|
b4f2e9b442 | ||
|
|
1672645e73 | ||
|
|
4a42c44101 | ||
|
|
383b1a5769 | ||
|
|
77bac4cf9e | ||
|
|
e2b8e530c9 | ||
|
|
e9f752bd67 | ||
|
|
4b31921eb4 | ||
|
|
3df9fc6225 | ||
|
|
b57fe466ce | ||
|
|
bd4bff3b6b | ||
|
|
9d4618a223 | ||
|
|
93636180df | ||
|
|
fcceaa168f | ||
|
|
2639cc6138 | ||
|
|
4a99c2e928 | ||
|
|
7d5af3df05 | ||
|
|
c88b80d2a0 | ||
|
|
819d4abaa2 | ||
|
|
20630aeb47 | ||
|
|
0c0db3babb | ||
|
|
e7761f7e57 | ||
|
|
064fd497ae | ||
|
|
49c60b6b75 | ||
|
|
ca7f36506c | ||
|
|
155f0a9736 | ||
|
|
25e1eb3ce9 | ||
|
|
f2f980928b | ||
|
|
1d121a97a7 | ||
|
|
211d13da09 | ||
|
|
11343d469e | ||
|
|
d7c8041aa1 | ||
|
|
9587e30af8 | ||
|
|
76fa7affaf | ||
|
|
2971dd8672 | ||
|
|
2a33fe3564 | ||
|
|
46cdf5da70 | ||
|
|
28c801bfd4 | ||
|
|
c22cd40293 | ||
|
|
56bd430983 | ||
|
|
d873890e46 | ||
|
|
d29b8eca3c | ||
|
|
6f258000fe | ||
|
|
255211cd07 | ||
|
|
f6d28a90e3 | ||
|
|
ed66ff88a1 | ||
|
|
82e58f2bf9 | ||
|
|
797a87ca26 | ||
|
|
ec6a709393 | ||
|
|
07cbfdb424 | ||
|
|
3b9bd944fb | ||
|
|
934e585cb3 | ||
|
|
3a68f4cf54 | ||
|
|
bd00fcb875 | ||
|
|
905dd5a70f | ||
|
|
c65250ec39 | ||
|
|
607eec6ff0 | ||
|
|
14fb3bde60 | ||
|
|
6782bc8ca2 | ||
|
|
3db6841305 | ||
|
|
f478fa8029 | ||
|
|
d255f8400f | ||
|
|
a1545c60d6 | ||
|
|
ed48603ab5 | ||
|
|
23a0507439 | ||
|
|
482e013887 | ||
|
|
265727c30f | ||
|
|
4d3f4e096b | ||
|
|
7629bca62d | ||
|
|
2712f17262 | ||
|
|
86a37559ba | ||
|
|
b504a557f4 | ||
|
|
e849b46f6b | ||
|
|
738dc50a6f | ||
|
|
3138523b5b | ||
|
|
537643a4c3 | ||
|
|
04bfe098ed | ||
|
|
c507887bdd | ||
|
|
ee261313ac | ||
|
|
c9c152bc8a | ||
|
|
6c8e19a321 | ||
|
|
218e3b66f2 | ||
|
|
1d3488fa8e | ||
|
|
f4c1682592 | ||
|
|
28ac6623c7 | ||
|
|
16ab179e1d | ||
|
|
a8ff5385dc | ||
|
|
9dc33c6086 | ||
|
|
b17c576705 | ||
|
|
96f8f2891b | ||
|
|
581d73afe0 | ||
|
|
1baefebe8f | ||
|
|
39fb05033f | ||
|
|
c6093c084c | ||
|
|
dfec6d9a6d | ||
|
|
08b1261c75 | ||
|
|
2ad6faae3a | ||
|
|
4eff301db3 | ||
|
|
447e43e8f4 | ||
|
|
7457001275 | ||
|
|
fcabd5e79e | ||
|
|
594002316c | ||
|
|
eccf92ebaf | ||
|
|
ad9ddc5621 | ||
|
|
1825dd916e | ||
|
|
dfcde8171e | ||
|
|
b0361183df | ||
|
|
71fe13b249 | ||
|
|
442f51224d | ||
|
|
974678f500 | ||
|
|
8329409c03 | ||
|
|
06c2ac2724 | ||
|
|
04e9e8f9d8 | ||
|
|
7a3330cb8c | ||
|
|
cae29941ea | ||
|
|
15cf2ad076 | ||
|
|
2f16f6dc23 | ||
|
|
528aebffe4 | ||
|
|
e82b2f0cbe | ||
|
|
73e64f3e4a | ||
|
|
15f5b1f830 | ||
|
|
1b0a77f9a8 | ||
|
|
0f82ae3644 | ||
|
|
de3b01b54b | ||
|
|
c17e3646d5 | ||
|
|
26aed3e89e | ||
|
|
74caea8f8f | ||
|
|
2cf07fa072 | ||
|
|
1181cd2fd7 | ||
|
|
850d55ab45 | ||
|
|
a0c91b8754 | ||
|
|
937bdc05c8 | ||
|
|
453755bfa1 | ||
|
|
400b6fbb61 | ||
|
|
8c4e882fa3 | ||
|
|
84eec23793 | ||
|
|
7dfe69f6a5 | ||
|
|
ada6115073 | ||
|
|
e1643566f9 | ||
|
|
053a9a6317 | ||
|
|
425b976cc0 | ||
|
|
5f5f1b1e09 | ||
|
|
e6f4935c7b | ||
|
|
6452e5976b | ||
|
|
2383dff317 | ||
|
|
de3e5042fb | ||
|
|
0dcc35152c | ||
|
|
8eecfcbfaf | ||
|
|
efa3e60f89 | ||
|
|
782df659bc | ||
|
|
0aa158824f | ||
|
|
da7fb44e5d | ||
|
|
4b59ef802e | ||
|
|
be5789cd56 | ||
|
|
9adf0e5d59 | ||
|
|
e2de22470e | ||
|
|
3b7ab2e553 | ||
|
|
8617dedc46 | ||
|
|
0b8f1a9a58 | ||
|
|
16748c0920 | ||
|
|
01ec585a44 | ||
|
|
b5f2295f37 | ||
|
|
d6ca0199b7 | ||
|
|
2257c5e547 | ||
|
|
b5a3d39799 | ||
|
|
a26c3e9d3c | ||
|
|
98a09532eb | ||
|
|
d736789bbc | ||
|
|
82a6cfc03a | ||
|
|
62e9c7c75a | ||
|
|
eb32bd45e7 | ||
|
|
4b95f07923 | ||
|
|
dea8ad4c49 | ||
|
|
96553b217c | ||
|
|
3f79ed5d91 | ||
|
|
1e4283aad3 | ||
|
|
1dda31a28c | ||
|
|
10c87012be | ||
|
|
bda00bf512 | ||
|
|
c8f871ff2a | ||
|
|
58dc0b1aef | ||
|
|
4cd4d8f31a | ||
|
|
b751fd738d | ||
|
|
f97c6fb94c | ||
|
|
219138ade6 | ||
|
|
9086d189b9 | ||
|
|
d1178defe0 | ||
|
|
691a561a95 | ||
|
|
aaaac93bd0 | ||
|
|
fd790566b2 | ||
|
|
db3b429784 | ||
|
|
40ed3278d4 | ||
|
|
d174b13111 | ||
|
|
1708663b32 | ||
|
|
6fdce4ad0d | ||
|
|
fff8d5f07d | ||
|
|
9c8e1f4706 | ||
|
|
0a1036c78f | ||
|
|
0e881a7972 | ||
|
|
839e52ba30 | ||
|
|
8f7d5dcb4d | ||
|
|
1104b28bc1 | ||
|
|
48521cb1e4 | ||
|
|
17e113dafb | ||
|
|
c33825a904 | ||
|
|
b07ef98c8f | ||
|
|
b3d68893df | ||
|
|
1329599987 | ||
|
|
2adf3f364c | ||
|
|
436ee34a02 | ||
|
|
4a6e17b214 | ||
|
|
6e9cbccde6 | ||
|
|
a0cb8ec124 | ||
|
|
21217dfda3 | ||
|
|
25ba18e570 | ||
|
|
a210377f35 | ||
|
|
07b9ca457f | ||
|
|
5f1372d39c | ||
|
|
01b84c79f0 | ||
|
|
4017443b1e | ||
|
|
fd2a17d244 | ||
|
|
126804f7c3 | ||
|
|
5167bbf59e | ||
|
|
8bcdfa2793 | ||
|
|
2f9cb6a91e | ||
|
|
662be14535 | ||
|
|
d6d065cd61 | ||
|
|
ac7f045708 | ||
|
|
ffe02ad7bf | ||
|
|
db1a87d10c | ||
|
|
4bae41ffd8 | ||
|
|
be36fb979f | ||
|
|
0f66d763e0 | ||
|
|
06f4743f51 | ||
|
|
9cc11b8774 | ||
|
|
de821e55ae | ||
|
|
463b5c6e49 | ||
|
|
65ab5fdb34 | ||
|
|
d2f7a035b3 | ||
|
|
bc0b924283 | ||
|
|
56ad6af5b2 | ||
|
|
c50bb3a5a9 | ||
|
|
d993a62263 | ||
|
|
82bc52b909 | ||
|
|
f31598f916 | ||
|
|
6a9efd8ac6 | ||
|
|
a9dddb6066 | ||
|
|
40cf5c99ef | ||
|
|
42f58cbbb3 | ||
|
|
fd9c780015 | ||
|
|
383b92b207 | ||
|
|
7036ed5e2f | ||
|
|
30666aa111 | ||
|
|
9614d68baa | ||
|
|
c25fb4c743 | ||
|
|
09d5222b1f | ||
|
|
426ca78bf7 | ||
|
|
a77a0945fe | ||
|
|
5311a0f903 | ||
|
|
d421656be8 | ||
|
|
04459eaa50 | ||
|
|
3beda8eea0 | ||
|
|
5e894be06b | ||
|
|
bc8f93b596 | ||
|
|
2fb93bac99 | ||
|
|
d0c94c1aef | ||
|
|
77242bfb95 | ||
|
|
5d2d86bffc | ||
|
|
8492c13e72 | ||
|
|
e4eb5dadda | ||
|
|
8532dc4b75 | ||
|
|
1ca26ce676 | ||
|
|
d8e3e823a7 | ||
|
|
473dd7660b | ||
|
|
5afeed56ef | ||
|
|
b91b04f652 | ||
|
|
25de44a23d | ||
|
|
00cfb95971 | ||
|
|
f4ba0e1191 | ||
|
|
6499643769 | ||
|
|
f85287a444 | ||
|
|
483bc9ad87 | ||
|
|
93b89a93c1 | ||
|
|
10064c046c | ||
|
|
a5aecb9d0e | ||
|
|
de1e889f1d | ||
|
|
16f89b40c3 | ||
|
|
0e387d2cda | ||
|
|
837c15e4f9 | ||
|
|
ae7e353169 | ||
|
|
6c1bbd2344 | ||
|
|
27247e8e56 | ||
|
|
08249d78ea | ||
|
|
827091e522 | ||
|
|
13d901bf8d | ||
|
|
e69bdabc99 | ||
|
|
e8d19265e4 | ||
|
|
49e3a49dc5 | ||
|
|
82a7c01898 | ||
|
|
c0d7dbf639 | ||
|
|
569caa0bf2 | ||
|
|
f88ea1ee7d | ||
|
|
d5a8fa0b97 | ||
|
|
3f8f96edea | ||
|
|
04fb4aff28 | ||
|
|
83c6fb089e | ||
|
|
9d8d17b964 | ||
|
|
39d4842ff5 | ||
|
|
cad8473986 | ||
|
|
5f085ccb52 | ||
|
|
b406246689 | ||
|
|
cbe46afdff | ||
|
|
a59d6dc3c7 | ||
|
|
2afb2dd5fd | ||
|
|
4fc3c969d3 | ||
|
|
1796ce324b | ||
|
|
5e04c7f827 | ||
|
|
20fcede440 | ||
|
|
012c1833f2 | ||
|
|
32e8e03256 | ||
|
|
dca653cb92 | ||
|
|
0805eca979 | ||
|
|
17935a78ff | ||
|
|
e16918ee32 | ||
|
|
78471b4595 | ||
|
|
c30bcdd515 | ||
|
|
ac78c5f4e5 | ||
|
|
57a990ce25 | ||
|
|
24825b42a2 | ||
|
|
4f7323f7fc | ||
|
|
a228be85e2 | ||
|
|
fa565bdbdf | ||
|
|
2dc53223e5 | ||
|
|
958ac72805 | ||
|
|
f7297b84e7 | ||
|
|
9a7d9e7bb8 | ||
|
|
fa9df75cf7 | ||
|
|
e3ec76418b | ||
|
|
102d6d8c84 | ||
|
|
a742b5f3e2 | ||
|
|
a2a3bb291f | ||
|
|
b7c0ac7d67 | ||
|
|
13b1fc6b44 | ||
|
|
3939fcf6e7 | ||
|
|
13abbb81af | ||
|
|
019f0153c8 | ||
|
|
8abc2925e0 | ||
|
|
996c9a032a | ||
|
|
22d3794d22 | ||
|
|
ba948a38e9 | ||
|
|
e8a522c4df | ||
|
|
c60f3da32e | ||
|
|
0c92d3cbb2 | ||
|
|
e4fc8dd6fe | ||
|
|
1a849e2de0 | ||
|
|
ffdd79f86b | ||
|
|
e87e46b1b6 | ||
|
|
3ca81a4ff7 | ||
|
|
5477d3c292 | ||
|
|
08300183b3 | ||
|
|
095c77f22c | ||
|
|
09926e63a3 | ||
|
|
87d70f29a1 | ||
|
|
3a7661b111 | ||
|
|
ec976953cd | ||
|
|
1837562b50 | ||
|
|
f3bec4fc37 | ||
|
|
c2117ef4fd | ||
|
|
910804ecd1 | ||
|
|
ce5ae1dfdd | ||
|
|
2c31411ffb | ||
|
|
84d69fa2a1 | ||
|
|
2aea296d19 | ||
|
|
2b0bffc362 | ||
|
|
83356142c1 | ||
|
|
24dcc6947c | ||
|
|
a7e3136a0b | ||
|
|
71639cfea7 | ||
|
|
8c2d39fb82 | ||
|
|
e060d29337 | ||
|
|
79e9156d2f | ||
|
|
9100db55b0 | ||
|
|
141c10f6fe | ||
|
|
4613ab9dc3 | ||
|
|
061ad41b51 | ||
|
|
3a0007cd18 | ||
|
|
0044917943 | ||
|
|
0337c04278 | ||
|
|
4585acf70b | ||
|
|
2ad9bbae25 | ||
|
|
cf075df7d1 | ||
|
|
11cd9905c4 | ||
|
|
cf462542e9 | ||
|
|
b63f25a1ae | ||
|
|
7de69a21c5 | ||
|
|
21783e4ea0 | ||
|
|
53e5a756d7 | ||
|
|
8c911a2fd0 | ||
|
|
ce440e9f43 | ||
|
|
6465f8d8e6 | ||
|
|
4bdf28059a | ||
|
|
21010c6540 | ||
|
|
a5a6cabac6 | ||
|
|
f460c77f2c | ||
|
|
1c69d9213e | ||
|
|
c02c2d3b2c | ||
|
|
7adf5e763b | ||
|
|
0e4afefc7f | ||
|
|
c7f290f42e | ||
|
|
bb553b8a6a | ||
|
|
21eda2a1a3 | ||
|
|
48c13c990f | ||
|
|
a2665529f6 | ||
|
|
8d35d78eff | ||
|
|
a82a364c22 | ||
|
|
cc150ff9d2 | ||
|
|
feeb38293d | ||
|
|
5b9271ccfe | ||
|
|
e60bbc2fb7 | ||
|
|
387cc184e6 | ||
|
|
a830ddcb43 | ||
|
|
35fea30191 | ||
|
|
24b672b968 | ||
|
|
de6a3c5ab1 | ||
|
|
260ff6de3e | ||
|
|
7cb37411c9 | ||
|
|
e4e41e5ef8 | ||
|
|
985f4aafca | ||
|
|
0c25dd44b3 | ||
|
|
285f0bc6dd | ||
|
|
07a370fd24 | ||
|
|
95f07ea38a | ||
|
|
2890b92b21 | ||
|
|
8b80c5d0b5 | ||
|
|
04425786a1 |
18
.editorconfig
Normal file
18
.editorconfig
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# This file is for unifying the coding style for different editors and IDEs
|
||||||
|
# editorconfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[**.{js,json,md}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[**.html]
|
||||||
|
indent_style = tab
|
||||||
|
insert_final_newline = false
|
||||||
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
* text=auto
|
||||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,4 +1,6 @@
|
|||||||
*.custom.*
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
dist/
|
*.custom.*
|
||||||
node_modules/
|
*.log
|
||||||
|
*.map
|
||||||
|
lodash.compat.min.js
|
||||||
|
node_modules
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
*.custom.*
|
|
||||||
.*
|
|
||||||
dist/
|
|
||||||
doc/*.php
|
|
||||||
node_modules/
|
|
||||||
perf/*.sh
|
|
||||||
test/*.sh
|
|
||||||
16
.npmignore
16
.npmignore
@@ -1,16 +0,0 @@
|
|||||||
*.custom.*
|
|
||||||
.*
|
|
||||||
dist/
|
|
||||||
doc/*.php
|
|
||||||
node_modules/
|
|
||||||
perf/*.html
|
|
||||||
perf/*.sh
|
|
||||||
test/*.html
|
|
||||||
test/*-ui.js
|
|
||||||
test/*.sh
|
|
||||||
vendor/backbone/
|
|
||||||
vendor/docdown/
|
|
||||||
vendor/firebug-lite/
|
|
||||||
vendor/qunit/qunit/*.css
|
|
||||||
vendor/requirejs/
|
|
||||||
vendor/underscore/test/
|
|
||||||
77
.travis.yml
Normal file
77
.travis.yml
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- "0.12"
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- PATTERN1="s|^.+?!support\.funcNames\b[\s\S]+?\.name\b[\s\S]+?\}\n||m"
|
||||||
|
- PATTERN2="s|\s*else\s*\{\s*iteratee\(index\);\s*\}||"
|
||||||
|
- BIN="node" BUILD="compat" ISTANBUL=false OPTION=""
|
||||||
|
- NPM_VERSION="^2.0.0" SAUCE_LABS=false SAUCE_USERNAME="lodash"
|
||||||
|
- secure: "tg1JFsIFnxzLaTboFPOnm+aJCuMm5+JdhLlESlqg9x3fwro++7KCnwHKLNovhchaPe4otC43ZMB/nfWhDnDm11dKbm/V6HlTkED+dadTsaLxVDg6J+7yK41QhokBPJOxLV78iDaNaAQVYEirAgZ0yn8kFubxmNKV+bpCGQNc9yU="
|
||||||
|
matrix:
|
||||||
|
- BUILD="compat"
|
||||||
|
- BUILD="modern"
|
||||||
|
- BUILD="modern"
|
||||||
|
- BUILD="modern" ISTANBUL=true
|
||||||
|
- BIN="phantomjs"
|
||||||
|
- BIN="rhino"
|
||||||
|
- BIN="rhino" OPTION="-require"
|
||||||
|
- BIN="ringo"
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- node_js: "io.js"
|
||||||
|
env:
|
||||||
|
- node_js: "io.js"
|
||||||
|
env: BUILD="modern"
|
||||||
|
- node_js: "0.8"
|
||||||
|
env: NPM_VERSION="~1.4.0"
|
||||||
|
- node_js: "0.8"
|
||||||
|
env: BUILD="modern" NPM_VERSION="~1.4.0"
|
||||||
|
- node_js: "0.10"
|
||||||
|
env:
|
||||||
|
- node_js: "0.10"
|
||||||
|
env: BUILD="modern"
|
||||||
|
- node_js: "0.12"
|
||||||
|
env: SAUCE_LABS=true
|
||||||
|
- node_js: "0.12"
|
||||||
|
env: SAUCE_LABS=true BUILD="modern"
|
||||||
|
git:
|
||||||
|
depth: 10
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
notifications:
|
||||||
|
webhooks:
|
||||||
|
urls:
|
||||||
|
- https://webhooks.gitter.im/e/4aab6358b0e9aed0b628
|
||||||
|
on_success: change
|
||||||
|
on_failure: always
|
||||||
|
before_install:
|
||||||
|
- "nvm use $TRAVIS_NODE_VERSION"
|
||||||
|
- "npm config set loglevel error"
|
||||||
|
- "npm i -g npm@\"$NPM_VERSION\""
|
||||||
|
- "[ $SAUCE_LABS == false ] || npm i chalk@\"^1.0.0\" ecstatic@\"0.7.3\" request@\"^2.0.0\" sauce-tunnel@\"2.2.3\""
|
||||||
|
- "[ $ISTANBUL == false ] || (npm i -g coveralls@\"^2.0.0\" && npm i istanbul@\"0.3.13\")"
|
||||||
|
- "[ $BIN != 'rhino' ] || (sudo mkdir /opt/rhino-1.7R5 && sudo wget --no-check-certificate -O $_/js.jar https://lodash.com/_travis/rhino-1.7R5.jar)"
|
||||||
|
- "[ $BIN != 'rhino' ] || (echo -e '#!/bin/sh\\njava -jar /opt/rhino-1.7R5/js.jar $@' | sudo tee /usr/local/bin/rhino && sudo chmod +x /usr/local/bin/rhino)"
|
||||||
|
- "[ $BIN != 'ringo' ] || (wget --no-check-certificate https://lodash.com/_travis/ringojs-0.11.zip && sudo unzip ringojs-0.11 -d /opt && rm ringojs-0.11.zip)"
|
||||||
|
- "[ $BIN != 'ringo' ] || (sudo ln -s /opt/ringojs-0.11/bin/ringo /usr/local/bin/ringo && sudo chmod +x $_)"
|
||||||
|
- "perl -pi -e 's|\"lodash\"|\"lodash-compat\"|' ./package.json"
|
||||||
|
- "git clone --depth=10 --branch=master git://github.com/lodash/lodash-cli.git ./node_modules/lodash-cli && mkdir $_/node_modules && cd $_ && ln -s ../../../ ./lodash-compat && cd ../ && npm i && cd ../../"
|
||||||
|
- "node ./node_modules/lodash-cli/bin/lodash $BUILD -o ./lodash.$BUILD.js"
|
||||||
|
script:
|
||||||
|
- "[ $ISTANBUL == false ] || cp ./lodash.$BUILD.js ./lodash.js"
|
||||||
|
- "[ $ISTANBUL == false ] || perl -0pi -e \"$PATTERN1\" ./lodash.js && perl -0pi -e \"$PATTERN2\" $_"
|
||||||
|
- "[ $ISTANBUL == false ] || node ./node_modules/istanbul/lib/cli.js cover -x \"**/vendor/**\" --report lcovonly ./test/test.js -- ./lodash.js"
|
||||||
|
- "[ $ISTANBUL == false ] || [ $TRAVIS_SECURE_ENV_VARS == false ] || (cat ./coverage/lcov.info | coveralls)"
|
||||||
|
- "[ $SAUCE_LABS == true ] || [ $ISTANBUL == true ] || cd ./test"
|
||||||
|
- "[ $SAUCE_LABS == true ] || [ $ISTANBUL == true ] || $BIN $OPTION ./test.js ../lodash.$BUILD.js"
|
||||||
|
- "[ $SAUCE_LABS == true ] || [ $ISTANBUL == true ] || [ $TRAVIS_SECURE_ENV_VARS == false ] || $BIN $OPTION ./test.js ../lodash.$BUILD.min.js"
|
||||||
|
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"lodash tests\" runner=\"test/index.html?build=../lodash.$BUILD.js&noglobals=true\" tags=\"$BUILD,development\""
|
||||||
|
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"lodash tests\" runner=\"test/index.html?build=../lodash.$BUILD.min.js&noglobals=true\" tags=\"$BUILD,production\""
|
||||||
|
- "[ $SAUCE_LABS == false ] || [ $BUILD != 'compat' ] || $BIN ./test/saucelabs.js name=\"lodash tests\" runner=\"test/index.html?build=../lodash.$BUILD.js\" tags=\"$BUILD,development,ie-compat\" compatMode=7"
|
||||||
|
- "[ $SAUCE_LABS == false ] || [ $BUILD != 'compat' ] || $BIN ./test/saucelabs.js name=\"lodash tests\" runner=\"test/index.html?build=../lodash.$BUILD.min.js\" tags=\"$BUILD,production,ie-compat\" compatMode=7"
|
||||||
|
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"backbone tests\" runner=\"test/backbone.html?build=../lodash.$BUILD.min.js\" tags=\"$BUILD,production,backbone\""
|
||||||
|
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"backbone tests\" runner=\"test/backbone.html?build=../lodash.$BUILD.js\" tags=\"$BUILD,development,backbone\""
|
||||||
|
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"underscore tests\" runner=\"test/underscore.html?build=../lodash.$BUILD.min.js\" tags=\"$BUILD,production,underscore\""
|
||||||
|
- "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"underscore tests\" runner=\"test/underscore.html?build=../lodash.$BUILD.js\" tags=\"$BUILD,development,underscore\""
|
||||||
39
CONTRIBUTING.md
Normal file
39
CONTRIBUTING.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Contributing to lodash
|
||||||
|
|
||||||
|
If you’d like to contribute a feature or bug fix, you can [fork](https://help.github.com/articles/fork-a-repo/) lodash, commit your changes, & [send a pull request](https://help.github.com/articles/using-pull-requests/).
|
||||||
|
Please make sure to [search the issue tracker](https://github.com/lodash/lodash/issues) first; your issue may have already been discussed or fixed in `master`.
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
Include updated unit tests in the `test` directory as part of your pull request.
|
||||||
|
Don’t worry about regenerating the documentation, lodash.js, or lodash.min.js.
|
||||||
|
|
||||||
|
Before running the unit tests you’ll need to install, `npm i`, [development dependencies](https://docs.npmjs.com/files/package.json#devdependencies).
|
||||||
|
Run unit tests from the command-line via `node test/test`, or open `test/index.html` in a web browser.
|
||||||
|
|
||||||
|
The `test/run-test.sh` script attempts to run the tests in [Rhino](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino), [RingoJS](http://ringojs.org/), [PhantomJS](http://phantomjs.org/), & [Node](http://nodejs.org/), before running them in your default browser.
|
||||||
|
The [Backbone](http://backbonejs.org/) & [Underscore](http://underscorejs.org/) test suites are included as well.
|
||||||
|
|
||||||
|
## Contributor License Agreement
|
||||||
|
|
||||||
|
lodash is a member of the [Dojo Foundation](http://dojofoundation.org/).
|
||||||
|
As such, we request that all contributors sign the Dojo Foundation [contributor license agreement](http://dojofoundation.org/about/claForm).
|
||||||
|
|
||||||
|
For more information about CLAs, please check out Alex Russell’s excellent post, [“Why Do I Need to Sign This?”](http://infrequently.org/2008/06/why-do-i-need-to-sign-this/).
|
||||||
|
|
||||||
|
## Coding Guidelines
|
||||||
|
|
||||||
|
In addition to the following guidelines, please follow the conventions already established in the code.
|
||||||
|
|
||||||
|
- **Spacing**:<br>
|
||||||
|
Use two spaces for indentation. No tabs.
|
||||||
|
|
||||||
|
- **Naming**:<br>
|
||||||
|
Keep variable & method names concise & descriptive.<br>
|
||||||
|
Variable names `index`, `collection`, & `callback` are preferable to `i`, `arr`, & `fn`.
|
||||||
|
|
||||||
|
- **Quotes**:<br>
|
||||||
|
Single-quoted strings are preferred to double-quoted strings; however, please use a double-quoted string if the value contains a single-quote character to avoid unnecessary escaping.
|
||||||
|
|
||||||
|
- **Comments**:<br>
|
||||||
|
Please use single-line comments to annotate significant additions, & [JSDoc-style](http://www.2ality.com/2011/08/jsdoc-intro.html) comments for new methods.
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
Copyright 2012 John-David Dalton <http://allyoucanleet.com/>
|
Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
|
||||||
Based on Underscore.js 1.3.3, copyright 2009-2012 Jeremy Ashkenas,
|
Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas,
|
||||||
DocumentCloud Inc. <http://documentcloud.github.com/underscore>
|
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|||||||
307
README.md
307
README.md
@@ -1,300 +1,29 @@
|
|||||||
# Lo-Dash <sup>v0.5.0</sup>
|
# lodash v3.8.0
|
||||||
|
|
||||||
A drop-in replacement<sup>[*](https://github.com/bestiejs/lodash/wiki/Drop-in-Disclaimer)</sup> for Underscore.js, from the devs behind [jsPerf.com](http://jsperf.com), delivering [performance](http://lodash.com/benchmarks), [bug fixes](https://github.com/bestiejs/lodash#resolved-underscorejs-issues-20), and [additional features](https://github.com/bestiejs/lodash#features).
|
The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash](https://lodash.com/) with packages for [Bower](http://bower.io/), [Component](http://component.github.io/), & [Volo](http://volojs.org/).
|
||||||
|
|
||||||
Lo-Dash’s performance is gained by avoiding slower native methods, instead opting for simplified non-ES5 compliant methods optimized for common usage, and by leveraging function compilation to reduce the number of overall function calls.
|
Generated using [lodash-cli](https://www.npmjs.com/package/lodash-cli):
|
||||||
|
|
||||||
## Download
|
|
||||||
|
|
||||||
* [Development source](https://raw.github.com/bestiejs/lodash/v0.5.0/lodash.js)
|
|
||||||
* [Production source](https://raw.github.com/bestiejs/lodash/v0.5.0/lodash.min.js)
|
|
||||||
* CDN copies of ≤ [v0.4.2](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.4.2/lodash.min.js) are available on [cdnjs](http://cdnjs.com/) thanks to [CloudFlare](http://www.cloudflare.com/)
|
|
||||||
* For optimal performance, [create a custom build](https://github.com/bestiejs/lodash#custom-builds) with only the features you need
|
|
||||||
|
|
||||||
## Dive in
|
|
||||||
|
|
||||||
We’ve got [API docs](http://lodash.com/docs), [benchmarks](http://lodash.com/benchmarks), and [unit tests](http://lodash.com/tests).
|
|
||||||
|
|
||||||
Create your own benchmarks at [jsPerf](http://jsperf.com), or [search](http://jsperf.com/search?q=lodash) for existing ones.
|
|
||||||
|
|
||||||
For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/lodash/wiki/Roadmap).
|
|
||||||
|
|
||||||
## Screencasts
|
|
||||||
|
|
||||||
For more information check out these screencasts over Lo-Dash:
|
|
||||||
|
|
||||||
* [Introducing Lo-Dash](https://vimeo.com/44154599)
|
|
||||||
* [Lo-Dash optimizations and custom builds](https://vimeo.com/44154601)
|
|
||||||
* [Lo-Dash’s origin and why it’s a better utility belt](https://vimeo.com/44154600)
|
|
||||||
* [Unit testing in Lo-Dash](https://vimeo.com/45865290)
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
* AMD loader support ([RequireJS](http://requirejs.org/), [curl.js](https://github.com/cujojs/curl), etc.)
|
|
||||||
* [_.bind](http://lodash.com/docs#bind) supports *"lazy"* binding
|
|
||||||
* [_.clone](http://lodash.com/docs#clone) supports *"deep"* cloning
|
|
||||||
* [_.countBy](http://lodash.com/docs#countBy) as a compainion function for [_.groupBy](http://lodash.com/docs#groupBy) and [_.sortBy](http://lodash.com/docs#sortBy)
|
|
||||||
* [_.debounce](http://lodash.com/docs#debounce)’ed functions match [_.throttle](http://lodash.com/docs#throttle)’ed functions’ return value behavior
|
|
||||||
* [_.drop](http://lodash.com/docs#drop) for the inverse functionality of [_.pick](http://lodash.com/docs#pick)
|
|
||||||
* [_.forEach](http://lodash.com/docs#forEach) is chainable and supports exiting iteration early
|
|
||||||
* [_.forIn](http://lodash.com/docs#forIn) for iterating over an object’s own and inherited properties
|
|
||||||
* [_.forOwn](http://lodash.com/docs#forOwn) for iterating over an object’s own properties
|
|
||||||
* [_.groupBy](http://lodash.com/docs#groupBy), [_.sortedIndex](http://lodash.com/docs#sortedIndex), and [_.uniq](http://lodash.com/docs#uniq) accept a `thisArg` argument
|
|
||||||
* [_.indexOf](http://lodash.com/docs#indexOf) and [_.lastIndexOf](http://lodash.com/docs#lastIndexOf) accept a `fromIndex` argument
|
|
||||||
* [_.merge](http://lodash.com/docs#merge) for a *"deep"* [_.extend](http://lodash.com/docs#extend)
|
|
||||||
* [_.partial](http://lodash.com/docs#partial) for partial application without `this` binding
|
|
||||||
* [_.template](http://lodash.com/docs#template) utilizes [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) for easier debugging
|
|
||||||
* [_.where](http://lodash.com/docs#where) for filtering collections by contained properties
|
|
||||||
* [_.zipObject](http://lodash.com/docs#zipObject) for composing objects
|
|
||||||
* [_.contains](http://lodash.com/docs#contains), [_.size](http://lodash.com/docs#size), [_.toArray](http://lodash.com/docs#toArray),
|
|
||||||
[and more…](http://lodash.com/docs "_.every, _.filter, _.find, _.forEach, _.groupBy, _.invoke, _.map, _.pluck, _.reduce, _.reduceRight, _.reject, _.some, _sortBy") accept strings
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
Lo-Dash has been tested in at least Chrome 5-21, Firefox 1.5-13, IE 6-9, Opera 9.25-12.01, Safari 3-6, Node.js 0.4.8-0.8.7, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
|
|
||||||
|
|
||||||
## Custom builds
|
|
||||||
|
|
||||||
Custom builds make it easy to create lightweight versions of Lo-Dash containing only the methods you need.
|
|
||||||
We handle all the method dependency and alias mapping for you.
|
|
||||||
|
|
||||||
* Backbone builds, containing all methods required by Backbone, may be created using the `backbone` modifier argument.
|
|
||||||
```bash
|
```bash
|
||||||
lodash backbone
|
$ lodash modern -o ./lodash.js
|
||||||
```
|
```
|
||||||
|
|
||||||
* CSP builds, supporting default Content Security Policy restrictions, may be created using the `csp` modifier argument.
|
## Community
|
||||||
```bash
|
|
||||||
lodash csp
|
|
||||||
```
|
|
||||||
|
|
||||||
* Legacy builds, tailored for older browsers without [ES5 support](http://es5.github.com/), may be created using the `legacy` modifier argument.
|
[](https://gitter.im/lodash/lodash)
|
||||||
```bash
|
|
||||||
lodash legacy
|
|
||||||
```
|
|
||||||
|
|
||||||
* Mobile builds, with IE < 9 bug fixes and method compilation removed, may be created using the `mobile` modifier argument.
|
## Module formats
|
||||||
```bash
|
|
||||||
lodash mobile
|
|
||||||
```
|
|
||||||
|
|
||||||
* Strict builds, with `_.bindAll`, `_.defaults`, and `_.extend` in [strict mode](http://es5.github.com/#C), may be created using the `strict` modifier argument.
|
lodash is also available in a variety of other builds & module formats.
|
||||||
```bash
|
|
||||||
lodash strict
|
|
||||||
```
|
|
||||||
|
|
||||||
* Underscore builds, containing only methods included in Underscore, may be created using the `underscore` modifier argument.
|
* npm packages for [modern](https://www.npmjs.com/package/lodash), [compatibility](https://www.npmjs.com/package/lodash-compat), & [per method](https://www.npmjs.com/browse/keyword/lodash-modularized) builds
|
||||||
```bash
|
* AMD modules for [modern](https://github.com/lodash/lodash/tree/3.8.0-amd) & [compatibility](https://github.com/lodash/lodash-compat/tree/3.8.0-amd) builds
|
||||||
lodash underscore
|
* ES modules for the [modern](https://github.com/lodash/lodash/tree/3.8.0-es) build
|
||||||
```
|
|
||||||
|
|
||||||
Custom builds may be created in three ways:
|
## Further Reading
|
||||||
|
|
||||||
1. Use the `category` argument to pass the categories of methods to include in the build.<br>
|
* [API Documentation](https://lodash.com/docs)
|
||||||
Valid categories are *"arrays"*, *"chaining"*, *"collections"*, *"functions"*, *"objects"*, and *"utilities"*.
|
* [Build Differences](https://github.com/lodash/lodash/wiki/Build-Differences)
|
||||||
```bash
|
* [Changelog](https://github.com/lodash/lodash/wiki/Changelog)
|
||||||
lodash category=collections,functions
|
* [Release Notes](https://github.com/lodash/lodash/releases)
|
||||||
lodash category="collections, functions"
|
* [Roadmap](https://github.com/lodash/lodash/wiki/Roadmap)
|
||||||
```
|
* [More Resources](https://github.com/lodash/lodash/wiki/Resources)
|
||||||
|
|
||||||
2. Use the `exclude` argument to pass the names of methods to exclude from the build.
|
|
||||||
```bash
|
|
||||||
lodash exclude=union,uniq,zip
|
|
||||||
lodash exclude="union, uniq, zip"
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Use the `include` argument to pass the names of methods to include in the build.
|
|
||||||
```bash
|
|
||||||
lodash include=each,filter,map
|
|
||||||
lodash include="each, filter, map"
|
|
||||||
```
|
|
||||||
|
|
||||||
All arguments, except `backbone` with `underscore`, `exclude` with `include`, and `legacy` with `csp`/`mobile`, may be combined.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
lodash backbone legacy category=utilities exclude=first,last
|
|
||||||
lodash underscore mobile strict category=functions include=pick,uniq
|
|
||||||
```
|
|
||||||
|
|
||||||
The `lodash` command-line utility is available when Lo-Dash is installed as a global package (i.e. `npm install -g lodash`).
|
|
||||||
|
|
||||||
Custom builds are saved to `lodash.custom.js` and `lodash.custom.min.js`.
|
|
||||||
|
|
||||||
## Installation and usage
|
|
||||||
|
|
||||||
In browsers:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<script src="lodash.js"></script>
|
|
||||||
```
|
|
||||||
|
|
||||||
Using [npm](http://npmjs.org/):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install lodash
|
|
||||||
npm install -g lodash
|
|
||||||
```
|
|
||||||
|
|
||||||
In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/):
|
|
||||||
|
|
||||||
```js
|
|
||||||
var _ = require('lodash');
|
|
||||||
```
|
|
||||||
|
|
||||||
In [RingoJS v0.7.0-](http://ringojs.org/):
|
|
||||||
|
|
||||||
```js
|
|
||||||
var _ = require('lodash')._;
|
|
||||||
```
|
|
||||||
|
|
||||||
In [Rhino](http://www.mozilla.org/rhino/):
|
|
||||||
|
|
||||||
```js
|
|
||||||
load('lodash.js');
|
|
||||||
```
|
|
||||||
|
|
||||||
In an AMD loader like [RequireJS](http://requirejs.org/):
|
|
||||||
|
|
||||||
```js
|
|
||||||
require({
|
|
||||||
'paths': {
|
|
||||||
'underscore': 'path/to/lodash'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
['underscore'], function(_) {
|
|
||||||
console.log(_.VERSION);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Resolved Underscore.js issues <sup>(20+)</sup>
|
|
||||||
|
|
||||||
* Allow iteration of objects with a `length` property [[#148](https://github.com/documentcloud/underscore/issues/148), [#154](https://github.com/documentcloud/underscore/issues/154), [#252](https://github.com/documentcloud/underscore/issues/252), [#448](https://github.com/documentcloud/underscore/issues/448), [#659](https://github.com/documentcloud/underscore/issues/659), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L544-550)]
|
|
||||||
* Ensure array-like objects with invalid `length` properties are treated like regular objects [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L491-501)]
|
|
||||||
* Ensure *"Arrays"* methods allow falsey `array` arguments [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1487-1525)]
|
|
||||||
* Ensure *"Collections"* methods allow string `collection` arguments [[#247](https://github.com/documentcloud/underscore/issues/247), [#276](https://github.com/documentcloud/underscore/issues/276), [#561](https://github.com/documentcloud/underscore/pull/561), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L503-521)]
|
|
||||||
* Ensure templates compiled with errors are inspectable [[#666](https://github.com/documentcloud/underscore/issues/666), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1232-1235)]
|
|
||||||
* Fix cross-browser object iteration bugs [[#60](https://github.com/documentcloud/underscore/issues/60), [#376](https://github.com/documentcloud/underscore/issues/376), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L555-580)]
|
|
||||||
* Handle arrays with `undefined` values correctly in IE < 9 [[#601](https://github.com/documentcloud/underscore/issues/601)]
|
|
||||||
* Methods should work on pages with incorrectly shimmed native methods [[#7](https://github.com/documentcloud/underscore/issues/7), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L117-123)]
|
|
||||||
* Register as an AMD module, but still export to global [[#431](https://github.com/documentcloud/underscore/pull/431), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L101-115)]
|
|
||||||
* `_(…)` should return passed wrapper instances [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L135-138)]
|
|
||||||
* `_.clone` should allow `deep` cloning [[#595](https://github.com/documentcloud/underscore/pull/595), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L197-212)]
|
|
||||||
* `_.contains` should work with strings [[#667](https://github.com/documentcloud/underscore/pull/667), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L267-276)]
|
|
||||||
* `_.escape` should return an empty string when passed `null` or `undefined` [[#427](https://github.com/documentcloud/underscore/issues/427), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L367-370)]
|
|
||||||
* `_.extend` should recursively extend objects [[#379](https://github.com/documentcloud/underscore/pull/379), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L882-955)]
|
|
||||||
* `_.forEach` should be chainable [[#142](https://github.com/documentcloud/underscore/issues/142), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L486-489)]
|
|
||||||
* `_.forEach` should allow exiting iteration early [[#211](https://github.com/documentcloud/underscore/issues/211), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L582-601)]
|
|
||||||
* `_.groupBy` should add values to own, not inherited, properties [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L616-623)]
|
|
||||||
* `_.isEmpty` and `_.size` should support jQuery/MooTools DOM query collections [[#690](https://github.com/documentcloud/underscore/pull/690), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L716-721)]
|
|
||||||
* `_.isEqual` should return `true` for like-objects from different documents [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L757-777)]
|
|
||||||
* `_.isObject` should avoid V8 bug [#2291](http://code.google.com/p/v8/issues/detail?id=2291) [[#605](https://github.com/documentcloud/underscore/issues/605), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L785-797)]
|
|
||||||
* `_.isNaN(new Number(NaN))` should return `true` [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L805-807)]
|
|
||||||
* `_.keys` and `_.size` should work with `arguments` objects cross-browser [[#396](https://github.com/documentcloud/underscore/issues/396), [#653](https://github.com/documentcloud/underscore/issues/653), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L817-819)]
|
|
||||||
* `_.once` should free the given function for garbage collection [[#693](https://github.com/documentcloud/underscore/pull/693)]
|
|
||||||
* `_.range` should coerce arguments to numbers [[#634](https://github.com/documentcloud/underscore/issues/634), [#683](https://github.com/documentcloud/underscore/issues/683), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1042-1045)]
|
|
||||||
* `_.reduceRight` should pass correct callback arguments when iterating objects [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1053-1067)]
|
|
||||||
* `_.size` should return the `length` of string values [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1112-1114)]
|
|
||||||
* `_.size` shouldn’t error on falsey values [[#650](https://github.com/documentcloud/underscore/pull/650), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1116-1123)]
|
|
||||||
* `_.sortedIndex` should support arrays with high `length` values [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1202-1211)]
|
|
||||||
* `_.template` should not augment the `options` object [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1226-1230)]
|
|
||||||
* `_.throttle` should work when called in a loop [[#502](https://github.com/documentcloud/underscore/issues/502), [test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1322-1332)]
|
|
||||||
* `_.zipObject` should accept less than two arguments [[test](https://github.com/bestiejs/lodash/blob/v0.5.0/test/test.js#L1449-1451)]
|
|
||||||
|
|
||||||
## Optimized methods <sup>(50+)</sup>
|
|
||||||
|
|
||||||
* `_.bind`
|
|
||||||
* `_.bindAll`
|
|
||||||
* `_.clone`
|
|
||||||
* `_.compact`
|
|
||||||
* `_.contains`, `_.include`
|
|
||||||
* `_.defaults`
|
|
||||||
* `_.defer`
|
|
||||||
* `_.difference`
|
|
||||||
* `_.each`
|
|
||||||
* `_.escape`
|
|
||||||
* `_.every`, `_.all`
|
|
||||||
* `_.extend`
|
|
||||||
* `_.filter`, `_.select`
|
|
||||||
* `_.find`, `_.detect`
|
|
||||||
* `_.flatten`
|
|
||||||
* `_.forEach`, `_.each`
|
|
||||||
* `_.functions`, `_.methods`
|
|
||||||
* `_.groupBy`
|
|
||||||
* `_.indexOf`
|
|
||||||
* `_.intersection`
|
|
||||||
* `_.invoke`
|
|
||||||
* `_.isArguments`
|
|
||||||
* `_.isDate`
|
|
||||||
* `_.isEmpty`
|
|
||||||
* `_.isFinite`
|
|
||||||
* `_.isFunction`
|
|
||||||
* `_.isObject`
|
|
||||||
* `_.isNumber`
|
|
||||||
* `_.isRegExp`
|
|
||||||
* `_.isString`
|
|
||||||
* `_.keys`
|
|
||||||
* `_.lastIndexOf`
|
|
||||||
* `_.map`, `_.collect`
|
|
||||||
* `_.max`
|
|
||||||
* `_.memoize`
|
|
||||||
* `_.min`
|
|
||||||
* `_.mixin`
|
|
||||||
* `_.pick`
|
|
||||||
* `_.pluck`
|
|
||||||
* `_.reduce`, `_.foldl`, `_.inject`
|
|
||||||
* `_.reject`
|
|
||||||
* `_.result`
|
|
||||||
* `_.shuffle`
|
|
||||||
* `_.some`, `_.any`
|
|
||||||
* `_.sortBy`
|
|
||||||
* `_.sortedIndex`
|
|
||||||
* `_.template`
|
|
||||||
* `_.throttle`
|
|
||||||
* `_.times`
|
|
||||||
* `_.toArray`
|
|
||||||
* `_.union`
|
|
||||||
* `_.uniq`, `_.unique`
|
|
||||||
* `_.values`
|
|
||||||
* `_.without`
|
|
||||||
* `_.wrap`
|
|
||||||
* `_.zip`
|
|
||||||
* plus all `_(…)` method wrappers
|
|
||||||
|
|
||||||
## Release Notes
|
|
||||||
|
|
||||||
### <sup>v0.5.0</sup>
|
|
||||||
|
|
||||||
* Added [_.countBy](http://lodash.com/docs#countBy), [_.drop](http://lodash.com/docs#drop), [_.merge](http://lodash.com/docs#merge), and [_.where](http://lodash.com/docs#where)
|
|
||||||
* Added `csp` *(Content Security Policy)* and `underscore` build options
|
|
||||||
* Added `deep` cloning support to `_.clone`
|
|
||||||
* Added [Jam](http://jamjs.org/) package support
|
|
||||||
* Added support for exiting `_.forEach`, `_.forIn`, and `_.forOwn` early by returning `false` in the `callback`
|
|
||||||
* Added support for jQuery/MooTools DOM query collections to `_.isEmpty` and `_.size`
|
|
||||||
* Ensured development build works with IE conditional compilation enabled
|
|
||||||
* Ensured `_.clone` doesn't clone functions, DOM nodes, `arguments` objects, and objects created by constructors other than `Object`
|
|
||||||
* Ensured `_.filter`’s `callback` can't modify result values
|
|
||||||
* Ensured `_.isEmpty`, `_.isEquals`, and `_.size` support `arguments` objects
|
|
||||||
* Ensured `_.isEqual` doesn't inspect DOM nodes, works with objects from other documents, and calls custom `isEqual` methods before checking strict equality
|
|
||||||
* Ensured `_.once` frees the given function for garbage collection
|
|
||||||
* Ensured `_.sortBy` performs a stable sort
|
|
||||||
* Ensured `reEvaluateDelimiter` is assigned when `_.templateSettings.evaluate` is undefined
|
|
||||||
* Made `_.range` coerce arguments to numbers
|
|
||||||
* Optimized `_.isFunction`
|
|
||||||
|
|
||||||
The full changelog is available [here](https://github.com/bestiejs/lodash/wiki/Changelog).
|
|
||||||
|
|
||||||
## BestieJS
|
|
||||||
|
|
||||||
Lo-Dash is part of the BestieJS *"Best in Class"* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation.
|
|
||||||
|
|
||||||
## Author
|
|
||||||
|
|
||||||
* [John-David Dalton](http://allyoucanleet.com/)
|
|
||||||
[](https://twitter.com/jdalton "Follow @jdalton on Twitter")
|
|
||||||
|
|
||||||
## Contributors
|
|
||||||
|
|
||||||
* [Kit Cambridge](http://kitcambridge.github.com/)
|
|
||||||
[](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter")
|
|
||||||
* [Mathias Bynens](http://mathiasbynens.be/)
|
|
||||||
[](https://twitter.com/mathias "Follow @mathias on Twitter")
|
|
||||||
|
|||||||
20
bower.json
Normal file
20
bower.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "lodash",
|
||||||
|
"version": "3.8.0",
|
||||||
|
"main": "lodash.js",
|
||||||
|
"ignore": [
|
||||||
|
".*",
|
||||||
|
"*.custom.*",
|
||||||
|
"*.log",
|
||||||
|
"*.map",
|
||||||
|
"*.md",
|
||||||
|
"lodash.src.js",
|
||||||
|
"component.json",
|
||||||
|
"package.json",
|
||||||
|
"doc",
|
||||||
|
"node_modules",
|
||||||
|
"perf",
|
||||||
|
"test",
|
||||||
|
"vendor"
|
||||||
|
]
|
||||||
|
}
|
||||||
347
build/minify.js
347
build/minify.js
@@ -1,347 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
;(function() {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/** The Node filesystem, path, `zlib`, and child process modules */
|
|
||||||
var fs = require('fs'),
|
|
||||||
gzip = require('zlib').gzip,
|
|
||||||
path = require('path'),
|
|
||||||
spawn = require('child_process').spawn;
|
|
||||||
|
|
||||||
/** The directory that is the base of the repository */
|
|
||||||
var basePath = path.join(__dirname, '../');
|
|
||||||
|
|
||||||
/** The directory where the Closure Compiler is located */
|
|
||||||
var closurePath = path.join(basePath, 'vendor', 'closure-compiler', 'compiler.jar');
|
|
||||||
|
|
||||||
/** The distribution directory */
|
|
||||||
var distPath = path.join(basePath, 'dist');
|
|
||||||
|
|
||||||
/** Load other modules */
|
|
||||||
var preprocess = require(path.join(__dirname, 'pre-compile')),
|
|
||||||
postprocess = require(path.join(__dirname, 'post-compile')),
|
|
||||||
uglifyJS = require(path.join(basePath, 'vendor', 'uglifyjs', 'uglify-js'));
|
|
||||||
|
|
||||||
/** Closure Compiler command-line options */
|
|
||||||
var closureOptions = [
|
|
||||||
'--compilation_level=ADVANCED_OPTIMIZATIONS',
|
|
||||||
'--language_in=ECMASCRIPT5_STRICT',
|
|
||||||
'--warning_level=QUIET'
|
|
||||||
];
|
|
||||||
|
|
||||||
/** Reassign `existsSync` for older versions of Node */
|
|
||||||
fs.existsSync || (fs.existsSync = path.existsSync);
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The exposed `minify` function minifies a given Lo-Dash `source` and invokes
|
|
||||||
* the `onComplete` callback when finished.
|
|
||||||
*
|
|
||||||
* @param {String} source The source to minify.
|
|
||||||
* @param {String} workingName The name to give temporary files creates during the minification process.
|
|
||||||
* @param {Function} onComplete A function called when minification has completed.
|
|
||||||
*/
|
|
||||||
function minify(source, workingName, onComplete) {
|
|
||||||
new Minify(source, workingName, onComplete);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Minify constructor used to keep state of each `minify` invocation.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @constructor
|
|
||||||
* @param {String} source The source to minify.
|
|
||||||
* @param {String} workingName The name to give temporary files creates during the minification process.
|
|
||||||
* @param {Function} onComplete A function called when minification has completed.
|
|
||||||
*/
|
|
||||||
function Minify(source, workingName, onComplete) {
|
|
||||||
// create the destination directory if it doesn't exist
|
|
||||||
if (!fs.existsSync(distPath)) {
|
|
||||||
// avoid errors when called as a npm executable
|
|
||||||
try {
|
|
||||||
fs.mkdirSync(distPath);
|
|
||||||
} catch(e) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
this.compiled = {};
|
|
||||||
this.hybrid = {};
|
|
||||||
this.uglified = {};
|
|
||||||
this.onComplete = onComplete;
|
|
||||||
this.source = source = preprocess(source);
|
|
||||||
this.workingName = workingName;
|
|
||||||
|
|
||||||
// begin the minification process
|
|
||||||
closureCompile.call(this, source, onClosureCompile.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compresses a `source` string using the Closure Compiler. Yields the
|
|
||||||
* minified result, and any exceptions encountered, to a `callback` function.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {String} source The JavaScript source to minify.
|
|
||||||
* @param {String} [message] The message to log.
|
|
||||||
* @param {Function} callback The function to call once the process completes.
|
|
||||||
*/
|
|
||||||
function closureCompile(source, message, callback) {
|
|
||||||
// the standard error stream, standard output stream, and Closure Compiler process
|
|
||||||
var error = '',
|
|
||||||
output = '',
|
|
||||||
compiler = spawn('java', ['-jar', closurePath].concat(closureOptions));
|
|
||||||
|
|
||||||
// juggle arguments
|
|
||||||
if (typeof message == 'function') {
|
|
||||||
callback = message;
|
|
||||||
message = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(message == null
|
|
||||||
? 'Compressing ' + this.workingName + ' using the Closure Compiler...'
|
|
||||||
: message
|
|
||||||
);
|
|
||||||
|
|
||||||
compiler.stdout.on('data', function(data) {
|
|
||||||
// append the data to the output stream
|
|
||||||
output += data;
|
|
||||||
});
|
|
||||||
|
|
||||||
compiler.stderr.on('data', function(data) {
|
|
||||||
// append the error message to the error stream
|
|
||||||
error += data;
|
|
||||||
});
|
|
||||||
|
|
||||||
compiler.on('exit', function(status) {
|
|
||||||
var exception = null;
|
|
||||||
|
|
||||||
// `status` contains the process exit code
|
|
||||||
if (status) {
|
|
||||||
exception = new Error(error);
|
|
||||||
exception.status = status;
|
|
||||||
}
|
|
||||||
callback(exception, output);
|
|
||||||
});
|
|
||||||
|
|
||||||
// proxy the standard input to the Closure Compiler
|
|
||||||
compiler.stdin.end(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compresses a `source` string using UglifyJS. Yields the result to a
|
|
||||||
* `callback` function. This function is synchronous; the `callback` is used
|
|
||||||
* for symmetry.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {String} source The JavaScript source to minify.
|
|
||||||
* @param {String} [message] The message to log.
|
|
||||||
* @param {Function} callback The function to call once the process completes.
|
|
||||||
*/
|
|
||||||
function uglify(source, message, callback) {
|
|
||||||
var exception,
|
|
||||||
result,
|
|
||||||
ugly = uglifyJS.uglify;
|
|
||||||
|
|
||||||
// juggle arguments
|
|
||||||
if (typeof message == 'function') {
|
|
||||||
callback = message;
|
|
||||||
message = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(message == null
|
|
||||||
? 'Compressing ' + this.workingName + ' using UglifyJS...'
|
|
||||||
: message
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
|
||||||
result = ugly.gen_code(
|
|
||||||
// enable unsafe transformations
|
|
||||||
ugly.ast_squeeze_more(
|
|
||||||
ugly.ast_squeeze(
|
|
||||||
// munge variable and function names, excluding the special `define`
|
|
||||||
// function exposed by AMD loaders
|
|
||||||
ugly.ast_mangle(uglifyJS.parser.parse(source), {
|
|
||||||
'except': ['define']
|
|
||||||
}
|
|
||||||
))), {
|
|
||||||
'ascii_only': true
|
|
||||||
});
|
|
||||||
} catch(e) {
|
|
||||||
exception = e;
|
|
||||||
}
|
|
||||||
// lines are restricted to 500 characters for consistency with the Closure Compiler
|
|
||||||
callback(exception, result && ugly.split_lines(result, 500));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `closureCompile()` callback.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Object|Undefined} exception The error object.
|
|
||||||
* @param {String} result The resulting minified source.
|
|
||||||
*/
|
|
||||||
function onClosureCompile(exception, result) {
|
|
||||||
if (exception) {
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
// store the post-processed Closure Compiler result and gzip it
|
|
||||||
this.compiled.source = result = postprocess(result);
|
|
||||||
gzip(result, onClosureGzip.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Closure Compiler `gzip` callback.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Object|Undefined} exception The error object.
|
|
||||||
* @param {Buffer} result The resulting gzipped source.
|
|
||||||
*/
|
|
||||||
function onClosureGzip(exception, result) {
|
|
||||||
if (exception) {
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
// store the gzipped result and report the size
|
|
||||||
this.compiled.gzip = result;
|
|
||||||
console.log('Done. Size: %d bytes.', result.length);
|
|
||||||
|
|
||||||
// next, minify the source using only UglifyJS
|
|
||||||
uglify.call(this, this.source, onUglify.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `uglify()` callback.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Object|Undefined} exception The error object.
|
|
||||||
* @param {String} result The resulting minified source.
|
|
||||||
*/
|
|
||||||
function onUglify(exception, result) {
|
|
||||||
if (exception) {
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
// store the post-processed Uglified result and gzip it
|
|
||||||
this.uglified.source = result = postprocess(result);
|
|
||||||
gzip(result, onUglifyGzip.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The UglifyJS `gzip` callback.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Object|Undefined} exception The error object.
|
|
||||||
* @param {Buffer} result The resulting gzipped source.
|
|
||||||
*/
|
|
||||||
function onUglifyGzip(exception, result) {
|
|
||||||
if (exception) {
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
var message = 'Compressing ' + this.workingName + ' using hybrid minification...';
|
|
||||||
|
|
||||||
// store the gzipped result and report the size
|
|
||||||
this.uglified.gzip = result;
|
|
||||||
console.log('Done. Size: %d bytes.', result.length);
|
|
||||||
|
|
||||||
// next, minify the Closure Compiler minified source using UglifyJS
|
|
||||||
uglify.call(this, this.compiled.source, message, onHybrid.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The hybrid `uglify()` callback.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Object|Undefined} exception The error object.
|
|
||||||
* @param {String} result The resulting minified source.
|
|
||||||
*/
|
|
||||||
function onHybrid(exception, result) {
|
|
||||||
if (exception) {
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
// store the post-processed Uglified result and gzip it
|
|
||||||
this.hybrid.source = result = postprocess(result);
|
|
||||||
gzip(result, onHybridGzip.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The hybrid `gzip` callback.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Object|Undefined} exception The error object.
|
|
||||||
* @param {Buffer} result The resulting gzipped source.
|
|
||||||
*/
|
|
||||||
function onHybridGzip(exception, result) {
|
|
||||||
if (exception) {
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
// store the gzipped result and report the size
|
|
||||||
this.hybrid.gzip = result;
|
|
||||||
console.log('Done. Size: %d bytes.', result.length);
|
|
||||||
|
|
||||||
// finish by choosing the smallest compressed file
|
|
||||||
onComplete.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The callback executed after JavaScript source is minified and gzipped.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
function onComplete() {
|
|
||||||
var compiled = this.compiled,
|
|
||||||
hybrid = this.hybrid,
|
|
||||||
name = this.workingName,
|
|
||||||
uglified = this.uglified;
|
|
||||||
|
|
||||||
// avoid errors when called as a npm executable
|
|
||||||
try {
|
|
||||||
// save the Closure Compiled version to disk
|
|
||||||
fs.writeFileSync(path.join(distPath, name + '.compiler.js'), compiled.source);
|
|
||||||
fs.writeFileSync(path.join(distPath, name + '.compiler.js.gz'), compiled.gzip);
|
|
||||||
|
|
||||||
// save the Uglified version to disk
|
|
||||||
fs.writeFileSync(path.join(distPath, name + '.uglify.js'), uglified.source);
|
|
||||||
fs.writeFileSync(path.join(distPath, name + '.uglify.js.gz'), uglified.gzip);
|
|
||||||
|
|
||||||
// save the hybrid minified version to disk
|
|
||||||
fs.writeFileSync(path.join(distPath, name + '.hybrid.js'), hybrid.source);
|
|
||||||
fs.writeFileSync(path.join(distPath, name + '.hybrid.js.gz'), hybrid.gzip);
|
|
||||||
} catch(e) { }
|
|
||||||
|
|
||||||
// select the smallest gzipped file and use its minified counterpart as the
|
|
||||||
// official minified release (ties go to Closure Compiler)
|
|
||||||
var min = Math.min(compiled.gzip.length, hybrid.gzip.length, uglified.gzip.length);
|
|
||||||
|
|
||||||
// pass the minified source to the minify instances "onComplete" callback
|
|
||||||
this.onComplete(
|
|
||||||
compiled.gzip.length == min
|
|
||||||
? compiled.source
|
|
||||||
: uglified.gzip.length == min
|
|
||||||
? uglified.source
|
|
||||||
: hybrid.source
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
// expose `minify`
|
|
||||||
if (module != require.main) {
|
|
||||||
module.exports = minify;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// read the Lo-Dash source file from the first argument if the script
|
|
||||||
// was invoked directly (e.g. `node minify.js source.js`) and write to
|
|
||||||
// `<filename>.min.js`
|
|
||||||
(function() {
|
|
||||||
var filePath = process.argv[2],
|
|
||||||
dirPath = path.dirname(filePath),
|
|
||||||
source = fs.readFileSync(filePath, 'utf8'),
|
|
||||||
workingName = path.basename(filePath, '.js') + '.min';
|
|
||||||
|
|
||||||
minify(source, workingName, function(result) {
|
|
||||||
fs.writeFileSync(path.join(dirPath, workingName + '.js'), result, 'utf8');
|
|
||||||
});
|
|
||||||
}());
|
|
||||||
}
|
|
||||||
}());
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
;(function() {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/** The Node filesystem module */
|
|
||||||
var fs = require('fs');
|
|
||||||
|
|
||||||
/** The minimal license/copyright template */
|
|
||||||
var licenseTemplate =
|
|
||||||
'/*!\n' +
|
|
||||||
' Lo-Dash @VERSION lodash.com/license\n' +
|
|
||||||
' Underscore.js 1.3.3 github.com/documentcloud/underscore/blob/master/LICENSE\n' +
|
|
||||||
'*/';
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Post-process a given minified Lo-Dash `source`, preparing it for
|
|
||||||
* deployment.
|
|
||||||
*
|
|
||||||
* @param {String} source The source to process.
|
|
||||||
* @returns {String} Returns the processed source.
|
|
||||||
*/
|
|
||||||
function postprocess(source) {
|
|
||||||
// exit early if snippet isn't found
|
|
||||||
var snippet = /VERSION\s*[=:]\s*([\'"])(.*?)\1/.exec(source);
|
|
||||||
if (!snippet) {
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the version
|
|
||||||
var license = licenseTemplate.replace('@VERSION', snippet[2]);
|
|
||||||
|
|
||||||
// move vars exposed by Closure Compiler into the IIFE
|
|
||||||
source = source.replace(/^([^(\n]+)\s*(\(function[^)]+\){)/, '$2$1');
|
|
||||||
|
|
||||||
// unescape properties (i.e. foo["bar"] => foo.bar)
|
|
||||||
source = source.replace(/(\w)\["([^."]+)"\]/g, '$1.$2');
|
|
||||||
|
|
||||||
// correct AMD module definition for AMD build optimizers
|
|
||||||
source = source.replace(/("function")\s*==\s*(typeof define)\s*&&\s*\(?\s*("object")\s*==\s*(typeof define\.amd)\s*&&\s*(define\.amd)\s*\)?/, '$2==$1&&$4==$3&&$5');
|
|
||||||
|
|
||||||
// add license
|
|
||||||
source = license + '\n;' + source;
|
|
||||||
|
|
||||||
// add trailing semicolon
|
|
||||||
return source.replace(/[\s;]*$/, ';');
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
// expose `postprocess`
|
|
||||||
if (module != require.main) {
|
|
||||||
module.exports = postprocess;
|
|
||||||
} else {
|
|
||||||
// read the Lo-Dash source file from the first argument if the script
|
|
||||||
// was invoked directly (e.g. `node post-compile.js source.js`) and write to
|
|
||||||
// the same file
|
|
||||||
(function() {
|
|
||||||
var source = fs.readFileSync(process.argv[2], 'utf8');
|
|
||||||
fs.writeFileSync(process.argv[2], postprocess(source), 'utf8');
|
|
||||||
}());
|
|
||||||
}
|
|
||||||
}());
|
|
||||||
@@ -1,448 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
;(function() {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/** The Node filesystem module */
|
|
||||||
var fs = require('fs');
|
|
||||||
|
|
||||||
/** Used to minify variables embedded in compiled strings */
|
|
||||||
var compiledVars = [
|
|
||||||
'callback',
|
|
||||||
'collection',
|
|
||||||
'concat',
|
|
||||||
'ctor',
|
|
||||||
'hasOwnProperty',
|
|
||||||
'identity',
|
|
||||||
'index',
|
|
||||||
'iteratee',
|
|
||||||
'iteratorBind',
|
|
||||||
'length',
|
|
||||||
'nativeKeys',
|
|
||||||
'object',
|
|
||||||
'ownIndex',
|
|
||||||
'ownProps',
|
|
||||||
'prop',
|
|
||||||
'propertyIsEnumerable',
|
|
||||||
'propIndex',
|
|
||||||
'props',
|
|
||||||
'result',
|
|
||||||
'skipProto',
|
|
||||||
'slice',
|
|
||||||
'stringClass',
|
|
||||||
'thisArg',
|
|
||||||
'toString',
|
|
||||||
'value',
|
|
||||||
|
|
||||||
// lesser used variables
|
|
||||||
'accumulator',
|
|
||||||
'args',
|
|
||||||
'argsIndex',
|
|
||||||
'argsLength',
|
|
||||||
'arrayLikeClasses',
|
|
||||||
'ArrayProto',
|
|
||||||
'bind',
|
|
||||||
'callee',
|
|
||||||
'className',
|
|
||||||
'compareAscending',
|
|
||||||
'destValue',
|
|
||||||
'forIn',
|
|
||||||
'found',
|
|
||||||
'funcs',
|
|
||||||
'indexOf',
|
|
||||||
'indicator',
|
|
||||||
'isArguments',
|
|
||||||
'isArr',
|
|
||||||
'isArray',
|
|
||||||
'isFunc',
|
|
||||||
'isFunction',
|
|
||||||
'isPlainObject',
|
|
||||||
'methodName',
|
|
||||||
'noaccum',
|
|
||||||
'objectClass',
|
|
||||||
'objectTypes',
|
|
||||||
'pass',
|
|
||||||
'properties',
|
|
||||||
'property',
|
|
||||||
'propsLength',
|
|
||||||
'recursive',
|
|
||||||
'source',
|
|
||||||
'stack',
|
|
||||||
'stackLength',
|
|
||||||
'target',
|
|
||||||
'valueProp'
|
|
||||||
];
|
|
||||||
|
|
||||||
/** Used to minify `compileIterator` option properties */
|
|
||||||
var iteratorOptions = [
|
|
||||||
'args',
|
|
||||||
'array',
|
|
||||||
'arrayBranch',
|
|
||||||
'beforeLoop',
|
|
||||||
'bottom',
|
|
||||||
'exit',
|
|
||||||
'firstArg',
|
|
||||||
'hasDontEnumBug',
|
|
||||||
'inLoop',
|
|
||||||
'init',
|
|
||||||
'isKeysFast',
|
|
||||||
'object',
|
|
||||||
'objectBranch',
|
|
||||||
'noArgsEnum',
|
|
||||||
'noCharByIndex',
|
|
||||||
'shadowed',
|
|
||||||
'top',
|
|
||||||
'useHas',
|
|
||||||
'useStrict'
|
|
||||||
];
|
|
||||||
|
|
||||||
/** Used to minify variables and string values to a single character */
|
|
||||||
var minNames = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
|
|
||||||
minNames.push.apply(minNames, minNames.map(function(value) {
|
|
||||||
return value + value;
|
|
||||||
}));
|
|
||||||
|
|
||||||
/** Used to protect the specified properties from getting minified */
|
|
||||||
var propWhitelist = [
|
|
||||||
'_',
|
|
||||||
'_chain',
|
|
||||||
'_wrapped',
|
|
||||||
'after',
|
|
||||||
'all',
|
|
||||||
'amd',
|
|
||||||
'any',
|
|
||||||
'attachEvent',
|
|
||||||
'bind',
|
|
||||||
'bindAll',
|
|
||||||
'chain',
|
|
||||||
'clearTimeout',
|
|
||||||
'clone',
|
|
||||||
'collect',
|
|
||||||
'compact',
|
|
||||||
'compose',
|
|
||||||
'contains',
|
|
||||||
'countBy',
|
|
||||||
'criteria',
|
|
||||||
'debounce',
|
|
||||||
'defaults',
|
|
||||||
'defer',
|
|
||||||
'delay',
|
|
||||||
'detect',
|
|
||||||
'difference',
|
|
||||||
'drop',
|
|
||||||
'each',
|
|
||||||
'environment',
|
|
||||||
'escape',
|
|
||||||
'escape',
|
|
||||||
'evaluate',
|
|
||||||
'every',
|
|
||||||
'extend',
|
|
||||||
'filter',
|
|
||||||
'find',
|
|
||||||
'first',
|
|
||||||
'flatten',
|
|
||||||
'foldl',
|
|
||||||
'foldr',
|
|
||||||
'forEach',
|
|
||||||
'forIn',
|
|
||||||
'forOwn',
|
|
||||||
'functions',
|
|
||||||
'groupBy',
|
|
||||||
'has',
|
|
||||||
'head',
|
|
||||||
'identity',
|
|
||||||
'include',
|
|
||||||
'index',
|
|
||||||
'indexOf',
|
|
||||||
'initial',
|
|
||||||
'inject',
|
|
||||||
'interpolate',
|
|
||||||
'intersection',
|
|
||||||
'invoke',
|
|
||||||
'isArguments',
|
|
||||||
'isArray',
|
|
||||||
'isBoolean',
|
|
||||||
'isDate',
|
|
||||||
'isElement',
|
|
||||||
'isEmpty',
|
|
||||||
'isEqual',
|
|
||||||
'isEqual',
|
|
||||||
'isFinite',
|
|
||||||
'isFinite',
|
|
||||||
'isFunction',
|
|
||||||
'isNaN',
|
|
||||||
'isNull',
|
|
||||||
'isNumber',
|
|
||||||
'isObject',
|
|
||||||
'isRegExp',
|
|
||||||
'isString',
|
|
||||||
'isUndefined',
|
|
||||||
'keys',
|
|
||||||
'last',
|
|
||||||
'lastIndexOf',
|
|
||||||
'map',
|
|
||||||
'max',
|
|
||||||
'memoize',
|
|
||||||
'merge',
|
|
||||||
'methods',
|
|
||||||
'min',
|
|
||||||
'mixin',
|
|
||||||
'noConflict',
|
|
||||||
'once',
|
|
||||||
'opera',
|
|
||||||
'partial',
|
|
||||||
'pick',
|
|
||||||
'pluck',
|
|
||||||
'range',
|
|
||||||
'reduce',
|
|
||||||
'reduceRight',
|
|
||||||
'reject',
|
|
||||||
'rest',
|
|
||||||
'result',
|
|
||||||
'select',
|
|
||||||
'setTimeout',
|
|
||||||
'shuffle',
|
|
||||||
'size',
|
|
||||||
'some',
|
|
||||||
'sortBy',
|
|
||||||
'sortedIndex',
|
|
||||||
'source',
|
|
||||||
'tail',
|
|
||||||
'take',
|
|
||||||
'tap',
|
|
||||||
'template',
|
|
||||||
'templateSettings',
|
|
||||||
'throttle',
|
|
||||||
'times',
|
|
||||||
'toArray',
|
|
||||||
'union',
|
|
||||||
'uniq',
|
|
||||||
'unique',
|
|
||||||
'uniqueId',
|
|
||||||
'value',
|
|
||||||
'values',
|
|
||||||
'variable',
|
|
||||||
'VERSION',
|
|
||||||
'where',
|
|
||||||
'without',
|
|
||||||
'wrap',
|
|
||||||
'zip',
|
|
||||||
'zipObject'
|
|
||||||
];
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pre-process a given Lo-Dash `source`, preparing it for minification.
|
|
||||||
*
|
|
||||||
* @param {String} source The source to process.
|
|
||||||
* @returns {String} Returns the processed source.
|
|
||||||
*/
|
|
||||||
function preprocess(source) {
|
|
||||||
// remove copyright to add later in post-compile.js
|
|
||||||
source = source.replace(/\/\*![\s\S]+?\*\//, '');
|
|
||||||
|
|
||||||
// remove unrecognized JSDoc tags so Closure Compiler won't complain
|
|
||||||
source = source.replace(/@(?:alias|category)\b.*/g, '');
|
|
||||||
|
|
||||||
// manually convert `arrayLikeClasses` property assignments because
|
|
||||||
// Closure Compiler errors trying to minify them
|
|
||||||
source = source.replace(/(arrayLikeClasses =)[\s\S]+?= *true/,
|
|
||||||
"$1{'[object Arguments]': true, '[object Array]': true, '[object Boolean]': false, " +
|
|
||||||
"'[object Date]': false, '[object Function]': false, '[object Number]': false, " +
|
|
||||||
"'[object Object]': false, '[object RegExp]': false, '[object String]': true }"
|
|
||||||
);
|
|
||||||
|
|
||||||
// manually convert `cloneableClasses` property assignments because
|
|
||||||
// Closure Compiler errors trying to minify them
|
|
||||||
source = source.replace(/(cloneableClasses =)[\s\S]+?= *true/,
|
|
||||||
"$1{'[object Arguments]': false, '[object Array]': true, '[object Boolean]': true, " +
|
|
||||||
"'[object Date]': true, '[object Function]': false, '[object Number]': true, " +
|
|
||||||
"'[object Object]': true, '[object RegExp]': true, '[object String]': true }"
|
|
||||||
);
|
|
||||||
|
|
||||||
// add brackets to whitelisted properties so Closure Compiler won't mung them
|
|
||||||
// http://code.google.com/closure/compiler/docs/api-tutorial3.html#export
|
|
||||||
source = source.replace(RegExp('\\.(' + propWhitelist.join('|') + ')\\b', 'g'), "['$1']");
|
|
||||||
|
|
||||||
// remove brackets from `_.escape()` in `tokenizeEscape`
|
|
||||||
source = source.replace(/_\['escape']\("/, '_.escape("');
|
|
||||||
|
|
||||||
// remove brackets from `_.escape()` in `_.template`
|
|
||||||
source = source.replace(/__e *= *_\['escape']/, '__e=_.escape');
|
|
||||||
|
|
||||||
// remove brackets from `collection.indexOf` in `_.contains`
|
|
||||||
source = source.replace("collection['indexOf'](target)", 'collection.indexOf(target)');
|
|
||||||
|
|
||||||
// remove brackets from `result[length].value` in `_.sortBy`
|
|
||||||
source = source.replace("result[length]['value']", 'result[length].value');
|
|
||||||
|
|
||||||
// remove whitespace from string literals
|
|
||||||
source = source.replace(/'(?:(?=(\\?))\1.)*?'/g, function(string) {
|
|
||||||
// avoids removing the '\n' of the `stringEscapes` object
|
|
||||||
return string.replace(/\[object |else if|function | in |return\s+[\w']|throw |typeof |use strict|var |@ |'\\n'|\\\\n|\\n|\s+/g, function(match) {
|
|
||||||
return match == false || match == '\\n' ? '' : match;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// remove whitespace from `_.template` related regexes
|
|
||||||
source = source.replace(/(?:reDelimiterCode\w+|reEmptyString\w+|reInsertVariable) *=.+/g, function(match) {
|
|
||||||
return match.replace(/ |\\n/g, '');
|
|
||||||
});
|
|
||||||
|
|
||||||
// remove newline from double-quoted strings in `_.template`
|
|
||||||
source = source
|
|
||||||
.replace('"\';\\n__with ("', '"\';__with("')
|
|
||||||
.replace('"\\n}__\\n__p += \'"', '"}____p+=\'"')
|
|
||||||
.replace('"__p = \'"', '"__p=\'"')
|
|
||||||
.replace('"\';\\n"', '"\';"')
|
|
||||||
.replace("') {\\n'", "'){'")
|
|
||||||
|
|
||||||
// remove `useSourceURL` variable
|
|
||||||
source = source.replace(/(?:\n +\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\/)?\n *try *\{(?:\s*\/\/.*)*\n *var useSourceURL[\s\S]+?catch[^}]+}\n/, '');
|
|
||||||
|
|
||||||
// remove debug sourceURL use in `_.template`
|
|
||||||
source = source.replace(/(?:\s*\/\/.*\n)* *if *\(useSourceURL[^}]+}/, '');
|
|
||||||
|
|
||||||
// minify internal properties used by 'compareAscending', `_.clone`, `_.merge`, and `_.sortBy`
|
|
||||||
(function() {
|
|
||||||
var properties = ['criteria', 'index', 'source', 'value'],
|
|
||||||
snippets = source.match(/( +)(?:function clone|function compareAscending|var merge|var sortBy)\b[\s\S]+?\n\1}/g);
|
|
||||||
|
|
||||||
if (!snippets) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
snippets.forEach(function(snippet) {
|
|
||||||
var modified = snippet,
|
|
||||||
isCompilable = /(?:var merge|var sortBy)\b/.test(modified),
|
|
||||||
isInlined = !/\bcreateIterator\b/.test(modified);
|
|
||||||
|
|
||||||
// minify properties
|
|
||||||
properties.forEach(function(property, index) {
|
|
||||||
var reBracketProp = RegExp("\\['(" + property + ")'\\]", 'g'),
|
|
||||||
reDotProp = RegExp('\\.' + property + '\\b', 'g'),
|
|
||||||
rePropColon = RegExp("(')?\\b" + property + "\\1 *:", 'g');
|
|
||||||
|
|
||||||
if (isCompilable) {
|
|
||||||
// add quotes around properties in the inlined `_.merge` and `_.sortBy`
|
|
||||||
// of the mobile build so Closure Compiler won't mung them
|
|
||||||
if (isInlined) {
|
|
||||||
modified = modified
|
|
||||||
.replace(reBracketProp, "['" + minNames[index] + "']")
|
|
||||||
.replace(reDotProp, "['" + minNames[index] + "']")
|
|
||||||
.replace(rePropColon, "'" + minNames[index] + "':");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
modified = modified
|
|
||||||
.replace(reBracketProp, '.' + minNames[index])
|
|
||||||
.replace(reDotProp, '.' + minNames[index])
|
|
||||||
.replace(rePropColon, minNames[index] + ':');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
modified = modified
|
|
||||||
.replace(reBracketProp, "['" + minNames[index] + "']")
|
|
||||||
.replace(reDotProp, '.' + minNames[index])
|
|
||||||
.replace(rePropColon, "'" + minNames[index] + "':")
|
|
||||||
|
|
||||||
// correct `value.source` in regexp branch of `_.clone`
|
|
||||||
if (property == 'source') {
|
|
||||||
modified = modified.replace("value['" + minNames[index] + "']", "value['source']");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// replace with modified snippet
|
|
||||||
source = source.replace(snippet, modified);
|
|
||||||
});
|
|
||||||
}());
|
|
||||||
|
|
||||||
// minify all compilable snippets
|
|
||||||
var snippets = source.match(
|
|
||||||
RegExp([
|
|
||||||
// match the `iteratorTemplate`
|
|
||||||
'( +)var iteratorTemplate\\b[\\s\\S]+?\\n\\1}',
|
|
||||||
// match methods created by `createIterator` calls
|
|
||||||
'createIterator\\((?:{|[a-zA-Z]+)[\\s\\S]+?\\);\\n',
|
|
||||||
// match variables storing `createIterator` options
|
|
||||||
'( +)var [a-zA-Z]+IteratorOptions\\b[\\s\\S]+?\\n\\2}',
|
|
||||||
// match the the `createIterator` function
|
|
||||||
'( +)function createIterator\\b[\\s\\S]+?\\n\\3}'
|
|
||||||
].join('|'), 'g')
|
|
||||||
);
|
|
||||||
|
|
||||||
// exit early if no compilable snippets
|
|
||||||
if (!snippets) {
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
snippets.forEach(function(snippet, index) {
|
|
||||||
var isCreateIterator = /function createIterator\b/.test(snippet),
|
|
||||||
isIteratorTemplate = /var iteratorTemplate\b/.test(snippet),
|
|
||||||
modified = snippet;
|
|
||||||
|
|
||||||
// add brackets to whitelisted properties so Closure Compiler won't mung them
|
|
||||||
modified = modified.replace(RegExp('\\.(' + iteratorOptions.join('|') + ')\\b', 'g'), "['$1']");
|
|
||||||
|
|
||||||
if (isCreateIterator) {
|
|
||||||
// replace with modified snippet early and clip snippet to the `factory`
|
|
||||||
// call so other arguments aren't minified
|
|
||||||
source = source.replace(snippet, modified);
|
|
||||||
snippet = modified = modified.replace(/factory\([\s\S]+$/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
// minify snippet variables / arguments
|
|
||||||
compiledVars.forEach(function(variable, index) {
|
|
||||||
// ensure properties in compiled strings aren't minified
|
|
||||||
modified = modified.replace(RegExp('([^.]\\b)' + variable + '\\b(?!\' *[\\]:])', 'g'), '$1' + minNames[index]);
|
|
||||||
|
|
||||||
// correct `typeof x == 'object'`
|
|
||||||
if (variable == 'object') {
|
|
||||||
modified = modified.replace(RegExp("(typeof [^']+')" + minNames[index] + "'", 'g'), "$1object'");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// minify `createIterator` option property names
|
|
||||||
iteratorOptions.forEach(function(property, index) {
|
|
||||||
if (isIteratorTemplate) {
|
|
||||||
// minify property names as interpolated template variables
|
|
||||||
modified = modified.replace(RegExp('\\b' + property + '\\b', 'g'), minNames[index]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (property == 'array' || property == 'object') {
|
|
||||||
// minify "array" and "object" sub property names
|
|
||||||
modified = modified.replace(RegExp("'" + property + "'( *[\\]:])", 'g'), "'" + minNames[index] + "'$1");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// minify property name strings
|
|
||||||
modified = modified.replace(RegExp("'" + property + "'", 'g'), "'" + minNames[index] + "'");
|
|
||||||
// minify property names in regexes and accessors
|
|
||||||
if (isCreateIterator) {
|
|
||||||
modified = modified.replace(RegExp('([\\.|/])' + property + '\\b' , 'g'), '$1' + minNames[index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// replace with modified snippet
|
|
||||||
source = source.replace(snippet, modified);
|
|
||||||
});
|
|
||||||
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
// expose `preprocess`
|
|
||||||
if (module != require.main) {
|
|
||||||
module.exports = preprocess;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// read the Lo-Dash source file from the first argument if the script
|
|
||||||
// was invoked directly (e.g. `node pre-compile.js source.js`) and write to
|
|
||||||
// the same file
|
|
||||||
(function() {
|
|
||||||
var source = fs.readFileSync(process.argv[2], 'utf8');
|
|
||||||
fs.writeFileSync(process.argv[2], preprocess(source), 'utf8');
|
|
||||||
}());
|
|
||||||
}
|
|
||||||
}());
|
|
||||||
10
component.json
Normal file
10
component.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"name": "lodash",
|
||||||
|
"repo": "lodash/lodash",
|
||||||
|
"version": "3.8.0",
|
||||||
|
"description": "The modern build of lodash.",
|
||||||
|
"license": "MIT",
|
||||||
|
"main": "lodash.js",
|
||||||
|
"keywords": ["stdlib", "util"],
|
||||||
|
"scripts": ["lodash.js"]
|
||||||
|
}
|
||||||
8703
doc/README.md
8703
doc/README.md
File diff suppressed because it is too large
Load Diff
@@ -1,35 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// cleanup requested filepath
|
|
||||||
$file = isset($_GET['f']) ? $_GET['f'] : 'lodash';
|
|
||||||
$file = preg_replace('#(\.*[\/])+#', '', $file);
|
|
||||||
$file .= preg_match('/\.[a-z]+$/', $file) ? '' : '.js';
|
|
||||||
|
|
||||||
// output filename
|
|
||||||
if (isset($_GET['o'])) {
|
|
||||||
$output = $_GET['o'];
|
|
||||||
} else if (isset($_SERVER['argv'][1])) {
|
|
||||||
$output = $_SERVER['argv'][1];
|
|
||||||
} else {
|
|
||||||
$output = basename($file);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
require('../vendor/docdown/docdown.php');
|
|
||||||
|
|
||||||
// generate Markdown
|
|
||||||
$markdown = docdown(array(
|
|
||||||
'path' => '../' . $file,
|
|
||||||
'title' => 'Lo-Dash <sup>v0.5.0</sup>',
|
|
||||||
'url' => 'https://github.com/bestiejs/lodash/blob/master/lodash.js'
|
|
||||||
));
|
|
||||||
|
|
||||||
// save to a .md file
|
|
||||||
file_put_contents($output . '.md', $markdown);
|
|
||||||
|
|
||||||
// print
|
|
||||||
header('Content-Type: text/plain;charset=utf-8');
|
|
||||||
echo $markdown . PHP_EOL;
|
|
||||||
|
|
||||||
?>
|
|
||||||
177
lodash.min.js
vendored
177
lodash.min.js
vendored
@@ -1,40 +1,137 @@
|
|||||||
/*!
|
/**
|
||||||
Lo-Dash 0.5.0 lodash.com/license
|
* @license
|
||||||
Underscore.js 1.3.3 github.com/documentcloud/underscore/blob/master/LICENSE
|
* lodash 3.8.0 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
|
||||||
*/
|
* Build: `lodash modern -o ./lodash.js`
|
||||||
;(function(e,t){"use strict";function s(e){return new o(e)}function o(e){if(e&&e._wrapped)return e;this._wrapped=e}function u(e,t,n){t||(t=0);var r=e.length,i=r-t>=(n||30),s=i?{}:e;if(i)for(var o=t-1;++o<r;)n=e[o]+"",(ot.call(s,n)?s[n]:s[n]=[]).push(e[o]);return function(e){if(i){var n=e+"";return ot.call(s,n)&&-1<C(s[n],e)}return-1<C(s,e,t)}}function a(){for(var e,t,n,s=-1,o=arguments.length,u={e:"",f:"",j:"",q:"",c:{d:""},m:{d:""}};++s<o;)for(t in e=arguments[s],e)n=(n=e[t])==r?"":n,/d|i/.test(t
|
*/
|
||||||
)?("string"==typeof n&&(n={b:n,l:n}),u.c[t]=n.b,u.m[t]=n.l):u[t]=n;e=u.a,t=/^[^,]+/.exec(e)[0],u.g=t,u.h=Nt,u.k=Pt,u.n=kt,u.p=nt,u.r=u.r!==i,u.s=u.s!==i,"o"in u||(u.o=Ot),u.f||(u.f="if(!"+t+")return s");if("b"!=t||!u.c.i)u.c=r;t="",u.s&&(t+="'use strict';"),t+="var g,y,h="+u.g+",s",u.j&&(t+="="+u.j),t+=";"+u.f+";"+u.q+";",u.c&&(t+="var j=h.length;g=-1;",u.m&&(t+="if(j>-1&&j===j>>>0){"),u.o&&(t+="if(x.call(h)==v){h=h.split('')}"),t+=u.c.d+";while(++g<j){y=h[g];"+u.c.i+"}",u.m&&(t+="}"));if(u.m){u.
|
;(function(){function n(n,t){if(n!==t){var r=n===n,e=t===t;if(n>t||!r||n===w&&e)return 1;if(n<t||!e||t===w&&r)return-1}return 0}function t(n,t,r){for(var e=n.length,u=r?e:-1;r?u--:++u<e;)if(t(n[u],u,n))return u;return-1}function r(n,t,r){if(t!==t)return p(n,r);r-=1;for(var e=n.length;++r<e;)if(n[r]===t)return r;return-1}function e(n){return typeof n=="function"||false}function u(n){return typeof n=="string"?n:null==n?"":n+""}function o(n){return n.charCodeAt(0)}function i(n,t){for(var r=-1,e=n.length;++r<e&&-1<t.indexOf(n.charAt(r)););
|
||||||
c?t+="else{":u.n&&(t+="var j=h.length;g=-1;if(j&&P(h)){while(++g<j){y=h[g+=''];"+u.m.i+"}}else{"),u.h||(t+="var t=typeof h=='function'&&p.call(h,'prototype');"),u.k&&u.r?t+="var m=-1,n=k(h),j=n.length;"+u.m.d+";while(++m<j){g=n[m];if(!(t&&g=='prototype')){y=h[g];"+u.m.i+"}}":(t+=u.m.d+";for(g in h){",u.h?(u.r&&(t+="if(e.call(h,g)){"),t+="y=h[g];"+u.m.i+";",u.r&&(t+="}")):(t+="if(!(t&&g=='prototype')",u.r&&(t+="&&e.call(h,g)"),t+="){y=h[g];"+u.m.i+"}"),t+="}");if(u.h){t+="var d=h.constructor;";for(
|
return r}function f(n,t){for(var r=n.length;r--&&-1<t.indexOf(n.charAt(r)););return r}function a(t,r){return n(t.a,r.a)||t.b-r.b}function c(n){return $n[n]}function l(n){return Ln[n]}function s(n){return"\\"+Mn[n]}function p(n,t,r){var e=n.length;for(t+=r?0:-1;r?t--:++t<e;){var u=n[t];if(u!==u)return t}return-1}function h(n){return!!n&&typeof n=="object"}function _(n){return 160>=n&&9<=n&&13>=n||32==n||160==n||5760==n||6158==n||8192<=n&&(8202>=n||8232==n||8233==n||8239==n||8287==n||12288==n||65279==n);
|
||||||
n=0;7>n;n++)t+="g='"+u.p[n]+"';if(","constructor"==u.p[n]&&(t+="!(d&&d.prototype===h)&&"),t+="e.call(h,g)){y=h[g];"+u.m.i+"}"}if(u.c||u.n)t+="}"}return t+=u.e+";return s",Function("D,E,F,I,c,K,e,f,N,P,R,T,U,i,X,Y,k,p,u,v,x","var G=function("+e+"){"+t+"};return G")(Ht,I,M,f,st,Zt,ot,_,C,b,Jt,w,p,d,wt,Ft,dt,at,ft,St,lt)}function f(e,n){var r=e.b,i=n.b,e=e.a,n=n.a;return e===t?1:n===t?-1:e<n?-1:e>n?1:r<i?-1:1}function l(e,t){return it[t]}function c(e){return"\\"+It[e]}function h(e){return jt[e]}function p
|
|
||||||
(e,t){var n=i;if(!e||"object"!=typeof e||!t&&b(e))return n;var r=e.constructor;return(!Mt||"function"==typeof e.toString||"string"!=typeof (e+""))&&(!w(r)||r instanceof r)?Ct?(Zt(e,function(t,r){return n=!ot.call(e,r),i}),n===i):(Zt(e,function(e,t){n=t}),n===i||ot.call(e,n)):n}function d(e,t){return function(n,r,i){return e.call(t,n,r,i)}}function v(){}function m(e,t){if(V.test(t))return"<e%-"+t+"%>";var n=it.length;return it[n]="'+__e("+t+")+'",rt+n}function g(e,t,n,r){return e=it.length,t?it[e]="'+__e("+
|
}function v(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;)n[r]===t&&(n[r]=z,o[++u]=r);return o}function g(n){for(var t=-1,r=n.length;++t<r&&_(n.charCodeAt(t)););return t}function y(n){for(var t=n.length;t--&&_(n.charCodeAt(t)););return t}function d(n){return zn[n]}function m(_){function $n(n){if(h(n)&&!(To(n)||n instanceof Bn)){if(n instanceof zn)return n;if(Ge.call(n,"__chain__")&&Ge.call(n,"__wrapped__"))return Lr(n)}return new zn(n)}function Ln(){}function zn(n,t,r){this.__wrapped__=n,this.__actions__=r||[],
|
||||||
t+")+'":r?it[e]="';"+r+";__p+='":n&&(it[e]="'+((__t=("+n+"))==null?'':__t)+'"),rt+e}function y(e,t){if(V.test(t))return"<e%="+t+"%>";var n=it.length;return it[n]="'+((__t=("+t+"))==null?'':__t)+'",rt+n}function b(e){return lt.call(e)==vt}function w(e){return"function"==typeof e}function E(e,t,s,o,u){if(e==r)return e;s&&(t=i),u||(u={d:r}),u.d==r&&(u.d=!(!q.clone&&!U.clone&&!z.clone));if(((s=Ft[typeof e])||u.d)&&e.clone&&w(e.clone))return u.d=r,e.clone(t);if(s){var a=lt.call(e);if(!Bt[a]||Lt&&b(e))
|
this.__chain__=!!t}function Bn(n){this.__wrapped__=n,this.__actions__=null,this.__dir__=1,this.__filtered__=false,this.__iteratees__=null,this.__takeCount__=Iu,this.__views__=null}function Mn(){this.__data__={}}function Dn(n){var t=n?n.length:0;for(this.data={hash:du(null),set:new lu};t--;)this.push(n[t])}function Pn(n,t){var r=n.data;return(typeof t=="string"||se(t)?r.set.has(t):r.hash[t])?0:-1}function qn(n,t){var r=-1,e=n.length;for(t||(t=Ue(e));++r<e;)t[r]=n[r];return t}function Kn(n,t){for(var r=-1,e=n.length;++r<e&&false!==t(n[r],r,n););
|
||||||
return e;var f=a==mt,s=f||(a==wt?p(e,n):s)}if(!s||!t)return s?f?ft.call(e):Yt({},e):e;s=e.constructor;switch(a){case gt:return new s(e==n);case yt:return new s(+e);case bt:case St:return new s(e);case Et:return s(e.source,Q.exec(e))}o||(o=[]);for(a=o.length;a--;)if(o[a].c==e)return o[a].d;var a=e.length,l=f?s(a):{};o.push({d:l,c:e});if(f)for(f=-1;++f<a;)l[f]=E(e[f],t,r,o,u);else en(e,function(e,n){l[n]=E(e,t,r,o,u)});return l}function S(e,t,s,o){if(e==r||t==r)return e===t;o||(o={value:r}),o.value==
|
return n}function Vn(n,t){for(var r=-1,e=n.length;++r<e;)if(!t(n[r],r,n))return false;return true}function Gn(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;){var i=n[r];t(i,r,n)&&(o[++u]=i)}return o}function Jn(n,t){for(var r=-1,e=n.length,u=Ue(e);++r<e;)u[r]=t(n[r],r,n);return u}function Xn(n,t,r,e){var u=-1,o=n.length;for(e&&o&&(r=n[++u]);++u<o;)r=t(r,n[u],u,n);return r}function Hn(n,t){for(var r=-1,e=n.length;++r<e;)if(t(n[r],r,n))return true;return false}function Qn(n,t){return n===w?t:n}function nt(n,t,r,e){
|
||||||
r&&(o.value=!(!q.isEqual&&!U.isEqual&&!z.isEqual));if(Ft[typeof e]||Ft[typeof t]||o.value){e._chain&&(e=e._wrapped),t._chain&&(t=t._wrapped);if(e.isEqual&&w(e.isEqual))return o.value=r,e.isEqual(t);if(t.isEqual&&w(t.isEqual))return o.value=r,t.isEqual(e)}if(e===t)return 0!==e||1/e==1/t;var u=lt.call(e);if(u!=lt.call(t))return i;switch(u){case gt:case yt:return+e==+t;case bt:return e!=+e?t!=+t:0==e?1/e==1/t:e==+t;case Et:case St:return e==t+""}var a=Ht[u];if(Lt&&!a&&(a=b(e))&&!b(t)||!a&&(u!=wt||Mt&&
|
return n!==w&&Ge.call(e,r)?n:t}function tt(n,t,r){var e=Ko(t);fu.apply(e,Zu(t));for(var u=-1,o=e.length;++u<o;){var i=e[u],f=n[i],a=r(f,t[i],i,n,t);(a===a?a===f:f!==f)&&(f!==w||i in n)||(n[i]=a)}return n}function rt(n,t){for(var r=-1,e=null==n,u=!e&&jr(n),o=u&&n.length,i=t.length,f=Ue(i);++r<i;){var a=t[r];f[r]=u?kr(a,o)?n[a]:w:e?w:n[a]}return f}function et(n,t,r){r||(r={});for(var e=-1,u=t.length;++e<u;){var o=t[e];r[o]=n[o]}return r}function ut(n,t,r){var e=typeof n;return"function"==e?t===w?n:zt(n,t,r):null==n?Re:"object"==e?wt(n):t===w?Te(n):bt(n,t);
|
||||||
("function"!=typeof e.toString&&"string"==typeof (e+"")||"function"!=typeof t.toString&&"string"==typeof (t+""))))return i;s||(s=[]);for(u=s.length;u--;)if(s[u]==e)return n;var u=-1,f=n,l=0;s.push(e);if(a){l=e.length;if(f=l==t.length)for(;l--&&(f=S(e[l],t[l],s,o)););return f}a=e.constructor,f=t.constructor;if(a!=f&&(!w(a)||!(a instanceof a&&w(f)&&f instanceof f)))return i;for(var c in e)if(ot.call(e,c)&&(l++,!ot.call(t,c)||!S(e[c],t[c],s,o)))return i;for(c in t)if(ot.call(t,c)&&!(l--))return i;if(
|
|
||||||
Nt)for(;7>++u;)if(c=nt[u],ot.call(e,c)&&(!ot.call(t,c)||!S(e[c],t[c],s,o)))return i;return n}function x(e,t,n,r){if(!e)return n;var i=e.length,s=3>arguments.length;r&&(t=d(t,r));if(-1<i&&i===i>>>0){var o=Ot&<.call(e)==St?e.split(""):e;for(i&&s&&(n=o[--i]);i--;)n=t(n,o[i],i,e);return n}o=rn(e);for((i=o.length)&&s&&(n=e[o[--i]]);i--;)s=o[i],n=t(n,e[s],s,e);return n}function T(e,t,n){if(e)return t==r||n?e[0]:ft.call(e,0,t)}function N(e,t){var n=[];if(!e)return n;for(var r,i=-1,s=e.length;++i<s;)r=
|
}function ot(n,t,r,e,u,o,i){var f;if(r&&(f=u?r(n,e,u):r(n)),f!==w)return f;if(!se(n))return n;if(e=To(n)){if(f=wr(n),!t)return qn(n,f)}else{var a=Xe.call(n),c=a==K;if(a!=Y&&a!=B&&(!c||u))return Nn[a]?xr(n,a,t):u?n:{};if(f=br(c?{}:n),!t)return $u(f,n)}for(o||(o=[]),i||(i=[]),u=o.length;u--;)if(o[u]==n)return i[u];return o.push(n),i.push(f),(e?Kn:ht)(n,function(e,u){f[u]=ot(e,t,r,u,n,o,i)}),f}function it(n,t,r){if(typeof n!="function")throw new Pe(L);return su(function(){n.apply(w,r)},t)}function ft(n,t){
|
||||||
e[i],Jt(r)?ut.apply(n,t?r:N(r)):n.push(r);return n}function C(e,t,n){if(!e)return-1;var r=-1,i=e.length;if(n){if("number"!=typeof n)return r=A(e,t),e[r]===t?r:-1;r=(0>n?Math.max(0,i+n):n)-1}for(;++r<i;)if(e[r]===t)return r;return-1}function k(e,t,n){var r=-Infinity,i=r;if(!e)return i;var s=-1,o=e.length;if(!t){for(;++s<o;)e[s]>i&&(i=e[s]);return i}for(n&&(t=d(t,n));++s<o;)n=t(e[s],s,e),n>r&&(r=n,i=e[s]);return i}function L(e,t,n){return e?ft.call(e,t==r||n?1:t):[]}function A(e,t,n,r){if(!e)return 0
|
var e=n?n.length:0,u=[];if(!e)return u;var o=-1,i=mr(),f=i==r,a=f&&200<=t.length?qu(t):null,c=t.length;a&&(i=Pn,f=false,t=a);n:for(;++o<e;)if(a=n[o],f&&a===a){for(var l=c;l--;)if(t[l]===a)continue n;u.push(a)}else 0>i(t,a,0)&&u.push(a);return u}function at(n,t){var r=true;return zu(n,function(n,e,u){return r=!!t(n,e,u)}),r}function ct(n,t){var r=[];return zu(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function lt(n,t,r,e){var u;return r(n,function(n,r,o){return t(n,r,o)?(u=e?r:n,false):void 0}),u}function st(n,t,r){
|
||||||
;var i=0,s=e.length;if(n){r&&(n=M(n,r));for(t=n(t);i<s;)r=i+s>>>1,n(e[r])<t?i=r+1:s=r}else for(;i<s;)r=i+s>>>1,e[r]<t?i=r+1:s=r;return i}function O(e,t,n,r){var s=[];if(!e)return s;var o=-1,u=e.length,a=[];"function"==typeof t&&(r=n,n=t,t=i);for(n?r&&(n=d(n,r)):n=_;++o<u;)if(r=n(e[o],o,e),t?!o||a[a.length-1]!==r:0>C(a,r))a.push(r),s.push(e[o]);return s}function M(e,t){function n(){var o=arguments,u=t;return i||(e=t[r]),s.length&&(o=o.length?st.apply(s,o):s),this instanceof n?(v.prototype=e.prototype
|
for(var e=-1,u=n.length,o=-1,i=[];++e<u;){var f=n[e];if(h(f)&&jr(f)&&(r||To(f)||ae(f))){t&&(f=st(f,t,r));for(var a=-1,c=f.length;++a<c;)i[++o]=f[a]}else r||(i[++o]=f)}return i}function pt(n,t){Mu(n,t,me)}function ht(n,t){return Mu(n,t,Ko)}function _t(n,t){return Du(n,t,Ko)}function vt(n,t){for(var r=-1,e=t.length,u=-1,o=[];++r<e;){var i=t[r];No(n[i])&&(o[++u]=i)}return o}function gt(n,t,r){if(null!=n){r!==w&&r in Fr(n)&&(t=[r]),r=-1;for(var e=t.length;null!=n&&++r<e;)n=n[t[r]];return r&&r==e?n:w}
|
||||||
,u=new v,(o=e.apply(u,o))&&Ft[typeof o]?o:u):e.apply(u,o)}var r,i=w(e);if(i){if(Dt||ct&&2<arguments.length)return ct.call.apply(ct,arguments)}else r=t,t=e;var s=ft.call(arguments,2);return n}function _(e){return e}function D(e){cn(tn(e),function(t){var r=s[t]=e[t];o.prototype[t]=function(){var e=[this._wrapped];return arguments.length&&ut.apply(e,arguments),e=r.apply(s,e),this._chain&&(e=new o(e),e._chain=n),e}})}var n=!0,r=null,i=!1,P,H,B,j,F="object"==typeof exports&&exports&&("object"==typeof
|
}function yt(n,t,r,e,u,o){if(n===t)return true;var i=typeof n,f=typeof t;if("function"!=i&&"object"!=i&&"function"!=f&&"object"!=f||null==n||null==t)n=n!==n&&t!==t;else n:{var i=yt,f=To(n),a=To(t),c=M,l=M;f||(c=Xe.call(n),c==B?c=Y:c!=Y&&(f=ge(n))),a||(l=Xe.call(t),l==B?l=Y:l!=Y&&ge(t));var s=c==Y,a=l==Y,l=c==l;if(!l||f||s){if(!e&&(c=s&&Ge.call(n,"__wrapped__"),a=a&&Ge.call(t,"__wrapped__"),c||a)){n=i(c?n.value():n,a?t.value():t,r,e,u,o);break n}if(l){for(u||(u=[]),o||(o=[]),c=u.length;c--;)if(u[c]==n){
|
||||||
global&&global&&global==global.global&&(e=global),exports),I=Array.prototype,q=Boolean.prototype,R=Object.prototype,U=Number.prototype,z=String.prototype,W=0,X=e._,V=/[-+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/,$=/\b__p\+='';/g,J=/\b(__p\+=)''\+/g,K=/(__e\(.*?\)|\b__t\))\+'';/g,Q=/\w*$/,G=/(?:__e|__t=)\(\s*(?![\d\s"']|this\.)/g,Y=RegExp("^"+(R.valueOf+"").replace(/[.*+?^=!:${}()|[\]\/\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),Z=/__token__(\d+)/g,et=/[&<"']/g
|
n=o[c]==t;break n}u.push(n),o.push(t),n=(f?_r:gr)(n,t,i,r,e,u,o),u.pop(),o.pop()}else n=false}else n=vr(n,t,c)}return n}function dt(n,t,r,e,u){for(var o=-1,i=t.length,f=!u;++o<i;)if(f&&e[o]?r[o]!==n[t[o]]:!(t[o]in n))return false;for(o=-1;++o<i;){var a=t[o],c=n[a],l=r[o];if(f&&e[o]?a=c!==w||a in n:(a=u?u(c,l,a):w,a===w&&(a=yt(l,c,u,true))),!a)return false}return true}function mt(n,t){var r=-1,e=jr(n)?Ue(n.length):[];return zu(n,function(n,u,o){e[++r]=t(n,u,o)}),e}function wt(n){var t=Ko(n),r=t.length;if(!r)return Ie(true);
|
||||||
,tt=/['\n\r\t\u2028\u2029\\]/g,nt="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),rt="__token__",it=[],st=I.concat,ot=R.hasOwnProperty,ut=I.push,at=R.propertyIsEnumerable,ft=I.slice,lt=R.toString,ct=Y.test(ct=ft.bind)&&ct,ht=Y.test(ht=Array.isArray)&&ht,pt=e.isFinite,dt=Y.test(dt=Object.keys)&&dt,vt="[object Arguments]",mt="[object Array]",gt="[object Boolean]",yt="[object Date]",bt="[object Number]",wt="[object Object]",Et="[object RegExp]"
|
|
||||||
,St="[object String]",xt=e.clearTimeout,Tt=e.setTimeout,Nt,Ct,kt=n;(function(){function e(){this.x=1}var t=[];e.prototype={valueOf:1,y:1};for(var n in new e)t.push(n);for(n in arguments)kt=!n;Nt=4>(t+"").length,Ct="x"!=t[0]})(1);var Lt=!b(arguments),At="x"!=ft.call("x")[0],Ot="xx"!="x"[0]+Object("x")[0];try{var Mt=("[object Object]",lt.call(e.document||0)==wt)}catch(_t){}var Dt=ct&&/\n|Opera/.test(ct+lt.call(e.opera)),Pt=dt&&/^.+$|true/.test(dt+!!e.attachEvent),Ht={"[object Arguments]":n,"[object Array]"
|
if(1==r){var e=t[0],u=n[e];if(Cr(u))return function(n){return null==n?false:n[e]===u&&(u!==w||e in Fr(n))}}for(var o=Ue(r),i=Ue(r);r--;)u=n[t[r]],o[r]=u,i[r]=Cr(u);return function(n){return null!=n&&dt(Fr(n),t,o,i)}}function bt(n,t){var r=To(n),e=Er(n)&&Cr(t),u=n+"";return n=$r(n),function(o){if(null==o)return false;var i=u;if(o=Fr(o),!(!r&&e||i in o)){if(o=1==n.length?o:gt(o,It(n,0,-1)),null==o)return false;i=Pr(n),o=Fr(o)}return o[i]===t?t!==w||i in o:yt(t,o[i],null,true)}}function xt(n,t,r,e,u){if(!se(n))return n;
|
||||||
:n,"[object Boolean]":i,"[object Date]":i,"[object Function]":i,"[object Number]":i,"[object Object]":i,"[object RegExp]":i,"[object String]":n},Bt={"[object Arguments]":i,"[object Array]":n,"[object Boolean]":n,"[object Date]":n,"[object Function]":i,"[object Number]":n,"[object Object]":n,"[object RegExp]":n,"[object String]":n},jt={"&":"&","<":"<",'"':""","'":"'"},Ft={"boolean":i,"function":n,object:n,number:i,string:i,"undefined":i,unknown:n},It={"\\":"\\","'":"'","\n":"n","\r"
|
|
||||||
:"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};s.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:"obj"};var qt={a:"b,a,w",j:"b",q:"if(!a)a=f;else if(w)a=i(a,w)",i:"if(a(y,g,b)===false)return s"},Rt={j:"{}",q:"var o;if(typeof a!='function'){var ii=a;a=function(y){return y[ii]}}else if(w)a=i(a,w)",i:"o=a(y,g,b);(e.call(s,o)?s[o]++:s[o]=1)"},Ut={j:"true",i:"if(!a(y,g,b))return!s"},zt={r:i,s:i,a:"l",j:"l",q:"for(var B=1,C=arguments.length;B<C;B++){if(h=arguments[B]){"
|
var o=jr(t)&&(To(t)||ge(t));if(!o){var i=Ko(t);fu.apply(i,Zu(t))}return Kn(i||t,function(f,a){if(i&&(a=f,f=t[a]),h(f)){e||(e=[]),u||(u=[]);n:{for(var c=a,l=e,s=u,p=l.length,_=t[c];p--;)if(l[p]==_){n[c]=s[p];break n}var p=n[c],v=r?r(p,_,c,n,t):w,g=v===w;g&&(v=_,jr(_)&&(To(_)||ge(_))?v=To(p)?p:jr(p)?qn(p):[]:Fo(_)||ae(_)?v=ae(p)?ye(p):Fo(p)?p:{}:g=false),l.push(_),s.push(v),g?n[c]=xt(v,_,r,l,s):(v===v?v!==p:p===p)&&(n[c]=v)}}else c=n[a],l=r?r(c,f,a,n,t):w,(s=l===w)&&(l=f),!o&&l===w||!s&&(l===l?l===c:c!==c)||(n[a]=l);
|
||||||
,i:"s[g]=y",e:"}}"},Wt={j:"[]",i:"a(y,g,b)&&s.push(y)"},Xt={q:"if(w)a=i(a,w)"},Vt={i:{l:qt.i}},$t={j:"",f:"if(!b)return[]",d:{b:"s=Array(j)",l:"s="+(Pt?"Array(j)":"[]")},i:{b:"s[g]=a(y,g,b)",l:"s"+(Pt?"[m]=":".push")+"(a(y,g,b))"}};Lt&&(b=function(e){return!!e&&!!ot.call(e,"callee")});var Jt=ht||function(e){return lt.call(e)==mt};w(/x/)&&(w=function(e){return"[object Function]"==lt.call(e)});var Kt=a({a:"l",f:"if(!(l&&Y[typeof l]))throw TypeError()",j:"[]",i:"s.push(g)"}),Qt=a(zt,{i:"if(s[g]==null)"+
|
|
||||||
zt.i}),Gt=a({r:i,a:"l",j:"{}",q:"var r=c.apply(E,arguments)",i:"if(N(r,g)<0)s[g]=y"}),Yt=a(zt),Zt=a(qt,Xt,Vt,{r:i}),en=a(qt,Xt,Vt),tn=a({r:i,a:"l",j:"[]",i:"if(T(y))s.push(g)",e:"s.sort()"}),nn=a({a:"y",j:"true",q:"var H=x.call(y),j=y.length;if(D[H]"+(Lt?"||P(y)":"")+"||(H==X&&j>-1&&j===j>>>0&&T(y.splice)))return!j",i:{l:"return false"}}),rn=dt?function(e){return"function"==typeof e&&at.call(e,"prototype")?Kt(e):dt(e)}:Kt,sn=a({a:"l",j:"[]",i:"s.push(y)"}),on=a({a:"b,hh",j:"false",o:i,d:{b:"if(x.call(h)==v)return b.indexOf(hh)>-1"
|
}),n}function At(n){return function(t){return null==t?w:t[n]}}function jt(n){var t=n+"";return n=$r(n),function(r){return gt(r,n,t)}}function kt(n,t){for(var r=n?t.length:0;r--;){var e=parseFloat(t[r]);if(e!=u&&kr(e)){var u=e;pu.call(n,e,1)}}}function Ot(n,t){return n+uu(Ou()*(t-n+1))}function Et(n,t,r,e,u){return u(n,function(n,u,o){r=e?(e=false,n):t(r,n,u,o)}),r}function It(n,t,r){var e=-1,u=n.length;for(t=null==t?0:+t||0,0>t&&(t=-t>u?0:u+t),r=r===w||r>u?u:+r||0,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,
|
||||||
},i:"if(y===hh)return true"}),un=a(qt,Rt),an=a(qt,Ut),fn=a(qt,Wt),ln=a(qt,Xt,{j:"",i:"if(a(y,g,b))return y"}),cn=a(qt,Xt),hn=a(qt,Rt,{i:"o=a(y,g,b);(e.call(s,o)?s[o]:s[o]=[]).push(y)"}),pn=a($t,{a:"b,V",q:"var A=u.call(arguments,2),S=typeof V=='function'",i:{b:"s[g]=(S?V:y[V]).apply(y,A)",l:"s"+(Pt?"[m]=":".push")+"((S?V:y[V]).apply(y,A))"}}),dn=a(qt,$t),vn=a(zt,{a:"l,ee,O,ff",q:"var J,L,Q,gg,dd=O==U;if(!dd)ff=[];for(var B=1,C=dd?2:arguments.length;B<C;B++){if(h=arguments[B]){",i:"if(y&&((Q=R(y))||U(y))){L=false;gg=ff.length;while(gg--)if(L=ff[gg].c==y)break;if(L){s[g]=ff[gg].d}else{J=(J=s[g])&&Q?(R(J)?J:[]):(U(J)?J:{});ff.push({d:J,c:y});s[g]=G(J,y,U,ff)}}else if(y!=null)s[g]=y"
|
r=Ue(u);++e<u;)r[e]=n[e+t];return r}function Rt(n,t){var r;return zu(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function Ct(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;return n}function Wt(t,r,e){var u=dr(),o=-1;return r=Jn(r,function(n){return u(n)}),t=mt(t,function(n){return{a:Jn(r,function(t){return t(n)}),b:++o,c:n}}),Ct(t,function(t,r){var u;n:{u=-1;for(var o=t.a,i=r.a,f=o.length,a=e.length;++u<f;){var c=n(o[u],i[u]);if(c){u=u<a?c*(e[u]?1:-1):c;break n}}u=t.b-r.b}return u})}function St(n,t){
|
||||||
}),mn=a($t,{a:"b,bb",i:{b:"s[g]=y[bb]",l:"s"+(Pt?"[m]=":".push")+"(y[bb])"}}),gn=a({a:"b,a,z,w",j:"z",q:"var W=arguments.length<3;if(w)a=i(a,w)",d:{b:"if(W)s=b[++g]"},i:{b:"s=a(s,y,g,b)",l:"s=W?(W=false,y):a(s,y,g,b)"}}),yn=a(qt,Wt,{i:"!"+Wt.i}),bn=a(qt,Ut,{j:"false",i:Ut.i.replace("!","")}),wn=a(qt,Rt,$t,{i:{b:"s[g]={a:a(y,g,b),b:g,d:y}",l:"s"+(Pt?"[m]=":".push")+"({a:a(y,g,b),b:g,d:y})"},e:"s.sort(I);j=s.length;while(j--)s[j]=s[j].d"}),En=a(Wt,{a:"b,aa",q:"var Z,o,q,r=[];K(aa,function(y,o){r.push(o)});var cc=r.length"
|
var r=0;return zu(n,function(n,e,u){r+=+t(n,e,u)||0}),r}function Tt(n,t){var e=-1,u=mr(),o=n.length,i=u==r,f=i&&200<=o,a=f?qu():null,c=[];a?(u=Pn,i=false):(f=false,a=t?[]:c);n:for(;++e<o;){var l=n[e],s=t?t(l,e,n):l;if(i&&l===l){for(var p=a.length;p--;)if(a[p]===s)continue n;t&&a.push(s),c.push(l)}else 0>u(a,s,0)&&((t||f)&&a.push(s),c.push(l))}return c}function Ut(n,t){for(var r=-1,e=t.length,u=Ue(e);++r<e;)u[r]=n[t[r]];return u}function Nt(n,t,r,e){for(var u=n.length,o=e?u:-1;(e?o--:++o<u)&&t(n[o],o,n););
|
||||||
,i:"for(Z=true,q=0;q<cc;q++){o=r[q];if(!(Z=y[o]===aa[o]))break}if(Z)s.push(y)"}),Sn=a({r:i,s:i,a:"l",j:"l",q:"var M=arguments,j=M.length;if(j>1){for(var g=1;g<j;g++)s[M[g]]=F(s[M[g]],s);return s}",i:"if(T(s[g]))s[g]=F(s[g],s)"});s.VERSION="0.5.0",s.after=function(e,t){return 1>e?t():function(){if(1>--e)return t.apply(this,arguments)}},s.bind=M,s.bindAll=Sn,s.chain=function(e){return e=new o(e),e._chain=n,e},s.clone=E,s.compact=function(e){var t=[];if(!e)return t;for(var n=-1,r=e.length;++n<r;)e[n
|
return r?It(n,e?0:o,e?o+1:u):It(n,e?o+1:0,e?u:o)}function Ft(n,t){var r=n;r instanceof Bn&&(r=r.value());for(var e=-1,u=t.length;++e<u;){var r=[r],o=t[e];fu.apply(r,o.args),r=o.func.apply(o.thisArg,r)}return r}function $t(n,t,r){var e=0,u=n?n.length:e;if(typeof t=="number"&&t===t&&u<=Wu){for(;e<u;){var o=e+u>>>1,i=n[o];(r?i<=t:i<t)?e=o+1:u=o}return u}return Lt(n,t,Re,r)}function Lt(n,t,r,e){t=r(t);for(var u=0,o=n?n.length:0,i=t!==t,f=t===w;u<o;){var a=uu((u+o)/2),c=r(n[a]),l=c===c;(i?l||e:f?l&&(e||c!==w):e?c<=t:c<t)?u=a+1:o=a;
|
||||||
]&&t.push(e[n]);return t},s.compose=function(){var e=arguments;return function(){for(var t=arguments,n=e.length;n--;)t=[e[n].apply(this,t)];return t[0]}},s.contains=on,s.countBy=un,s.debounce=function(e,t,n){function i(){a=r,n||e.apply(u,s)}var s,o,u,a;return function(){var r=n&&!a;return s=arguments,u=this,xt(a),a=Tt(i,t),r&&(o=e.apply(u,s)),o}},s.defaults=Qt,s.defer=function(e){var n=ft.call(arguments,1);return Tt(function(){return e.apply(t,n)},1)},s.delay=function(e,n){var r=ft.call(arguments
|
|
||||||
,2);return Tt(function(){return e.apply(t,r)},n)},s.difference=function(e){var t=[];if(!e)return t;for(var n=-1,r=e.length,i=st.apply(t,arguments),i=u(i,r);++n<r;)i(e[n])||t.push(e[n]);return t},s.drop=Gt,s.escape=function(e){return e==r?"":(e+"").replace(et,h)},s.every=an,s.extend=Yt,s.filter=fn,s.find=ln,s.first=T,s.flatten=N,s.forEach=cn,s.forIn=Zt,s.forOwn=en,s.functions=tn,s.groupBy=hn,s.has=function(e,t){return ot.call(e,t)},s.identity=_,s.indexOf=C,s.initial=function(e,t,n){return e?ft.call
|
}return xu(o,Cu)}function zt(n,t,r){if(typeof n!="function")return Re;if(t===w)return n;switch(r){case 1:return function(r){return n.call(t,r)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,o){return n.call(t,r,e,u,o)};case 5:return function(r,e,u,o,i){return n.call(t,r,e,u,o,i)}}return function(){return n.apply(t,arguments)}}function Bt(n){return tu.call(n,0)}function Mt(n,t,r){for(var e=r.length,u=-1,o=bu(n.length-e,0),i=-1,f=t.length,a=Ue(o+f);++i<f;)a[i]=t[i];
|
||||||
(e,0,-(t==r||n?1:t)):[]},s.intersection=function(e){var t=[];if(!e)return t;for(var n,r=-1,i=e.length,s=ft.call(arguments,1),o=[];++r<i;)n=e[r],0>C(t,n)&&an(s,function(e,t){return(o[t]||(o[t]=u(e)))(n)})&&t.push(n);return t},s.invoke=pn,s.isArguments=b,s.isArray=Jt,s.isBoolean=function(e){return e===n||e===i||lt.call(e)==gt},s.isElement=function(e){return!!e&&1==e.nodeType},s.isEmpty=nn,s.isEqual=S,s.isFinite=function(e){return pt(e)&<.call(e)==bt},s.isFunction=w,s.isNaN=function(e){return lt.call
|
|
||||||
(e)==bt&&e!=+e},s.isNull=function(e){return e===r},s.isObject=function(e){return e&&Ft[typeof e]},s.isUndefined=function(e){return e===t},s.keys=rn,s.last=function(e,t,n){if(e){var i=e.length;return t==r||n?e[i-1]:ft.call(e,-t||i)}},s.lastIndexOf=function(e,t,n){if(!e)return-1;var r=e.length;for(n&&"number"==typeof n&&(r=(0>n?Math.max(0,r+n):Math.min(n,r-1))+1);r--;)if(e[r]===t)return r;return-1},s.map=dn,s.max=k,s.memoize=function(e,t){var n={};return function(){var r=t?t.apply(this,arguments):arguments
|
for(;++u<e;)a[r[u]]=n[u];for(;o--;)a[i++]=n[u++];return a}function Dt(n,t,r){for(var e=-1,u=r.length,o=-1,i=bu(n.length-u,0),f=-1,a=t.length,c=Ue(i+a);++o<i;)c[o]=n[o];for(i=o;++f<a;)c[i+f]=t[f];for(;++e<u;)c[i+r[e]]=n[o++];return c}function Pt(n,t){return function(r,e,u){var o=t?t():{};if(e=dr(e,u,3),To(r)){u=-1;for(var i=r.length;++u<i;){var f=r[u];n(o,f,e(f,u,r),r)}}else zu(r,function(t,r,u){n(o,t,e(t,r,u),u)});return o}}function qt(n){return fe(function(t,r){var e=-1,u=null==t?0:r.length,o=2<u&&r[u-2],i=2<u&&r[2],f=1<u&&r[u-1];
|
||||||
[0];return ot.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},s.merge=vn,s.min=function(e,t,n){var r=Infinity,i=r;if(!e)return i;var s=-1,o=e.length;if(!t){for(;++s<o;)e[s]<i&&(i=e[s]);return i}for(n&&(t=d(t,n));++s<o;)n=t(e[s],s,e),n<r&&(r=n,i=e[s]);return i},s.mixin=D,s.noConflict=function(){return e._=X,this},s.once=function(e){var t,s=i;return function(){return s?t:(s=n,t=e.apply(this,arguments),e=r,t)}},s.partial=function(e){var t=ft.call(arguments,1),n=t.length;return function(){var r;return r=
|
|
||||||
arguments,r.length&&(t.length=n,ut.apply(t,r)),r=1==t.length?e.call(this,t[0]):e.apply(this,t),t.length=n,r}},s.pick=function(e){for(var t,n=0,r=st.apply(I,arguments),i=r.length,s={};++n<i;)t=r[n],t in e&&(s[t]=e[t]);return s},s.pluck=mn,s.range=function(e,t,n){e=+e||0,n=+n||1,t==r&&(t=e,e=0);for(var i=-1,t=Math.max(0,Math.ceil((t-e)/n)),s=Array(t);++i<t;)s[i]=e,e+=n;return s},s.reduce=gn,s.reduceRight=x,s.reject=yn,s.rest=L,s.result=function(e,t){if(!e)return r;var n=e[t];return w(n)?e[t]():n},s
|
for(typeof o=="function"?(o=zt(o,f,5),u-=2):(o=typeof f=="function"?f:null,u-=o?1:0),i&&Or(r[0],r[1],i)&&(o=3>u?null:o,u=1);++e<u;)(i=r[e])&&n(t,i,o);return t})}function Kt(n,t){return function(r,e){var u=r?Yu(r):0;if(!Rr(u))return n(r,e);for(var o=t?u:-1,i=Fr(r);(t?o--:++o<u)&&false!==e(i[o],o,i););return r}}function Vt(n){return function(t,r,e){var u=Fr(t);e=e(t);for(var o=e.length,i=n?o:-1;n?i--:++i<o;){var f=e[i];if(false===r(u[f],f,u))break}return t}}function Yt(n,t){function r(){return(this&&this!==Yn&&this instanceof r?e:n).apply(t,arguments);
|
||||||
.shuffle=function(e){if(!e)return[];for(var t,n=-1,r=e.length,i=Array(r);++n<r;)t=Math.floor(Math.random()*(n+1)),i[n]=i[t],i[t]=e[n];return i},s.size=function(e){if(!e)return 0;var t=lt.call(e),n=e.length;return Ht[t]||Lt&&b(e)||t==wt&&-1<n&&n===n>>>0&&w(e.splice)?n:rn(e).length},s.some=bn,s.sortBy=wn,s.sortedIndex=A,s.tap=function(e,t){return t(e),e},s.template=function(e,t,n){n||(n={});var o,u;o=n.escape;var a=n.evaluate,f=n.interpolate,h=s.templateSettings,n=n.variable;o==r&&(o=h.escape),a==r&&
|
|
||||||
(a=h.evaluate||i),f==r&&(f=h.interpolate),o&&(e=e.replace(o,m)),f&&(e=e.replace(f,y)),a!=P&&(P=a,j=RegExp("<e%-([\\s\\S]+?)%>|<e%=([\\s\\S]+?)%>"+(a?"|"+a.source:""),"g")),o=it.length,e=e.replace(j,g),o=o!=it.length,e="__p += '"+e.replace(tt,c).replace(Z,l)+"';",it.length=0,n||(n=h.variable||H||"obj",o?e="with("+n+"){"+e+"}":(n!=H&&(H=n,B=RegExp("(\\(\\s*)"+n+"\\."+n+"\\b","g")),e=e.replace(G,"$&"+n+".").replace(B,"$1__d"))),e=(o?e.replace($,""):e).replace(J,"$1").replace(K,"$1;"),e="function("+n+"){"+
|
}var e=Gt(n);return r}function Zt(n){return function(t){var r=-1;t=Oe(be(t));for(var e=t.length,u="";++r<e;)u=n(u,t[r],r);return u}}function Gt(n){return function(){var t=Lu(n.prototype),r=n.apply(t,arguments);return se(r)?r:t}}function Jt(n){function t(r,e,u){return u&&Or(r,e,u)&&(e=null),r=hr(r,n,null,null,null,null,null,e),r.placeholder=t.placeholder,r}return t}function Xt(n,t){return function(r,e,u){u&&Or(r,e,u)&&(e=null);var i=dr(),f=null==e;if(i===ut&&f||(f=false,e=i(e,u,3)),f){if(e=To(r),e||!ve(r))return n(e?r:Nr(r));
|
||||||
n+"||("+n+"={});var __t,__p='',__e=_.escape"+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":",__d="+n+"."+n+"||"+n+";")+e+"return __p}";try{u=Function("_","return "+e)(s)}catch(p){u=function(){throw p}}return t?u(t):(u.source=e,u)},s.throttle=function(e,t){function n(){a=new Date,u=r,e.apply(o,i)}var i,s,o,u,a=0;return function(){var r=new Date,f=t-(r-a);return i=arguments,o=this,0>=f?(a=r,s=e.apply(o,i)):u||(u=Tt(n,f)),s}},s.times=function(e,t,n){var r=-1;if(n)for(;++
|
|
||||||
r<e;)t.call(n,r);else for(;++r<e;)t(r)},s.toArray=function(e){if(!e)return[];if(e.toArray&&w(e.toArray))return e.toArray();var t=e.length;return-1<t&&t===t>>>0?(At?lt.call(e)==St:"string"==typeof e)?e.split(""):ft.call(e):sn(e)},s.union=function(){for(var e=-1,t=[],n=st.apply(t,arguments),r=n.length;++e<r;)0>C(t,n[e])&&t.push(n[e]);return t},s.uniq=O,s.uniqueId=function(e){var t=W++;return e?e+t:t},s.values=sn,s.where=En,s.without=function(e){var t=[];if(!e)return t;for(var n=-1,r=e.length,i=u(arguments
|
e=o}return yr(r,e,t)}}function Ht(n,r){return function(e,u,o){return u=dr(u,o,3),To(e)?(u=t(e,u,r),-1<u?e[u]:w):lt(e,u,n)}}function Qt(n){return function(r,e,u){return r&&r.length?(e=dr(e,u,3),t(r,e,n)):-1}}function nr(n){return function(t,r,e){return r=dr(r,e,3),lt(t,r,n,true)}}function tr(n){return function(){var t=arguments.length;if(!t)return function(){return arguments[0]};for(var r,e=n?t:-1,u=0,o=Ue(t);n?e--:++e<t;){var i=o[u++]=arguments[e];if(typeof i!="function")throw new Pe(L);var f=r?"":Vu(i);
|
||||||
,1,20);++n<r;)i(e[n])||t.push(e[n]);return t},s.wrap=function(e,t){return function(){var n=[e];return arguments.length&&ut.apply(n,arguments),t.apply(this,n)}},s.zip=function(e){if(!e)return[];for(var t=-1,n=k(mn(arguments,"length")),r=Array(n);++t<n;)r[t]=mn(arguments,t);return r},s.zipObject=function(e,t){if(!e)return{};var n=-1,r=e.length,i={};for(t||(t=[]);++n<r;)i[e[n]]=t[n];return i},s.all=an,s.any=bn,s.collect=dn,s.detect=ln,s.each=cn,s.foldl=gn,s.foldr=x,s.head=T,s.include=on,s.inject=gn,
|
|
||||||
s.methods=tn,s.select=fn,s.tail=L,s.take=T,s.unique=O,cn({Date:yt,Number:bt,RegExp:Et,String:St},function(e,t){s["is"+t]=function(t){return lt.call(t)==e}}),o.prototype=s.prototype,D(s),o.prototype.chain=function(){return this._chain=n,this},o.prototype.value=function(){return this._wrapped},cn("pop push reverse shift sort splice unshift".split(" "),function(e){var t=I[e];o.prototype[e]=function(){var e=this._wrapped;return t.apply(e,arguments),e.length===0&&delete e[0],this._chain&&(e=new o(e),e
|
r="wrapper"==f?new zn([]):r}for(e=r?-1:t;++e<t;)i=o[e],f=Vu(i),r=(u="wrapper"==f?Ku(i):null)&&Ir(u[0])&&u[1]==(R|k|E|C)&&!u[4].length&&1==u[9]?r[Vu(u[0])].apply(r,u[3]):1==i.length&&Ir(i)?r[f]():r.thru(i);return function(){var n=arguments;if(r&&1==n.length&&To(n[0]))return r.plant(n[0]).value();for(var e=0,n=o[e].apply(this,n);++e<t;)n=o[e].call(this,n);return n}}}function rr(n,t){return function(r,e,u){return typeof e=="function"&&u===w&&To(r)?n(r,e):t(r,zt(e,u,3))}}function er(n){return function(t,r,e){
|
||||||
._chain=n),e}}),cn(["concat","join","slice"],function(e){var t=I[e];o.prototype[e]=function(){var e=t.apply(this._wrapped,arguments);return this._chain&&(e=new o(e),e._chain=n),e}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(e._=s,define(function(){return s})):F?"object"==typeof module&&module&&module.t==F?(module.t=s)._=s:F._=s:e._=s})(this);
|
return(typeof r!="function"||e!==w)&&(r=zt(r,e,3)),n(t,r,me)}}function ur(n){return function(t,r,e){return(typeof r!="function"||e!==w)&&(r=zt(r,e,3)),n(t,r)}}function or(n){return function(t,r,e){var u={};return r=dr(r,e,3),ht(t,function(t,e,o){o=r(t,e,o),e=n?o:e,t=n?t:o,u[e]=t}),u}}function ir(n){return function(t,r,e){return t=u(t),(n?t:"")+lr(t,r,e)+(n?"":t)}}function fr(n){var t=fe(function(r,e){var u=v(e,t.placeholder);return hr(r,n,null,e,u)});return t}function ar(n,t){return function(r,e,u,o){
|
||||||
|
var i=3>arguments.length;return typeof e=="function"&&o===w&&To(r)?n(r,e,u,i):Et(r,dr(e,o,4),u,i,t)}}function cr(n,t,r,e,u,o,i,f,a,c){function l(){for(var b=arguments.length,j=b,k=Ue(b);j--;)k[j]=arguments[j];if(e&&(k=Mt(k,e,u)),o&&(k=Dt(k,o,i)),_||y){var j=l.placeholder,O=v(k,j),b=b-O.length;if(b<c){var R=f?qn(f):null,b=bu(c-b,0),C=_?O:null,O=_?null:O,W=_?k:null,k=_?null:k;return t|=_?E:I,t&=~(_?I:E),g||(t&=~(x|A)),k=[n,t,r,W,C,k,O,R,a,b],R=cr.apply(w,k),Ir(n)&&Gu(R,k),R.placeholder=j,R}}if(j=p?r:this,
|
||||||
|
h&&(n=j[m]),f)for(R=k.length,b=xu(f.length,R),C=qn(k);b--;)O=f[b],k[b]=kr(O,R)?C[O]:w;return s&&a<k.length&&(k.length=a),(this&&this!==Yn&&this instanceof l?d||Gt(n):n).apply(j,k)}var s=t&R,p=t&x,h=t&A,_=t&k,g=t&j,y=t&O,d=!h&&Gt(n),m=n;return l}function lr(n,t,r){return n=n.length,t=+t,n<t&&mu(t)?(t-=n,r=null==r?" ":r+"",je(r,ru(t/r.length)).slice(0,t)):""}function sr(n,t,r,e){function u(){for(var t=-1,f=arguments.length,a=-1,c=e.length,l=Ue(f+c);++a<c;)l[a]=e[a];for(;f--;)l[a++]=arguments[++t];return(this&&this!==Yn&&this instanceof u?i:n).apply(o?r:this,l);
|
||||||
|
|
||||||
|
}var o=t&x,i=Gt(n);return u}function pr(n){return function(t,r,e,u){var o=dr(e);return o===ut&&null==e?$t(t,r,n):Lt(t,r,o(e,u,1),n)}}function hr(n,t,r,e,u,o,i,f){var a=t&A;if(!a&&typeof n!="function")throw new Pe(L);var c=e?e.length:0;if(c||(t&=~(E|I),e=u=null),c-=u?u.length:0,t&I){var l=e,s=u;e=u=null}var p=a?null:Ku(n);return r=[n,t,r,e,u,l,s,o,i,f],p&&(e=r[1],t=p[1],f=e|t,u=t==R&&e==k||t==R&&e==C&&r[7].length<=p[8]||t==(R|C)&&e==k,(f<R||u)&&(t&x&&(r[2]=p[2],f|=e&x?0:j),(e=p[3])&&(u=r[3],r[3]=u?Mt(u,e,p[4]):qn(e),
|
||||||
|
r[4]=u?v(r[3],z):qn(p[4])),(e=p[5])&&(u=r[5],r[5]=u?Dt(u,e,p[6]):qn(e),r[6]=u?v(r[5],z):qn(p[6])),(e=p[7])&&(r[7]=qn(e)),t&R&&(r[8]=null==r[8]?p[8]:xu(r[8],p[8])),null==r[9]&&(r[9]=p[9]),r[0]=p[0],r[1]=f),t=r[1],f=r[9]),r[9]=null==f?a?0:n.length:bu(f-c,0)||0,(p?Pu:Gu)(t==x?Yt(r[0],r[2]):t!=E&&t!=(x|E)||r[4].length?cr.apply(w,r):sr.apply(w,r),r)}function _r(n,t,r,e,u,o,i){var f=-1,a=n.length,c=t.length,l=true;if(a!=c&&(!u||c<=a))return false;for(;l&&++f<a;){var s=n[f],p=t[f],l=w;if(e&&(l=u?e(p,s,f):e(s,p,f)),
|
||||||
|
l===w)if(u)for(var h=c;h--&&(p=t[h],!(l=s&&s===p||r(s,p,e,u,o,i))););else l=s&&s===p||r(s,p,e,u,o,i)}return!!l}function vr(n,t,r){switch(r){case D:case P:return+n==+t;case q:return n.name==t.name&&n.message==t.message;case V:return n!=+n?t!=+t:n==+t;case Z:case G:return n==t+""}return false}function gr(n,t,r,e,u,o,i){var f=Ko(n),a=f.length,c=Ko(t).length;if(a!=c&&!u)return false;for(var c=u,l=-1;++l<a;){var s=f[l],p=u?s in t:Ge.call(t,s);if(p){var h=n[s],_=t[s],p=w;e&&(p=u?e(_,h,s):e(h,_,s)),p===w&&(p=h&&h===_||r(h,_,e,u,o,i));
|
||||||
|
|
||||||
|
}if(!p)return false;c||(c="constructor"==s)}return c||(r=n.constructor,e=t.constructor,!(r!=e&&"constructor"in n&&"constructor"in t)||typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)?true:false}function yr(n,t,r){var e=r?Iu:Eu,u=e,o=u;return zu(n,function(n,i,f){i=t(n,i,f),((r?i<u:i>u)||i===e&&i===o)&&(u=i,o=n)}),o}function dr(n,t,r){var e=$n.callback||Ee,e=e===Ee?ut:e;return r?e(n,t,r):e}function mr(n,t,e){var u=$n.indexOf||Dr,u=u===Dr?r:u;return n?u(n,t,e):u}function wr(n){var t=n.length,r=new n.constructor(t);
|
||||||
|
|
||||||
|
return t&&"string"==typeof n[0]&&Ge.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function br(n){return n=n.constructor,typeof n=="function"&&n instanceof n||(n=Be),new n}function xr(n,t,r){var e=n.constructor;switch(t){case J:return Bt(n);case D:case P:return new e(+n);case X:case H:case Q:case nn:case tn:case rn:case en:case un:case on:return t=n.buffer,new e(r?Bt(t):t,n.byteOffset,n.length);case V:case G:return new e(n);case Z:var u=new e(n.source,kn.exec(n));u.lastIndex=n.lastIndex}return u;
|
||||||
|
|
||||||
|
}function Ar(n,t,r){return null==n||Er(t,n)||(t=$r(t),n=1==t.length?n:gt(n,It(t,0,-1)),t=Pr(t)),t=null==n?n:n[t],null==t?w:t.apply(n,r)}function jr(n){return null!=n&&Rr(Yu(n))}function kr(n,t){return n=+n,t=null==t?Tu:t,-1<n&&0==n%1&&n<t}function Or(n,t,r){if(!se(r))return false;var e=typeof t;return("number"==e?jr(r)&&kr(t,r.length):"string"==e&&t in r)?(t=r[t],n===n?n===t:t!==t):false}function Er(n,t){var r=typeof n;return"string"==r&&dn.test(n)||"number"==r?true:To(n)?false:!yn.test(n)||null!=t&&n in Fr(t);
|
||||||
|
|
||||||
|
}function Ir(n){var t=Vu(n);return!!t&&n===$n[t]&&t in Bn.prototype}function Rr(n){return typeof n=="number"&&-1<n&&0==n%1&&n<=Tu}function Cr(n){return n===n&&!se(n)}function Wr(n,t){n=Fr(n);for(var r=-1,e=t.length,u={};++r<e;){var o=t[r];o in n&&(u[o]=n[o])}return u}function Sr(n,t){var r={};return pt(n,function(n,e,u){t(n,e,u)&&(r[e]=n)}),r}function Tr(n){var t;if(!h(n)||Xe.call(n)!=Y||!(Ge.call(n,"constructor")||(t=n.constructor,typeof t!="function"||t instanceof t)))return false;var r;return pt(n,function(n,t){
|
||||||
|
r=t}),r===w||Ge.call(n,r)}function Ur(n){for(var t=me(n),r=t.length,e=r&&n.length,u=$n.support,u=e&&Rr(e)&&(To(n)||u.nonEnumArgs&&ae(n)),o=-1,i=[];++o<r;){var f=t[o];(u&&kr(f,e)||Ge.call(n,f))&&i.push(f)}return i}function Nr(n){return null==n?[]:jr(n)?se(n)?n:Be(n):we(n)}function Fr(n){return se(n)?n:Be(n)}function $r(n){if(To(n))return n;var t=[];return u(n).replace(mn,function(n,r,e,u){t.push(e?u.replace(An,"$1"):r||n)}),t}function Lr(n){return n instanceof Bn?n.clone():new zn(n.__wrapped__,n.__chain__,qn(n.__actions__));
|
||||||
|
|
||||||
|
}function zr(n,t,r){return n&&n.length?((r?Or(n,t,r):null==t)&&(t=1),It(n,0>t?0:t)):[]}function Br(n,t,r){var e=n?n.length:0;return e?((r?Or(n,t,r):null==t)&&(t=1),t=e-(+t||0),It(n,0,0>t?0:t)):[]}function Mr(n){return n?n[0]:w}function Dr(n,t,e){var u=n?n.length:0;if(!u)return-1;if(typeof e=="number")e=0>e?bu(u+e,0):e;else if(e)return e=$t(n,t),n=n[e],(t===t?t===n:n!==n)?e:-1;return r(n,t,e||0)}function Pr(n){var t=n?n.length:0;return t?n[t-1]:w}function qr(n){return zr(n,1)}function Kr(n,t,e,u){
|
||||||
|
if(!n||!n.length)return[];null!=t&&typeof t!="boolean"&&(u=e,e=Or(n,t,u)?null:t,t=false);var o=dr();if((o!==ut||null!=e)&&(e=o(e,u,3)),t&&mr()==r){t=e;var i;e=-1,u=n.length;for(var o=-1,f=[];++e<u;){var a=n[e],c=t?t(a,e,n):a;e&&i===c||(i=c,f[++o]=a)}n=f}else n=Tt(n,e);return n}function Vr(n){if(!n||!n.length)return[];var t=-1,r=0;n=Gn(n,function(n){return jr(n)?(r=bu(n.length,r),true):void 0});for(var e=Ue(r);++t<r;)e[t]=Jn(n,At(t));return e}function Yr(n,t,r){return n&&n.length?(n=Vr(n),null==t?n:(t=zt(t,r,4),
|
||||||
|
Jn(n,function(n){return Xn(n,t,w,true)}))):[]}function Zr(n,t){var r=-1,e=n?n.length:0,u={};for(!e||t||To(n[0])||(t=[]);++r<e;){var o=n[r];t?u[o]=t[r]:o&&(u[o[0]]=o[1])}return u}function Gr(n){return n=$n(n),n.__chain__=true,n}function Jr(n,t,r){return t.call(r,n)}function Xr(n,t,r){var e=To(n)?Vn:at;return r&&Or(n,t,r)&&(t=null),(typeof t!="function"||r!==w)&&(t=dr(t,r,3)),e(n,t)}function Hr(n,t,r){var e=To(n)?Gn:ct;return t=dr(t,r,3),e(n,t)}function Qr(n,t,r,e){var u=n?Yu(n):0;return Rr(u)||(n=we(n),
|
||||||
|
u=n.length),u?(r=typeof r!="number"||e&&Or(t,r,e)?0:0>r?bu(u+r,0):r||0,typeof n=="string"||!To(n)&&ve(n)?r<u&&-1<n.indexOf(t,r):-1<mr(n,t,r)):false}function ne(n,t,r){var e=To(n)?Jn:mt;return t=dr(t,r,3),e(n,t)}function te(n,t,r){return(r?Or(n,t,r):null==t)?(n=Nr(n),t=n.length,0<t?n[Ot(0,t-1)]:w):(n=re(n),n.length=xu(0>t?0:+t||0,n.length),n)}function re(n){n=Nr(n);for(var t=-1,r=n.length,e=Ue(r);++t<r;){var u=Ot(0,t);t!=u&&(e[t]=e[u]),e[u]=n[t]}return e}function ee(n,t,r){var e=To(n)?Hn:Rt;return r&&Or(n,t,r)&&(t=null),
|
||||||
|
(typeof t!="function"||r!==w)&&(t=dr(t,r,3)),e(n,t)}function ue(n,t){var r;if(typeof t!="function"){if(typeof n!="function")throw new Pe(L);var e=n;n=t,t=e}return function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=null),r}}function oe(n,t,r){function e(){var r=t-(wo()-c);0>=r||r>t?(f&&eu(f),r=p,f=s=p=w,r&&(h=wo(),a=n.apply(l,i),s||f||(i=l=null))):s=su(e,r)}function u(){s&&eu(s),f=s=p=w,(v||_!==t)&&(h=wo(),a=n.apply(l,i),s||f||(i=l=null))}function o(){if(i=arguments,c=wo(),l=this,p=v&&(s||!g),
|
||||||
|
!1===_)var r=g&&!s;else{f||g||(h=c);var o=_-(c-h),y=0>=o||o>_;y?(f&&(f=eu(f)),h=c,a=n.apply(l,i)):f||(f=su(u,o))}return y&&s?s=eu(s):s||t===_||(s=su(e,t)),r&&(y=true,a=n.apply(l,i)),!y||s||f||(i=l=null),a}var i,f,a,c,l,s,p,h=0,_=false,v=true;if(typeof n!="function")throw new Pe(L);if(t=0>t?0:+t||0,true===r)var g=true,v=false;else se(r)&&(g=r.leading,_="maxWait"in r&&bu(+r.maxWait||0,t),v="trailing"in r?r.trailing:v);return o.cancel=function(){s&&eu(s),f&&eu(f),f=s=p=w},o}function ie(n,t){function r(){var e=arguments,u=r.cache,o=t?t.apply(this,e):e[0];
|
||||||
|
|
||||||
|
return u.has(o)?u.get(o):(e=n.apply(this,e),u.set(o,e),e)}if(typeof n!="function"||t&&typeof t!="function")throw new Pe(L);return r.cache=new ie.Cache,r}function fe(n,t){if(typeof n!="function")throw new Pe(L);return t=bu(t===w?n.length-1:+t||0,0),function(){for(var r=arguments,e=-1,u=bu(r.length-t,0),o=Ue(u);++e<u;)o[e]=r[t+e];switch(t){case 0:return n.call(this,o);case 1:return n.call(this,r[0],o);case 2:return n.call(this,r[0],r[1],o)}for(u=Ue(t+1),e=-1;++e<t;)u[e]=r[e];return u[t]=o,n.apply(this,u);
|
||||||
|
|
||||||
|
}}function ae(n){return h(n)&&jr(n)&&Xe.call(n)==B}function ce(n){return!!n&&1===n.nodeType&&h(n)&&-1<Xe.call(n).indexOf("Element")}function le(n){return h(n)&&typeof n.message=="string"&&Xe.call(n)==q}function se(n){var t=typeof n;return"function"==t||!!n&&"object"==t}function pe(n){return null==n?false:Xe.call(n)==K?Qe.test(Ze.call(n)):h(n)&&En.test(n)}function he(n){return typeof n=="number"||h(n)&&Xe.call(n)==V}function _e(n){return h(n)&&Xe.call(n)==Z}function ve(n){return typeof n=="string"||h(n)&&Xe.call(n)==G;
|
||||||
|
|
||||||
|
}function ge(n){return h(n)&&Rr(n.length)&&!!Un[Xe.call(n)]}function ye(n){return et(n,me(n))}function de(n){return vt(n,me(n))}function me(n){if(null==n)return[];se(n)||(n=Be(n));for(var t=n.length,t=t&&Rr(t)&&(To(n)||Fu.nonEnumArgs&&ae(n))&&t||0,r=n.constructor,e=-1,r=typeof r=="function"&&r.prototype===n,u=Ue(t),o=0<t;++e<t;)u[e]=e+"";for(var i in n)o&&kr(i,t)||"constructor"==i&&(r||!Ge.call(n,i))||u.push(i);return u}function we(n){return Ut(n,Ko(n))}function be(n){return(n=u(n))&&n.replace(In,c).replace(xn,"");
|
||||||
|
|
||||||
|
}function xe(n){return(n=u(n))&&bn.test(n)?n.replace(wn,"\\$&"):n}function Ae(n,t,r){return r&&Or(n,t,r)&&(t=0),ku(n,t)}function je(n,t){var r="";if(n=u(n),t=+t,1>t||!n||!mu(t))return r;do t%2&&(r+=n),t=uu(t/2),n+=n;while(t);return r}function ke(n,t,r){var e=n;return(n=u(n))?(r?Or(e,t,r):null==t)?n.slice(g(n),y(n)+1):(t+="",n.slice(i(n,t),f(n,t)+1)):n}function Oe(n,t,r){return r&&Or(n,t,r)&&(t=null),n=u(n),n.match(t||Wn)||[]}function Ee(n,t,r){return r&&Or(n,t,r)&&(t=null),h(n)?Ce(n):ut(n,t)}function Ie(n){
|
||||||
|
return function(){return n}}function Re(n){return n}function Ce(n){return wt(ot(n,true))}function We(n,t,r){if(null==r){var e=se(t),u=e&&Ko(t);((u=u&&u.length&&vt(t,u))?u.length:e)||(u=false,r=t,t=n,n=this)}u||(u=vt(t,Ko(t)));var o=true,e=-1,i=No(n),f=u.length;false===r?o=false:se(r)&&"chain"in r&&(o=r.chain);for(;++e<f;){r=u[e];var a=t[r];n[r]=a,i&&(n.prototype[r]=function(t){return function(){var r=this.__chain__;if(o||r){var e=n(this.__wrapped__);return(e.__actions__=qn(this.__actions__)).push({func:t,args:arguments,
|
||||||
|
thisArg:n}),e.__chain__=r,e}return r=[this.value()],fu.apply(r,arguments),t.apply(n,r)}}(a))}return n}function Se(){}function Te(n){return Er(n)?At(n):jt(n)}_=_?Zn.defaults(Yn.Object(),_,Zn.pick(Yn,Tn)):Yn;var Ue=_.Array,Ne=_.Date,Fe=_.Error,$e=_.Function,Le=_.Math,ze=_.Number,Be=_.Object,Me=_.RegExp,De=_.String,Pe=_.TypeError,qe=Ue.prototype,Ke=Be.prototype,Ve=De.prototype,Ye=(Ye=_.window)&&Ye.document,Ze=$e.prototype.toString,Ge=Ke.hasOwnProperty,Je=0,Xe=Ke.toString,He=_._,Qe=Me("^"+xe(Xe).replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),nu=pe(nu=_.ArrayBuffer)&&nu,tu=pe(tu=nu&&new nu(0).slice)&&tu,ru=Le.ceil,eu=_.clearTimeout,uu=Le.floor,ou=pe(ou=Be.getOwnPropertySymbols)&&ou,iu=pe(iu=Be.getPrototypeOf)&&iu,fu=qe.push,au=pe(au=Be.preventExtensions)&&au,cu=Ke.propertyIsEnumerable,lu=pe(lu=_.Set)&&lu,su=_.setTimeout,pu=qe.splice,hu=pe(hu=_.Uint8Array)&&hu,_u=pe(_u=_.WeakMap)&&_u,vu=function(){
|
||||||
|
try{var n=pe(n=_.Float64Array)&&n,t=new n(new nu(10),0,1)&&n}catch(r){}return t}(),gu=function(){var n=au&&pe(n=Be.assign)&&n;try{if(n){var t=au({1:0});t[0]=1}}catch(r){try{n(t,"xo")}catch(e){}return!t[1]&&n}return false}(),yu=pe(yu=Ue.isArray)&&yu,du=pe(du=Be.create)&&du,mu=_.isFinite,wu=pe(wu=Be.keys)&&wu,bu=Le.max,xu=Le.min,Au=pe(Au=Ne.now)&&Au,ju=pe(ju=ze.isFinite)&&ju,ku=_.parseInt,Ou=Le.random,Eu=ze.NEGATIVE_INFINITY,Iu=ze.POSITIVE_INFINITY,Ru=Le.pow(2,32)-1,Cu=Ru-1,Wu=Ru>>>1,Su=vu?vu.BYTES_PER_ELEMENT:0,Tu=Le.pow(2,53)-1,Uu=_u&&new _u,Nu={},Fu=$n.support={};
|
||||||
|
|
||||||
|
!function(n){function t(){this.x=n}var r=arguments,e=[];t.prototype={valueOf:n,y:n};for(var u in new t)e.push(u);Fu.funcDecomp=/\bthis\b/.test(function(){return this}),Fu.funcNames=typeof $e.name=="string";try{Fu.dom=11===Ye.createDocumentFragment().nodeType}catch(o){Fu.dom=false}try{Fu.nonEnumArgs=!cu.call(r,1)}catch(i){Fu.nonEnumArgs=true}}(1,0),$n.templateSettings={escape:_n,evaluate:vn,interpolate:gn,variable:"",imports:{_:$n}};var $u=gu||function(n,t){return null==t?n:et(t,Zu(t),et(t,Ko(t),n))},Lu=function(){
|
||||||
|
function n(){}return function(t){if(se(t)){n.prototype=t;var r=new n;n.prototype=null}return r||_.Object()}}(),zu=Kt(ht),Bu=Kt(_t,true),Mu=Vt(),Du=Vt(true),Pu=Uu?function(n,t){return Uu.set(n,t),n}:Re;tu||(Bt=nu&&hu?function(n){var t=n.byteLength,r=vu?uu(t/Su):0,e=r*Su,u=new nu(t);if(r){var o=new vu(u,0,r);o.set(new vu(n,0,r))}return t!=e&&(o=new hu(u,e),o.set(new hu(n,e))),u}:Ie(null));var qu=du&&lu?function(n){return new Dn(n)}:Ie(null),Ku=Uu?function(n){return Uu.get(n)}:Se,Vu=function(){return Fu.funcNames?"constant"==Ie.name?At("name"):function(n){
|
||||||
|
for(var t=n.name,r=Nu[t],e=r?r.length:0;e--;){var u=r[e],o=u.func;if(null==o||o==n)return u.name}return t}:Ie("")}(),Yu=At("length"),Zu=ou?function(n){return ou(Fr(n))}:Ie([]),Gu=function(){var n=0,t=0;return function(r,e){var u=wo(),o=U-(u-t);if(t=u,0<o){if(++n>=T)return r}else n=0;return Pu(r,e)}}(),Ju=fe(function(n,t){return jr(n)?ft(n,st(t,false,true)):[]}),Xu=Qt(),Hu=Qt(true),Qu=fe(function(t,r){r=st(r);var e=rt(t,r);return kt(t,r.sort(n)),e}),no=pr(),to=pr(true),ro=fe(function(n){return Tt(st(n,false,true));
|
||||||
|
|
||||||
|
}),eo=fe(function(n,t){return jr(n)?ft(n,t):[]}),uo=fe(Vr),oo=fe(function(n){var t=n.length,r=n[t-2],e=n[t-1];return 2<t&&typeof r=="function"?t-=2:(r=1<t&&typeof e=="function"?(--t,e):w,e=w),n.length=t,Yr(n,r,e)}),io=fe(function(n,t){return rt(n,st(t))}),fo=Pt(function(n,t,r){Ge.call(n,r)?++n[r]:n[r]=1}),ao=Ht(zu),co=Ht(Bu,true),lo=rr(Kn,zu),so=rr(function(n,t){for(var r=n.length;r--&&false!==t(n[r],r,n););return n},Bu),po=Pt(function(n,t,r){Ge.call(n,r)?n[r].push(t):n[r]=[t]}),ho=Pt(function(n,t,r){
|
||||||
|
n[r]=t}),_o=fe(function(n,t,r){var e=-1,u=typeof t=="function",o=Er(t),i=jr(n)?Ue(n.length):[];return zu(n,function(n){var f=u?t:o&&null!=n&&n[t];i[++e]=f?f.apply(n,r):Ar(n,t,r)}),i}),vo=Pt(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),go=ar(Xn,zu),yo=ar(function(n,t,r,e){var u=n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r},Bu),mo=fe(function(n,t){if(null==n)return[];var r=t[2];return r&&Or(t[0],t[1],r)&&(t.length=1),Wt(n,st(t),[])}),wo=Au||function(){return(new Ne).getTime();
|
||||||
|
|
||||||
|
},bo=fe(function(n,t,r){var e=x;if(r.length)var u=v(r,bo.placeholder),e=e|E;return hr(n,e,t,r,u)}),xo=fe(function(n,t){t=t.length?st(t):de(n);for(var r=-1,e=t.length;++r<e;){var u=t[r];n[u]=hr(n[u],x,n)}return n}),Ao=fe(function(n,t,r){var e=x|A;if(r.length)var u=v(r,Ao.placeholder),e=e|E;return hr(t,e,n,r,u)}),jo=Jt(k),ko=Jt(O),Oo=fe(function(n,t){return it(n,1,t)}),Eo=fe(function(n,t,r){return it(n,t,r)}),Io=tr(),Ro=tr(true),Co=fr(E),Wo=fr(I),So=fe(function(n,t){return hr(n,C,null,null,null,st(t));
|
||||||
|
|
||||||
|
}),To=yu||function(n){return h(n)&&Rr(n.length)&&Xe.call(n)==M};Fu.dom||(ce=function(n){return!!n&&1===n.nodeType&&h(n)&&!Fo(n)});var Uo=ju||function(n){return typeof n=="number"&&mu(n)},No=e(/x/)||hu&&!e(hu)?function(n){return Xe.call(n)==K}:e,Fo=iu?function(n){if(!n||Xe.call(n)!=Y)return false;var t=n.valueOf,r=pe(t)&&(r=iu(t))&&iu(r);return r?n==r||iu(n)==r:Tr(n)}:Tr,$o=qt(function(n,t,r){return r?tt(n,t,r):$u(n,t)}),Lo=fe(function(n){var t=n[0];return null==t?t:(n.push(Qn),$o.apply(w,n))}),zo=nr(ht),Bo=nr(_t),Mo=er(Mu),Do=er(Du),Po=ur(ht),qo=ur(_t),Ko=wu?function(n){
|
||||||
|
var t=null!=n&&n.constructor;return typeof t=="function"&&t.prototype===n||typeof n!="function"&&jr(n)?Ur(n):se(n)?wu(n):[]}:Ur,Vo=or(true),Yo=or(),Zo=qt(xt),Go=fe(function(n,t){if(null==n)return{};if("function"!=typeof t[0])return t=Jn(st(t),De),Wr(n,ft(me(n),t));var r=zt(t[0],t[1],3);return Sr(n,function(n,t,e){return!r(n,t,e)})}),Jo=fe(function(n,t){return null==n?{}:"function"==typeof t[0]?Sr(n,zt(t[0],t[1],3)):Wr(n,st(t))}),Xo=Zt(function(n,t,r){return t=t.toLowerCase(),n+(r?t.charAt(0).toUpperCase()+t.slice(1):t);
|
||||||
|
|
||||||
|
}),Ho=Zt(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Qo=ir(),ni=ir(true);8!=ku(Sn+"08")&&(Ae=function(n,t,r){return(r?Or(n,t,r):null==t)?t=0:t&&(t=+t),n=ke(n),ku(n,t||(On.test(n)?16:10))});var ti=Zt(function(n,t,r){return n+(r?"_":"")+t.toLowerCase()}),ri=Zt(function(n,t,r){return n+(r?" ":"")+(t.charAt(0).toUpperCase()+t.slice(1))}),ei=fe(function(n,t){try{return n.apply(w,t)}catch(r){return le(r)?r:new Fe(r)}}),ui=fe(function(n,t){return function(r){return Ar(r,n,t)}}),oi=fe(function(n,t){
|
||||||
|
return function(r){return Ar(n,r,t)}}),ii=Xt(function(n){for(var t=-1,r=n.length,e=Eu;++t<r;){var u=n[t];u>e&&(e=u)}return e}),fi=Xt(function(n){for(var t=-1,r=n.length,e=Iu;++t<r;){var u=n[t];u<e&&(e=u)}return e},true);return $n.prototype=Ln.prototype,zn.prototype=Lu(Ln.prototype),zn.prototype.constructor=zn,Bn.prototype=Lu(Ln.prototype),Bn.prototype.constructor=Bn,Mn.prototype["delete"]=function(n){return this.has(n)&&delete this.__data__[n]},Mn.prototype.get=function(n){return"__proto__"==n?w:this.__data__[n];
|
||||||
|
|
||||||
|
},Mn.prototype.has=function(n){return"__proto__"!=n&&Ge.call(this.__data__,n)},Mn.prototype.set=function(n,t){return"__proto__"!=n&&(this.__data__[n]=t),this},Dn.prototype.push=function(n){var t=this.data;typeof n=="string"||se(n)?t.set.add(n):t.hash[n]=true},ie.Cache=Mn,$n.after=function(n,t){if(typeof t!="function"){if(typeof n!="function")throw new Pe(L);var r=n;n=t,t=r}return n=mu(n=+n)?n:0,function(){return 1>--n?t.apply(this,arguments):void 0}},$n.ary=function(n,t,r){return r&&Or(n,t,r)&&(t=null),
|
||||||
|
t=n&&null==t?n.length:bu(+t||0,0),hr(n,R,null,null,null,null,t)},$n.assign=$o,$n.at=io,$n.before=ue,$n.bind=bo,$n.bindAll=xo,$n.bindKey=Ao,$n.callback=Ee,$n.chain=Gr,$n.chunk=function(n,t,r){t=(r?Or(n,t,r):null==t)?1:bu(+t||1,1),r=0;for(var e=n?n.length:0,u=-1,o=Ue(ru(e/t));r<e;)o[++u]=It(n,r,r+=t);return o},$n.compact=function(n){for(var t=-1,r=n?n.length:0,e=-1,u=[];++t<r;){var o=n[t];o&&(u[++e]=o)}return u},$n.constant=Ie,$n.countBy=fo,$n.create=function(n,t,r){var e=Lu(n);return r&&Or(n,t,r)&&(t=null),
|
||||||
|
t?$u(e,t):e},$n.curry=jo,$n.curryRight=ko,$n.debounce=oe,$n.defaults=Lo,$n.defer=Oo,$n.delay=Eo,$n.difference=Ju,$n.drop=zr,$n.dropRight=Br,$n.dropRightWhile=function(n,t,r){return n&&n.length?Nt(n,dr(t,r,3),true,true):[]},$n.dropWhile=function(n,t,r){return n&&n.length?Nt(n,dr(t,r,3),true):[]},$n.fill=function(n,t,r,e){var u=n?n.length:0;if(!u)return[];for(r&&typeof r!="number"&&Or(n,t,r)&&(r=0,e=u),u=n.length,r=null==r?0:+r||0,0>r&&(r=-r>u?0:u+r),e=e===w||e>u?u:+e||0,0>e&&(e+=u),u=r>e?0:e>>>0,r>>>=0;r<u;)n[r++]=t;
|
||||||
|
|
||||||
|
return n},$n.filter=Hr,$n.flatten=function(n,t,r){var e=n?n.length:0;return r&&Or(n,t,r)&&(t=false),e?st(n,t):[]},$n.flattenDeep=function(n){return n&&n.length?st(n,true):[]},$n.flow=Io,$n.flowRight=Ro,$n.forEach=lo,$n.forEachRight=so,$n.forIn=Mo,$n.forInRight=Do,$n.forOwn=Po,$n.forOwnRight=qo,$n.functions=de,$n.groupBy=po,$n.indexBy=ho,$n.initial=function(n){return Br(n,1)},$n.intersection=function(){for(var n=[],t=-1,e=arguments.length,u=[],o=mr(),i=o==r,f=[];++t<e;){var a=arguments[t];jr(a)&&(n.push(a),
|
||||||
|
u.push(i&&120<=a.length?qu(t&&a):null))}if(e=n.length,2>e)return f;var i=n[0],c=-1,l=i?i.length:0,s=u[0];n:for(;++c<l;)if(a=i[c],0>(s?Pn(s,a):o(f,a,0))){for(t=e;--t;){var p=u[t];if(0>(p?Pn(p,a):o(n[t],a,0)))continue n}s&&s.push(a),f.push(a)}return f},$n.invert=function(n,t,r){r&&Or(n,t,r)&&(t=null),r=-1;for(var e=Ko(n),u=e.length,o={};++r<u;){var i=e[r],f=n[i];t?Ge.call(o,f)?o[f].push(i):o[f]=[i]:o[f]=i}return o},$n.invoke=_o,$n.keys=Ko,$n.keysIn=me,$n.map=ne,$n.mapKeys=Vo,$n.mapValues=Yo,$n.matches=Ce,
|
||||||
|
$n.matchesProperty=function(n,t){return bt(n,ot(t,true))},$n.memoize=ie,$n.merge=Zo,$n.method=ui,$n.methodOf=oi,$n.mixin=We,$n.negate=function(n){if(typeof n!="function")throw new Pe(L);return function(){return!n.apply(this,arguments)}},$n.omit=Go,$n.once=function(n){return ue(2,n)},$n.pairs=function(n){for(var t=-1,r=Ko(n),e=r.length,u=Ue(e);++t<e;){var o=r[t];u[t]=[o,n[o]]}return u},$n.partial=Co,$n.partialRight=Wo,$n.partition=vo,$n.pick=Jo,$n.pluck=function(n,t){return ne(n,Te(t))},$n.property=Te,
|
||||||
|
$n.propertyOf=function(n){return function(t){return gt(n,$r(t),t+"")}},$n.pull=function(){var n=arguments,t=n[0];if(!t||!t.length)return t;for(var r=0,e=mr(),u=n.length;++r<u;)for(var o=0,i=n[r];-1<(o=e(t,i,o));)pu.call(t,o,1);return t},$n.pullAt=Qu,$n.range=function(n,t,r){r&&Or(n,t,r)&&(t=r=null),n=+n||0,r=null==r?1:+r||0,null==t?(t=n,n=0):t=+t||0;var e=-1;t=bu(ru((t-n)/(r||1)),0);for(var u=Ue(t);++e<t;)u[e]=n,n+=r;return u},$n.rearg=So,$n.reject=function(n,t,r){var e=To(n)?Gn:ct;return t=dr(t,r,3),
|
||||||
|
e(n,function(n,r,e){return!t(n,r,e)})},$n.remove=function(n,t,r){var e=[];if(!n||!n.length)return e;var u=-1,o=[],i=n.length;for(t=dr(t,r,3);++u<i;)r=n[u],t(r,u,n)&&(e.push(r),o.push(u));return kt(n,o),e},$n.rest=qr,$n.restParam=fe,$n.set=function(n,t,r){if(null==n)return n;var e=t+"";t=null!=n[e]||Er(t,n)?[e]:$r(t);for(var e=-1,u=t.length,o=u-1,i=n;null!=i&&++e<u;){var f=t[e];se(i)&&(e==o?i[f]=r:null==i[f]&&(i[f]=kr(t[e+1])?[]:{})),i=i[f]}return n},$n.shuffle=re,$n.slice=function(n,t,r){var e=n?n.length:0;
|
||||||
|
|
||||||
|
return e?(r&&typeof r!="number"&&Or(n,t,r)&&(t=0,r=e),It(n,t,r)):[]},$n.sortBy=function(n,t,r){if(null==n)return[];r&&Or(n,t,r)&&(t=null);var e=-1;return t=dr(t,r,3),n=mt(n,function(n,r,u){return{a:t(n,r,u),b:++e,c:n}}),Ct(n,a)},$n.sortByAll=mo,$n.sortByOrder=function(n,t,r,e){return null==n?[]:(e&&Or(t,r,e)&&(r=null),To(t)||(t=null==t?[]:[t]),To(r)||(r=null==r?[]:[r]),Wt(n,t,r))},$n.spread=function(n){if(typeof n!="function")throw new Pe(L);return function(t){return n.apply(this,t)}},$n.take=function(n,t,r){
|
||||||
|
return n&&n.length?((r?Or(n,t,r):null==t)&&(t=1),It(n,0,0>t?0:t)):[]},$n.takeRight=function(n,t,r){var e=n?n.length:0;return e?((r?Or(n,t,r):null==t)&&(t=1),t=e-(+t||0),It(n,0>t?0:t)):[]},$n.takeRightWhile=function(n,t,r){return n&&n.length?Nt(n,dr(t,r,3),false,true):[]},$n.takeWhile=function(n,t,r){return n&&n.length?Nt(n,dr(t,r,3)):[]},$n.tap=function(n,t,r){return t.call(r,n),n},$n.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new Pe(L);return false===r?e=false:se(r)&&(e="leading"in r?!!r.leading:e,
|
||||||
|
u="trailing"in r?!!r.trailing:u),Fn.leading=e,Fn.maxWait=+t,Fn.trailing=u,oe(n,t,Fn)},$n.thru=Jr,$n.times=function(n,t,r){if(n=uu(n),1>n||!mu(n))return[];var e=-1,u=Ue(xu(n,Ru));for(t=zt(t,r,1);++e<n;)e<Ru?u[e]=t(e):t(e);return u},$n.toArray=function(n){var t=n?Yu(n):0;return Rr(t)?t?qn(n):[]:we(n)},$n.toPlainObject=ye,$n.transform=function(n,t,r,e){var u=To(n)||ge(n);return t=dr(t,e,4),null==r&&(u||se(n)?(e=n.constructor,r=u?To(n)?new e:[]:Lu(No(e)&&e.prototype)):r={}),(u?Kn:ht)(n,function(n,e,u){
|
||||||
|
return t(r,n,e,u)}),r},$n.union=ro,$n.uniq=Kr,$n.unzip=Vr,$n.unzipWith=Yr,$n.values=we,$n.valuesIn=function(n){return Ut(n,me(n))},$n.where=function(n,t){return Hr(n,wt(t))},$n.without=eo,$n.wrap=function(n,t){return t=null==t?Re:t,hr(t,E,null,[n],[])},$n.xor=function(){for(var n=-1,t=arguments.length;++n<t;){var r=arguments[n];if(jr(r))var e=e?ft(e,r).concat(ft(r,e)):r}return e?Tt(e):[]},$n.zip=uo,$n.zipObject=Zr,$n.zipWith=oo,$n.backflow=Ro,$n.collect=ne,$n.compose=Ro,$n.each=lo,$n.eachRight=so,
|
||||||
|
$n.extend=$o,$n.iteratee=Ee,$n.methods=de,$n.object=Zr,$n.select=Hr,$n.tail=qr,$n.unique=Kr,We($n,$n),$n.add=function(n,t){return(+n||0)+(+t||0)},$n.attempt=ei,$n.camelCase=Xo,$n.capitalize=function(n){return(n=u(n))&&n.charAt(0).toUpperCase()+n.slice(1)},$n.clone=function(n,t,r,e){return t&&typeof t!="boolean"&&Or(n,t,r)?t=false:typeof t=="function"&&(e=r,r=t,t=false),r=typeof r=="function"&&zt(r,e,1),ot(n,t,r)},$n.cloneDeep=function(n,t,r){return t=typeof t=="function"&&zt(t,r,1),ot(n,true,t)},$n.deburr=be,
|
||||||
|
$n.endsWith=function(n,t,r){n=u(n),t+="";var e=n.length;return r=r===w?e:xu(0>r?0:+r||0,e),r-=t.length,0<=r&&n.indexOf(t,r)==r},$n.escape=function(n){return(n=u(n))&&hn.test(n)?n.replace(sn,l):n},$n.escapeRegExp=xe,$n.every=Xr,$n.find=ao,$n.findIndex=Xu,$n.findKey=zo,$n.findLast=co,$n.findLastIndex=Hu,$n.findLastKey=Bo,$n.findWhere=function(n,t){return ao(n,wt(t))},$n.first=Mr,$n.get=function(n,t,r){return n=null==n?w:gt(n,$r(t),t+""),n===w?r:n},$n.has=function(n,t){if(null==n)return false;var r=Ge.call(n,t);
|
||||||
|
|
||||||
|
return r||Er(t)||(t=$r(t),n=1==t.length?n:gt(n,It(t,0,-1)),t=Pr(t),r=null!=n&&Ge.call(n,t)),r},$n.identity=Re,$n.includes=Qr,$n.indexOf=Dr,$n.inRange=function(n,t,r){return t=+t||0,"undefined"===typeof r?(r=t,t=0):r=+r||0,n>=xu(t,r)&&n<bu(t,r)},$n.isArguments=ae,$n.isArray=To,$n.isBoolean=function(n){return true===n||false===n||h(n)&&Xe.call(n)==D},$n.isDate=function(n){return h(n)&&Xe.call(n)==P},$n.isElement=ce,$n.isEmpty=function(n){return null==n?true:jr(n)&&(To(n)||ve(n)||ae(n)||h(n)&&No(n.splice))?!n.length:!Ko(n).length;
|
||||||
|
|
||||||
|
},$n.isEqual=function(n,t,r,e){return r=typeof r=="function"&&zt(r,e,3),!r&&Cr(n)&&Cr(t)?n===t:(e=r?r(n,t):w,e===w?yt(n,t,r):!!e)},$n.isError=le,$n.isFinite=Uo,$n.isFunction=No,$n.isMatch=function(n,t,r,e){var u=Ko(t),o=u.length;if(!o)return true;if(null==n)return false;if(r=typeof r=="function"&&zt(r,e,3),n=Fr(n),!r&&1==o){var i=u[0];if(e=t[i],Cr(e))return e===n[i]&&(e!==w||i in n)}for(var i=Ue(o),f=Ue(o);o--;)e=i[o]=t[u[o]],f[o]=Cr(e);return dt(n,u,i,f,r)},$n.isNaN=function(n){return he(n)&&n!=+n},$n.isNative=pe,
|
||||||
|
$n.isNull=function(n){return null===n},$n.isNumber=he,$n.isObject=se,$n.isPlainObject=Fo,$n.isRegExp=_e,$n.isString=ve,$n.isTypedArray=ge,$n.isUndefined=function(n){return n===w},$n.kebabCase=Ho,$n.last=Pr,$n.lastIndexOf=function(n,t,r){var e=n?n.length:0;if(!e)return-1;var u=e;if(typeof r=="number")u=(0>r?bu(e+r,0):xu(r||0,e-1))+1;else if(r)return u=$t(n,t,true)-1,n=n[u],(t===t?t===n:n!==n)?u:-1;if(t!==t)return p(n,u,true);for(;u--;)if(n[u]===t)return u;return-1},$n.max=ii,$n.min=fi,$n.noConflict=function(){
|
||||||
|
return _._=He,this},$n.noop=Se,$n.now=wo,$n.pad=function(n,t,r){n=u(n),t=+t;var e=n.length;return e<t&&mu(t)?(e=(t-e)/2,t=uu(e),e=ru(e),r=lr("",e,r),r.slice(0,t)+n+r):n},$n.padLeft=Qo,$n.padRight=ni,$n.parseInt=Ae,$n.random=function(n,t,r){r&&Or(n,t,r)&&(t=r=null);var e=null==n,u=null==t;return null==r&&(u&&typeof n=="boolean"?(r=n,n=1):typeof t=="boolean"&&(r=t,u=true)),e&&u&&(t=1,u=false),n=+n||0,u?(t=n,n=0):t=+t||0,r||n%1||t%1?(r=Ou(),xu(n+r*(t-n+parseFloat("1e-"+((r+"").length-1))),t)):Ot(n,t)},$n.reduce=go,
|
||||||
|
$n.reduceRight=yo,$n.repeat=je,$n.result=function(n,t,r){var e=null==n?w:n[t];return e===w&&(null==n||Er(t,n)||(t=$r(t),n=1==t.length?n:gt(n,It(t,0,-1)),e=null==n?w:n[Pr(t)]),e=e===w?r:e),No(e)?e.call(n):e},$n.runInContext=m,$n.size=function(n){var t=n?Yu(n):0;return Rr(t)?t:Ko(n).length},$n.snakeCase=ti,$n.some=ee,$n.sortedIndex=no,$n.sortedLastIndex=to,$n.startCase=ri,$n.startsWith=function(n,t,r){return n=u(n),r=null==r?0:xu(0>r?0:+r||0,n.length),n.lastIndexOf(t,r)==r},$n.sum=function(n,t,r){r&&Or(n,t,r)&&(t=null);
|
||||||
|
|
||||||
|
var e=dr(),u=null==t;if(e===ut&&u||(u=false,t=e(t,r,3)),u){for(n=To(n)?n:Nr(n),t=n.length,r=0;t--;)r+=+n[t]||0;n=r}else n=St(n,t);return n},$n.template=function(n,t,r){var e=$n.templateSettings;r&&Or(n,t,r)&&(t=r=null),n=u(n),t=tt($u({},r||t),e,nt),r=tt($u({},t.imports),e.imports,nt);var o,i,f=Ko(r),a=Ut(r,f),c=0;r=t.interpolate||Rn;var l="__p+='";r=Me((t.escape||Rn).source+"|"+r.source+"|"+(r===gn?jn:Rn).source+"|"+(t.evaluate||Rn).source+"|$","g");var p="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";
|
||||||
|
|
||||||
|
if(n.replace(r,function(t,r,e,u,f,a){return e||(e=u),l+=n.slice(c,a).replace(Cn,s),r&&(o=true,l+="'+__e("+r+")+'"),f&&(i=true,l+="';"+f+";\n__p+='"),e&&(l+="'+((__t=("+e+"))==null?'':__t)+'"),c=a+t.length,t}),l+="';",(t=t.variable)||(l="with(obj){"+l+"}"),l=(i?l.replace(fn,""):l).replace(an,"$1").replace(cn,"$1;"),l="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(o?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}",
|
||||||
|
t=ei(function(){return $e(f,p+"return "+l).apply(w,a)}),t.source=l,le(t))throw t;return t},$n.trim=ke,$n.trimLeft=function(n,t,r){var e=n;return(n=u(n))?n.slice((r?Or(e,t,r):null==t)?g(n):i(n,t+"")):n},$n.trimRight=function(n,t,r){var e=n;return(n=u(n))?(r?Or(e,t,r):null==t)?n.slice(0,y(n)+1):n.slice(0,f(n,t+"")+1):n},$n.trunc=function(n,t,r){r&&Or(n,t,r)&&(t=null);var e=W;if(r=S,null!=t)if(se(t)){var o="separator"in t?t.separator:o,e="length"in t?+t.length||0:e;r="omission"in t?u(t.omission):r}else e=+t||0;
|
||||||
|
|
||||||
|
if(n=u(n),e>=n.length)return n;if(e-=r.length,1>e)return r;if(t=n.slice(0,e),null==o)return t+r;if(_e(o)){if(n.slice(e).search(o)){var i,f=n.slice(0,e);for(o.global||(o=Me(o.source,(kn.exec(o)||"")+"g")),o.lastIndex=0;n=o.exec(f);)i=n.index;t=t.slice(0,null==i?e:i)}}else n.indexOf(o,e)!=e&&(o=t.lastIndexOf(o),-1<o&&(t=t.slice(0,o)));return t+r},$n.unescape=function(n){return(n=u(n))&&pn.test(n)?n.replace(ln,d):n},$n.uniqueId=function(n){var t=++Je;return u(n)+t},$n.words=Oe,$n.all=Xr,$n.any=ee,$n.contains=Qr,
|
||||||
|
$n.detect=ao,$n.foldl=go,$n.foldr=yo,$n.head=Mr,$n.include=Qr,$n.inject=go,We($n,function(){var n={};return ht($n,function(t,r){$n.prototype[r]||(n[r]=t)}),n}(),false),$n.sample=te,$n.prototype.sample=function(n){return this.__chain__||null!=n?this.thru(function(t){return te(t,n)}):te(this.value())},$n.VERSION=b,Kn("bind bindKey curry curryRight partial partialRight".split(" "),function(n){$n[n].placeholder=$n}),Kn(["dropWhile","filter","map","takeWhile"],function(n,t){var r=t!=$,e=t==N;Bn.prototype[n]=function(n,u){
|
||||||
|
var o=this.__filtered__,i=o&&e?new Bn(this):this.clone();return(i.__iteratees__||(i.__iteratees__=[])).push({done:false,count:0,index:0,iteratee:dr(n,u,1),limit:-1,type:t}),i.__filtered__=o||r,i}}),Kn(["drop","take"],function(n,t){var r=n+"While";Bn.prototype[n]=function(r){var e=this.__filtered__,u=e&&!t?this.dropWhile():this.clone();return r=null==r?1:bu(uu(r)||0,0),e?t?u.__takeCount__=xu(u.__takeCount__,r):Pr(u.__iteratees__).limit=r:(u.__views__||(u.__views__=[])).push({size:r,type:n+(0>u.__dir__?"Right":"")
|
||||||
|
}),u},Bn.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()},Bn.prototype[n+"RightWhile"]=function(n,t){return this.reverse()[r](n,t).reverse()}}),Kn(["first","last"],function(n,t){var r="take"+(t?"Right":"");Bn.prototype[n]=function(){return this[r](1).value()[0]}}),Kn(["initial","rest"],function(n,t){var r="drop"+(t?"":"Right");Bn.prototype[n]=function(){return this[r](1)}}),Kn(["pluck","where"],function(n,t){var r=t?"filter":"map",e=t?wt:Te;Bn.prototype[n]=function(n){return this[r](e(n));
|
||||||
|
|
||||||
|
}}),Bn.prototype.compact=function(){return this.filter(Re)},Bn.prototype.reject=function(n,t){return n=dr(n,t,1),this.filter(function(t){return!n(t)})},Bn.prototype.slice=function(n,t){n=null==n?0:+n||0;var r=this;return 0>n?r=this.takeRight(-n):n&&(r=this.drop(n)),t!==w&&(t=+t||0,r=0>t?r.dropRight(-t):r.take(t-n)),r},Bn.prototype.toArray=function(){return this.drop(0)},ht(Bn.prototype,function(n,t){var r=$n[t];if(r){var e=/^(?:filter|map|reject)|While$/.test(t),u=/^(?:first|last)$/.test(t);$n.prototype[t]=function(){
|
||||||
|
function t(n){return n=[n],fu.apply(n,o),r.apply($n,n)}var o=arguments,i=this.__chain__,f=this.__wrapped__,a=!!this.__actions__.length,c=f instanceof Bn,l=o[0],s=c||To(f);return s&&e&&typeof l=="function"&&1!=l.length&&(c=s=false),c=c&&!a,u&&!i?c?n.call(f):r.call($n,this.value()):s?(f=n.apply(c?f:new Bn(this),o),u||!a&&!f.__actions__||(f.__actions__||(f.__actions__=[])).push({func:Jr,args:[t],thisArg:$n}),new zn(f,i)):this.thru(t)}}}),Kn("concat join pop push replace shift sort splice split unshift".split(" "),function(n){
|
||||||
|
var t=(/^(?:replace|split)$/.test(n)?Ve:qe)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:join|pop|replace|shift)$/.test(n);$n.prototype[n]=function(){var n=arguments;return e&&!this.__chain__?t.apply(this.value(),n):this[r](function(r){return t.apply(r,n)})}}),ht(Bn.prototype,function(n,t){var r=$n[t];if(r){var e=r.name;(Nu[e]||(Nu[e]=[])).push({name:t,func:r})}}),Nu[cr(null,A).name]=[{name:"wrapper",func:null}],Bn.prototype.clone=function(){var n=this.__actions__,t=this.__iteratees__,r=this.__views__,e=new Bn(this.__wrapped__);
|
||||||
|
|
||||||
|
return e.__actions__=n?qn(n):null,e.__dir__=this.__dir__,e.__filtered__=this.__filtered__,e.__iteratees__=t?qn(t):null,e.__takeCount__=this.__takeCount__,e.__views__=r?qn(r):null,e},Bn.prototype.reverse=function(){if(this.__filtered__){var n=new Bn(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},Bn.prototype.value=function(){var n=this.__wrapped__.value();if(!To(n))return Ft(n,this.__actions__);var t,r=this.__dir__,e=0>r;t=n.length;for(var u=this.__views__,o=0,i=-1,f=u?u.length:0;++i<f;){
|
||||||
|
var a=u[i],c=a.size;switch(a.type){case"drop":o+=c;break;case"dropRight":t-=c;break;case"take":t=xu(t,o+c);break;case"takeRight":o=bu(o,t-c)}}t={start:o,end:t},u=t.start,o=t.end,t=o-u,u=e?o:u-1,o=xu(t,this.__takeCount__),f=(i=this.__iteratees__)?i.length:0,a=0,c=[];n:for(;t--&&a<o;){for(var u=u+r,l=-1,s=n[u];++l<f;){var p=i[l],h=p.iteratee,_=p.type;if(_==N){if(p.done&&(e?u>p.index:u<p.index)&&(p.count=0,p.done=false),p.index=u,!(p.done||(_=p.limit,p.done=-1<_?p.count++>=_:!h(s))))continue n}else if(p=h(s),
|
||||||
|
_==$)s=p;else if(!p){if(_==F)continue n;break n}}c[a++]=s}return c},$n.prototype.chain=function(){return Gr(this)},$n.prototype.commit=function(){return new zn(this.value(),this.__chain__)},$n.prototype.plant=function(n){for(var t,r=this;r instanceof Ln;){var e=Lr(r);t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},$n.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Bn?(this.__actions__.length&&(n=new Bn(this)),new zn(n.reverse(),this.__chain__)):this.thru(function(n){
|
||||||
|
return n.reverse()})},$n.prototype.toString=function(){return this.value()+""},$n.prototype.run=$n.prototype.toJSON=$n.prototype.valueOf=$n.prototype.value=function(){return Ft(this.__wrapped__,this.__actions__)},$n.prototype.collect=$n.prototype.map,$n.prototype.head=$n.prototype.first,$n.prototype.select=$n.prototype.filter,$n.prototype.tail=$n.prototype.rest,$n}var w,b="3.8.0",x=1,A=2,j=4,k=8,O=16,E=32,I=64,R=128,C=256,W=30,S="...",T=150,U=16,N=0,F=1,$=2,L="Expected a function",z="__lodash_placeholder__",B="[object Arguments]",M="[object Array]",D="[object Boolean]",P="[object Date]",q="[object Error]",K="[object Function]",V="[object Number]",Y="[object Object]",Z="[object RegExp]",G="[object String]",J="[object ArrayBuffer]",X="[object Float32Array]",H="[object Float64Array]",Q="[object Int8Array]",nn="[object Int16Array]",tn="[object Int32Array]",rn="[object Uint8Array]",en="[object Uint8ClampedArray]",un="[object Uint16Array]",on="[object Uint32Array]",fn=/\b__p\+='';/g,an=/\b(__p\+=)''\+/g,cn=/(__e\(.*?\)|\b__t\))\+'';/g,ln=/&(?:amp|lt|gt|quot|#39|#96);/g,sn=/[&<>"'`]/g,pn=RegExp(ln.source),hn=RegExp(sn.source),_n=/<%-([\s\S]+?)%>/g,vn=/<%([\s\S]+?)%>/g,gn=/<%=([\s\S]+?)%>/g,yn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,dn=/^\w*$/,mn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,wn=/[.*+?^${}()|[\]\/\\]/g,bn=RegExp(wn.source),xn=/[\u0300-\u036f\ufe20-\ufe23]/g,An=/\\(\\)?/g,jn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,kn=/\w*$/,On=/^0[xX]/,En=/^\[object .+?Constructor\]$/,In=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,Rn=/($^)/,Cn=/['\n\r\u2028\u2029\\]/g,Wn=RegExp("[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?=[A-Z\\xc0-\\xd6\\xd8-\\xde][a-z\\xdf-\\xf6\\xf8-\\xff]+)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|[0-9]+","g"),Sn=" \t\x0b\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000",Tn="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout document isFinite parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap window".split(" "),Un={};
|
||||||
|
|
||||||
|
Un[X]=Un[H]=Un[Q]=Un[nn]=Un[tn]=Un[rn]=Un[en]=Un[un]=Un[on]=true,Un[B]=Un[M]=Un[J]=Un[D]=Un[P]=Un[q]=Un[K]=Un["[object Map]"]=Un[V]=Un[Y]=Un[Z]=Un["[object Set]"]=Un[G]=Un["[object WeakMap]"]=false;var Nn={};Nn[B]=Nn[M]=Nn[J]=Nn[D]=Nn[P]=Nn[X]=Nn[H]=Nn[Q]=Nn[nn]=Nn[tn]=Nn[V]=Nn[Y]=Nn[Z]=Nn[G]=Nn[rn]=Nn[en]=Nn[un]=Nn[on]=true,Nn[q]=Nn[K]=Nn["[object Map]"]=Nn["[object Set]"]=Nn["[object WeakMap]"]=false;var Fn={leading:false,maxWait:0,trailing:false},$n={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A",
|
||||||
|
"\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u",
|
||||||
|
"\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss"},Ln={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},zn={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},Bn={"function":true,object:true},Mn={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Dn=Bn[typeof exports]&&exports&&!exports.nodeType&&exports,Pn=Bn[typeof module]&&module&&!module.nodeType&&module,qn=Bn[typeof self]&&self&&self.Object&&self,Kn=Bn[typeof window]&&window&&window.Object&&window,Vn=Pn&&Pn.exports===Dn&&Dn,Yn=Dn&&Pn&&typeof global=="object"&&global&&global.Object&&global||Kn!==(this&&this.window)&&Kn||qn||this,Zn=m();
|
||||||
|
|
||||||
|
typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Yn._=Zn, define(function(){return Zn})):Dn&&Pn?Vn?(Pn.exports=Zn)._=Zn:Dn._=Zn:Yn._=Zn}).call(this);
|
||||||
12478
lodash.src.js
Normal file
12478
lodash.src.js
Normal file
File diff suppressed because it is too large
Load Diff
75
package.json
75
package.json
@@ -1,52 +1,33 @@
|
|||||||
{
|
{
|
||||||
"name": "lodash",
|
"name": "lodash",
|
||||||
"version": "0.5.0",
|
"version": "3.8.0",
|
||||||
"description": "A drop-in replacement for Underscore.js delivering performance, bug fixes, and additional features.",
|
"main": "lodash.src.js",
|
||||||
"homepage": "http://lodash.com",
|
"private": true,
|
||||||
"main": "lodash",
|
"devDependencies": {
|
||||||
"keywords": [
|
"curl-amd": "0.8.12",
|
||||||
"browser",
|
"dojo": "~1.10.0",
|
||||||
"client",
|
"jquery": "~1.11.0",
|
||||||
"functional",
|
"platform": "~1.3.0",
|
||||||
"performance",
|
"qunit-extras": "~1.4.0",
|
||||||
"server",
|
"qunitjs": "~1.17.0",
|
||||||
"speed",
|
"requirejs": "~2.1.0"
|
||||||
"util"
|
|
||||||
],
|
|
||||||
"licenses": [
|
|
||||||
{
|
|
||||||
"type": "MIT",
|
|
||||||
"url": "http://lodash.com/license"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"author": {
|
|
||||||
"name": "John-David Dalton",
|
|
||||||
"email": "john.david.dalton@gmail.com",
|
|
||||||
"web": "http://allyoucanleet.com/"
|
|
||||||
},
|
},
|
||||||
"bugs": {
|
"volo": {
|
||||||
"url": "https://github.com/bestiejs/lodash/issues"
|
"type": "directory",
|
||||||
},
|
"ignore": [
|
||||||
"repository": {
|
".*",
|
||||||
"type": "git",
|
"*.custom.*",
|
||||||
"url": "https://github.com/bestiejs/lodash.git"
|
"*.log",
|
||||||
},
|
"*.map",
|
||||||
"bin": {
|
"*.md",
|
||||||
"lodash": "./build.js"
|
"lodash.src.js",
|
||||||
},
|
"bower.json",
|
||||||
"directories": {
|
"component.json",
|
||||||
"doc": "./doc",
|
"doc",
|
||||||
"test": "./test"
|
"node_modules",
|
||||||
},
|
"perf",
|
||||||
"engines": [
|
"test",
|
||||||
"node",
|
"vendor"
|
||||||
"rhino"
|
]
|
||||||
],
|
|
||||||
"jam": {
|
|
||||||
"main": "lodash.min.js"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"build": "node build",
|
|
||||||
"test": "node test/test"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
149
perf/asset/perf-ui.js
Normal file
149
perf/asset/perf-ui.js
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
;(function(window) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/** The base path of the lodash builds. */
|
||||||
|
var basePath = '../';
|
||||||
|
|
||||||
|
/** The lodash build to load. */
|
||||||
|
var build = (build = /build=([^&]+)/.exec(location.search)) && decodeURIComponent(build[1]);
|
||||||
|
|
||||||
|
/** The other library to load. */
|
||||||
|
var other = (other = /other=([^&]+)/.exec(location.search)) && decodeURIComponent(other[1]);
|
||||||
|
|
||||||
|
/** The `ui` object. */
|
||||||
|
var ui = {};
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers an event listener on an element.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Element} element The element.
|
||||||
|
* @param {string} eventName The name of the event.
|
||||||
|
* @param {Function} handler The event handler.
|
||||||
|
* @returns {Element} The element.
|
||||||
|
*/
|
||||||
|
function addListener(element, eventName, handler) {
|
||||||
|
if (typeof element.addEventListener != 'undefined') {
|
||||||
|
element.addEventListener(eventName, handler, false);
|
||||||
|
} else if (typeof element.attachEvent != 'undefined') {
|
||||||
|
element.attachEvent('on' + eventName, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// Initialize controls.
|
||||||
|
addListener(window, 'load', function() {
|
||||||
|
function eventHandler(event) {
|
||||||
|
var buildIndex = buildList.selectedIndex,
|
||||||
|
otherIndex = otherList.selectedIndex,
|
||||||
|
search = location.search.replace(/^\?|&?(?:build|other)=[^&]*&?/g, '');
|
||||||
|
|
||||||
|
if (event.stopPropagation) {
|
||||||
|
event.stopPropagation();
|
||||||
|
} else {
|
||||||
|
event.cancelBubble = true;
|
||||||
|
}
|
||||||
|
location.href =
|
||||||
|
location.href.split('?')[0] + '?' +
|
||||||
|
(search ? search + '&' : '') +
|
||||||
|
'build=' + (buildIndex < 0 ? build : buildList[buildIndex].value) + '&' +
|
||||||
|
'other=' + (otherIndex < 0 ? other : otherList[otherIndex].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
var span1 = document.createElement('span');
|
||||||
|
span1.style.cssText = 'float:right';
|
||||||
|
span1.innerHTML =
|
||||||
|
'<label for="perf-build">Build: </label>' +
|
||||||
|
'<select id="perf-build">' +
|
||||||
|
'<option value="lodash-compat">lodash (compat)</option>' +
|
||||||
|
'<option value="lodash-modern">lodash (modern)</option>' +
|
||||||
|
'<option value="lodash-custom-dev">lodash (custom development)</option>' +
|
||||||
|
'<option value="lodash-custom">lodash (custom production)</option>' +
|
||||||
|
'</select>';
|
||||||
|
|
||||||
|
var span2 = document.createElement('span');
|
||||||
|
span2.style.cssText = 'float:right';
|
||||||
|
span2.innerHTML =
|
||||||
|
'<label for="perf-other">Other Library: </label>' +
|
||||||
|
'<select id="perf-other">' +
|
||||||
|
'<option value="underscore-dev">Underscore (development)</option>' +
|
||||||
|
'<option value="underscore">Underscore (production)</option>' +
|
||||||
|
'<option value="lodash-compat">lodash (compat)</option>' +
|
||||||
|
'<option value="lodash-modern">lodash (modern)</option>' +
|
||||||
|
'<option value="lodash-custom-dev">lodash (custom development)</option>' +
|
||||||
|
'<option value="lodash-custom">lodash (custom production)</option>' +
|
||||||
|
'</select>';
|
||||||
|
|
||||||
|
var buildList = span1.lastChild,
|
||||||
|
otherList = span2.lastChild,
|
||||||
|
toolbar = document.getElementById('perf-toolbar');
|
||||||
|
|
||||||
|
toolbar.appendChild(span2);
|
||||||
|
toolbar.appendChild(span1);
|
||||||
|
|
||||||
|
buildList.selectedIndex = (function() {
|
||||||
|
switch (build) {
|
||||||
|
case 'lodash-compat': return 0;
|
||||||
|
case 'lodash-custom-dev': return 2;
|
||||||
|
case 'lodash-custom': return 3;
|
||||||
|
case 'lodash-modern':
|
||||||
|
case null: return 1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}());
|
||||||
|
|
||||||
|
otherList.selectedIndex = (function() {
|
||||||
|
switch (other) {
|
||||||
|
case 'underscore-dev': return 0;
|
||||||
|
case 'lodash-compat': return 2;
|
||||||
|
case 'lodash-modern': return 3;
|
||||||
|
case 'lodash-custom-dev': return 4;
|
||||||
|
case 'lodash-custom': return 5;
|
||||||
|
case 'underscore':
|
||||||
|
case null: return 1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}());
|
||||||
|
|
||||||
|
addListener(buildList, 'change', eventHandler);
|
||||||
|
addListener(otherList, 'change', eventHandler);
|
||||||
|
});
|
||||||
|
|
||||||
|
// The lodash build file path.
|
||||||
|
ui.buildPath = (function() {
|
||||||
|
var result;
|
||||||
|
switch (build) {
|
||||||
|
case 'lodash-compat': result = 'lodash.compat.min.js'; break;
|
||||||
|
case 'lodash-custom-dev': result = 'lodash.custom.js'; break;
|
||||||
|
case 'lodash-custom': result = 'lodash.custom.min.js'; break;
|
||||||
|
case null: build = 'lodash-modern';
|
||||||
|
case 'lodash-modern': result = 'lodash.min.js'; break;
|
||||||
|
default: return build;
|
||||||
|
}
|
||||||
|
return basePath + result;
|
||||||
|
}());
|
||||||
|
|
||||||
|
// The other library file path.
|
||||||
|
ui.otherPath = (function() {
|
||||||
|
var result;
|
||||||
|
switch (other) {
|
||||||
|
case 'lodash-compat': result = 'lodash.compat.min.js'; break;
|
||||||
|
case 'lodash-modern': result = 'lodash.min.js'; break;
|
||||||
|
case 'lodash-custom-dev': result = 'lodash.custom.js'; break;
|
||||||
|
case 'lodash-custom': result = 'lodash.custom.min.js'; break;
|
||||||
|
case 'underscore-dev': result = 'vendor/underscore/underscore.js'; break;
|
||||||
|
case null: other = 'underscore';
|
||||||
|
case 'underscore': result = 'vendor/underscore/underscore-min.js'; break;
|
||||||
|
default: return other;
|
||||||
|
}
|
||||||
|
return basePath + result;
|
||||||
|
}());
|
||||||
|
|
||||||
|
ui.urlParams = { 'build': build, 'other': other };
|
||||||
|
|
||||||
|
window.ui = ui;
|
||||||
|
|
||||||
|
}(this));
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Lo-Dash Performance Suite</title>
|
<title>lodash Performance Suite</title>
|
||||||
<style>
|
<style>
|
||||||
html, body {
|
html, body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -13,21 +13,41 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: -9999em;
|
left: -9999em;
|
||||||
}
|
}
|
||||||
|
#FirebugUI {
|
||||||
|
top: 2em;
|
||||||
|
}
|
||||||
|
#perf-toolbar {
|
||||||
|
background-color: #EEE;
|
||||||
|
color: #5E740B;
|
||||||
|
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
|
||||||
|
font-size: small;
|
||||||
|
padding: 0.5em 0 0.5em 2em;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script src="../lodash.min.js"></script>
|
<div id="perf-toolbar"></div>
|
||||||
|
<script src="../node_modules/platform/platform.js"></script>
|
||||||
|
<script src="../lodash.src.js"></script>
|
||||||
|
<script src="../vendor/benchmark.js/benchmark.js"></script>
|
||||||
|
<script src="../vendor/firebug-lite/src/firebug-lite-debug.js"></script>
|
||||||
|
<script src="./asset/perf-ui.js"></script>
|
||||||
|
<script>
|
||||||
|
document.write('<script src="' + ui.buildPath + '"><\/script>');
|
||||||
|
</script>
|
||||||
<script>
|
<script>
|
||||||
var lodash = _.noConflict();
|
var lodash = _.noConflict();
|
||||||
</script>
|
</script>
|
||||||
<script src="../vendor/underscore/underscore-min.js"></script>
|
<script>
|
||||||
<script src="../vendor/platform.js/platform.js"></script>
|
document.write('<script src="' + ui.otherPath + '"><\/script>');
|
||||||
<script src="../vendor/benchmark.js/benchmark.js"></script>
|
</script>
|
||||||
<script src="../vendor/firebug-lite/src/firebug-lite-debug.js"></script>
|
|
||||||
<script src="perf.js"></script>
|
<script src="perf.js"></script>
|
||||||
<script>
|
<script>
|
||||||
(function() {
|
(function() {
|
||||||
var useApplet = !/[?&]nojava=true(?:&|$)/.test(location.search);
|
var measured,
|
||||||
|
perfNow,
|
||||||
|
begin = new Date;
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
var fbUI = document.getElementById('FirebugUI'),
|
var fbUI = document.getElementById('FirebugUI'),
|
||||||
@@ -37,19 +57,24 @@
|
|||||||
if (!fbCommandLine) {
|
if (!fbCommandLine) {
|
||||||
return setTimeout(init, 15);
|
return setTimeout(init, 15);
|
||||||
}
|
}
|
||||||
fbUI.style.height = fbDoc.body.style.height = fbDoc.documentElement.style.height = '100%';
|
fbUI.style.height = (
|
||||||
|
Math.max(document.documentElement.clientHeight, document.body.clientHeight) -
|
||||||
|
document.getElementById('perf-toolbar').clientHeight
|
||||||
|
) + 'px';
|
||||||
|
|
||||||
// give applet time to initialize
|
fbDoc.body.style.height = fbDoc.documentElement.style.height = '100%';
|
||||||
lodash.delay(run, useApplet ? 500 : 15);
|
setTimeout(run, 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useApplet) {
|
// is the applet permitted?
|
||||||
// using innerHTML avoids an alert in some versions of IE6
|
if (!/[?&]nojava=true(?:&|$)/.test(location.search)) {
|
||||||
var div = document.createElement('div');
|
// is the applet really needed?
|
||||||
div.innerHTML = '<applet code=nano archive="../vendor/benchmark.js/nano.jar">';
|
while (!(measured = new Date - begin)) {}
|
||||||
document.body.insertBefore(div.lastChild, document.body.firstChild);
|
if (measured > 1 && !((perfNow = window.performance) && typeof (perfNow.now || perfNow.webkitNow) == 'function')) {
|
||||||
|
// load applet
|
||||||
|
document.write('<applet code="nano" archive="../vendor/benchmark.js/nano.jar"></applet>');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onload = init;
|
window.onload = init;
|
||||||
}());
|
}());
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
2628
perf/perf.js
2628
perf/perf.js
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,14 @@
|
|||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
for cmd in node narwhal ringo rhino; do
|
|
||||||
echo ""
|
echo "Running performance suite in node..."
|
||||||
echo "Running performance suite in $cmd..."
|
node perf.js ../lodash.js && node perf.js ../lodash.min.js
|
||||||
$cmd perf.js
|
|
||||||
|
for cmd in rhino "rhino -require" narwhal ringo phantomjs; do
|
||||||
|
echo ""
|
||||||
|
echo "Running performance suite in $cmd..."
|
||||||
|
$cmd perf.js ../lodash.src.js
|
||||||
done
|
done
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Running performance suite in a browser..."
|
echo "Running performance suite in a browser..."
|
||||||
open index.html
|
open index.html
|
||||||
|
|||||||
157
test/asset/set.js
Normal file
157
test/asset/set.js
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
;(function() {
|
||||||
|
|
||||||
|
/** Used to determine if values are of the language type Object. */
|
||||||
|
var objectTypes = {
|
||||||
|
'function': true,
|
||||||
|
'object': true
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Used as the `Set#toString` return value. */
|
||||||
|
var nativeString = String(Object.prototype.toString).replace(/toString/g, 'Set');
|
||||||
|
|
||||||
|
/** Detect free variable `exports`. */
|
||||||
|
var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
|
||||||
|
|
||||||
|
/** Detect free variable `module`. */
|
||||||
|
var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
|
||||||
|
|
||||||
|
/** Detect free variable `global` from Node.js. */
|
||||||
|
var freeGlobal = freeExports && freeModule && typeof global == 'object' && global;
|
||||||
|
|
||||||
|
/** Detect free variable `self`. */
|
||||||
|
var freeSelf = objectTypes[typeof self] && self && self.Object && self;
|
||||||
|
|
||||||
|
/** Detect free variable `window`. */
|
||||||
|
var freeWindow = objectTypes[typeof window] && window && window.Object && window;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used as a reference to the global object.
|
||||||
|
*
|
||||||
|
* The `this` value is used if it is the global object to avoid Greasemonkey's
|
||||||
|
* restricted `window` object, otherwise the `window` object is used.
|
||||||
|
*/
|
||||||
|
var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Installs `Set` on the given `context` object.
|
||||||
|
*
|
||||||
|
* @memberOf exports
|
||||||
|
* @param {Object} context The context object.
|
||||||
|
*/
|
||||||
|
function runInContext(context) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a `Set` object.
|
||||||
|
*/
|
||||||
|
function Set() {
|
||||||
|
this.__cache__ = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the index at which the first occurrence of `value` is found using
|
||||||
|
* strict equality for comparisons, i.e. `===`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Array} array The array to search.
|
||||||
|
* @param {*} value The value to search for.
|
||||||
|
* @returns {number} Returns the index of the matched value or `-1`.
|
||||||
|
*/
|
||||||
|
function indexOf(array, value) {
|
||||||
|
var index = -1,
|
||||||
|
length = array.length;
|
||||||
|
|
||||||
|
while (++index < length) {
|
||||||
|
if (array[index] === value) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if `value` is in the set.
|
||||||
|
*
|
||||||
|
* @memberOf Set
|
||||||
|
* @param {*} value The value to search for.
|
||||||
|
* @returns {boolean} Returns `true` if `value` is found, else `false`.
|
||||||
|
*/
|
||||||
|
function has(value) {
|
||||||
|
var type = typeof value,
|
||||||
|
cache = this.__cache__;
|
||||||
|
|
||||||
|
if (type == 'boolean' || value == null) {
|
||||||
|
return cache[value] || false;
|
||||||
|
}
|
||||||
|
if (type != 'number' && type != 'string') {
|
||||||
|
type = 'object';
|
||||||
|
}
|
||||||
|
var key = type == 'number' ? value : '_' + value;
|
||||||
|
cache = (cache = cache[type]) && cache[key];
|
||||||
|
|
||||||
|
return type == 'object'
|
||||||
|
? (cache && indexOf(cache, value) > -1 ? true : false)
|
||||||
|
: (cache || false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds `value` to the set.
|
||||||
|
*
|
||||||
|
* @memberOf Set
|
||||||
|
* @param {*} value The value to add.
|
||||||
|
*/
|
||||||
|
function add(value) {
|
||||||
|
var cache = this.__cache__,
|
||||||
|
type = typeof value;
|
||||||
|
|
||||||
|
if (type == 'boolean' || value == null) {
|
||||||
|
cache[value] = true;
|
||||||
|
} else {
|
||||||
|
if (type != 'number' && type != 'string') {
|
||||||
|
type = 'object';
|
||||||
|
}
|
||||||
|
var key = type == 'number' ? value : '_' + value,
|
||||||
|
typeCache = cache[type] || (cache[type] = {});
|
||||||
|
|
||||||
|
if (type == 'object') {
|
||||||
|
var array = typeCache[key];
|
||||||
|
if (array) {
|
||||||
|
array.push(value);
|
||||||
|
} else {
|
||||||
|
typeCache[key] = [value];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
typeCache[key] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produces the `toString` result of `Set`.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @memberOf Set
|
||||||
|
* @returns {string} Returns the string result.
|
||||||
|
*/
|
||||||
|
function toString() {
|
||||||
|
return nativeString;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set.toString = toString;
|
||||||
|
Set.prototype.add = add;
|
||||||
|
Set.prototype.has = has;
|
||||||
|
|
||||||
|
if (!root.Set) {
|
||||||
|
context.Set = Set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
if (freeExports) {
|
||||||
|
freeExports.runInContext = runInContext;
|
||||||
|
} else {
|
||||||
|
runInContext(root);
|
||||||
|
}
|
||||||
|
}.call(this));
|
||||||
173
test/asset/test-ui.js
Normal file
173
test/asset/test-ui.js
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
;(function(window) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/** The base path of the lodash builds. */
|
||||||
|
var basePath = '../';
|
||||||
|
|
||||||
|
/** The lodash build to load. */
|
||||||
|
var build = (build = /build=([^&]+)/.exec(location.search)) && decodeURIComponent(build[1]);
|
||||||
|
|
||||||
|
/** The module loader to use. */
|
||||||
|
var loader = (loader = /loader=([^&]+)/.exec(location.search)) && decodeURIComponent(loader[1]);
|
||||||
|
|
||||||
|
/** The `ui` object. */
|
||||||
|
var ui = {};
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers an event listener on an element.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Element} element The element.
|
||||||
|
* @param {string} eventName The name of the event.
|
||||||
|
* @param {Function} handler The event handler.
|
||||||
|
* @returns {Element} The element.
|
||||||
|
*/
|
||||||
|
function addListener(element, eventName, handler) {
|
||||||
|
if (typeof element.addEventListener != 'undefined') {
|
||||||
|
element.addEventListener(eventName, handler, false);
|
||||||
|
} else if (typeof element.attachEvent != 'undefined') {
|
||||||
|
element.attachEvent('on' + eventName, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// Initialize controls.
|
||||||
|
addListener(window, 'load', function() {
|
||||||
|
function eventHandler(event) {
|
||||||
|
var buildIndex = buildList.selectedIndex,
|
||||||
|
loaderIndex = loaderList.selectedIndex,
|
||||||
|
search = location.search.replace(/^\?|&?(?:build|loader)=[^&]*&?/g, '');
|
||||||
|
|
||||||
|
if (event.stopPropagation) {
|
||||||
|
event.stopPropagation();
|
||||||
|
} else {
|
||||||
|
event.cancelBubble = true;
|
||||||
|
}
|
||||||
|
location.href =
|
||||||
|
location.href.split('?')[0] + '?' +
|
||||||
|
(search ? search + '&' : '') +
|
||||||
|
'build=' + (buildIndex < 0 ? build : buildList[buildIndex].value) + '&' +
|
||||||
|
'loader=' + (loaderIndex < 0 ? loader : loaderList[loaderIndex].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
var toolbar = document.getElementById('qunit-testrunner-toolbar');
|
||||||
|
if (!toolbar) {
|
||||||
|
setTimeout(init, 15);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
toolbar.appendChild(span1);
|
||||||
|
toolbar.appendChild(span2);
|
||||||
|
|
||||||
|
buildList.selectedIndex = (function() {
|
||||||
|
switch (build) {
|
||||||
|
case 'lodash-compat': return 1;
|
||||||
|
case 'lodash-modern-dev': return 2;
|
||||||
|
case 'lodash-modern': return 3;
|
||||||
|
case 'lodash-custom-dev': return 4;
|
||||||
|
case 'lodash-custom': return 5;
|
||||||
|
case 'lodash-compat-dev':
|
||||||
|
case null: return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}());
|
||||||
|
|
||||||
|
loaderList.selectedIndex = (function() {
|
||||||
|
switch (loader) {
|
||||||
|
case 'curl': return 1;
|
||||||
|
case 'dojo': return 2;
|
||||||
|
case 'requirejs': return 3;
|
||||||
|
case 'none':
|
||||||
|
case null: return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}());
|
||||||
|
|
||||||
|
addListener(buildList, 'change', eventHandler);
|
||||||
|
addListener(loaderList, 'change', eventHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
var span1 = document.createElement('span');
|
||||||
|
span1.style.cssText = 'float:right';
|
||||||
|
span1.innerHTML =
|
||||||
|
'<label for="qunit-build">Build: </label>' +
|
||||||
|
'<select id="qunit-build">' +
|
||||||
|
'<option value="lodash-compat-dev">lodash (compat development)</option>' +
|
||||||
|
'<option value="lodash-compat">lodash (compat production)</option>' +
|
||||||
|
'<option value="lodash-modern-dev">lodash (modern development)</option>' +
|
||||||
|
'<option value="lodash-modern">lodash (modern production)</option>' +
|
||||||
|
'<option value="lodash-custom-dev">lodash (custom development)</option>' +
|
||||||
|
'<option value="lodash-custom">lodash (custom production)</option>' +
|
||||||
|
'</select>';
|
||||||
|
|
||||||
|
var span2 = document.createElement('span');
|
||||||
|
span2.style.cssText = 'float:right';
|
||||||
|
span2.innerHTML =
|
||||||
|
'<label for="qunit-loader">Loader: </label>' +
|
||||||
|
'<select id="qunit-loader">' +
|
||||||
|
'<option value="none">None</option>' +
|
||||||
|
'<option value="curl">Curl</option>' +
|
||||||
|
'<option value="dojo">Dojo</option>' +
|
||||||
|
'<option value="requirejs">RequireJS</option>' +
|
||||||
|
'</select>';
|
||||||
|
|
||||||
|
var buildList = span1.lastChild,
|
||||||
|
loaderList = span2.lastChild;
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
ui.timing.loadEventEnd = +new Date;
|
||||||
|
}, 1);
|
||||||
|
|
||||||
|
init();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Used to indicate testing a foreign file.
|
||||||
|
ui.isForeign = RegExp('^(\\w+:)?//').test(build);
|
||||||
|
|
||||||
|
// Used to indicate testing a modularized build.
|
||||||
|
ui.isModularize = /\b(?:amd|commonjs|es6?|node|npm|(index|main)\.js)\b/.test([location.pathname, location.search]);
|
||||||
|
|
||||||
|
// Used to indicate testing in Sauce Labs' automated test cloud.
|
||||||
|
ui.isSauceLabs = location.port == '9001';
|
||||||
|
|
||||||
|
// Used to indicate that lodash is in strict mode.
|
||||||
|
ui.isStrict = /\bes6?\b/.test([location.pathname, location.search]);
|
||||||
|
|
||||||
|
// The lodash build file path.
|
||||||
|
ui.buildPath = (function() {
|
||||||
|
var result;
|
||||||
|
switch (build) {
|
||||||
|
case 'lodash-compat': result = 'lodash.compat.min.js'; break;
|
||||||
|
case 'lodash-modern-dev': result = 'lodash.js'; break;
|
||||||
|
case 'lodash-modern': result = 'lodash.min.js'; break;
|
||||||
|
case 'lodash-custom-dev': result = 'lodash.custom.js'; break;
|
||||||
|
case 'lodash-custom': result = 'lodash.custom.min.js'; break;
|
||||||
|
case null: build = 'lodash-compat-dev';
|
||||||
|
case 'lodash-compat-dev': result = 'lodash.src.js'; break;
|
||||||
|
default: return build;
|
||||||
|
}
|
||||||
|
return basePath + result;
|
||||||
|
}());
|
||||||
|
|
||||||
|
// The module loader file path.
|
||||||
|
ui.loaderPath = (function() {
|
||||||
|
var result;
|
||||||
|
switch (loader) {
|
||||||
|
case 'curl': result = 'node_modules/curl-amd/dist/curl-kitchen-sink/curl.js'; break;
|
||||||
|
case 'dojo': result = 'node_modules/dojo/dojo.js'; break;
|
||||||
|
case 'requirejs': result = 'node_modules/requirejs/require.js'; break;
|
||||||
|
case null: loader = 'none'; return '';
|
||||||
|
default: return loader;
|
||||||
|
}
|
||||||
|
return basePath + result;
|
||||||
|
}());
|
||||||
|
|
||||||
|
ui.urlParams = { 'build': build, 'loader': loader };
|
||||||
|
ui.timing = { 'loadEventEnd': 0 };
|
||||||
|
|
||||||
|
window.ui = ui;
|
||||||
|
|
||||||
|
}(this));
|
||||||
102
test/asset/weakmap.js
Normal file
102
test/asset/weakmap.js
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
;(function() {
|
||||||
|
|
||||||
|
/** Used to determine if values are of the language type Object. */
|
||||||
|
var objectTypes = {
|
||||||
|
'function': true,
|
||||||
|
'object': true
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Used as the `WeakMap#toString` return value. */
|
||||||
|
var nativeString = String(Object.prototype.toString).replace(/toString/g, 'WeakMap');
|
||||||
|
|
||||||
|
/** Detect free variable `exports`. */
|
||||||
|
var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
|
||||||
|
|
||||||
|
/** Detect free variable `module`. */
|
||||||
|
var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
|
||||||
|
|
||||||
|
/** Detect free variable `global` from Node.js. */
|
||||||
|
var freeGlobal = freeExports && freeModule && typeof global == 'object' && global;
|
||||||
|
|
||||||
|
/** Detect free variable `self`. */
|
||||||
|
var freeSelf = objectTypes[typeof self] && self && self.Object && self;
|
||||||
|
|
||||||
|
/** Detect free variable `window`. */
|
||||||
|
var freeWindow = objectTypes[typeof window] && window && window.Object && window;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used as a reference to the global object.
|
||||||
|
*
|
||||||
|
* The `this` value is used if it is the global object to avoid Greasemonkey's
|
||||||
|
* restricted `window` object, otherwise the `window` object is used.
|
||||||
|
*/
|
||||||
|
var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Installs `WeakMap` on the given `context` object.
|
||||||
|
*
|
||||||
|
* @memberOf exports
|
||||||
|
* @param {Object} context The context object.
|
||||||
|
*/
|
||||||
|
function runInContext(context) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a `WeakMap` object.
|
||||||
|
*/
|
||||||
|
function WeakMap() {
|
||||||
|
// No operation performed.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value associated with the given key.
|
||||||
|
*
|
||||||
|
* @memberOf WeakMap
|
||||||
|
* @param {Object} key The key object.
|
||||||
|
* @returns {*} Returns the associated value, else `undefined`.
|
||||||
|
*/
|
||||||
|
function get(key) {
|
||||||
|
return key.__weakmap__;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a value for the given key.
|
||||||
|
*
|
||||||
|
* @memberOf WeakMap
|
||||||
|
* @param {Object} key The key object.
|
||||||
|
* @param {*} value The value to set.
|
||||||
|
*/
|
||||||
|
function set(key, value) {
|
||||||
|
key.__weakmap__ = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produces the `toString` result of `WeakMap`.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @memberOf WeakMap
|
||||||
|
* @returns {string} Returns the string result.
|
||||||
|
*/
|
||||||
|
function toString() {
|
||||||
|
return nativeString;
|
||||||
|
}
|
||||||
|
|
||||||
|
WeakMap.toString = toString;
|
||||||
|
WeakMap.prototype.get = get;
|
||||||
|
WeakMap.prototype.set = set;
|
||||||
|
|
||||||
|
if (!root.WeakMap) {
|
||||||
|
context.WeakMap = WeakMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
if (freeExports) {
|
||||||
|
freeExports.runInContext = runInContext;
|
||||||
|
} else {
|
||||||
|
runInContext(root);
|
||||||
|
}
|
||||||
|
}.call(this));
|
||||||
12
test/asset/worker.js
Normal file
12
test/asset/worker.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
self.console || (self.console = { 'log': function() {} });
|
||||||
|
|
||||||
|
addEventListener('message', function(e) {
|
||||||
|
if (e.data) {
|
||||||
|
try {
|
||||||
|
importScripts('../' + e.data);
|
||||||
|
} catch(e) {
|
||||||
|
self._ = { 'VERSION': e.message };
|
||||||
|
}
|
||||||
|
postMessage(_.VERSION);
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
@@ -3,39 +3,139 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Backbone Test Suite</title>
|
<title>Backbone Test Suite</title>
|
||||||
<link rel="stylesheet" href="../vendor/backbone/test/vendor/qunit.css">
|
<link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css">
|
||||||
<style>
|
|
||||||
body > #qunit-header {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
#jslitmus {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="qunit"></div>
|
<div id="qunit"></div>
|
||||||
<h1 id="qunit-header"><a href="#">Backbone Speed Suite</a></h1>
|
|
||||||
<div id="qunit-fixture">
|
<div id="qunit-fixture">
|
||||||
<div id='testElement'>
|
<div id='testElement'>
|
||||||
<h1>Test</h1>
|
<h1>Test</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="../vendor/backbone/test/vendor/json2.js"></script>
|
|
||||||
<script src="../vendor/backbone/test/vendor/jquery-1.7.1.js"></script>
|
|
||||||
<script src="../vendor/backbone/test/vendor/qunit.js"></script>
|
|
||||||
<script src="../vendor/backbone/test/vendor/jslitmus.js"></script>
|
|
||||||
<script src="test-ui.js"></script>
|
|
||||||
<script>
|
<script>
|
||||||
document.write('<script src="../' + QUnit.config.lodashFilename + '.js"><\/script>');
|
// avoid reporting tests to Sauce Labs when script errors occur
|
||||||
|
if (location.port == '9001') {
|
||||||
|
window.onerror = function(message) {
|
||||||
|
if (window.QUnit) {
|
||||||
|
QUnit.config.done.length = 0;
|
||||||
|
}
|
||||||
|
global_test_results = { 'message': message };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script src="../node_modules/qunitjs/qunit/qunit.js"></script>
|
||||||
|
<script src="../node_modules/qunit-extras/qunit-extras.js"></script>
|
||||||
|
<script src="../vendor/json-js/json2.js"></script>
|
||||||
|
<script src="../node_modules/platform/platform.js"></script>
|
||||||
|
<script src="./asset/test-ui.js"></script>
|
||||||
|
<script src="../lodash.src.js"></script>
|
||||||
|
<script>
|
||||||
|
var mixinPrereqs = (function() {
|
||||||
|
var lodash = _.noConflict();
|
||||||
|
return function(_) {
|
||||||
|
_.mixin({
|
||||||
|
'debounce': _.debounce || lodash.debounce,
|
||||||
|
'defer': _.defer || lodash.defer,
|
||||||
|
'pluck': _.pluck || lodash.pluck
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
|
||||||
|
QUnit.config.asyncRetries = 10;
|
||||||
|
QUnit.config.hidepassed = true;
|
||||||
|
|
||||||
|
// load lodash
|
||||||
|
if (!ui.isModularize) {
|
||||||
|
document.write('<script src="' + ui.buildPath + '"><\/script>');
|
||||||
|
}
|
||||||
|
// load test scripts
|
||||||
|
document.write(ui.urlParams.loader != 'none'
|
||||||
|
? '<script data-dojo-config="async:1" src="' + ui.loaderPath + '"><\/script>'
|
||||||
|
: ([
|
||||||
|
'<script src="' + ui.buildPath + '"><\/script>',
|
||||||
|
'<script src="../node_modules/jquery/dist/jquery.js"><\/script>',
|
||||||
|
'<script src="../vendor/backbone/backbone.js"><\/script>',
|
||||||
|
'<script src="../vendor/backbone/test/environment.js"><\/script>',
|
||||||
|
'<script src="../vendor/backbone/test/noconflict.js"><\/script>',
|
||||||
|
'<script src="../vendor/backbone/test/events.js"><\/script>',
|
||||||
|
'<script src="../vendor/backbone/test/model.js"><\/script>',
|
||||||
|
'<script src="../vendor/backbone/test/collection.js"><\/script>',
|
||||||
|
'<script src="../vendor/backbone/test/router.js"><\/script>',
|
||||||
|
'<script src="../vendor/backbone/test/view.js"><\/script>',
|
||||||
|
'<script src="../vendor/backbone/test/sync.js"><\/script>'
|
||||||
|
].join('\n'))
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
if (window.curl) {
|
||||||
|
curl.config({ 'apiName': 'require' });
|
||||||
|
}
|
||||||
|
if (!window.require) {
|
||||||
|
mixinPrereqs(_);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var reBasename = /[\w.-]+$/,
|
||||||
|
basePath = ('//' + location.host + location.pathname.replace(reBasename, '')).replace(/\btest\/$/, ''),
|
||||||
|
modulePath = ui.buildPath.replace(/\.js$/, ''),
|
||||||
|
locationPath = modulePath.replace(reBasename, '').replace(/^\/|\/$/g, ''),
|
||||||
|
moduleMain = modulePath.match(reBasename)[0],
|
||||||
|
uid = +new Date;
|
||||||
|
|
||||||
|
function getConfig() {
|
||||||
|
var result = {
|
||||||
|
'baseUrl': './',
|
||||||
|
'urlArgs': 't=' + uid++,
|
||||||
|
'waitSeconds': 0,
|
||||||
|
'paths': {
|
||||||
|
'backbone': '../vendor/backbone/backbone',
|
||||||
|
'jquery': '../node_modules/jquery/dist/jquery'
|
||||||
|
},
|
||||||
|
'packages': [{
|
||||||
|
'name': 'test',
|
||||||
|
'location': '../vendor/backbone/test',
|
||||||
|
'config': {
|
||||||
|
// work around no global being exported
|
||||||
|
'exports': 'QUnit',
|
||||||
|
'loader': 'curl/loader/legacy'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ui.isModularize) {
|
||||||
|
result.packages.push({
|
||||||
|
'name': 'underscore',
|
||||||
|
'location': locationPath,
|
||||||
|
'main': moduleMain
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
result.paths.underscore = modulePath;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUnit.config.autostart = false;
|
||||||
|
|
||||||
|
require(getConfig(), ['underscore', 'backbone'], function(lodash) {
|
||||||
|
mixinPrereqs(lodash);
|
||||||
|
|
||||||
|
if (ui.isModularize) {
|
||||||
|
window._ = lodash;
|
||||||
|
}
|
||||||
|
require(getConfig(), [
|
||||||
|
'test/environment',
|
||||||
|
'test/noconflict',
|
||||||
|
'test/events',
|
||||||
|
'test/model',
|
||||||
|
'test/collection',
|
||||||
|
'test/router',
|
||||||
|
'test/view',
|
||||||
|
'test/sync'
|
||||||
|
], function() {
|
||||||
|
QUnit.start();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}());
|
||||||
</script>
|
</script>
|
||||||
<script src="../vendor/backbone/backbone.js"></script>
|
|
||||||
<script src="../vendor/backbone/test/noconflict.js"></script>
|
|
||||||
<script src="../vendor/backbone/test/events.js"></script>
|
|
||||||
<script src="../vendor/backbone/test/model.js"></script>
|
|
||||||
<script src="../vendor/backbone/test/collection.js"></script>
|
|
||||||
<script src="../vendor/backbone/test/router.js"></script>
|
|
||||||
<script src="../vendor/backbone/test/view.js"></script>
|
|
||||||
<script src="../vendor/backbone/test/sync.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
435
test/index.html
435
test/index.html
@@ -2,70 +2,407 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Lo-Dash Test Suite</title>
|
<title>lodash Test Suite</title>
|
||||||
<link rel="stylesheet" href="../vendor/qunit/qunit/qunit.css">
|
<link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css">
|
||||||
|
<style>
|
||||||
|
#exports {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<script>
|
||||||
|
// avoid reporting tests to Sauce Labs when script errors occur
|
||||||
|
if (location.port == '9001') {
|
||||||
|
window.onerror = function(message) {
|
||||||
|
if (window.QUnit) {
|
||||||
|
QUnit.config.done.length = 0;
|
||||||
|
}
|
||||||
|
global_test_results = { 'message': message };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script src="../node_modules/qunitjs/qunit/qunit.js"></script>
|
||||||
|
<script src="../node_modules/qunit-extras/qunit-extras.js"></script>
|
||||||
|
<script src="../node_modules/platform/platform.js"></script>
|
||||||
|
<script src="./asset/set.js"></script>
|
||||||
|
<script src="./asset/weakmap.js"></script>
|
||||||
|
<script src="./asset/test-ui.js"></script>
|
||||||
<div id="qunit"></div>
|
<div id="qunit"></div>
|
||||||
<script src="../vendor/platform.js/platform.js"></script>
|
<div id="exports"></div>
|
||||||
<script>
|
<script>
|
||||||
// avoid syntax errors for `QUnit.throws` in older Firefoxes
|
var setProperty = (function() {
|
||||||
document.write(platform.name == 'Firefox' && /^1\b/.test(platform.version)
|
var _defineProperty = Object.defineProperty;
|
||||||
? '<script src="../vendor/qunit/qunit/qunit-1.8.0.js"><\/script>'
|
return function(object, key, value) {
|
||||||
: '<script src="../vendor/qunit/qunit/qunit.js"><\/script>'
|
try {
|
||||||
);
|
_defineProperty(object, key, {
|
||||||
</script>
|
'configurable': true,
|
||||||
<script src="test-ui.js"></script>
|
'enumerable': false,
|
||||||
<script>
|
'writable': true,
|
||||||
// set a bad shim
|
'value': value
|
||||||
Object._keys = Object.keys;
|
});
|
||||||
Object.keys = function() { return []; };
|
} catch(e) {
|
||||||
|
object[key] = value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
|
||||||
// load Lo-Dash and expose it to the bad `Object.keys` shim
|
function addBizarroMethods() {
|
||||||
document.write('<script src="../' + QUnit.config.lodashFilename + '.js"><\/script>');
|
var funcProto = Function.prototype,
|
||||||
|
objectProto = Object.prototype,
|
||||||
|
stringProto = String.prototype;
|
||||||
|
|
||||||
|
var hasOwnProperty = objectProto.hasOwnProperty,
|
||||||
|
fnToString = funcProto.toString,
|
||||||
|
nativeString = fnToString.call(objectProto.toString),
|
||||||
|
noop = function() {},
|
||||||
|
parseInt = window.parseInt,
|
||||||
|
propertyIsEnumerable = objectProto.propertyIsEnumerable,
|
||||||
|
reToString = /toString/g,
|
||||||
|
whitespace = ' \t\x0B\f\xA0\ufeff\n\r\u2028\u2029\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000';
|
||||||
|
|
||||||
|
function constant(value) {
|
||||||
|
return function() {
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function createToString(funcName) {
|
||||||
|
return constant(nativeString.replace(reToString, funcName));
|
||||||
|
}
|
||||||
|
// allow bypassing native checks
|
||||||
|
setProperty(funcProto, 'toString', (function() {
|
||||||
|
function wrapper() {
|
||||||
|
setProperty(funcProto, 'toString', fnToString);
|
||||||
|
var result = hasOwnProperty.call(this, 'toString') ? this.toString() : fnToString.call(this);
|
||||||
|
setProperty(funcProto, 'toString', wrapper);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return wrapper;
|
||||||
|
}()));
|
||||||
|
|
||||||
|
// add extensions
|
||||||
|
funcProto._method = noop;
|
||||||
|
|
||||||
|
// set bad shims
|
||||||
|
setProperty(Array, '_isArray', Array.isArray);
|
||||||
|
setProperty(Array, 'isArray', noop);
|
||||||
|
|
||||||
|
setProperty(Date, '_now', Date.now);
|
||||||
|
setProperty(Date, 'now', noop);
|
||||||
|
|
||||||
|
setProperty(Object, '_getOwnPropertySymbols', Object.getOwnPropertySymbols);
|
||||||
|
setProperty(Object, 'getOwnPropertySymbols', (function() {
|
||||||
|
function getOwnPropertySymbols() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
setProperty(getOwnPropertySymbols, 'toString', createToString('getOwnPropertySymbols'));
|
||||||
|
return getOwnPropertySymbols;
|
||||||
|
}()));
|
||||||
|
|
||||||
|
setProperty(Object, '_getPrototypeOf', Object.getPrototypeOf);
|
||||||
|
setProperty(Object, 'getPrototypeOf', noop);
|
||||||
|
|
||||||
|
setProperty(Object, '_keys', Object.keys);
|
||||||
|
setProperty(Object, 'keys', noop);
|
||||||
|
|
||||||
|
setProperty(objectProto, '_propertyIsEnumerable', propertyIsEnumerable);
|
||||||
|
setProperty(objectProto, 'propertyIsEnumerable', function(key) {
|
||||||
|
if (key == '1' && this && typeof this == 'object' &&
|
||||||
|
hasOwnProperty.call(this, 'callee') &&
|
||||||
|
!propertyIsEnumerable.call(this, 'callee') &&
|
||||||
|
this.length === 2 && this[0] === 1 && this[1] === 0) {
|
||||||
|
throw new Error;
|
||||||
|
}
|
||||||
|
return propertyIsEnumerable.call(this, key);
|
||||||
|
});
|
||||||
|
|
||||||
|
setProperty(Number, '_isFinite', Number.isFinite);
|
||||||
|
setProperty(Number, 'isFinite', noop);
|
||||||
|
|
||||||
|
setProperty(window, '_ArrayBuffer', window.ArrayBuffer);
|
||||||
|
if (window.ArrayBuffer && window.Uint8Array) {
|
||||||
|
ArrayBuffer = (function(_ArrayBuffer) {
|
||||||
|
function ArrayBuffer(byteLength) {
|
||||||
|
var buffer = new _ArrayBuffer(byteLength);
|
||||||
|
if (!byteLength) {
|
||||||
|
setProperty(buffer, 'slice', buffer.slice ? null : bufferSlice);
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
function bufferSlice() {
|
||||||
|
var newBuffer = new _ArrayBuffer(this.byteLength),
|
||||||
|
view = new Uint8Array(newBuffer);
|
||||||
|
|
||||||
|
view.set(new Uint8Array(this));
|
||||||
|
return newBuffer;
|
||||||
|
}
|
||||||
|
setProperty(ArrayBuffer, 'toString', createToString('ArrayBuffer'));
|
||||||
|
setProperty(bufferSlice, 'toString', createToString('slice'));
|
||||||
|
return ArrayBuffer;
|
||||||
|
}(_ArrayBuffer));
|
||||||
|
}
|
||||||
|
if (!window.Float64Array && window.Uint8Array) {
|
||||||
|
Float64Array = (function() {
|
||||||
|
function Float64Array(buffer, byteOffset, length) {
|
||||||
|
return arguments.length == 1
|
||||||
|
? new Uint8Array(buffer)
|
||||||
|
: new Uint8Array(buffer, byteOffset || 0, length || buffer.byteLength);
|
||||||
|
}
|
||||||
|
setProperty(Float64Array, 'BYTES_PER_ELEMENT', 8);
|
||||||
|
setProperty(Float64Array, 'toString', createToString('Float64Array'));
|
||||||
|
return Float64Array;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
setProperty(window, '_Set', window.Set);
|
||||||
|
setProperty(window, 'Set', noop);
|
||||||
|
|
||||||
|
setProperty(window, '_WeakMap', window.WeakMap);
|
||||||
|
setProperty(window, 'WeakMap', noop);
|
||||||
|
|
||||||
|
setProperty(window, '_parseInt', parseInt);
|
||||||
|
setProperty(window, 'parseInt', (function() {
|
||||||
|
var checkStr = whitespace + '08',
|
||||||
|
isFaked = parseInt(checkStr) != 8,
|
||||||
|
reHexPrefix = /^0[xX]/,
|
||||||
|
reTrim = RegExp('^[' + whitespace + ']+|[' + whitespace + ']+$');
|
||||||
|
|
||||||
|
return function(value, radix) {
|
||||||
|
if (value == checkStr && !isFaked) {
|
||||||
|
isFaked = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
value = String(value == null ? '' : value).replace(reTrim, '');
|
||||||
|
return parseInt(value, +radix || (reHexPrefix.test(value) ? 16 : 10));
|
||||||
|
};
|
||||||
|
}()));
|
||||||
|
|
||||||
|
// fake lack of DOM support
|
||||||
|
setProperty(document, '_createDocumentFragment', document.createDocumentFragment);
|
||||||
|
document.createDocumentFragment = noop;
|
||||||
|
|
||||||
|
// fake `WinRTError`
|
||||||
|
setProperty(window, 'WinRTError', Error);
|
||||||
|
|
||||||
|
// fake free variable `global`
|
||||||
|
setProperty(window, 'exports', window);
|
||||||
|
setProperty(window, 'global', window);
|
||||||
|
setProperty(window, 'module', {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeBizarroMethods() {
|
||||||
|
var funcProto = Function.prototype,
|
||||||
|
objectProto = Object.prototype,
|
||||||
|
stringProto = String.prototype;
|
||||||
|
|
||||||
|
if (Array._isArray) {
|
||||||
|
setProperty(Array, 'isArray', Array._isArray);
|
||||||
|
} else {
|
||||||
|
delete Array.isArray;
|
||||||
|
}
|
||||||
|
if (Date._now) {
|
||||||
|
setProperty(Date, 'now', Date._now);
|
||||||
|
} else {
|
||||||
|
delete Date.now;
|
||||||
|
}
|
||||||
|
if (Object._getOwnPropertySymbols) {
|
||||||
|
setProperty(Object, 'getOwnPropertySymbols', Object._getOwnPropertySymbols);
|
||||||
|
} else {
|
||||||
|
delete Object.getOwnPropertySymbols;
|
||||||
|
}
|
||||||
|
if (Object._getPrototypeOf) {
|
||||||
|
setProperty(Object, 'getPrototypeOf', Object._getPrototypeOf);
|
||||||
|
} else {
|
||||||
|
delete Object.getPrototypeOf;
|
||||||
|
}
|
||||||
|
if (Object._keys) {
|
||||||
|
setProperty(Object, 'keys', Object._keys);
|
||||||
|
} else {
|
||||||
|
delete Object.keys;
|
||||||
|
}
|
||||||
|
if (Number._isFinite) {
|
||||||
|
setProperty(Number, 'isFinite', Number._isFinite);
|
||||||
|
} else {
|
||||||
|
delete Number.isFinite;
|
||||||
|
}
|
||||||
|
if (window._ArrayBuffer) {
|
||||||
|
ArrayBuffer = _ArrayBuffer;
|
||||||
|
}
|
||||||
|
setProperty(window, '_ArrayBuffer', undefined);
|
||||||
|
|
||||||
|
if (window._Set) {
|
||||||
|
Set = _Set;
|
||||||
|
}
|
||||||
|
setProperty(window, '_Set', undefined);
|
||||||
|
|
||||||
|
if (window._WeakMap) {
|
||||||
|
WeakMap = _WeakMap;
|
||||||
|
}
|
||||||
|
setProperty(window, '_WeakMap', undefined);
|
||||||
|
|
||||||
|
setProperty(window, 'parseInt', window._parseInt);
|
||||||
|
setProperty(window, '_parseInt', undefined);
|
||||||
|
|
||||||
|
document.createDocumentFragment = document._createDocumentFragment;
|
||||||
|
setProperty(document, '_createDocumentFragment', undefined);
|
||||||
|
|
||||||
|
setProperty(window, 'WinRTError', undefined);
|
||||||
|
|
||||||
|
setProperty(window, 'exports', undefined);
|
||||||
|
setProperty(window, 'global', undefined);
|
||||||
|
setProperty(window, 'module', undefined);
|
||||||
|
|
||||||
|
setProperty(objectProto, 'propertyIsEnumerable', objectProto._propertyIsEnumerable);
|
||||||
|
|
||||||
|
delete Array._isArray;
|
||||||
|
delete Date._now;
|
||||||
|
delete Object._getOwnPropertySymbols;
|
||||||
|
delete Object._getPrototypeOf;
|
||||||
|
delete Object._keys;
|
||||||
|
delete funcProto._method;
|
||||||
|
delete objectProto._propertyIsEnumerable;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load lodash and expose it to the bad extensions/shims
|
||||||
|
if (!ui.isModularize) {
|
||||||
|
addBizarroMethods();
|
||||||
|
document.write('<script src="' + ui.buildPath + '"><\/script>');
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
// store Lo-Dash to test for bad shim detection
|
// store lodash to test for bad extensions/shims
|
||||||
var lodashBadShim = _;
|
if (!ui.isModularize) {
|
||||||
|
var lodashBizarro = window._;
|
||||||
// restore nativeKeys
|
window._ = undefined;
|
||||||
Object.keys = Object._keys;
|
removeBizarroMethods();
|
||||||
delete Object._keys;
|
}
|
||||||
|
// load test scripts
|
||||||
// set to test `_.noConflict`
|
document.write((ui.isForeign || ui.urlParams.loader == 'none')
|
||||||
_ = 1;
|
? '<script src="' + ui.buildPath + '"><\/script><script src="test.js"><\/script>'
|
||||||
|
: '<script data-dojo-config="async:1" src="' + ui.loaderPath + '"><\/script>'
|
||||||
// load Lo-Dash again to overwrite the existing `_` value
|
|
||||||
document.write('<script src="../' + QUnit.config.lodashFilename + '.js"><\/script>');
|
|
||||||
|
|
||||||
// load test.js if not using require.js
|
|
||||||
document.write(QUnit.urlParams.norequire
|
|
||||||
? '<script src="test.js"><\/script>'
|
|
||||||
: '<script src="../vendor/requirejs/require.js"><\/script>'
|
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
// load Lo-Dash as a module
|
|
||||||
var lodashModule,
|
var lodashModule,
|
||||||
|
shimmedModule,
|
||||||
underscoreModule;
|
underscoreModule;
|
||||||
|
|
||||||
window.require && require({
|
(function() {
|
||||||
'baseUrl': '../vendor/requirejs/',
|
if (window.curl) {
|
||||||
'urlArgs': 't=' + (+new Date),
|
curl.config({ 'apiName': 'require' });
|
||||||
'paths': {
|
|
||||||
'lodash': '../../' + QUnit.config.lodashFilename,
|
|
||||||
'underscore': './../../' + QUnit.config.lodashFilename
|
|
||||||
}
|
}
|
||||||
},
|
if (ui.isForeign || !window.require) {
|
||||||
['lodash', 'underscore'], function(lodash, underscore) {
|
return;
|
||||||
lodashModule = lodash.noConflict();
|
}
|
||||||
lodashModule.moduleName = 'lodash';
|
var reBasename = /[\w.-]+$/,
|
||||||
|
basePath = ('//' + location.host + location.pathname.replace(reBasename, '')).replace(/\btest\/$/, ''),
|
||||||
|
modulePath = ui.buildPath.replace(/\.js$/, ''),
|
||||||
|
moduleMain = modulePath.match(reBasename)[0],
|
||||||
|
locationPath = modulePath.replace(reBasename, '').replace(/^\/|\/$/g, ''),
|
||||||
|
shimmedLocationPath = './abc/../' + locationPath,
|
||||||
|
underscoreLocationPath = './xyz/../' + locationPath,
|
||||||
|
uid = +new Date;
|
||||||
|
|
||||||
underscoreModule = underscore.noConflict();
|
function getConfig() {
|
||||||
underscoreModule.moduleName = 'underscore';
|
var result = {
|
||||||
|
'baseUrl': './',
|
||||||
|
'urlArgs': 't=' + uid++,
|
||||||
|
'waitSeconds': 0,
|
||||||
|
'paths': {},
|
||||||
|
'packages': [{
|
||||||
|
'name': 'test',
|
||||||
|
'location': basePath + 'test',
|
||||||
|
'main': 'test',
|
||||||
|
'config': {
|
||||||
|
// work around no global being exported
|
||||||
|
'exports': 'QUnit',
|
||||||
|
'loader': 'curl/loader/legacy'
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
'shim': {
|
||||||
|
'shimmed': {
|
||||||
|
'exports': '_'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
require(['test.js']);
|
if (ui.isModularize) {
|
||||||
});
|
result.packages.push({
|
||||||
|
'name': 'lodash',
|
||||||
|
'location': locationPath,
|
||||||
|
'main': moduleMain
|
||||||
|
}, {
|
||||||
|
'name': 'shimmed',
|
||||||
|
'location': shimmedLocationPath,
|
||||||
|
'main': moduleMain
|
||||||
|
}, {
|
||||||
|
'name': 'underscore',
|
||||||
|
'location': underscoreLocationPath,
|
||||||
|
'main': moduleMain
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
result.paths.lodash = modulePath;
|
||||||
|
result.paths.shimmed = shimmedLocationPath + '/' + moduleMain;
|
||||||
|
result.paths.underscore = underscoreLocationPath + '/' + moduleMain;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadTests() {
|
||||||
|
require(getConfig(), ['test'], function() {
|
||||||
|
QUnit.start();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadModulesAndTests() {
|
||||||
|
require(getConfig(), ['lodash', 'shimmed', 'underscore'], function(lodash, shimmed, underscore) {
|
||||||
|
lodashModule = lodash;
|
||||||
|
lodashModule.moduleName = 'lodash';
|
||||||
|
|
||||||
|
if (shimmed) {
|
||||||
|
shimmedModule = shimmed.result(shimmed, 'noConflict') || shimmed;
|
||||||
|
shimmedModule.moduleName = 'shimmed';
|
||||||
|
}
|
||||||
|
if (underscore) {
|
||||||
|
underscoreModule = underscore.result(underscore, 'noConflict') || underscore;
|
||||||
|
underscoreModule.moduleName = 'underscore';
|
||||||
|
}
|
||||||
|
if (ui.isModularize) {
|
||||||
|
window._ = lodash;
|
||||||
|
}
|
||||||
|
if (ui.isModularize) {
|
||||||
|
require(getConfig(), [
|
||||||
|
'lodash/internal/baseEach',
|
||||||
|
'lodash/internal/isIndex',
|
||||||
|
'lodash/internal/isIterateeCall',
|
||||||
|
'lodash/internal/isLength'
|
||||||
|
], function(baseEach, isIndex, isIterateeCall, isLength) {
|
||||||
|
lodash._baseEach = baseEach;
|
||||||
|
lodash._isIndex = isIndex;
|
||||||
|
lodash._isIterateeCall = isIterateeCall;
|
||||||
|
lodash._isLength = isLength;
|
||||||
|
loadTests();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
loadTests();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QUnit.config.autostart = false;
|
||||||
|
|
||||||
|
if (window.requirejs) {
|
||||||
|
addBizarroMethods();
|
||||||
|
require(getConfig(), ['lodash'], function(lodash) {
|
||||||
|
lodashBizarro = lodash.result(lodash, 'noConflict') || lodash;
|
||||||
|
delete requirejs.s.contexts._;
|
||||||
|
|
||||||
|
removeBizarroMethods();
|
||||||
|
loadModulesAndTests();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
loadModulesAndTests();
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
|
||||||
// set a more readable browser name
|
// set a more readable browser name
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
@@ -75,7 +412,7 @@
|
|||||||
ua.innerHTML = platform;
|
ua.innerHTML = platform;
|
||||||
clearInterval(timeoutId);
|
clearInterval(timeoutId);
|
||||||
}
|
}
|
||||||
}, 15);
|
}, 16);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
13
test/run-test.sh
Executable file → Normal file
13
test/run-test.sh
Executable file → Normal file
@@ -1,9 +1,14 @@
|
|||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
for cmd in rhino ringo narwhal node; do
|
|
||||||
echo ""
|
echo "Testing in node..."
|
||||||
echo "Testing in $cmd..."
|
node test.js ../lodash.src.js
|
||||||
$cmd test.js
|
|
||||||
|
for cmd in rhino "rhino -require" ringo phantomjs; do
|
||||||
|
echo ""
|
||||||
|
echo "Testing in $cmd..."
|
||||||
|
$cmd test.js ../lodash.src.js
|
||||||
done
|
done
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Testing in a browser..."
|
echo "Testing in a browser..."
|
||||||
open index.html
|
open index.html
|
||||||
|
|||||||
930
test/saucelabs.js
Normal file
930
test/saucelabs.js
Normal file
@@ -0,0 +1,930 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/** Environment shortcut. */
|
||||||
|
var env = process.env;
|
||||||
|
|
||||||
|
if (env.TRAVIS_SECURE_ENV_VARS == 'false') {
|
||||||
|
console.log('Skipping Sauce Labs jobs; secure environment variables are unavailable');
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Load Node.js modules. */
|
||||||
|
var EventEmitter = require('events').EventEmitter,
|
||||||
|
http = require('http'),
|
||||||
|
path = require('path'),
|
||||||
|
url = require('url'),
|
||||||
|
util = require('util');
|
||||||
|
|
||||||
|
/** Load other modules. */
|
||||||
|
var _ = require('../lodash.src.js'),
|
||||||
|
chalk = require('chalk'),
|
||||||
|
ecstatic = require('ecstatic'),
|
||||||
|
request = require('request'),
|
||||||
|
SauceTunnel = require('sauce-tunnel');
|
||||||
|
|
||||||
|
/** Used for Sauce Labs credentials. */
|
||||||
|
var accessKey = env.SAUCE_ACCESS_KEY,
|
||||||
|
username = env.SAUCE_USERNAME;
|
||||||
|
|
||||||
|
/** Used as the default maximum number of times to retry a job and tunnel. */
|
||||||
|
var maxJobRetries = 3,
|
||||||
|
maxTunnelRetries = 3;
|
||||||
|
|
||||||
|
/** Used as the static file server middleware. */
|
||||||
|
var mount = ecstatic({
|
||||||
|
'cache': 'no-cache',
|
||||||
|
'root': process.cwd()
|
||||||
|
});
|
||||||
|
|
||||||
|
/** Used as the list of ports supported by Sauce Connect. */
|
||||||
|
var ports = [
|
||||||
|
80, 443, 888, 2000, 2001, 2020, 2109, 2222, 2310, 3000, 3001, 3030, 3210,
|
||||||
|
3333, 4000, 4001, 4040, 4321, 4502, 4503, 4567, 5000, 5001, 5050, 5555, 5432,
|
||||||
|
6000, 6001, 6060, 6666, 6543, 7000, 7070, 7774, 7777, 8000, 8001, 8003, 8031,
|
||||||
|
8080, 8081, 8765, 8777, 8888, 9000, 9001, 9080, 9090, 9876, 9877, 9999, 49221,
|
||||||
|
55001
|
||||||
|
];
|
||||||
|
|
||||||
|
/** Used by `logInline` to clear previously logged messages. */
|
||||||
|
var prevLine = '';
|
||||||
|
|
||||||
|
/** Method shortcut. */
|
||||||
|
var push = Array.prototype.push;
|
||||||
|
|
||||||
|
/** Used to detect error messages. */
|
||||||
|
var reError = /(?:\be|E)rror\b/;
|
||||||
|
|
||||||
|
/** Used to detect valid job ids. */
|
||||||
|
var reJobId = /^[a-z0-9]{32}$/;
|
||||||
|
|
||||||
|
/** Used to display the wait throbber. */
|
||||||
|
var throbberDelay = 500,
|
||||||
|
waitCount = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used as Sauce Labs config values.
|
||||||
|
* See the [Sauce Labs documentation](https://docs.saucelabs.com/reference/test-configuration/)
|
||||||
|
* for more details.
|
||||||
|
*/
|
||||||
|
var advisor = getOption('advisor', false),
|
||||||
|
build = getOption('build', (env.TRAVIS_COMMIT || '').slice(0, 10)),
|
||||||
|
commandTimeout = getOption('commandTimeout', 90),
|
||||||
|
compatMode = getOption('compatMode', null),
|
||||||
|
customData = Function('return {' + getOption('customData', '').replace(/^\{|}$/g, '') + '}')(),
|
||||||
|
deviceOrientation = getOption('deviceOrientation', 'portrait'),
|
||||||
|
framework = getOption('framework', 'qunit'),
|
||||||
|
idleTimeout = getOption('idleTimeout', 60),
|
||||||
|
jobName = getOption('name', 'unit tests'),
|
||||||
|
maxDuration = getOption('maxDuration', 120),
|
||||||
|
port = ports[Math.min(_.sortedIndex(ports, getOption('port', 9001)), ports.length - 1)],
|
||||||
|
publicAccess = getOption('public', true),
|
||||||
|
queueTimeout = getOption('queueTimeout', 240),
|
||||||
|
recordVideo = getOption('recordVideo', true),
|
||||||
|
recordScreenshots = getOption('recordScreenshots', false),
|
||||||
|
runner = getOption('runner', 'test/index.html').replace(/^\W+/, ''),
|
||||||
|
runnerUrl = getOption('runnerUrl', 'http://localhost:' + port + '/' + runner),
|
||||||
|
statusInterval = getOption('statusInterval', 5),
|
||||||
|
tags = getOption('tags', []),
|
||||||
|
throttled = getOption('throttled', 10),
|
||||||
|
tunneled = getOption('tunneled', true),
|
||||||
|
tunnelId = getOption('tunnelId', 'tunnel_' + (env.TRAVIS_JOB_ID || 0)),
|
||||||
|
tunnelTimeout = getOption('tunnelTimeout', 120),
|
||||||
|
videoUploadOnPass = getOption('videoUploadOnPass', false);
|
||||||
|
|
||||||
|
/** Used to convert Sauce Labs browser identifiers to their formal names. */
|
||||||
|
var browserNameMap = {
|
||||||
|
'googlechrome': 'Chrome',
|
||||||
|
'iehta': 'Internet Explorer',
|
||||||
|
'ipad': 'iPad',
|
||||||
|
'iphone': 'iPhone'
|
||||||
|
};
|
||||||
|
|
||||||
|
/** List of platforms to load the runner on. */
|
||||||
|
var platforms = [
|
||||||
|
['Linux', 'android', '5.0'],
|
||||||
|
['Linux', 'android', '4.4'],
|
||||||
|
['Linux', 'android', '4.0'],
|
||||||
|
['Windows 8.1', 'firefox', '37'],
|
||||||
|
['Windows 8.1', 'firefox', '36'],
|
||||||
|
['Windows 8.1', 'firefox', '20'],
|
||||||
|
['Windows 8.1', 'chrome', '41'],
|
||||||
|
['Windows 8.1', 'chrome', '40'],
|
||||||
|
['Windows 8.1', 'internet explorer', '11'],
|
||||||
|
['Windows 8', 'internet explorer', '10'],
|
||||||
|
['Windows 7', 'internet explorer', '9'],
|
||||||
|
['Windows 7', 'internet explorer', '8'],
|
||||||
|
['Windows XP', 'internet explorer', '7'],
|
||||||
|
['Windows XP', 'internet explorer', '6'],
|
||||||
|
['Windows 7', 'opera', '12'],
|
||||||
|
['Windows 7', 'opera', '11'],
|
||||||
|
['OS X 10.9', 'ipad', '8.1'],
|
||||||
|
['OS X 10.6', 'ipad', '4'],
|
||||||
|
['OS X 10.10', 'safari', '8'],
|
||||||
|
['OS X 10.9', 'safari', '7'],
|
||||||
|
['OS X 10.8', 'safari', '6'],
|
||||||
|
['OS X 10.6', 'safari', '5']
|
||||||
|
];
|
||||||
|
|
||||||
|
/** Used to tailor the `platforms` array. */
|
||||||
|
var isAMD = _.includes(tags, 'amd'),
|
||||||
|
isBackbone = _.includes(tags, 'backbone'),
|
||||||
|
isModern = _.includes(tags, 'modern');
|
||||||
|
|
||||||
|
// The platforms to test IE compatibility modes.
|
||||||
|
if (compatMode) {
|
||||||
|
platforms = [
|
||||||
|
['Windows 8.1', 'internet explorer', '11'],
|
||||||
|
['Windows 8', 'internet explorer', '10'],
|
||||||
|
['Windows 7', 'internet explorer', '9'],
|
||||||
|
['Windows 7', 'internet explorer', '8']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
// The platforms for AMD tests.
|
||||||
|
if (isAMD) {
|
||||||
|
platforms = _.filter(platforms, function(platform) {
|
||||||
|
var browser = browserName(platform[1]),
|
||||||
|
version = +platform[2];
|
||||||
|
|
||||||
|
switch (browser) {
|
||||||
|
case 'Android': return version >= 4.4;
|
||||||
|
case 'Opera': return version >= 10;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// The platforms for Backbone tests.
|
||||||
|
if (isBackbone) {
|
||||||
|
platforms = _.filter(platforms, function(platform) {
|
||||||
|
var browser = browserName(platform[1]),
|
||||||
|
version = +platform[2];
|
||||||
|
|
||||||
|
switch (browser) {
|
||||||
|
case 'Firefox': return version >= 4;
|
||||||
|
case 'iPad': return version >= 5;
|
||||||
|
case 'Opera': return version >= 12;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// The platforms for modern builds.
|
||||||
|
if (isModern) {
|
||||||
|
platforms = _.filter(platforms, function(platform) {
|
||||||
|
var browser = browserName(platform[1]),
|
||||||
|
version = +platform[2];
|
||||||
|
|
||||||
|
switch (browser) {
|
||||||
|
case 'Android': return version >= 4.1;
|
||||||
|
case 'Firefox': return version >= 10;
|
||||||
|
case 'Internet Explorer': return version >= 9;
|
||||||
|
case 'iPad': return version >= 6;
|
||||||
|
case 'Opera': return version >= 12;
|
||||||
|
case 'Safari': return version >= 6;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Used as the default `Job` options object. */
|
||||||
|
var jobOptions = {
|
||||||
|
'build': build,
|
||||||
|
'command-timeout': commandTimeout,
|
||||||
|
'custom-data': customData,
|
||||||
|
'device-orientation': deviceOrientation,
|
||||||
|
'framework': framework,
|
||||||
|
'idle-timeout': idleTimeout,
|
||||||
|
'max-duration': maxDuration,
|
||||||
|
'name': jobName,
|
||||||
|
'public': publicAccess,
|
||||||
|
'platforms': platforms,
|
||||||
|
'record-screenshots': recordScreenshots,
|
||||||
|
'record-video': recordVideo,
|
||||||
|
'sauce-advisor': advisor,
|
||||||
|
'tags': tags,
|
||||||
|
'url': runnerUrl,
|
||||||
|
'video-upload-on-pass': videoUploadOnPass
|
||||||
|
};
|
||||||
|
|
||||||
|
if (publicAccess === true) {
|
||||||
|
jobOptions['public'] = 'public';
|
||||||
|
}
|
||||||
|
if (tunneled) {
|
||||||
|
jobOptions['tunnel-identifier'] = tunnelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves the formal browser name for a given Sauce Labs browser identifier.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {string} identifier The browser identifier.
|
||||||
|
* @returns {string} Returns the formal browser name.
|
||||||
|
*/
|
||||||
|
function browserName(identifier) {
|
||||||
|
return browserNameMap[identifier] || capitalizeWords(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Capitalizes the first character of each word in `string`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {string} string The string to augment.
|
||||||
|
* @returns {string} Returns the augmented string.
|
||||||
|
*/
|
||||||
|
function capitalizeWords(string) {
|
||||||
|
return _.map(string.split(' '), _.capitalize).join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value for the given option name. If no value is available the
|
||||||
|
* `defaultValue` is returned.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {string} name The name of the option.
|
||||||
|
* @param {*} defaultValue The default option value.
|
||||||
|
* @returns {*} Returns the option value.
|
||||||
|
*/
|
||||||
|
function getOption(name, defaultValue) {
|
||||||
|
var isArr = _.isArray(defaultValue);
|
||||||
|
return _.reduce(process.argv, function(result, value) {
|
||||||
|
if (isArr) {
|
||||||
|
value = optionToArray(name, value);
|
||||||
|
return _.isEmpty(value) ? result : value;
|
||||||
|
}
|
||||||
|
value = optionToValue(name, value);
|
||||||
|
|
||||||
|
return value == null ? result : value;
|
||||||
|
}, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if `value` is a job ID.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {*} value The value to check.
|
||||||
|
* @returns {boolean} Returns `true` if `value` is a job ID, else `false`.
|
||||||
|
*/
|
||||||
|
function isJobId(value) {
|
||||||
|
return reJobId.test(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes an inline message to standard output.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {string} [text=''] The text to log.
|
||||||
|
*/
|
||||||
|
function logInline(text) {
|
||||||
|
var blankLine = _.repeat(' ', _.size(prevLine));
|
||||||
|
prevLine = text = _.trunc(text, 40);
|
||||||
|
process.stdout.write(text + blankLine.slice(text.length) + '\r');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the wait throbber to standard output.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function logThrobber() {
|
||||||
|
logInline('Please wait' + _.repeat('.', (++waitCount % 3) + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a comma separated option value into an array.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {string} name The name of the option to inspect.
|
||||||
|
* @param {string} string The options string.
|
||||||
|
* @returns {Array} Returns the new converted array.
|
||||||
|
*/
|
||||||
|
function optionToArray(name, string) {
|
||||||
|
return _.compact(_.invoke((optionToValue(name, string) || '').split(/, */), 'trim'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the option value from an option string.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {string} name The name of the option to inspect.
|
||||||
|
* @param {string} string The options string.
|
||||||
|
* @returns {string|undefined} Returns the option value, else `undefined`.
|
||||||
|
*/
|
||||||
|
function optionToValue(name, string) {
|
||||||
|
var result = string.match(RegExp('^' + name + '(?:=([\\s\\S]+))?$'));
|
||||||
|
if (result) {
|
||||||
|
result = _.result(result, 1);
|
||||||
|
result = result ? _.trim(result) : true;
|
||||||
|
}
|
||||||
|
if (result === 'false') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return result || undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `Job#remove` and `Tunnel#stop` callback used by `Jobs#restart`
|
||||||
|
* and `Tunnel#restart` respectively.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function onGenericRestart() {
|
||||||
|
this.restarting = false;
|
||||||
|
this.emit('restart');
|
||||||
|
this.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `request.put` and `SauceTunnel#stop` callback used by `Jobs#stop`
|
||||||
|
* and `Tunnel#stop` respectively.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} [error] The error object.
|
||||||
|
*/
|
||||||
|
function onGenericStop(error) {
|
||||||
|
this.running = this.stopping = false;
|
||||||
|
this.emit('stop', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `request.del` callback used by `Jobs#remove`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function onJobRemove(error, res, body) {
|
||||||
|
this.id = this.taskId = this.url = null;
|
||||||
|
this.removing = false;
|
||||||
|
this.emit('remove');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `Job#remove` callback used by `Jobs#reset`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function onJobReset() {
|
||||||
|
this.attempts = 0;
|
||||||
|
this.failed = this.resetting = false;
|
||||||
|
this._pollerId = this.id = this.result = this.taskId = this.url = null;
|
||||||
|
this.emit('reset');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `request.post` callback used by `Jobs#start`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} [error] The error object.
|
||||||
|
* @param {Object} res The response data object.
|
||||||
|
* @param {Object} body The response body JSON object.
|
||||||
|
*/
|
||||||
|
function onJobStart(error, res, body) {
|
||||||
|
this.starting = false;
|
||||||
|
|
||||||
|
if (this.stopping) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var statusCode = _.result(res, 'statusCode'),
|
||||||
|
taskId = _.first(_.result(body, 'js tests'));
|
||||||
|
|
||||||
|
if (error || !taskId || statusCode != 200) {
|
||||||
|
if (this.attempts < this.retries) {
|
||||||
|
this.restart();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var na = 'unavailable',
|
||||||
|
bodyStr = _.isObject(body) ? '\n' + JSON.stringify(body) : na,
|
||||||
|
statusStr = _.isFinite(statusCode) ? statusCode : na;
|
||||||
|
|
||||||
|
logInline();
|
||||||
|
console.error('Failed to start job; status: %s, body: %s', statusStr, bodyStr);
|
||||||
|
if (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
this.failed = true;
|
||||||
|
this.emit('complete');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.running = true;
|
||||||
|
this.taskId = taskId;
|
||||||
|
this.timestamp = _.now();
|
||||||
|
this.emit('start');
|
||||||
|
this.status();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `request.post` callback used by `Job#status`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} [error] The error object.
|
||||||
|
* @param {Object} res The response data object.
|
||||||
|
* @param {Object} body The response body JSON object.
|
||||||
|
*/
|
||||||
|
function onJobStatus(error, res, body) {
|
||||||
|
this.checking = false;
|
||||||
|
|
||||||
|
if (!this.running || this.stopping) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var completed = _.result(body, 'completed', false),
|
||||||
|
data = _.first(_.result(body, 'js tests')),
|
||||||
|
elapsed = (_.now() - this.timestamp) / 1000,
|
||||||
|
jobId = _.result(data, 'job_id', null),
|
||||||
|
jobResult = _.result(data, 'result', null),
|
||||||
|
jobStatus = _.result(data, 'status', ''),
|
||||||
|
jobUrl = _.result(data, 'url', null),
|
||||||
|
expired = (elapsed >= queueTimeout && !_.includes(jobStatus, 'in progress')),
|
||||||
|
options = this.options,
|
||||||
|
platform = options.platforms[0];
|
||||||
|
|
||||||
|
if (_.isObject(jobResult)) {
|
||||||
|
var message = _.result(jobResult, 'message');
|
||||||
|
} else {
|
||||||
|
if (typeof jobResult == 'string') {
|
||||||
|
message = jobResult;
|
||||||
|
}
|
||||||
|
jobResult = null;
|
||||||
|
}
|
||||||
|
if (isJobId(jobId)) {
|
||||||
|
this.id = jobId;
|
||||||
|
this.result = jobResult;
|
||||||
|
this.url = jobUrl;
|
||||||
|
} else {
|
||||||
|
completed = false;
|
||||||
|
}
|
||||||
|
this.emit('status', jobStatus);
|
||||||
|
|
||||||
|
if (!completed && !expired) {
|
||||||
|
this._pollerId = _.delay(_.bind(this.status, this), this.statusInterval * 1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var description = browserName(platform[1]) + ' ' + platform[2] + ' on ' + capitalizeWords(platform[0]),
|
||||||
|
errored = !jobResult || !jobResult.passed || reError.test(message) || reError.test(jobStatus),
|
||||||
|
failures = _.result(jobResult, 'failed'),
|
||||||
|
label = options.name + ':',
|
||||||
|
tunnel = this.tunnel;
|
||||||
|
|
||||||
|
if (errored || failures) {
|
||||||
|
if (errored && this.attempts < this.retries) {
|
||||||
|
this.restart();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var details = 'See ' + jobUrl + ' for details.';
|
||||||
|
this.failed = true;
|
||||||
|
|
||||||
|
logInline();
|
||||||
|
if (failures) {
|
||||||
|
console.error(label + ' %s ' + chalk.red('failed') + ' %d test' + (failures > 1 ? 's' : '') + '. %s', description, failures, details);
|
||||||
|
}
|
||||||
|
else if (tunnel.attempts < tunnel.retries) {
|
||||||
|
tunnel.restart();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (typeof message == 'undefined') {
|
||||||
|
message = 'Results are unavailable. ' + details;
|
||||||
|
}
|
||||||
|
console.error(label, description, chalk.red('failed') + ';', message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logInline();
|
||||||
|
console.log(label, description, chalk.green('passed'));
|
||||||
|
}
|
||||||
|
this.running = false;
|
||||||
|
this.emit('complete');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `SauceTunnel#start` callback used by `Tunnel#start`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {boolean} success The connection success indicator.
|
||||||
|
*/
|
||||||
|
function onTunnelStart(success) {
|
||||||
|
this.starting = false;
|
||||||
|
|
||||||
|
if (this._timeoutId) {
|
||||||
|
clearTimeout(this._timeoutId);
|
||||||
|
this._timeoutId = null;
|
||||||
|
}
|
||||||
|
if (!success) {
|
||||||
|
if (this.attempts < this.retries) {
|
||||||
|
this.restart();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logInline();
|
||||||
|
console.error('Failed to open Sauce Connect tunnel');
|
||||||
|
process.exit(2);
|
||||||
|
}
|
||||||
|
logInline();
|
||||||
|
console.log('Sauce Connect tunnel opened');
|
||||||
|
|
||||||
|
var jobs = this.jobs;
|
||||||
|
push.apply(jobs.queue, jobs.all);
|
||||||
|
|
||||||
|
this.running = true;
|
||||||
|
this.emit('start');
|
||||||
|
|
||||||
|
console.log('Starting jobs...');
|
||||||
|
this.dequeue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Job constructor.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} [properties] The properties to initialize a job with.
|
||||||
|
*/
|
||||||
|
function Job(properties) {
|
||||||
|
EventEmitter.call(this);
|
||||||
|
|
||||||
|
this.options = {};
|
||||||
|
_.merge(this, properties);
|
||||||
|
_.defaults(this.options, _.cloneDeep(jobOptions));
|
||||||
|
|
||||||
|
this.attempts = 0;
|
||||||
|
this.checking = this.failed = this.removing = this.resetting = this.restarting = this.running = this.starting = this.stopping = false;
|
||||||
|
this._pollerId = this.id = this.result = this.taskId = this.url = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
util.inherits(Job, EventEmitter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the job.
|
||||||
|
*
|
||||||
|
* @memberOf Job
|
||||||
|
* @param {Function} callback The function called once the job is removed.
|
||||||
|
* @param {Object} Returns the job instance.
|
||||||
|
*/
|
||||||
|
Job.prototype.remove = function(callback) {
|
||||||
|
this.once('remove', _.callback(callback));
|
||||||
|
if (this.removing) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.removing = true;
|
||||||
|
return this.stop(function() {
|
||||||
|
var onRemove = _.bind(onJobRemove, this);
|
||||||
|
if (!this.id) {
|
||||||
|
_.defer(onRemove);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
request.del(_.template('https://saucelabs.com/rest/v1/${user}/jobs/${id}')(this), {
|
||||||
|
'auth': { 'user': this.user, 'pass': this.pass }
|
||||||
|
}, onRemove);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the job.
|
||||||
|
*
|
||||||
|
* @memberOf Job
|
||||||
|
* @param {Function} callback The function called once the job is reset.
|
||||||
|
* @param {Object} Returns the job instance.
|
||||||
|
*/
|
||||||
|
Job.prototype.reset = function(callback) {
|
||||||
|
this.once('reset', _.callback(callback));
|
||||||
|
if (this.resetting) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.resetting = true;
|
||||||
|
return this.remove(onJobReset);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restarts the job.
|
||||||
|
*
|
||||||
|
* @memberOf Job
|
||||||
|
* @param {Function} callback The function called once the job is restarted.
|
||||||
|
* @param {Object} Returns the job instance.
|
||||||
|
*/
|
||||||
|
Job.prototype.restart = function(callback) {
|
||||||
|
this.once('restart', _.callback(callback));
|
||||||
|
if (this.restarting) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.restarting = true;
|
||||||
|
|
||||||
|
var options = this.options,
|
||||||
|
platform = options.platforms[0],
|
||||||
|
description = browserName(platform[1]) + ' ' + platform[2] + ' on ' + capitalizeWords(platform[0]),
|
||||||
|
label = options.name + ':';
|
||||||
|
|
||||||
|
logInline();
|
||||||
|
console.log('%s %s restart %d of %d', label, description, ++this.attempts, this.retries);
|
||||||
|
|
||||||
|
return this.remove(onGenericRestart);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the job.
|
||||||
|
*
|
||||||
|
* @memberOf Job
|
||||||
|
* @param {Function} callback The function called once the job is started.
|
||||||
|
* @param {Object} Returns the job instance.
|
||||||
|
*/
|
||||||
|
Job.prototype.start = function(callback) {
|
||||||
|
this.once('start', _.callback(callback));
|
||||||
|
if (this.starting || this.running) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.starting = true;
|
||||||
|
request.post(_.template('https://saucelabs.com/rest/v1/${user}/js-tests')(this), {
|
||||||
|
'auth': { 'user': this.user, 'pass': this.pass },
|
||||||
|
'json': this.options
|
||||||
|
}, _.bind(onJobStart, this));
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the status of a job.
|
||||||
|
*
|
||||||
|
* @memberOf Job
|
||||||
|
* @param {Function} callback The function called once the status is resolved.
|
||||||
|
* @param {Object} Returns the job instance.
|
||||||
|
*/
|
||||||
|
Job.prototype.status = function(callback) {
|
||||||
|
this.once('status', _.callback(callback));
|
||||||
|
if (this.checking || this.removing || this.resetting || this.restarting || this.starting || this.stopping) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this._pollerId = null;
|
||||||
|
this.checking = true;
|
||||||
|
request.post(_.template('https://saucelabs.com/rest/v1/${user}/js-tests/status')(this), {
|
||||||
|
'auth': { 'user': this.user, 'pass': this.pass },
|
||||||
|
'json': { 'js tests': [this.taskId] }
|
||||||
|
}, _.bind(onJobStatus, this));
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the job.
|
||||||
|
*
|
||||||
|
* @memberOf Job
|
||||||
|
* @param {Function} callback The function called once the job is stopped.
|
||||||
|
* @param {Object} Returns the job instance.
|
||||||
|
*/
|
||||||
|
Job.prototype.stop = function(callback) {
|
||||||
|
this.once('stop', _.callback(callback));
|
||||||
|
if (this.stopping) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.stopping = true;
|
||||||
|
if (this._pollerId) {
|
||||||
|
clearTimeout(this._pollerId);
|
||||||
|
this._pollerId = null;
|
||||||
|
this.checking = false;
|
||||||
|
}
|
||||||
|
var onStop = _.bind(onGenericStop, this);
|
||||||
|
if (!this.running || !this.id) {
|
||||||
|
_.defer(onStop);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
request.put(_.template('https://saucelabs.com/rest/v1/${user}/jobs/${id}/stop')(this), {
|
||||||
|
'auth': { 'user': this.user, 'pass': this.pass }
|
||||||
|
}, onStop);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Tunnel constructor.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} [properties] The properties to initialize the tunnel with.
|
||||||
|
*/
|
||||||
|
function Tunnel(properties) {
|
||||||
|
EventEmitter.call(this);
|
||||||
|
|
||||||
|
_.merge(this, properties);
|
||||||
|
|
||||||
|
var active = [],
|
||||||
|
queue = [];
|
||||||
|
|
||||||
|
var all = _.map(this.platforms, function(platform) {
|
||||||
|
return new Job(_.merge({
|
||||||
|
'user': this.user,
|
||||||
|
'pass': this.pass,
|
||||||
|
'tunnel': this,
|
||||||
|
'options': { 'platforms': [platform] }
|
||||||
|
}, this.job));
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
var completed = 0,
|
||||||
|
restarted = [],
|
||||||
|
success = true,
|
||||||
|
total = all.length,
|
||||||
|
tunnel = this;
|
||||||
|
|
||||||
|
_.invoke(all, 'on', 'complete', function() {
|
||||||
|
_.pull(active, this);
|
||||||
|
if (success) {
|
||||||
|
success = !this.failed;
|
||||||
|
}
|
||||||
|
if (++completed == total) {
|
||||||
|
tunnel.stop(_.partial(tunnel.emit, 'complete', success));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tunnel.dequeue();
|
||||||
|
});
|
||||||
|
|
||||||
|
_.invoke(all, 'on', 'restart', function() {
|
||||||
|
if (!_.includes(restarted, this)) {
|
||||||
|
restarted.push(this);
|
||||||
|
}
|
||||||
|
// Restart tunnel if all active jobs have restarted.
|
||||||
|
var threshold = Math.min(all.length, _.isFinite(throttled) ? throttled : 3);
|
||||||
|
if (tunnel.attempts < tunnel.retries &&
|
||||||
|
active.length >= threshold && _.isEmpty(_.difference(active, restarted))) {
|
||||||
|
tunnel.restart();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.on('restart', function() {
|
||||||
|
completed = 0;
|
||||||
|
success = true;
|
||||||
|
restarted.length = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
this._timeoutId = null;
|
||||||
|
this.attempts = 0;
|
||||||
|
this.restarting = this.running = this.starting = this.stopping = false;
|
||||||
|
this.jobs = { 'active': active, 'all': all, 'queue': queue };
|
||||||
|
this.connection = new SauceTunnel(this.user, this.pass, this.id, this.tunneled, ['-P', '0']);
|
||||||
|
}
|
||||||
|
|
||||||
|
util.inherits(Tunnel, EventEmitter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restarts the tunnel.
|
||||||
|
*
|
||||||
|
* @memberOf Tunnel
|
||||||
|
* @param {Function} callback The function called once the tunnel is restarted.
|
||||||
|
*/
|
||||||
|
Tunnel.prototype.restart = function(callback) {
|
||||||
|
this.once('restart', _.callback(callback));
|
||||||
|
if (this.restarting) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.restarting = true;
|
||||||
|
|
||||||
|
logInline();
|
||||||
|
console.log('Tunnel %s: restart %d of %d', this.id, ++this.attempts, this.retries);
|
||||||
|
|
||||||
|
var jobs = this.jobs,
|
||||||
|
active = jobs.active,
|
||||||
|
all = jobs.all;
|
||||||
|
|
||||||
|
var reset = _.after(all.length, _.bind(this.stop, this, onGenericRestart)),
|
||||||
|
stop = _.after(active.length, _.partial(_.invoke, all, 'reset', reset));
|
||||||
|
|
||||||
|
if (_.isEmpty(active)) {
|
||||||
|
_.defer(stop);
|
||||||
|
}
|
||||||
|
if (_.isEmpty(all)) {
|
||||||
|
_.defer(reset);
|
||||||
|
}
|
||||||
|
_.invoke(active, 'stop', function() {
|
||||||
|
_.pull(active, this);
|
||||||
|
stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this._timeoutId) {
|
||||||
|
clearTimeout(this._timeoutId);
|
||||||
|
this._timeoutId = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the tunnel.
|
||||||
|
*
|
||||||
|
* @memberOf Tunnel
|
||||||
|
* @param {Function} callback The function called once the tunnel is started.
|
||||||
|
* @param {Object} Returns the tunnel instance.
|
||||||
|
*/
|
||||||
|
Tunnel.prototype.start = function(callback) {
|
||||||
|
this.once('start', _.callback(callback));
|
||||||
|
if (this.starting || this.running) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.starting = true;
|
||||||
|
|
||||||
|
logInline();
|
||||||
|
console.log('Opening Sauce Connect tunnel...');
|
||||||
|
|
||||||
|
var onStart = _.bind(onTunnelStart, this);
|
||||||
|
if (this.timeout) {
|
||||||
|
this._timeoutId = _.delay(onStart, this.timeout * 1000, false);
|
||||||
|
}
|
||||||
|
this.connection.start(onStart);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes jobs from the queue and starts them.
|
||||||
|
*
|
||||||
|
* @memberOf Tunnel
|
||||||
|
* @param {Object} Returns the tunnel instance.
|
||||||
|
*/
|
||||||
|
Tunnel.prototype.dequeue = function() {
|
||||||
|
var jobs = this.jobs,
|
||||||
|
active = jobs.active,
|
||||||
|
queue = jobs.queue,
|
||||||
|
throttled = this.throttled;
|
||||||
|
|
||||||
|
while (queue.length && (active.length < throttled)) {
|
||||||
|
active.push(queue.shift().start());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the tunnel.
|
||||||
|
*
|
||||||
|
* @memberOf Tunnel
|
||||||
|
* @param {Function} callback The function called once the tunnel is stopped.
|
||||||
|
* @param {Object} Returns the tunnel instance.
|
||||||
|
*/
|
||||||
|
Tunnel.prototype.stop = function(callback) {
|
||||||
|
this.once('stop', _.callback(callback));
|
||||||
|
if (this.stopping) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.stopping = true;
|
||||||
|
|
||||||
|
logInline();
|
||||||
|
console.log('Shutting down Sauce Connect tunnel...');
|
||||||
|
|
||||||
|
var jobs = this.jobs,
|
||||||
|
active = jobs.active;
|
||||||
|
|
||||||
|
var stop = _.after(active.length, _.bind(function() {
|
||||||
|
var onStop = _.bind(onGenericStop, this);
|
||||||
|
if (this.running) {
|
||||||
|
this.connection.stop(onStop);
|
||||||
|
} else {
|
||||||
|
onStop();
|
||||||
|
}
|
||||||
|
}, this));
|
||||||
|
|
||||||
|
jobs.queue.length = 0;
|
||||||
|
if (_.isEmpty(active)) {
|
||||||
|
_.defer(stop);
|
||||||
|
}
|
||||||
|
_.invoke(active, 'stop', function() {
|
||||||
|
_.pull(active, this);
|
||||||
|
stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this._timeoutId) {
|
||||||
|
clearTimeout(this._timeoutId);
|
||||||
|
this._timeoutId = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// Cleanup any inline logs when exited via `ctrl+c`.
|
||||||
|
process.on('SIGINT', function() {
|
||||||
|
logInline();
|
||||||
|
process.exit();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create a web server for the current working directory.
|
||||||
|
http.createServer(function(req, res) {
|
||||||
|
// See http://msdn.microsoft.com/en-us/library/ff955275(v=vs.85).aspx.
|
||||||
|
if (compatMode && path.extname(url.parse(req.url).pathname) == '.html') {
|
||||||
|
res.setHeader('X-UA-Compatible', 'IE=' + compatMode);
|
||||||
|
}
|
||||||
|
mount(req, res);
|
||||||
|
}).listen(port);
|
||||||
|
|
||||||
|
// Setup Sauce Connect so we can use this server from Sauce Labs.
|
||||||
|
var tunnel = new Tunnel({
|
||||||
|
'user': username,
|
||||||
|
'pass': accessKey,
|
||||||
|
'id': tunnelId,
|
||||||
|
'job': { 'retries': maxJobRetries, 'statusInterval': statusInterval },
|
||||||
|
'platforms': platforms,
|
||||||
|
'retries': maxTunnelRetries,
|
||||||
|
'throttled': throttled,
|
||||||
|
'tunneled': tunneled,
|
||||||
|
'timeout': tunnelTimeout
|
||||||
|
});
|
||||||
|
|
||||||
|
tunnel.on('complete', function(success) {
|
||||||
|
process.exit(success ? 0 : 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
tunnel.start();
|
||||||
|
|
||||||
|
setInterval(logThrobber, throbberDelay);
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
;(function(window) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/** `QUnit.addEvent` shortcut */
|
|
||||||
var addEvent = QUnit.addEvent;
|
|
||||||
|
|
||||||
/** The Lo-Dash build to load */
|
|
||||||
var build = (/build=([^&]+)/.exec(location.search) || [])[1];
|
|
||||||
|
|
||||||
/** A flag to determine if RequireJS should be loaded */
|
|
||||||
var norequire = /[?&]norequire=true(?:&|$)/.test(location.search);
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
// assign `QUnit.config` properties
|
|
||||||
QUnit.config.lodashFilename = (function() {
|
|
||||||
switch (build) {
|
|
||||||
case 'prod': return 'lodash.min';
|
|
||||||
case 'custom': return 'lodash.custom.min';
|
|
||||||
case 'custom-debug': return 'lodash.custom';
|
|
||||||
}
|
|
||||||
return 'lodash';
|
|
||||||
}());
|
|
||||||
|
|
||||||
// assign `QUnit.urlParams` properties
|
|
||||||
QUnit.extend(QUnit.urlParams, {
|
|
||||||
'build': build,
|
|
||||||
'norequire': norequire
|
|
||||||
});
|
|
||||||
|
|
||||||
// initialize the build dropdown
|
|
||||||
addEvent(window, 'load', function() {
|
|
||||||
function eventHandler(event) {
|
|
||||||
var search = location.search.replace(/^\?|&?(?:build|norequire)=[^&]*&?/g, '');
|
|
||||||
if (event.stopPropagation) {
|
|
||||||
event.stopPropagation();
|
|
||||||
} else {
|
|
||||||
event.cancelBubble = true;
|
|
||||||
}
|
|
||||||
location.href =
|
|
||||||
location.href.split('?')[0] + '?' +
|
|
||||||
(search ? search + '&' : '') + 'build=' +
|
|
||||||
dropdown[dropdown.selectedIndex].value +
|
|
||||||
(checkbox.checked ? '&norequire=true' : '');
|
|
||||||
}
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
var toolbar = document.getElementById('qunit-testrunner-toolbar');
|
|
||||||
if (toolbar) {
|
|
||||||
toolbar.appendChild(label1);
|
|
||||||
toolbar.appendChild(label2);
|
|
||||||
|
|
||||||
dropdown.selectedIndex = (function() {
|
|
||||||
switch (build) {
|
|
||||||
case 'prod': return 1;
|
|
||||||
case 'custom': return 2;
|
|
||||||
case 'custom-debug': return 3;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}());
|
|
||||||
|
|
||||||
checkbox.checked = norequire;
|
|
||||||
addEvent(checkbox, 'click', eventHandler);
|
|
||||||
addEvent(dropdown, 'change', eventHandler);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setTimeout(init, 15);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var label1 = document.createElement('label');
|
|
||||||
label1.innerHTML =
|
|
||||||
'<input name="norequire" type="checkbox">No RequireJS';
|
|
||||||
|
|
||||||
var label2 = document.createElement('label');
|
|
||||||
label2.innerHTML = ' ' +
|
|
||||||
'<select name="build">' +
|
|
||||||
'<option value="dev">Developement</option>' +
|
|
||||||
'<option value="prod">Production</option>' +
|
|
||||||
'<option value="custom">Custom</option>' +
|
|
||||||
'<option value="custom-debug">Custom (debug)</option>' +
|
|
||||||
'</select> Build';
|
|
||||||
|
|
||||||
var checkbox = label1.firstChild,
|
|
||||||
dropdown = label2.getElementsByTagName('select')[0];
|
|
||||||
|
|
||||||
init();
|
|
||||||
});
|
|
||||||
|
|
||||||
}(this));
|
|
||||||
17913
test/test.js
17913
test/test.js
File diff suppressed because it is too large
Load Diff
@@ -3,9 +3,9 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Underscore Test Suite</title>
|
<title>Underscore Test Suite</title>
|
||||||
<link rel="stylesheet" href="../vendor/underscore/test/vendor/qunit.css">
|
<link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css">
|
||||||
<style>
|
<style>
|
||||||
#jslitmus, iframe {
|
iframe {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -17,21 +17,237 @@
|
|||||||
<div id="id1"></div>
|
<div id="id1"></div>
|
||||||
<div id="id2"></div>
|
<div id="id2"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<img id="chart_image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">
|
||||||
</div>
|
</div>
|
||||||
<script src="../vendor/backbone/test/vendor/json2.js"></script>
|
|
||||||
<script src="../vendor/underscore/test/vendor/jquery.js"></script>
|
|
||||||
<script src="../vendor/underscore/test/vendor/qunit.js"></script>
|
|
||||||
<script src="../vendor/underscore/test/vendor/jslitmus.js"></script>
|
|
||||||
<script src="test-ui.js"></script>
|
|
||||||
<script>
|
<script>
|
||||||
document.write('<script src="../' + QUnit.config.lodashFilename + '.js"><\/script>');
|
// avoid reporting tests to Sauce Labs when script errors occur
|
||||||
|
if (location.port == '9001') {
|
||||||
|
window.onerror = function(message) {
|
||||||
|
if (window.QUnit) {
|
||||||
|
QUnit.config.done.length = 0;
|
||||||
|
}
|
||||||
|
global_test_results = { 'message': message };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script src="../node_modules/qunitjs/qunit/qunit.js"></script>
|
||||||
|
<script src="../node_modules/qunit-extras/qunit-extras.js"></script>
|
||||||
|
<script src="../node_modules/jquery/dist/jquery.js"></script>
|
||||||
|
<script src="../node_modules/platform/platform.js"></script>
|
||||||
|
<script src="./asset/test-ui.js"></script>
|
||||||
|
<script>
|
||||||
|
QUnit.config.asyncRetries = 10;
|
||||||
|
QUnit.config.hidepassed = true;
|
||||||
|
|
||||||
|
// excuse tests we intentionally fail or those with problems
|
||||||
|
QUnit.config.excused = {
|
||||||
|
'Arrays': {
|
||||||
|
'drop': [
|
||||||
|
'alias for rest'
|
||||||
|
],
|
||||||
|
'first': [
|
||||||
|
'can pass an index to first',
|
||||||
|
'[1,2]',
|
||||||
|
'0'
|
||||||
|
],
|
||||||
|
'flatten': [
|
||||||
|
'Flattens empty arrays',
|
||||||
|
'can flatten nested arrays',
|
||||||
|
'can shallowly flatten nested arrays',
|
||||||
|
'works on an arguments object',
|
||||||
|
'can shallowly flatten arrays containing only other arrays'
|
||||||
|
],
|
||||||
|
'initial': [
|
||||||
|
'initial can take an index',
|
||||||
|
'initial can take a large index',
|
||||||
|
'initial works on arguments object'
|
||||||
|
],
|
||||||
|
'intersection': [
|
||||||
|
'can perform an OO-style intersection'
|
||||||
|
],
|
||||||
|
'last': [
|
||||||
|
'can pass an index to last',
|
||||||
|
'0'
|
||||||
|
],
|
||||||
|
'lastIndexOf': [
|
||||||
|
'[0,-1,-1]'
|
||||||
|
],
|
||||||
|
'rest': [
|
||||||
|
'working rest(0)',
|
||||||
|
'rest can take an index',
|
||||||
|
'works on arguments object'
|
||||||
|
],
|
||||||
|
'take': [
|
||||||
|
'alias for first'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'Chaining': {
|
||||||
|
'pop': true,
|
||||||
|
'shift': true,
|
||||||
|
'splice': true,
|
||||||
|
'reverse/concat/unshift/pop/map': [
|
||||||
|
'can chain together array functions.'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'Collections': {
|
||||||
|
'filter': [
|
||||||
|
'OO-filter'
|
||||||
|
],
|
||||||
|
'invoke': [
|
||||||
|
'handles null & undefined'
|
||||||
|
],
|
||||||
|
'map': [
|
||||||
|
'OO-style doubled numbers'
|
||||||
|
],
|
||||||
|
'Resistant to collection length and properties changing while iterating': [
|
||||||
|
'Died on test #50'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'Functions': {
|
||||||
|
'bind': [
|
||||||
|
'Died on test #2'
|
||||||
|
],
|
||||||
|
'bindAll': [
|
||||||
|
'throws an error for bindAll with no functions named'
|
||||||
|
],
|
||||||
|
'memoize': [
|
||||||
|
'{"bar":"BAR","foo":"FOO"}',
|
||||||
|
'Died on test #8'
|
||||||
|
],
|
||||||
|
'throttle repeatedly with results': true,
|
||||||
|
'more throttle does not trigger leading call when leading is set to false': true,
|
||||||
|
'throttle does not trigger trailing call when trailing is set to false': true,
|
||||||
|
'debounce asap': true
|
||||||
|
},
|
||||||
|
'Objects': {
|
||||||
|
'#1929 Typed Array constructors are functions': true,
|
||||||
|
'allKeys': true,
|
||||||
|
'extendOwn': true,
|
||||||
|
'mapObject': true,
|
||||||
|
'matcher': true,
|
||||||
|
'matcher ': true,
|
||||||
|
'extend': [
|
||||||
|
'extend copies all properties from source'
|
||||||
|
],
|
||||||
|
'isEqual': [
|
||||||
|
'`0` is not equal to `-0`',
|
||||||
|
'Commutative equality is implemented for `0` and `-0`',
|
||||||
|
'`new Number(0)` and `-0` are not equal',
|
||||||
|
'Commutative equality is implemented for `new Number(0)` and `-0`'
|
||||||
|
],
|
||||||
|
'isFinite': [
|
||||||
|
'Numeric strings are numbers',
|
||||||
|
'Number instances can be finite'
|
||||||
|
],
|
||||||
|
'isMatch': [
|
||||||
|
'inherited and own properties are checked on the test object',
|
||||||
|
'doesnt falsey match constructor on undefined/null'
|
||||||
|
],
|
||||||
|
'keys': [
|
||||||
|
'is not fooled by sparse arrays; see issue #95',
|
||||||
|
'[]'
|
||||||
|
],
|
||||||
|
'matches': [
|
||||||
|
'inherited and own properties are checked on the test object',
|
||||||
|
'doesnt fasley match constructor on undefined/null'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'Utility': {
|
||||||
|
'now': [
|
||||||
|
'Produces the correct time in milliseconds'
|
||||||
|
],
|
||||||
|
'times': [
|
||||||
|
'works as a wrapper'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// only excuse in Sauce Labs (buggy Safari and timers)
|
||||||
|
if (!ui.isSauceLabs) {
|
||||||
|
delete QUnit.config.excused.Functions['throttle repeatedly with results'];
|
||||||
|
delete QUnit.config.excused.Functions['more throttle does not trigger leading call when leading is set to false'];
|
||||||
|
delete QUnit.config.excused.Functions['throttle does not trigger trailing call when trailing is set to false'];
|
||||||
|
delete QUnit.config.excused.Functions['debounce asap'];
|
||||||
|
delete QUnit.config.excused.Utility.now;
|
||||||
|
}
|
||||||
|
// load test scripts
|
||||||
|
document.write(ui.urlParams.loader != 'none'
|
||||||
|
? '<script data-dojo-config="async:1" src="' + ui.loaderPath + '"><\/script>'
|
||||||
|
: ([
|
||||||
|
'<script src="' + ui.buildPath + '"><\/script>',
|
||||||
|
'<script src="../vendor/underscore/test/collections.js"><\/script>',
|
||||||
|
'<script src="../vendor/underscore/test/arrays.js"><\/script>',
|
||||||
|
'<script src="../vendor/underscore/test/functions.js"><\/script>',
|
||||||
|
'<script src="../vendor/underscore/test/objects.js"><\/script>',
|
||||||
|
'<script src="../vendor/underscore/test/utility.js"><\/script>',
|
||||||
|
'<script src="../vendor/underscore/test/chaining.js"><\/script>'
|
||||||
|
].join('\n'))
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
if (window.curl) {
|
||||||
|
curl.config({ 'apiName': 'require' });
|
||||||
|
}
|
||||||
|
if (!window.require) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var reBasename = /[\w.-]+$/,
|
||||||
|
basePath = ('//' + location.host + location.pathname.replace(reBasename, '')).replace(/\btest\/$/, ''),
|
||||||
|
modulePath = ui.buildPath.replace(/\.js$/, ''),
|
||||||
|
locationPath = modulePath.replace(reBasename, '').replace(/^\/|\/$/g, ''),
|
||||||
|
moduleId = /\bunderscore\b/i.test(ui.buildPath) ? 'underscore' : 'lodash',
|
||||||
|
moduleMain = modulePath.match(reBasename)[0],
|
||||||
|
uid = +new Date;
|
||||||
|
|
||||||
|
function getConfig() {
|
||||||
|
var result = {
|
||||||
|
'baseUrl': './',
|
||||||
|
'urlArgs': 't=' + uid++,
|
||||||
|
'waitSeconds': 0,
|
||||||
|
'paths': {},
|
||||||
|
'packages': [{
|
||||||
|
'name': 'test',
|
||||||
|
'location': '../vendor/underscore/test',
|
||||||
|
'config': {
|
||||||
|
// work around no global being exported
|
||||||
|
'exports': 'QUnit',
|
||||||
|
'loader': 'curl/loader/legacy'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ui.isModularize) {
|
||||||
|
result.packages.push({
|
||||||
|
'name': moduleId,
|
||||||
|
'location': locationPath,
|
||||||
|
'main': moduleMain
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
result.paths[moduleId] = modulePath;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUnit.config.autostart = false;
|
||||||
|
|
||||||
|
require(getConfig(), [moduleId], function(lodash) {
|
||||||
|
if (ui.isModularize) {
|
||||||
|
window._ = lodash;
|
||||||
|
}
|
||||||
|
require(getConfig(), [
|
||||||
|
'test/collections',
|
||||||
|
'test/arrays',
|
||||||
|
'test/functions',
|
||||||
|
'test/objects',
|
||||||
|
'test/utility',
|
||||||
|
'test/chaining'
|
||||||
|
], function() {
|
||||||
|
QUnit.start();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}());
|
||||||
</script>
|
</script>
|
||||||
<script src="../vendor/underscore/test/collections.js"></script>
|
|
||||||
<script src="../vendor/underscore/test/arrays.js"></script>
|
|
||||||
<script src="../vendor/underscore/test/functions.js"></script>
|
|
||||||
<script src="../vendor/underscore/test/objects.js"></script>
|
|
||||||
<script src="../vendor/underscore/test/utility.js"></script>
|
|
||||||
<script src="../vendor/underscore/test/chaining.js"></script>
|
|
||||||
<script type="text/html" id="template">
|
<script type="text/html" id="template">
|
||||||
<%
|
<%
|
||||||
// a comment
|
// a comment
|
||||||
|
|||||||
4
vendor/backbone/LICENSE
vendored
4
vendor/backbone/LICENSE
vendored
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2010-2012 Jeremy Ashkenas, DocumentCloud
|
Copyright (c) 2010-2014 Jeremy Ashkenas, DocumentCloud
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation
|
obtaining a copy of this software and associated documentation
|
||||||
@@ -19,4 +19,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|||||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|||||||
26
vendor/backbone/README.md
vendored
26
vendor/backbone/README.md
vendored
@@ -1,26 +0,0 @@
|
|||||||
____ __ __
|
|
||||||
/\ _`\ /\ \ /\ \ __
|
|
||||||
\ \ \ \ \ __ ___\ \ \/'\\ \ \____ ___ ___ __ /\_\ ____
|
|
||||||
\ \ _ <' /'__`\ /'___\ \ , < \ \ '__`\ / __`\ /' _ `\ /'__`\ \/\ \ /',__\
|
|
||||||
\ \ \ \ \/\ \ \.\_/\ \__/\ \ \\`\\ \ \ \ \/\ \ \ \/\ \/\ \/\ __/ __ \ \ \/\__, `\
|
|
||||||
\ \____/\ \__/.\_\ \____\\ \_\ \_\ \_,__/\ \____/\ \_\ \_\ \____\/\_\_\ \ \/\____/
|
|
||||||
\/___/ \/__/\/_/\/____/ \/_/\/_/\/___/ \/___/ \/_/\/_/\/____/\/_/\ \_\ \/___/
|
|
||||||
\ \____/
|
|
||||||
\/___/
|
|
||||||
(_'_______________________________________________________________________________'_)
|
|
||||||
(_.———————————————————————————————————————————————————————————————————————————————._)
|
|
||||||
|
|
||||||
|
|
||||||
Backbone supplies structure to JavaScript-heavy applications by providing models key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing application over a RESTful JSON interface.
|
|
||||||
|
|
||||||
For Docs, License, Tests, pre-packed downloads, and everything else, really, see:
|
|
||||||
http://backbonejs.org
|
|
||||||
|
|
||||||
To suggest a feature, report a bug, or general discussion:
|
|
||||||
http://github.com/documentcloud/backbone/issues/
|
|
||||||
|
|
||||||
All contributors are listed here:
|
|
||||||
http://github.com/documentcloud/backbone/contributors
|
|
||||||
|
|
||||||
Special thanks to Robert Kieffer for the original philosophy behind Backbone.
|
|
||||||
http://github.com/broofa
|
|
||||||
1818
vendor/backbone/backbone.js
vendored
1818
vendor/backbone/backbone.js
vendored
File diff suppressed because it is too large
Load Diff
967
vendor/backbone/test/collection.js
vendored
967
vendor/backbone/test/collection.js
vendored
File diff suppressed because it is too large
Load Diff
43
vendor/backbone/test/environment.js
vendored
Normal file
43
vendor/backbone/test/environment.js
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
(function() {
|
||||||
|
|
||||||
|
var sync = Backbone.sync;
|
||||||
|
var ajax = Backbone.ajax;
|
||||||
|
var emulateHTTP = Backbone.emulateHTTP;
|
||||||
|
var emulateJSON = Backbone.emulateJSON;
|
||||||
|
var history = window.history;
|
||||||
|
var pushState = history.pushState;
|
||||||
|
var replaceState = history.replaceState;
|
||||||
|
|
||||||
|
QUnit.testStart(function() {
|
||||||
|
var env = QUnit.config.current.testEnvironment;
|
||||||
|
|
||||||
|
// We never want to actually call these during tests.
|
||||||
|
history.pushState = history.replaceState = function(){};
|
||||||
|
|
||||||
|
// Capture ajax settings for comparison.
|
||||||
|
Backbone.ajax = function(settings) {
|
||||||
|
env.ajaxSettings = settings;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Capture the arguments to Backbone.sync for comparison.
|
||||||
|
Backbone.sync = function(method, model, options) {
|
||||||
|
env.syncArgs = {
|
||||||
|
method: method,
|
||||||
|
model: model,
|
||||||
|
options: options
|
||||||
|
};
|
||||||
|
sync.apply(this, arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.testDone(function() {
|
||||||
|
Backbone.sync = sync;
|
||||||
|
Backbone.ajax = ajax;
|
||||||
|
Backbone.emulateHTTP = emulateHTTP;
|
||||||
|
Backbone.emulateJSON = emulateJSON;
|
||||||
|
history.pushState = pushState;
|
||||||
|
history.replaceState = replaceState;
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
332
vendor/backbone/test/events.js
vendored
332
vendor/backbone/test/events.js
vendored
@@ -1,8 +1,8 @@
|
|||||||
$(document).ready(function() {
|
(function() {
|
||||||
|
|
||||||
module("Backbone.Events");
|
module("Backbone.Events");
|
||||||
|
|
||||||
test("Events: on and trigger", 2, function() {
|
test("on and trigger", 2, function() {
|
||||||
var obj = { counter: 0 };
|
var obj = { counter: 0 };
|
||||||
_.extend(obj,Backbone.Events);
|
_.extend(obj,Backbone.Events);
|
||||||
obj.on('event', function() { obj.counter += 1; });
|
obj.on('event', function() { obj.counter += 1; });
|
||||||
@@ -15,9 +15,9 @@ $(document).ready(function() {
|
|||||||
equal(obj.counter, 5, 'counter should be incremented five times.');
|
equal(obj.counter, 5, 'counter should be incremented five times.');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Events: binding and triggering multiple events", 4, function() {
|
test("binding and triggering multiple events", 4, function() {
|
||||||
var obj = { counter: 0 };
|
var obj = { counter: 0 };
|
||||||
_.extend(obj,Backbone.Events);
|
_.extend(obj, Backbone.Events);
|
||||||
|
|
||||||
obj.on('a b c', function() { obj.counter += 1; });
|
obj.on('a b c', function() { obj.counter += 1; });
|
||||||
|
|
||||||
@@ -35,7 +35,156 @@ $(document).ready(function() {
|
|||||||
equal(obj.counter, 5);
|
equal(obj.counter, 5);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Events: trigger all for each event", 3, function() {
|
test("binding and triggering with event maps", function() {
|
||||||
|
var obj = { counter: 0 };
|
||||||
|
_.extend(obj, Backbone.Events);
|
||||||
|
|
||||||
|
var increment = function() {
|
||||||
|
this.counter += 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
obj.on({
|
||||||
|
a: increment,
|
||||||
|
b: increment,
|
||||||
|
c: increment
|
||||||
|
}, obj);
|
||||||
|
|
||||||
|
obj.trigger('a');
|
||||||
|
equal(obj.counter, 1);
|
||||||
|
|
||||||
|
obj.trigger('a b');
|
||||||
|
equal(obj.counter, 3);
|
||||||
|
|
||||||
|
obj.trigger('c');
|
||||||
|
equal(obj.counter, 4);
|
||||||
|
|
||||||
|
obj.off({
|
||||||
|
a: increment,
|
||||||
|
c: increment
|
||||||
|
}, obj);
|
||||||
|
obj.trigger('a b c');
|
||||||
|
equal(obj.counter, 5);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("listenTo and stopListening", 1, function() {
|
||||||
|
var a = _.extend({}, Backbone.Events);
|
||||||
|
var b = _.extend({}, Backbone.Events);
|
||||||
|
a.listenTo(b, 'all', function(){ ok(true); });
|
||||||
|
b.trigger('anything');
|
||||||
|
a.listenTo(b, 'all', function(){ ok(false); });
|
||||||
|
a.stopListening();
|
||||||
|
b.trigger('anything');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("listenTo and stopListening with event maps", 4, function() {
|
||||||
|
var a = _.extend({}, Backbone.Events);
|
||||||
|
var b = _.extend({}, Backbone.Events);
|
||||||
|
var cb = function(){ ok(true); };
|
||||||
|
a.listenTo(b, {event: cb});
|
||||||
|
b.trigger('event');
|
||||||
|
a.listenTo(b, {event2: cb});
|
||||||
|
b.on('event2', cb);
|
||||||
|
a.stopListening(b, {event2: cb});
|
||||||
|
b.trigger('event event2');
|
||||||
|
a.stopListening();
|
||||||
|
b.trigger('event event2');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("stopListening with omitted args", 2, function () {
|
||||||
|
var a = _.extend({}, Backbone.Events);
|
||||||
|
var b = _.extend({}, Backbone.Events);
|
||||||
|
var cb = function () { ok(true); };
|
||||||
|
a.listenTo(b, 'event', cb);
|
||||||
|
b.on('event', cb);
|
||||||
|
a.listenTo(b, 'event2', cb);
|
||||||
|
a.stopListening(null, {event: cb});
|
||||||
|
b.trigger('event event2');
|
||||||
|
b.off();
|
||||||
|
a.listenTo(b, 'event event2', cb);
|
||||||
|
a.stopListening(null, 'event');
|
||||||
|
a.stopListening();
|
||||||
|
b.trigger('event2');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("listenToOnce and stopListening", 1, function() {
|
||||||
|
var a = _.extend({}, Backbone.Events);
|
||||||
|
var b = _.extend({}, Backbone.Events);
|
||||||
|
a.listenToOnce(b, 'all', function() { ok(true); });
|
||||||
|
b.trigger('anything');
|
||||||
|
b.trigger('anything');
|
||||||
|
a.listenToOnce(b, 'all', function() { ok(false); });
|
||||||
|
a.stopListening();
|
||||||
|
b.trigger('anything');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("listenTo, listenToOnce and stopListening", 1, function() {
|
||||||
|
var a = _.extend({}, Backbone.Events);
|
||||||
|
var b = _.extend({}, Backbone.Events);
|
||||||
|
a.listenToOnce(b, 'all', function() { ok(true); });
|
||||||
|
b.trigger('anything');
|
||||||
|
b.trigger('anything');
|
||||||
|
a.listenTo(b, 'all', function() { ok(false); });
|
||||||
|
a.stopListening();
|
||||||
|
b.trigger('anything');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("listenTo and stopListening with event maps", 1, function() {
|
||||||
|
var a = _.extend({}, Backbone.Events);
|
||||||
|
var b = _.extend({}, Backbone.Events);
|
||||||
|
a.listenTo(b, {change: function(){ ok(true); }});
|
||||||
|
b.trigger('change');
|
||||||
|
a.listenTo(b, {change: function(){ ok(false); }});
|
||||||
|
a.stopListening();
|
||||||
|
b.trigger('change');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("listenTo yourself", 1, function(){
|
||||||
|
var e = _.extend({}, Backbone.Events);
|
||||||
|
e.listenTo(e, "foo", function(){ ok(true); });
|
||||||
|
e.trigger("foo");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("listenTo yourself cleans yourself up with stopListening", 1, function(){
|
||||||
|
var e = _.extend({}, Backbone.Events);
|
||||||
|
e.listenTo(e, "foo", function(){ ok(true); });
|
||||||
|
e.trigger("foo");
|
||||||
|
e.stopListening();
|
||||||
|
e.trigger("foo");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("stopListening cleans up references", 4, function() {
|
||||||
|
var a = _.extend({}, Backbone.Events);
|
||||||
|
var b = _.extend({}, Backbone.Events);
|
||||||
|
var fn = function() {};
|
||||||
|
a.listenTo(b, 'all', fn).stopListening();
|
||||||
|
equal(_.size(a._listeningTo), 0);
|
||||||
|
a.listenTo(b, 'all', fn).stopListening(b);
|
||||||
|
equal(_.size(a._listeningTo), 0);
|
||||||
|
a.listenTo(b, 'all', fn).stopListening(null, 'all');
|
||||||
|
equal(_.size(a._listeningTo), 0);
|
||||||
|
a.listenTo(b, 'all', fn).stopListening(null, null, fn);
|
||||||
|
equal(_.size(a._listeningTo), 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("listenTo and stopListening cleaning up references", 2, function() {
|
||||||
|
var a = _.extend({}, Backbone.Events);
|
||||||
|
var b = _.extend({}, Backbone.Events);
|
||||||
|
a.listenTo(b, 'all', function(){ ok(true); });
|
||||||
|
b.trigger('anything');
|
||||||
|
a.listenTo(b, 'other', function(){ ok(false); });
|
||||||
|
a.stopListening(b, 'other');
|
||||||
|
a.stopListening(b, 'all');
|
||||||
|
equal(_.keys(a._listeningTo).length, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("listenTo with empty callback doesn't throw an error", 1, function(){
|
||||||
|
var e = _.extend({}, Backbone.Events);
|
||||||
|
e.listenTo(e, "foo", null);
|
||||||
|
e.trigger("foo");
|
||||||
|
ok(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("trigger all for each event", 3, function() {
|
||||||
var a, b, obj = { counter: 0 };
|
var a, b, obj = { counter: 0 };
|
||||||
_.extend(obj, Backbone.Events);
|
_.extend(obj, Backbone.Events);
|
||||||
obj.on('all', function(event) {
|
obj.on('all', function(event) {
|
||||||
@@ -49,7 +198,7 @@ $(document).ready(function() {
|
|||||||
equal(obj.counter, 2);
|
equal(obj.counter, 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Events: on, then unbind all functions", 1, function() {
|
test("on, then unbind all functions", 1, function() {
|
||||||
var obj = { counter: 0 };
|
var obj = { counter: 0 };
|
||||||
_.extend(obj,Backbone.Events);
|
_.extend(obj,Backbone.Events);
|
||||||
var callback = function() { obj.counter += 1; };
|
var callback = function() { obj.counter += 1; };
|
||||||
@@ -60,7 +209,7 @@ $(document).ready(function() {
|
|||||||
equal(obj.counter, 1, 'counter should have only been incremented once.');
|
equal(obj.counter, 1, 'counter should have only been incremented once.');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Events: bind two callbacks, unbind only one", 2, function() {
|
test("bind two callbacks, unbind only one", 2, function() {
|
||||||
var obj = { counterA: 0, counterB: 0 };
|
var obj = { counterA: 0, counterB: 0 };
|
||||||
_.extend(obj,Backbone.Events);
|
_.extend(obj,Backbone.Events);
|
||||||
var callback = function() { obj.counterA += 1; };
|
var callback = function() { obj.counterA += 1; };
|
||||||
@@ -73,7 +222,7 @@ $(document).ready(function() {
|
|||||||
equal(obj.counterB, 2, 'counterB should have been incremented twice.');
|
equal(obj.counterB, 2, 'counterB should have been incremented twice.');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Events: unbind a callback in the midst of it firing", 1, function() {
|
test("unbind a callback in the midst of it firing", 1, function() {
|
||||||
var obj = {counter: 0};
|
var obj = {counter: 0};
|
||||||
_.extend(obj, Backbone.Events);
|
_.extend(obj, Backbone.Events);
|
||||||
var callback = function() {
|
var callback = function() {
|
||||||
@@ -87,7 +236,7 @@ $(document).ready(function() {
|
|||||||
equal(obj.counter, 1, 'the callback should have been unbound.');
|
equal(obj.counter, 1, 'the callback should have been unbound.');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Events: two binds that unbind themeselves", 2, function() {
|
test("two binds that unbind themeselves", 2, function() {
|
||||||
var obj = { counterA: 0, counterB: 0 };
|
var obj = { counterA: 0, counterB: 0 };
|
||||||
_.extend(obj,Backbone.Events);
|
_.extend(obj,Backbone.Events);
|
||||||
var incrA = function(){ obj.counterA += 1; obj.off('event', incrA); };
|
var incrA = function(){ obj.counterA += 1; obj.off('event', incrA); };
|
||||||
@@ -101,7 +250,7 @@ $(document).ready(function() {
|
|||||||
equal(obj.counterB, 1, 'counterB should have only been incremented once.');
|
equal(obj.counterB, 1, 'counterB should have only been incremented once.');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Events: bind a callback with a supplied context", 1, function () {
|
test("bind a callback with a supplied context", 1, function () {
|
||||||
var TestClass = function () {
|
var TestClass = function () {
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@@ -114,7 +263,7 @@ $(document).ready(function() {
|
|||||||
obj.trigger('event');
|
obj.trigger('event');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Events: nested trigger with unbind", 1, function () {
|
test("nested trigger with unbind", 1, function () {
|
||||||
var obj = { counter: 0 };
|
var obj = { counter: 0 };
|
||||||
_.extend(obj, Backbone.Events);
|
_.extend(obj, Backbone.Events);
|
||||||
var incr1 = function(){ obj.counter += 1; obj.off('event', incr1); obj.trigger('event'); };
|
var incr1 = function(){ obj.counter += 1; obj.off('event', incr1); obj.trigger('event'); };
|
||||||
@@ -125,7 +274,7 @@ $(document).ready(function() {
|
|||||||
equal(obj.counter, 3, 'counter should have been incremented three times');
|
equal(obj.counter, 3, 'counter should have been incremented three times');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Events: callback list is not altered during trigger", 2, function () {
|
test("callback list is not altered during trigger", 2, function () {
|
||||||
var counter = 0, obj = _.extend({}, Backbone.Events);
|
var counter = 0, obj = _.extend({}, Backbone.Events);
|
||||||
var incr = function(){ counter++; };
|
var incr = function(){ counter++; };
|
||||||
obj.on('event', function(){ obj.on('event', incr).on('all', incr); })
|
obj.on('event', function(){ obj.on('event', incr).on('all', incr); })
|
||||||
@@ -154,6 +303,13 @@ $(document).ready(function() {
|
|||||||
_.extend({}, Backbone.Events).on('test').trigger('test');
|
_.extend({}, Backbone.Events).on('test').trigger('test');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("if callback is truthy but not a function, `on` should throw an error just like jQuery", 1, function() {
|
||||||
|
var view = _.extend({}, Backbone.Events).on('test', 'noop');
|
||||||
|
raises(function() {
|
||||||
|
view.trigger('test');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test("remove all events for a specific context", 4, function() {
|
test("remove all events for a specific context", 4, function() {
|
||||||
var obj = _.extend({}, Backbone.Events);
|
var obj = _.extend({}, Backbone.Events);
|
||||||
obj.on('x y all', function() { ok(true); });
|
obj.on('x y all', function() { ok(true); });
|
||||||
@@ -172,18 +328,6 @@ $(document).ready(function() {
|
|||||||
obj.trigger('x y');
|
obj.trigger('x y');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("off is chainable", 3, function() {
|
|
||||||
var obj = _.extend({}, Backbone.Events);
|
|
||||||
// With no events
|
|
||||||
ok(obj.off() === obj);
|
|
||||||
// When removing all events
|
|
||||||
obj.on('event', function(){}, obj);
|
|
||||||
ok(obj.off() === obj);
|
|
||||||
// When removing some events
|
|
||||||
obj.on('event', function(){}, obj);
|
|
||||||
ok(obj.off('event') === obj);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("#1310 - off does not skip consecutive events", 0, function() {
|
test("#1310 - off does not skip consecutive events", 0, function() {
|
||||||
var obj = _.extend({}, Backbone.Events);
|
var obj = _.extend({}, Backbone.Events);
|
||||||
obj.on('event', function() { ok(false); }, obj);
|
obj.on('event', function() { ok(false); }, obj);
|
||||||
@@ -192,4 +336,142 @@ $(document).ready(function() {
|
|||||||
obj.trigger('event');
|
obj.trigger('event');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
test("once", 2, function() {
|
||||||
|
// Same as the previous test, but we use once rather than having to explicitly unbind
|
||||||
|
var obj = { counterA: 0, counterB: 0 };
|
||||||
|
_.extend(obj, Backbone.Events);
|
||||||
|
var incrA = function(){ obj.counterA += 1; obj.trigger('event'); };
|
||||||
|
var incrB = function(){ obj.counterB += 1; };
|
||||||
|
obj.once('event', incrA);
|
||||||
|
obj.once('event', incrB);
|
||||||
|
obj.trigger('event');
|
||||||
|
equal(obj.counterA, 1, 'counterA should have only been incremented once.');
|
||||||
|
equal(obj.counterB, 1, 'counterB should have only been incremented once.');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("once variant one", 3, function() {
|
||||||
|
var f = function(){ ok(true); };
|
||||||
|
|
||||||
|
var a = _.extend({}, Backbone.Events).once('event', f);
|
||||||
|
var b = _.extend({}, Backbone.Events).on('event', f);
|
||||||
|
|
||||||
|
a.trigger('event');
|
||||||
|
|
||||||
|
b.trigger('event');
|
||||||
|
b.trigger('event');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("once variant two", 3, function() {
|
||||||
|
var f = function(){ ok(true); };
|
||||||
|
var obj = _.extend({}, Backbone.Events);
|
||||||
|
|
||||||
|
obj
|
||||||
|
.once('event', f)
|
||||||
|
.on('event', f)
|
||||||
|
.trigger('event')
|
||||||
|
.trigger('event');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("once with off", 0, function() {
|
||||||
|
var f = function(){ ok(true); };
|
||||||
|
var obj = _.extend({}, Backbone.Events);
|
||||||
|
|
||||||
|
obj.once('event', f);
|
||||||
|
obj.off('event', f);
|
||||||
|
obj.trigger('event');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("once with event maps", function() {
|
||||||
|
var obj = { counter: 0 };
|
||||||
|
_.extend(obj, Backbone.Events);
|
||||||
|
|
||||||
|
var increment = function() {
|
||||||
|
this.counter += 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
obj.once({
|
||||||
|
a: increment,
|
||||||
|
b: increment,
|
||||||
|
c: increment
|
||||||
|
}, obj);
|
||||||
|
|
||||||
|
obj.trigger('a');
|
||||||
|
equal(obj.counter, 1);
|
||||||
|
|
||||||
|
obj.trigger('a b');
|
||||||
|
equal(obj.counter, 2);
|
||||||
|
|
||||||
|
obj.trigger('c');
|
||||||
|
equal(obj.counter, 3);
|
||||||
|
|
||||||
|
obj.trigger('a b c');
|
||||||
|
equal(obj.counter, 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("once with off only by context", 0, function() {
|
||||||
|
var context = {};
|
||||||
|
var obj = _.extend({}, Backbone.Events);
|
||||||
|
obj.once('event', function(){ ok(false); }, context);
|
||||||
|
obj.off(null, null, context);
|
||||||
|
obj.trigger('event');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Backbone object inherits Events", function() {
|
||||||
|
ok(Backbone.on === Backbone.Events.on);
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest("once with asynchronous events", 1, function() {
|
||||||
|
var func = _.debounce(function() { ok(true); start(); }, 50);
|
||||||
|
var obj = _.extend({}, Backbone.Events).once('async', func);
|
||||||
|
|
||||||
|
obj.trigger('async');
|
||||||
|
obj.trigger('async');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("once with multiple events.", 2, function() {
|
||||||
|
var obj = _.extend({}, Backbone.Events);
|
||||||
|
obj.once('x y', function() { ok(true); });
|
||||||
|
obj.trigger('x y');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Off during iteration with once.", 2, function() {
|
||||||
|
var obj = _.extend({}, Backbone.Events);
|
||||||
|
var f = function(){ this.off('event', f); };
|
||||||
|
obj.on('event', f);
|
||||||
|
obj.once('event', function(){});
|
||||||
|
obj.on('event', function(){ ok(true); });
|
||||||
|
|
||||||
|
obj.trigger('event');
|
||||||
|
obj.trigger('event');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("`once` on `all` should work as expected", 1, function() {
|
||||||
|
Backbone.once('all', function() {
|
||||||
|
ok(true);
|
||||||
|
Backbone.trigger('all');
|
||||||
|
});
|
||||||
|
Backbone.trigger('all');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("once without a callback is a noop", 0, function() {
|
||||||
|
_.extend({}, Backbone.Events).once('event').trigger('event');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("event functions are chainable", function() {
|
||||||
|
var obj = _.extend({}, Backbone.Events);
|
||||||
|
var obj2 = _.extend({}, Backbone.Events);
|
||||||
|
var fn = function() {};
|
||||||
|
equal(obj, obj.trigger('noeventssetyet'));
|
||||||
|
equal(obj, obj.off('noeventssetyet'));
|
||||||
|
equal(obj, obj.stopListening('noeventssetyet'));
|
||||||
|
equal(obj, obj.on('a', fn));
|
||||||
|
equal(obj, obj.once('c', fn));
|
||||||
|
equal(obj, obj.trigger('a'));
|
||||||
|
equal(obj, obj.listenTo(obj2, 'a', fn));
|
||||||
|
equal(obj, obj.listenToOnce(obj2, 'b', fn));
|
||||||
|
equal(obj, obj.off('a c'));
|
||||||
|
equal(obj, obj.stopListening(obj2, 'a'));
|
||||||
|
equal(obj, obj.stopListening());
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
|
|||||||
663
vendor/backbone/test/model.js
vendored
663
vendor/backbone/test/model.js
vendored
File diff suppressed because it is too large
Load Diff
6
vendor/backbone/test/noconflict.js
vendored
6
vendor/backbone/test/noconflict.js
vendored
@@ -1,12 +1,12 @@
|
|||||||
$(document).ready(function() {
|
(function() {
|
||||||
|
|
||||||
module("Backbone.noConflict");
|
module("Backbone.noConflict");
|
||||||
|
|
||||||
test('Backbone.noConflict', 2, function() {
|
test('noConflict', 2, function() {
|
||||||
var noconflictBackbone = Backbone.noConflict();
|
var noconflictBackbone = Backbone.noConflict();
|
||||||
equal(window.Backbone, undefined, 'Returned window.Backbone');
|
equal(window.Backbone, undefined, 'Returned window.Backbone');
|
||||||
window.Backbone = noconflictBackbone;
|
window.Backbone = noconflictBackbone;
|
||||||
equal(window.Backbone, noconflictBackbone, 'Backbone is still pointing to the original Backbone');
|
equal(window.Backbone, noconflictBackbone, 'Backbone is still pointing to the original Backbone');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
})();
|
||||||
|
|||||||
545
vendor/backbone/test/router.js
vendored
545
vendor/backbone/test/router.js
vendored
@@ -1,14 +1,14 @@
|
|||||||
$(document).ready(function() {
|
(function() {
|
||||||
|
|
||||||
var router = null;
|
var router = null;
|
||||||
var location = null;
|
var location = null;
|
||||||
var lastRoute = null;
|
var lastRoute = null;
|
||||||
var lastArgs = [];
|
var lastArgs = [];
|
||||||
|
|
||||||
function onRoute(router, route, args) {
|
var onRoute = function(router, route, args) {
|
||||||
lastRoute = route;
|
lastRoute = route;
|
||||||
lastArgs = args;
|
lastArgs = args;
|
||||||
}
|
};
|
||||||
|
|
||||||
var Location = function(href) {
|
var Location = function(href) {
|
||||||
this.replace(href);
|
this.replace(href);
|
||||||
@@ -16,8 +16,11 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
_.extend(Location.prototype, {
|
_.extend(Location.prototype, {
|
||||||
|
|
||||||
|
parser: document.createElement('a'),
|
||||||
|
|
||||||
replace: function(href) {
|
replace: function(href) {
|
||||||
_.extend(this, _.pick($('<a></a>', {href: href})[0],
|
this.parser.href = href;
|
||||||
|
_.extend(this, _.pick(this.parser,
|
||||||
'href',
|
'href',
|
||||||
'hash',
|
'hash',
|
||||||
'host',
|
'host',
|
||||||
@@ -41,7 +44,7 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
setup: function() {
|
setup: function() {
|
||||||
location = new Location('http://example.com');
|
location = new Location('http://example.com');
|
||||||
Backbone.history = new Backbone.History({location: location});
|
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||||
router = new Router({testing: 101});
|
router = new Router({testing: 101});
|
||||||
Backbone.history.interval = 9;
|
Backbone.history.interval = 9;
|
||||||
Backbone.history.start({pushState: false});
|
Backbone.history.start({pushState: false});
|
||||||
@@ -57,6 +60,15 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var ExternalObject = {
|
||||||
|
value: 'unset',
|
||||||
|
|
||||||
|
routingFunction: function(value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
_.bindAll(ExternalObject, 'routingFunction');
|
||||||
|
|
||||||
var Router = Backbone.Router.extend({
|
var Router = Backbone.Router.extend({
|
||||||
|
|
||||||
count: 0,
|
count: 0,
|
||||||
@@ -66,12 +78,20 @@ $(document).ready(function() {
|
|||||||
"counter": "counter",
|
"counter": "counter",
|
||||||
"search/:query": "search",
|
"search/:query": "search",
|
||||||
"search/:query/p:page": "search",
|
"search/:query/p:page": "search",
|
||||||
|
"charñ": "charUTF",
|
||||||
|
"char%C3%B1": "charEscaped",
|
||||||
"contacts": "contacts",
|
"contacts": "contacts",
|
||||||
"contacts/new": "newContact",
|
"contacts/new": "newContact",
|
||||||
"contacts/:id": "loadContact",
|
"contacts/:id": "loadContact",
|
||||||
|
"route-event/:arg": "routeEvent",
|
||||||
|
"optional(/:item)": "optionalItem",
|
||||||
|
"named/optional/(y:z)": "namedOptional",
|
||||||
"splat/*args/end": "splat",
|
"splat/*args/end": "splat",
|
||||||
"*first/complex-:part/*rest": "complex",
|
":repo/compare/*from...*to": "github",
|
||||||
":entity?*args": "query",
|
"decode/:named/*splat": "decode",
|
||||||
|
"*first/complex-*part/*rest": "complex",
|
||||||
|
"query/:entity": "query",
|
||||||
|
"function/:value": ExternalObject.routingFunction,
|
||||||
"*anything": "anything"
|
"*anything": "anything"
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -88,11 +108,19 @@ $(document).ready(function() {
|
|||||||
this.count++;
|
this.count++;
|
||||||
},
|
},
|
||||||
|
|
||||||
search : function(query, page) {
|
search: function(query, page) {
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.page = page;
|
this.page = page;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
charUTF: function() {
|
||||||
|
this.charType = 'UTF';
|
||||||
|
},
|
||||||
|
|
||||||
|
charEscaped: function() {
|
||||||
|
this.charType = 'escaped';
|
||||||
|
},
|
||||||
|
|
||||||
contacts: function(){
|
contacts: function(){
|
||||||
this.contact = 'index';
|
this.contact = 'index';
|
||||||
},
|
},
|
||||||
@@ -105,60 +133,100 @@ $(document).ready(function() {
|
|||||||
this.contact = 'load';
|
this.contact = 'load';
|
||||||
},
|
},
|
||||||
|
|
||||||
splat : function(args) {
|
optionalItem: function(arg){
|
||||||
|
this.arg = arg != void 0 ? arg : null;
|
||||||
|
},
|
||||||
|
|
||||||
|
splat: function(args) {
|
||||||
this.args = args;
|
this.args = args;
|
||||||
},
|
},
|
||||||
|
|
||||||
complex : function(first, part, rest) {
|
github: function(repo, from, to) {
|
||||||
|
this.repo = repo;
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
},
|
||||||
|
|
||||||
|
complex: function(first, part, rest) {
|
||||||
this.first = first;
|
this.first = first;
|
||||||
this.part = part;
|
this.part = part;
|
||||||
this.rest = rest;
|
this.rest = rest;
|
||||||
},
|
},
|
||||||
|
|
||||||
query : function(entity, args) {
|
query: function(entity, args) {
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
this.queryArgs = args;
|
this.queryArgs = args;
|
||||||
},
|
},
|
||||||
|
|
||||||
anything : function(whatever) {
|
anything: function(whatever) {
|
||||||
this.anything = whatever;
|
this.anything = whatever;
|
||||||
|
},
|
||||||
|
|
||||||
|
namedOptional: function(z) {
|
||||||
|
this.z = z;
|
||||||
|
},
|
||||||
|
|
||||||
|
decode: function(named, path) {
|
||||||
|
this.named = named;
|
||||||
|
this.path = path;
|
||||||
|
},
|
||||||
|
|
||||||
|
routeEvent: function(arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: initialize", 1, function() {
|
test("initialize", 1, function() {
|
||||||
equal(router.testing, 101);
|
equal(router.testing, 101);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: routes (simple)", 4, function() {
|
test("routes (simple)", 4, function() {
|
||||||
location.replace('http://example.com#search/news');
|
location.replace('http://example.com#search/news');
|
||||||
Backbone.history.checkUrl();
|
Backbone.history.checkUrl();
|
||||||
equal(router.query, 'news');
|
equal(router.query, 'news');
|
||||||
equal(router.page, undefined);
|
equal(router.page, void 0);
|
||||||
equal(lastRoute, 'search');
|
equal(lastRoute, 'search');
|
||||||
equal(lastArgs[0], 'news');
|
equal(lastArgs[0], 'news');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: routes (two part)", 2, function() {
|
test("routes (simple, but unicode)", 4, function() {
|
||||||
|
location.replace('http://example.com#search/тест');
|
||||||
|
Backbone.history.checkUrl();
|
||||||
|
equal(router.query, "тест");
|
||||||
|
equal(router.page, void 0);
|
||||||
|
equal(lastRoute, 'search');
|
||||||
|
equal(lastArgs[0], "тест");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("routes (two part)", 2, function() {
|
||||||
location.replace('http://example.com#search/nyc/p10');
|
location.replace('http://example.com#search/nyc/p10');
|
||||||
Backbone.history.checkUrl();
|
Backbone.history.checkUrl();
|
||||||
equal(router.query, 'nyc');
|
equal(router.query, 'nyc');
|
||||||
equal(router.page, '10');
|
equal(router.page, '10');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: routes via navigate", 2, function() {
|
test("routes via navigate", 2, function() {
|
||||||
Backbone.history.navigate('search/manhattan/p20', {trigger: true});
|
Backbone.history.navigate('search/manhattan/p20', {trigger: true});
|
||||||
equal(router.query, 'manhattan');
|
equal(router.query, 'manhattan');
|
||||||
equal(router.page, '20');
|
equal(router.page, '20');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: routes via navigate for backwards-compatibility", 2, function() {
|
test("routes via navigate with params", 1, function() {
|
||||||
|
Backbone.history.navigate('query/test?a=b', {trigger: true});
|
||||||
|
equal(router.queryArgs, 'a=b');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("routes via navigate for backwards-compatibility", 2, function() {
|
||||||
Backbone.history.navigate('search/manhattan/p20', true);
|
Backbone.history.navigate('search/manhattan/p20', true);
|
||||||
equal(router.query, 'manhattan');
|
equal(router.query, 'manhattan');
|
||||||
equal(router.page, '20');
|
equal(router.page, '20');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: route precedence via navigate", 6, function(){
|
test("reports matched route via nagivate", 1, function() {
|
||||||
|
ok(Backbone.history.navigate('search/manhattan/p20', true));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("route precedence via navigate", 6, function(){
|
||||||
// check both 0.9.x and backwards-compatibility options
|
// check both 0.9.x and backwards-compatibility options
|
||||||
_.each([ { trigger: true }, true ], function( options ){
|
_.each([ { trigger: true }, true ], function( options ){
|
||||||
Backbone.history.navigate('contacts', options);
|
Backbone.history.navigate('contacts', options);
|
||||||
@@ -178,13 +246,13 @@ $(document).ready(function() {
|
|||||||
Backbone.history.navigate('/route');
|
Backbone.history.navigate('/route');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: use implicit callback if none provided", 1, function() {
|
test("use implicit callback if none provided", 1, function() {
|
||||||
router.count = 0;
|
router.count = 0;
|
||||||
router.navigate('implicit', {trigger: true});
|
router.navigate('implicit', {trigger: true});
|
||||||
equal(router.count, 1);
|
equal(router.count, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: routes via navigate with {replace: true}", 1, function() {
|
test("routes via navigate with {replace: true}", 1, function() {
|
||||||
location.replace('http://example.com#start_here');
|
location.replace('http://example.com#start_here');
|
||||||
Backbone.history.checkUrl();
|
Backbone.history.checkUrl();
|
||||||
location.replace = function(href) {
|
location.replace = function(href) {
|
||||||
@@ -193,13 +261,30 @@ $(document).ready(function() {
|
|||||||
Backbone.history.navigate('end_here', {replace: true});
|
Backbone.history.navigate('end_here', {replace: true});
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: routes (splats)", 1, function() {
|
test("routes (splats)", 1, function() {
|
||||||
location.replace('http://example.com#splat/long-list/of/splatted_99args/end');
|
location.replace('http://example.com#splat/long-list/of/splatted_99args/end');
|
||||||
Backbone.history.checkUrl();
|
Backbone.history.checkUrl();
|
||||||
equal(router.args, 'long-list/of/splatted_99args');
|
equal(router.args, 'long-list/of/splatted_99args');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: routes (complex)", 3, function() {
|
test("routes (github)", 3, function() {
|
||||||
|
location.replace('http://example.com#backbone/compare/1.0...braddunbar:with/slash');
|
||||||
|
Backbone.history.checkUrl();
|
||||||
|
equal(router.repo, 'backbone');
|
||||||
|
equal(router.from, '1.0');
|
||||||
|
equal(router.to, 'braddunbar:with/slash');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("routes (optional)", 2, function() {
|
||||||
|
location.replace('http://example.com#optional');
|
||||||
|
Backbone.history.checkUrl();
|
||||||
|
ok(!router.arg);
|
||||||
|
location.replace('http://example.com#optional/thing');
|
||||||
|
Backbone.history.checkUrl();
|
||||||
|
equal(router.arg, 'thing');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("routes (complex)", 3, function() {
|
||||||
location.replace('http://example.com#one/two/three/complex-part/four/five/six/seven');
|
location.replace('http://example.com#one/two/three/complex-part/four/five/six/seven');
|
||||||
Backbone.history.checkUrl();
|
Backbone.history.checkUrl();
|
||||||
equal(router.first, 'one/two/three');
|
equal(router.first, 'one/two/three');
|
||||||
@@ -207,8 +292,8 @@ $(document).ready(function() {
|
|||||||
equal(router.rest, 'four/five/six/seven');
|
equal(router.rest, 'four/five/six/seven');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: routes (query)", 5, function() {
|
test("routes (query)", 5, function() {
|
||||||
location.replace('http://example.com#mandel?a=b&c=d');
|
location.replace('http://example.com#query/mandel?a=b&c=d');
|
||||||
Backbone.history.checkUrl();
|
Backbone.history.checkUrl();
|
||||||
equal(router.entity, 'mandel');
|
equal(router.entity, 'mandel');
|
||||||
equal(router.queryArgs, 'a=b&c=d');
|
equal(router.queryArgs, 'a=b&c=d');
|
||||||
@@ -217,13 +302,30 @@ $(document).ready(function() {
|
|||||||
equal(lastArgs[1], 'a=b&c=d');
|
equal(lastArgs[1], 'a=b&c=d');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: routes (anything)", 1, function() {
|
test("routes (anything)", 1, function() {
|
||||||
location.replace('http://example.com#doesnt-match-a-route');
|
location.replace('http://example.com#doesnt-match-a-route');
|
||||||
Backbone.history.checkUrl();
|
Backbone.history.checkUrl();
|
||||||
equal(router.anything, 'doesnt-match-a-route');
|
equal(router.anything, 'doesnt-match-a-route');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: fires event when router doesn't have callback on it", 1, function() {
|
test("routes (function)", 3, function() {
|
||||||
|
router.on('route', function(name) {
|
||||||
|
ok(name === '');
|
||||||
|
});
|
||||||
|
equal(ExternalObject.value, 'unset');
|
||||||
|
location.replace('http://example.com#function/set');
|
||||||
|
Backbone.history.checkUrl();
|
||||||
|
equal(ExternalObject.value, 'set');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Decode named parameters, not splats.", 2, function() {
|
||||||
|
location.replace('http://example.com#decode/a%2Fb/c%2Fd/e');
|
||||||
|
Backbone.history.checkUrl();
|
||||||
|
strictEqual(router.named, 'a/b');
|
||||||
|
strictEqual(router.path, 'c/d/e');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("fires event when router doesn't have callback on it", 1, function() {
|
||||||
router.on("route:noCallback", function(){ ok(true); });
|
router.on("route:noCallback", function(){ ok(true); });
|
||||||
location.replace('http://example.com#noCallback');
|
location.replace('http://example.com#noCallback');
|
||||||
Backbone.history.checkUrl();
|
Backbone.history.checkUrl();
|
||||||
@@ -233,49 +335,53 @@ $(document).ready(function() {
|
|||||||
location.replace('http://example.com/root/foo');
|
location.replace('http://example.com/root/foo');
|
||||||
|
|
||||||
Backbone.history.stop();
|
Backbone.history.stop();
|
||||||
Backbone.history = new Backbone.History({location: location});
|
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||||
Backbone.history.start({root: '/root', hashChange: false, silent: true});
|
Backbone.history.start({root: '/root', hashChange: false, silent: true});
|
||||||
strictEqual(Backbone.history.getFragment(), 'foo');
|
strictEqual(Backbone.history.getFragment(), 'foo');
|
||||||
|
|
||||||
Backbone.history.stop();
|
Backbone.history.stop();
|
||||||
Backbone.history = new Backbone.History({location: location});
|
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||||
Backbone.history.start({root: '/root/', hashChange: false, silent: true});
|
Backbone.history.start({root: '/root/', hashChange: false, silent: true});
|
||||||
strictEqual(Backbone.history.getFragment(), 'foo');
|
strictEqual(Backbone.history.getFragment(), 'foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("#1003 - History is started before navigate is called", 1, function() {
|
test("#1003 - History is started before navigate is called", 1, function() {
|
||||||
var history = new Backbone.History();
|
|
||||||
history.navigate = function(){
|
|
||||||
ok(Backbone.History.started);
|
|
||||||
};
|
|
||||||
Backbone.history.stop();
|
Backbone.history.stop();
|
||||||
history.start();
|
Backbone.history.navigate = function(){ ok(Backbone.History.started); };
|
||||||
|
Backbone.history.start();
|
||||||
// If this is not an old IE navigate will not be called.
|
// If this is not an old IE navigate will not be called.
|
||||||
if (!history.iframe) ok(true);
|
if (!Backbone.history.iframe) ok(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: route callback gets passed decoded values", 3, function() {
|
test("#967 - Route callback gets passed encoded values.", 3, function() {
|
||||||
var route = 'has%2Fslash/complex-has%23hash/has%20space';
|
var route = 'has%2Fslash/complex-has%23hash/has%20space';
|
||||||
Backbone.history.navigate(route, {trigger: true});
|
Backbone.history.navigate(route, {trigger: true});
|
||||||
equal(router.first, 'has/slash');
|
strictEqual(router.first, 'has/slash');
|
||||||
equal(router.part, 'has#hash');
|
strictEqual(router.part, 'has#hash');
|
||||||
equal(router.rest, 'has space');
|
strictEqual(router.rest, 'has space');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: correctly handles URLs with % (#868)", 3, function() {
|
test("correctly handles URLs with % (#868)", 3, function() {
|
||||||
location.replace('http://example.com#search/fat%3A1.5%25');
|
location.replace('http://example.com#search/fat%3A1.5%25');
|
||||||
Backbone.history.checkUrl();
|
Backbone.history.checkUrl();
|
||||||
location.replace('http://example.com#search/fat');
|
location.replace('http://example.com#search/fat');
|
||||||
Backbone.history.checkUrl();
|
Backbone.history.checkUrl();
|
||||||
equal(router.query, 'fat');
|
equal(router.query, 'fat');
|
||||||
equal(router.page, undefined);
|
equal(router.page, void 0);
|
||||||
equal(lastRoute, 'search');
|
equal(lastRoute, 'search');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("#2666 - Hashes with UTF8 in them.", 2, function() {
|
||||||
|
Backbone.history.navigate('charñ', {trigger: true});
|
||||||
|
equal(router.charType, 'UTF');
|
||||||
|
Backbone.history.navigate('char%C3%B1', {trigger: true});
|
||||||
|
equal(router.charType, 'escaped');
|
||||||
|
});
|
||||||
|
|
||||||
test("#1185 - Use pathname when hashChange is not wanted.", 1, function() {
|
test("#1185 - Use pathname when hashChange is not wanted.", 1, function() {
|
||||||
Backbone.history.stop();
|
Backbone.history.stop();
|
||||||
location.replace('http://example.com/path/name#hash');
|
location.replace('http://example.com/path/name#hash');
|
||||||
Backbone.history = new Backbone.History({location: location});
|
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||||
Backbone.history.start({hashChange: false});
|
Backbone.history.start({hashChange: false});
|
||||||
var fragment = Backbone.history.getFragment();
|
var fragment = Backbone.history.getFragment();
|
||||||
strictEqual(fragment, location.pathname.replace(/^\//, ''));
|
strictEqual(fragment, location.pathname.replace(/^\//, ''));
|
||||||
@@ -284,7 +390,7 @@ $(document).ready(function() {
|
|||||||
test("#1206 - Strip leading slash before location.assign.", 1, function() {
|
test("#1206 - Strip leading slash before location.assign.", 1, function() {
|
||||||
Backbone.history.stop();
|
Backbone.history.stop();
|
||||||
location.replace('http://example.com/root/');
|
location.replace('http://example.com/root/');
|
||||||
Backbone.history = new Backbone.History({location: location});
|
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||||
Backbone.history.start({hashChange: false, root: '/root/'});
|
Backbone.history.start({hashChange: false, root: '/root/'});
|
||||||
location.assign = function(pathname) {
|
location.assign = function(pathname) {
|
||||||
strictEqual(pathname, '/root/fragment');
|
strictEqual(pathname, '/root/fragment');
|
||||||
@@ -295,7 +401,7 @@ $(document).ready(function() {
|
|||||||
test("#1387 - Root fragment without trailing slash.", 1, function() {
|
test("#1387 - Root fragment without trailing slash.", 1, function() {
|
||||||
Backbone.history.stop();
|
Backbone.history.stop();
|
||||||
location.replace('http://example.com/root');
|
location.replace('http://example.com/root');
|
||||||
Backbone.history = new Backbone.History({location: location});
|
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||||
Backbone.history.start({hashChange: false, root: '/root/', silent: true});
|
Backbone.history.start({hashChange: false, root: '/root/', silent: true});
|
||||||
strictEqual(Backbone.history.getFragment(), '');
|
strictEqual(Backbone.history.getFragment(), '');
|
||||||
});
|
});
|
||||||
@@ -303,7 +409,7 @@ $(document).ready(function() {
|
|||||||
test("#1366 - History does not prepend root to fragment.", 2, function() {
|
test("#1366 - History does not prepend root to fragment.", 2, function() {
|
||||||
Backbone.history.stop();
|
Backbone.history.stop();
|
||||||
location.replace('http://example.com/root/');
|
location.replace('http://example.com/root/');
|
||||||
Backbone.history = new Backbone.History({
|
Backbone.history = _.extend(new Backbone.History, {
|
||||||
location: location,
|
location: location,
|
||||||
history: {
|
history: {
|
||||||
pushState: function(state, title, url) {
|
pushState: function(state, title, url) {
|
||||||
@@ -320,10 +426,10 @@ $(document).ready(function() {
|
|||||||
strictEqual(Backbone.history.fragment, 'x');
|
strictEqual(Backbone.history.fragment, 'x');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: Normalize root.", 1, function() {
|
test("Normalize root.", 1, function() {
|
||||||
Backbone.history.stop();
|
Backbone.history.stop();
|
||||||
location.replace('http://example.com/root');
|
location.replace('http://example.com/root');
|
||||||
Backbone.history = new Backbone.History({
|
Backbone.history = _.extend(new Backbone.History, {
|
||||||
location: location,
|
location: location,
|
||||||
history: {
|
history: {
|
||||||
pushState: function(state, title, url) {
|
pushState: function(state, title, url) {
|
||||||
@@ -339,15 +445,15 @@ $(document).ready(function() {
|
|||||||
Backbone.history.navigate('fragment');
|
Backbone.history.navigate('fragment');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: Normalize root.", 1, function() {
|
test("Normalize root.", 1, function() {
|
||||||
Backbone.history.stop();
|
Backbone.history.stop();
|
||||||
location.replace('http://example.com/root#fragment');
|
location.replace('http://example.com/root#fragment');
|
||||||
Backbone.history = new Backbone.History({
|
Backbone.history = _.extend(new Backbone.History, {
|
||||||
location: location,
|
location: location,
|
||||||
history: {
|
history: {
|
||||||
pushState: function(state, title, url) {},
|
pushState: function(state, title, url) {},
|
||||||
replaceState: function(state, title, url) {
|
replaceState: function(state, title, url) {
|
||||||
strictEqual(url, 'http://example.com/root/fragment');
|
strictEqual(url, '/root/fragment');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -357,10 +463,10 @@ $(document).ready(function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Router: Normalize root.", 1, function() {
|
test("Normalize root.", 1, function() {
|
||||||
Backbone.history.stop();
|
Backbone.history.stop();
|
||||||
location.replace('http://example.com/root');
|
location.replace('http://example.com/root');
|
||||||
Backbone.history = new Backbone.History({location: location});
|
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||||
Backbone.history.loadUrl = function() { ok(true); };
|
Backbone.history.loadUrl = function() { ok(true); };
|
||||||
Backbone.history.start({
|
Backbone.history.start({
|
||||||
pushState: true,
|
pushState: true,
|
||||||
@@ -368,4 +474,337 @@ $(document).ready(function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
test("Normalize root - leading slash.", 1, function() {
|
||||||
|
Backbone.history.stop();
|
||||||
|
location.replace('http://example.com/root');
|
||||||
|
Backbone.history = _.extend(new Backbone.History, {
|
||||||
|
location: location,
|
||||||
|
history: {
|
||||||
|
pushState: function(){},
|
||||||
|
replaceState: function(){}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Backbone.history.start({root: 'root'});
|
||||||
|
strictEqual(Backbone.history.root, '/root/');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Transition from hashChange to pushState.", 1, function() {
|
||||||
|
Backbone.history.stop();
|
||||||
|
location.replace('http://example.com/root#x/y');
|
||||||
|
Backbone.history = _.extend(new Backbone.History, {
|
||||||
|
location: location,
|
||||||
|
history: {
|
||||||
|
pushState: function(){},
|
||||||
|
replaceState: function(state, title, url){
|
||||||
|
strictEqual(url, '/root/x/y');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Backbone.history.start({
|
||||||
|
root: 'root',
|
||||||
|
pushState: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("#1619: Router: Normalize empty root", 1, function() {
|
||||||
|
Backbone.history.stop();
|
||||||
|
location.replace('http://example.com/');
|
||||||
|
Backbone.history = _.extend(new Backbone.History, {
|
||||||
|
location: location,
|
||||||
|
history: {
|
||||||
|
pushState: function(){},
|
||||||
|
replaceState: function(){}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Backbone.history.start({root: ''});
|
||||||
|
strictEqual(Backbone.history.root, '/');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("#1619: Router: nagivate with empty root", 1, function() {
|
||||||
|
Backbone.history.stop();
|
||||||
|
location.replace('http://example.com/');
|
||||||
|
Backbone.history = _.extend(new Backbone.History, {
|
||||||
|
location: location,
|
||||||
|
history: {
|
||||||
|
pushState: function(state, title, url) {
|
||||||
|
strictEqual(url, '/fragment');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Backbone.history.start({
|
||||||
|
pushState: true,
|
||||||
|
root: '',
|
||||||
|
hashChange: false
|
||||||
|
});
|
||||||
|
Backbone.history.navigate('fragment');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Transition from pushState to hashChange.", 1, function() {
|
||||||
|
Backbone.history.stop();
|
||||||
|
location.replace('http://example.com/root/x/y?a=b');
|
||||||
|
location.replace = function(url) {
|
||||||
|
strictEqual(url, '/root/#x/y?a=b');
|
||||||
|
};
|
||||||
|
Backbone.history = _.extend(new Backbone.History, {
|
||||||
|
location: location,
|
||||||
|
history: {
|
||||||
|
pushState: null,
|
||||||
|
replaceState: null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Backbone.history.start({
|
||||||
|
root: 'root',
|
||||||
|
pushState: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("#1695 - hashChange to pushState with search.", 1, function() {
|
||||||
|
Backbone.history.stop();
|
||||||
|
location.replace('http://example.com/root#x/y?a=b');
|
||||||
|
Backbone.history = _.extend(new Backbone.History, {
|
||||||
|
location: location,
|
||||||
|
history: {
|
||||||
|
pushState: function(){},
|
||||||
|
replaceState: function(state, title, url){
|
||||||
|
strictEqual(url, '/root/x/y?a=b');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Backbone.history.start({
|
||||||
|
root: 'root',
|
||||||
|
pushState: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("#1746 - Router allows empty route.", 1, function() {
|
||||||
|
var Router = Backbone.Router.extend({
|
||||||
|
routes: {'': 'empty'},
|
||||||
|
empty: function(){},
|
||||||
|
route: function(route){
|
||||||
|
strictEqual(route, '');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
new Router;
|
||||||
|
});
|
||||||
|
|
||||||
|
test("#1794 - Trailing space in fragments.", 1, function() {
|
||||||
|
var history = new Backbone.History;
|
||||||
|
strictEqual(history.getFragment('fragment '), 'fragment');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("#1820 - Leading slash and trailing space.", 1, function() {
|
||||||
|
var history = new Backbone.History;
|
||||||
|
strictEqual(history.getFragment('/fragment '), 'fragment');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("#1980 - Optional parameters.", 2, function() {
|
||||||
|
location.replace('http://example.com#named/optional/y');
|
||||||
|
Backbone.history.checkUrl();
|
||||||
|
strictEqual(router.z, undefined);
|
||||||
|
location.replace('http://example.com#named/optional/y123');
|
||||||
|
Backbone.history.checkUrl();
|
||||||
|
strictEqual(router.z, '123');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("#2062 - Trigger 'route' event on router instance.", 2, function() {
|
||||||
|
router.on('route', function(name, args) {
|
||||||
|
strictEqual(name, 'routeEvent');
|
||||||
|
deepEqual(args, ['x', null]);
|
||||||
|
});
|
||||||
|
location.replace('http://example.com#route-event/x');
|
||||||
|
Backbone.history.checkUrl();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("#2255 - Extend routes by making routes a function.", 1, function() {
|
||||||
|
var RouterBase = Backbone.Router.extend({
|
||||||
|
routes: function() {
|
||||||
|
return {
|
||||||
|
home: "root",
|
||||||
|
index: "index.html"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var RouterExtended = RouterBase.extend({
|
||||||
|
routes: function() {
|
||||||
|
var _super = RouterExtended.__super__.routes;
|
||||||
|
return _.extend(_super(),
|
||||||
|
{ show: "show",
|
||||||
|
search: "search" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var router = new RouterExtended();
|
||||||
|
deepEqual({home: "root", index: "index.html", show: "show", search: "search"}, router.routes);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("#2538 - hashChange to pushState only if both requested.", 0, function() {
|
||||||
|
Backbone.history.stop();
|
||||||
|
location.replace('http://example.com/root?a=b#x/y');
|
||||||
|
Backbone.history = _.extend(new Backbone.History, {
|
||||||
|
location: location,
|
||||||
|
history: {
|
||||||
|
pushState: function(){},
|
||||||
|
replaceState: function(){ ok(false); }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Backbone.history.start({
|
||||||
|
root: 'root',
|
||||||
|
pushState: true,
|
||||||
|
hashChange: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('No hash fallback.', 0, function() {
|
||||||
|
Backbone.history.stop();
|
||||||
|
Backbone.history = _.extend(new Backbone.History, {
|
||||||
|
location: location,
|
||||||
|
history: {
|
||||||
|
pushState: function(){},
|
||||||
|
replaceState: function(){}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var Router = Backbone.Router.extend({
|
||||||
|
routes: {
|
||||||
|
hash: function() { ok(false); }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var router = new Router;
|
||||||
|
|
||||||
|
location.replace('http://example.com/');
|
||||||
|
Backbone.history.start({
|
||||||
|
pushState: true,
|
||||||
|
hashChange: false
|
||||||
|
});
|
||||||
|
location.replace('http://example.com/nomatch#hash');
|
||||||
|
Backbone.history.checkUrl();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('#2656 - No trailing slash on root.', 1, function() {
|
||||||
|
Backbone.history.stop();
|
||||||
|
Backbone.history = _.extend(new Backbone.History, {
|
||||||
|
location: location,
|
||||||
|
history: {
|
||||||
|
pushState: function(state, title, url){
|
||||||
|
strictEqual(url, '/root');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
location.replace('http://example.com/root/path');
|
||||||
|
Backbone.history.start({pushState: true, hashChange: false, root: 'root'});
|
||||||
|
Backbone.history.navigate('');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('#2656 - No trailing slash on root.', 1, function() {
|
||||||
|
Backbone.history.stop();
|
||||||
|
Backbone.history = _.extend(new Backbone.History, {
|
||||||
|
location: location,
|
||||||
|
history: {
|
||||||
|
pushState: function(state, title, url) {
|
||||||
|
strictEqual(url, '/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
location.replace('http://example.com/path');
|
||||||
|
Backbone.history.start({pushState: true, hashChange: false});
|
||||||
|
Backbone.history.navigate('');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('#2765 - Fragment matching sans query/hash.', 2, function() {
|
||||||
|
Backbone.history.stop();
|
||||||
|
Backbone.history = _.extend(new Backbone.History, {
|
||||||
|
location: location,
|
||||||
|
history: {
|
||||||
|
pushState: function(state, title, url) {
|
||||||
|
strictEqual(url, '/path?query#hash');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var Router = Backbone.Router.extend({
|
||||||
|
routes: {
|
||||||
|
path: function() { ok(true); }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var router = new Router;
|
||||||
|
|
||||||
|
location.replace('http://example.com/');
|
||||||
|
Backbone.history.start({pushState: true, hashChange: false});
|
||||||
|
Backbone.history.navigate('path?query#hash', true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Do not decode the search params.', function() {
|
||||||
|
var Router = Backbone.Router.extend({
|
||||||
|
routes: {
|
||||||
|
path: function(params){
|
||||||
|
strictEqual(params, 'x=y%20z');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var router = new Router;
|
||||||
|
Backbone.history.navigate('path?x=y%20z', true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Navigate to a hash url.', function() {
|
||||||
|
Backbone.history.stop();
|
||||||
|
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||||
|
Backbone.history.start({pushState: true});
|
||||||
|
var Router = Backbone.Router.extend({
|
||||||
|
routes: {
|
||||||
|
path: function(params) {
|
||||||
|
strictEqual(params, 'x=y');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var router = new Router;
|
||||||
|
location.replace('http://example.com/path?x=y#hash');
|
||||||
|
Backbone.history.checkUrl();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('#navigate to a hash url.', function() {
|
||||||
|
Backbone.history.stop();
|
||||||
|
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||||
|
Backbone.history.start({pushState: true});
|
||||||
|
var Router = Backbone.Router.extend({
|
||||||
|
routes: {
|
||||||
|
path: function(params) {
|
||||||
|
strictEqual(params, 'x=y');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var router = new Router;
|
||||||
|
Backbone.history.navigate('path?x=y#hash', true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('unicode pathname', 1, function() {
|
||||||
|
location.replace('http://example.com/myyjä');
|
||||||
|
Backbone.history.stop();
|
||||||
|
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||||
|
var Router = Backbone.Router.extend({
|
||||||
|
routes: {
|
||||||
|
myyjä: function() {
|
||||||
|
ok(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
new Router;
|
||||||
|
Backbone.history.start({pushState: true});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('newline in route', 1, function() {
|
||||||
|
location.replace('http://example.com/stuff%0Anonsense?param=foo%0Abar');
|
||||||
|
Backbone.history.stop();
|
||||||
|
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||||
|
var Router = Backbone.Router.extend({
|
||||||
|
routes: {
|
||||||
|
'stuff\nnonsense': function() {
|
||||||
|
ok(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
new Router;
|
||||||
|
Backbone.history.start({pushState: true});
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
|
|||||||
192
vendor/backbone/test/sync.js
vendored
192
vendor/backbone/test/sync.js
vendored
@@ -1,7 +1,4 @@
|
|||||||
$(document).ready(function() {
|
(function() {
|
||||||
|
|
||||||
var ajax = Backbone.ajax;
|
|
||||||
var lastRequest = null;
|
|
||||||
|
|
||||||
var Library = Backbone.Collection.extend({
|
var Library = Backbone.Collection.extend({
|
||||||
url : function() { return '/library'; }
|
url : function() { return '/library'; }
|
||||||
@@ -17,129 +14,128 @@ $(document).ready(function() {
|
|||||||
module("Backbone.sync", {
|
module("Backbone.sync", {
|
||||||
|
|
||||||
setup : function() {
|
setup : function() {
|
||||||
library = new Library();
|
library = new Library;
|
||||||
Backbone.ajax = function(obj) {
|
|
||||||
lastRequest = obj;
|
|
||||||
};
|
|
||||||
library.create(attrs, {wait: false});
|
library.create(attrs, {wait: false});
|
||||||
},
|
},
|
||||||
|
|
||||||
teardown: function() {
|
teardown: function() {
|
||||||
Backbone.ajax = ajax;
|
Backbone.emulateHTTP = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sync: read", 4, function() {
|
test("read", 4, function() {
|
||||||
library.fetch();
|
library.fetch();
|
||||||
equal(lastRequest.url, '/library');
|
equal(this.ajaxSettings.url, '/library');
|
||||||
equal(lastRequest.type, 'GET');
|
equal(this.ajaxSettings.type, 'GET');
|
||||||
equal(lastRequest.dataType, 'json');
|
equal(this.ajaxSettings.dataType, 'json');
|
||||||
ok(_.isEmpty(lastRequest.data));
|
ok(_.isEmpty(this.ajaxSettings.data));
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sync: passing data", 3, function() {
|
test("passing data", 3, function() {
|
||||||
library.fetch({data: {a: 'a', one: 1}});
|
library.fetch({data: {a: 'a', one: 1}});
|
||||||
equal(lastRequest.url, '/library');
|
equal(this.ajaxSettings.url, '/library');
|
||||||
equal(lastRequest.data.a, 'a');
|
equal(this.ajaxSettings.data.a, 'a');
|
||||||
equal(lastRequest.data.one, 1);
|
equal(this.ajaxSettings.data.one, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sync: create", 6, function() {
|
test("create", 6, function() {
|
||||||
equal(lastRequest.url, '/library');
|
equal(this.ajaxSettings.url, '/library');
|
||||||
equal(lastRequest.type, 'POST');
|
equal(this.ajaxSettings.type, 'POST');
|
||||||
equal(lastRequest.dataType, 'json');
|
equal(this.ajaxSettings.dataType, 'json');
|
||||||
var data = JSON.parse(lastRequest.data);
|
var data = JSON.parse(this.ajaxSettings.data);
|
||||||
equal(data.title, 'The Tempest');
|
equal(data.title, 'The Tempest');
|
||||||
equal(data.author, 'Bill Shakespeare');
|
equal(data.author, 'Bill Shakespeare');
|
||||||
equal(data.length, 123);
|
equal(data.length, 123);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sync: update", 7, function() {
|
test("update", 7, function() {
|
||||||
library.first().save({id: '1-the-tempest', author: 'William Shakespeare'});
|
library.first().save({id: '1-the-tempest', author: 'William Shakespeare'});
|
||||||
equal(lastRequest.url, '/library/1-the-tempest');
|
equal(this.ajaxSettings.url, '/library/1-the-tempest');
|
||||||
equal(lastRequest.type, 'PUT');
|
equal(this.ajaxSettings.type, 'PUT');
|
||||||
equal(lastRequest.dataType, 'json');
|
equal(this.ajaxSettings.dataType, 'json');
|
||||||
var data = JSON.parse(lastRequest.data);
|
var data = JSON.parse(this.ajaxSettings.data);
|
||||||
equal(data.id, '1-the-tempest');
|
equal(data.id, '1-the-tempest');
|
||||||
equal(data.title, 'The Tempest');
|
equal(data.title, 'The Tempest');
|
||||||
equal(data.author, 'William Shakespeare');
|
equal(data.author, 'William Shakespeare');
|
||||||
equal(data.length, 123);
|
equal(data.length, 123);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sync: update with emulateHTTP and emulateJSON", 7, function() {
|
test("update with emulateHTTP and emulateJSON", 7, function() {
|
||||||
Backbone.emulateHTTP = Backbone.emulateJSON = true;
|
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
|
||||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
emulateHTTP: true,
|
||||||
equal(lastRequest.url, '/library/2-the-tempest');
|
emulateJSON: true
|
||||||
equal(lastRequest.type, 'POST');
|
});
|
||||||
equal(lastRequest.dataType, 'json');
|
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||||
equal(lastRequest.data._method, 'PUT');
|
equal(this.ajaxSettings.type, 'POST');
|
||||||
var data = JSON.parse(lastRequest.data.model);
|
equal(this.ajaxSettings.dataType, 'json');
|
||||||
|
equal(this.ajaxSettings.data._method, 'PUT');
|
||||||
|
var data = JSON.parse(this.ajaxSettings.data.model);
|
||||||
equal(data.id, '2-the-tempest');
|
equal(data.id, '2-the-tempest');
|
||||||
equal(data.author, 'Tim Shakespeare');
|
equal(data.author, 'Tim Shakespeare');
|
||||||
equal(data.length, 123);
|
equal(data.length, 123);
|
||||||
Backbone.emulateHTTP = Backbone.emulateJSON = false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sync: update with just emulateHTTP", 6, function() {
|
test("update with just emulateHTTP", 6, function() {
|
||||||
Backbone.emulateHTTP = true;
|
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
|
||||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
emulateHTTP: true
|
||||||
equal(lastRequest.url, '/library/2-the-tempest');
|
});
|
||||||
equal(lastRequest.type, 'POST');
|
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||||
equal(lastRequest.contentType, 'application/json');
|
equal(this.ajaxSettings.type, 'POST');
|
||||||
var data = JSON.parse(lastRequest.data);
|
equal(this.ajaxSettings.contentType, 'application/json');
|
||||||
|
var data = JSON.parse(this.ajaxSettings.data);
|
||||||
equal(data.id, '2-the-tempest');
|
equal(data.id, '2-the-tempest');
|
||||||
equal(data.author, 'Tim Shakespeare');
|
equal(data.author, 'Tim Shakespeare');
|
||||||
equal(data.length, 123);
|
equal(data.length, 123);
|
||||||
Backbone.emulateHTTP = false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sync: update with just emulateJSON", 6, function() {
|
test("update with just emulateJSON", 6, function() {
|
||||||
Backbone.emulateJSON = true;
|
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
|
||||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
emulateJSON: true
|
||||||
equal(lastRequest.url, '/library/2-the-tempest');
|
});
|
||||||
equal(lastRequest.type, 'PUT');
|
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||||
equal(lastRequest.contentType, 'application/x-www-form-urlencoded');
|
equal(this.ajaxSettings.type, 'PUT');
|
||||||
var data = JSON.parse(lastRequest.data.model);
|
equal(this.ajaxSettings.contentType, 'application/x-www-form-urlencoded');
|
||||||
|
var data = JSON.parse(this.ajaxSettings.data.model);
|
||||||
equal(data.id, '2-the-tempest');
|
equal(data.id, '2-the-tempest');
|
||||||
equal(data.author, 'Tim Shakespeare');
|
equal(data.author, 'Tim Shakespeare');
|
||||||
equal(data.length, 123);
|
equal(data.length, 123);
|
||||||
Backbone.emulateJSON = false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sync: read model", 3, function() {
|
test("read model", 3, function() {
|
||||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
||||||
library.first().fetch();
|
library.first().fetch();
|
||||||
equal(lastRequest.url, '/library/2-the-tempest');
|
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||||
equal(lastRequest.type, 'GET');
|
equal(this.ajaxSettings.type, 'GET');
|
||||||
ok(_.isEmpty(lastRequest.data));
|
ok(_.isEmpty(this.ajaxSettings.data));
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sync: destroy", 3, function() {
|
test("destroy", 3, function() {
|
||||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
||||||
library.first().destroy({wait: true});
|
library.first().destroy({wait: true});
|
||||||
equal(lastRequest.url, '/library/2-the-tempest');
|
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||||
equal(lastRequest.type, 'DELETE');
|
equal(this.ajaxSettings.type, 'DELETE');
|
||||||
equal(lastRequest.data, null);
|
equal(this.ajaxSettings.data, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sync: destroy with emulateHTTP", 3, function() {
|
test("destroy with emulateHTTP", 3, function() {
|
||||||
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
|
||||||
Backbone.emulateHTTP = Backbone.emulateJSON = true;
|
library.first().destroy({
|
||||||
library.first().destroy();
|
emulateHTTP: true,
|
||||||
equal(lastRequest.url, '/library/2-the-tempest');
|
emulateJSON: true
|
||||||
equal(lastRequest.type, 'POST');
|
});
|
||||||
equal(JSON.stringify(lastRequest.data), '{"_method":"DELETE"}');
|
equal(this.ajaxSettings.url, '/library/2-the-tempest');
|
||||||
Backbone.emulateHTTP = Backbone.emulateJSON = false;
|
equal(this.ajaxSettings.type, 'POST');
|
||||||
|
equal(JSON.stringify(this.ajaxSettings.data), '{"_method":"DELETE"}');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sync: urlError", 2, function() {
|
test("urlError", 2, function() {
|
||||||
var model = new Backbone.Model();
|
var model = new Backbone.Model();
|
||||||
raises(function() {
|
raises(function() {
|
||||||
model.fetch();
|
model.fetch();
|
||||||
});
|
});
|
||||||
model.fetch({url: '/one/two'});
|
model.fetch({url: '/one/two'});
|
||||||
equal(lastRequest.url, '/one/two');
|
equal(this.ajaxSettings.url, '/one/two');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("#1052 - `options` is optional.", 0, function() {
|
test("#1052 - `options` is optional.", 0, function() {
|
||||||
@@ -157,4 +153,58 @@ $(document).ready(function() {
|
|||||||
Backbone.sync('create', model);
|
Backbone.sync('create', model);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
test("Call provided error callback on error.", 1, function() {
|
||||||
|
var model = new Backbone.Model;
|
||||||
|
model.url = '/test';
|
||||||
|
Backbone.sync('read', model, {
|
||||||
|
error: function() { ok(true); }
|
||||||
|
});
|
||||||
|
this.ajaxSettings.error();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Use Backbone.emulateHTTP as default.', 2, function() {
|
||||||
|
var model = new Backbone.Model;
|
||||||
|
model.url = '/test';
|
||||||
|
|
||||||
|
Backbone.emulateHTTP = true;
|
||||||
|
model.sync('create', model);
|
||||||
|
strictEqual(this.ajaxSettings.emulateHTTP, true);
|
||||||
|
|
||||||
|
Backbone.emulateHTTP = false;
|
||||||
|
model.sync('create', model);
|
||||||
|
strictEqual(this.ajaxSettings.emulateHTTP, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Use Backbone.emulateJSON as default.', 2, function() {
|
||||||
|
var model = new Backbone.Model;
|
||||||
|
model.url = '/test';
|
||||||
|
|
||||||
|
Backbone.emulateJSON = true;
|
||||||
|
model.sync('create', model);
|
||||||
|
strictEqual(this.ajaxSettings.emulateJSON, true);
|
||||||
|
|
||||||
|
Backbone.emulateJSON = false;
|
||||||
|
model.sync('create', model);
|
||||||
|
strictEqual(this.ajaxSettings.emulateJSON, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("#1756 - Call user provided beforeSend function.", 4, function() {
|
||||||
|
Backbone.emulateHTTP = true;
|
||||||
|
var model = new Backbone.Model;
|
||||||
|
model.url = '/test';
|
||||||
|
var xhr = {
|
||||||
|
setRequestHeader: function(header, value) {
|
||||||
|
strictEqual(header, 'X-HTTP-Method-Override');
|
||||||
|
strictEqual(value, 'DELETE');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
model.sync('delete', model, {
|
||||||
|
beforeSend: function(_xhr) {
|
||||||
|
ok(_xhr === xhr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
strictEqual(this.ajaxSettings.beforeSend(xhr), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
|
|||||||
9266
vendor/backbone/test/vendor/jquery-1.7.1.js
vendored
9266
vendor/backbone/test/vendor/jquery-1.7.1.js
vendored
File diff suppressed because it is too large
Load Diff
649
vendor/backbone/test/vendor/jslitmus.js
vendored
649
vendor/backbone/test/vendor/jslitmus.js
vendored
@@ -1,649 +0,0 @@
|
|||||||
// JSLitmus.js
|
|
||||||
//
|
|
||||||
// Copyright (c) 2010, Robert Kieffer, http://broofa.com
|
|
||||||
// Available under MIT license (http://en.wikipedia.org/wiki/MIT_License)
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
// Private methods and state
|
|
||||||
|
|
||||||
// Get platform info but don't go crazy trying to recognize everything
|
|
||||||
// that's out there. This is just for the major platforms and OSes.
|
|
||||||
var platform = 'unknown platform', ua = navigator.userAgent;
|
|
||||||
|
|
||||||
// Detect OS
|
|
||||||
var oses = ['Windows','iPhone OS','(Intel |PPC )?Mac OS X','Linux'].join('|');
|
|
||||||
var pOS = new RegExp('((' + oses + ') [^ \);]*)').test(ua) ? RegExp.$1 : null;
|
|
||||||
if (!pOS) pOS = new RegExp('((' + oses + ')[^ \);]*)').test(ua) ? RegExp.$1 : null;
|
|
||||||
|
|
||||||
// Detect browser
|
|
||||||
var pName = /(Chrome|MSIE|Safari|Opera|Firefox)/.test(ua) ? RegExp.$1 : null;
|
|
||||||
|
|
||||||
// Detect version
|
|
||||||
var vre = new RegExp('(Version|' + pName + ')[ \/]([^ ;]*)');
|
|
||||||
var pVersion = (pName && vre.test(ua)) ? RegExp.$2 : null;
|
|
||||||
var platform = (pOS && pName && pVersion) ? pName + ' ' + pVersion + ' on ' + pOS : 'unknown platform';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A smattering of methods that are needed to implement the JSLitmus testbed.
|
|
||||||
*/
|
|
||||||
var jsl = {
|
|
||||||
/**
|
|
||||||
* Enhanced version of escape()
|
|
||||||
*/
|
|
||||||
escape: function(s) {
|
|
||||||
s = s.replace(/,/g, '\\,');
|
|
||||||
s = escape(s);
|
|
||||||
s = s.replace(/\+/g, '%2b');
|
|
||||||
s = s.replace(/ /g, '+');
|
|
||||||
return s;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an element by ID.
|
|
||||||
*/
|
|
||||||
$: function(id) {
|
|
||||||
return document.getElementById(id);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Null function
|
|
||||||
*/
|
|
||||||
F: function() {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the status shown in the UI
|
|
||||||
*/
|
|
||||||
status: function(msg) {
|
|
||||||
var el = jsl.$('jsl_status');
|
|
||||||
if (el) el.innerHTML = msg || '';
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a number to an abbreviated string like, "15K" or "10M"
|
|
||||||
*/
|
|
||||||
toLabel: function(n) {
|
|
||||||
if (n == Infinity) {
|
|
||||||
return 'Infinity';
|
|
||||||
} else if (n > 1e9) {
|
|
||||||
n = Math.round(n/1e8);
|
|
||||||
return n/10 + 'B';
|
|
||||||
} else if (n > 1e6) {
|
|
||||||
n = Math.round(n/1e5);
|
|
||||||
return n/10 + 'M';
|
|
||||||
} else if (n > 1e3) {
|
|
||||||
n = Math.round(n/1e2);
|
|
||||||
return n/10 + 'K';
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy properties from src to dst
|
|
||||||
*/
|
|
||||||
extend: function(dst, src) {
|
|
||||||
for (var k in src) dst[k] = src[k]; return dst;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Like Array.join(), but for the key-value pairs in an object
|
|
||||||
*/
|
|
||||||
join: function(o, delimit1, delimit2) {
|
|
||||||
if (o.join) return o.join(delimit1); // If it's an array
|
|
||||||
var pairs = [];
|
|
||||||
for (var k in o) pairs.push(k + delimit1 + o[k]);
|
|
||||||
return pairs.join(delimit2);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Array#indexOf isn't supported in IE, so we use this as a cross-browser solution
|
|
||||||
*/
|
|
||||||
indexOf: function(arr, o) {
|
|
||||||
if (arr.indexOf) return arr.indexOf(o);
|
|
||||||
for (var i = 0; i < this.length; i++) if (arr[i] === o) return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test manages a single test (created with
|
|
||||||
* JSLitmus.test())
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
var Test = function (name, f) {
|
|
||||||
if (!f) throw new Error('Undefined test function');
|
|
||||||
if (!/function[^\(]*\(([^,\)]*)/.test(f.toString())) {
|
|
||||||
throw new Error('"' + name + '" test: Test is not a valid Function object');
|
|
||||||
}
|
|
||||||
this.loopArg = RegExp.$1;
|
|
||||||
this.name = name;
|
|
||||||
this.f = f;
|
|
||||||
};
|
|
||||||
|
|
||||||
jsl.extend(Test, /** @lends Test */ {
|
|
||||||
/** Calibration tests for establishing iteration loop overhead */
|
|
||||||
CALIBRATIONS: [
|
|
||||||
new Test('calibrating loop', function(count) {while (count--);}),
|
|
||||||
new Test('calibrating function', jsl.F)
|
|
||||||
],
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run calibration tests. Returns true if calibrations are not yet
|
|
||||||
* complete (in which case calling code should run the tests yet again).
|
|
||||||
* onCalibrated - Callback to invoke when calibrations have finished
|
|
||||||
*/
|
|
||||||
calibrate: function(onCalibrated) {
|
|
||||||
for (var i = 0; i < Test.CALIBRATIONS.length; i++) {
|
|
||||||
var cal = Test.CALIBRATIONS[i];
|
|
||||||
if (cal.running) return true;
|
|
||||||
if (!cal.count) {
|
|
||||||
cal.isCalibration = true;
|
|
||||||
cal.onStop = onCalibrated;
|
|
||||||
//cal.MIN_TIME = .1; // Do calibrations quickly
|
|
||||||
cal.run(2e4);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
jsl.extend(Test.prototype, {/** @lends Test.prototype */
|
|
||||||
/** Initial number of iterations */
|
|
||||||
INIT_COUNT: 10,
|
|
||||||
/** Max iterations allowed (i.e. used to detect bad looping functions) */
|
|
||||||
MAX_COUNT: 1e9,
|
|
||||||
/** Minimum time a test should take to get valid results (secs) */
|
|
||||||
MIN_TIME: .5,
|
|
||||||
|
|
||||||
/** Callback invoked when test state changes */
|
|
||||||
onChange: jsl.F,
|
|
||||||
|
|
||||||
/** Callback invoked when test is finished */
|
|
||||||
onStop: jsl.F,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset test state
|
|
||||||
*/
|
|
||||||
reset: function() {
|
|
||||||
delete this.count;
|
|
||||||
delete this.time;
|
|
||||||
delete this.running;
|
|
||||||
delete this.error;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the test (in a timeout). We use a timeout to make sure the browser
|
|
||||||
* has a chance to finish rendering any UI changes we've made, like
|
|
||||||
* updating the status message.
|
|
||||||
*/
|
|
||||||
run: function(count) {
|
|
||||||
count = count || this.INIT_COUNT;
|
|
||||||
jsl.status(this.name + ' x ' + count);
|
|
||||||
this.running = true;
|
|
||||||
var me = this;
|
|
||||||
setTimeout(function() {me._run(count);}, 200);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The nuts and bolts code that actually runs a test
|
|
||||||
*/
|
|
||||||
_run: function(count) {
|
|
||||||
var me = this;
|
|
||||||
|
|
||||||
// Make sure calibration tests have run
|
|
||||||
if (!me.isCalibration && Test.calibrate(function() {me.run(count);})) return;
|
|
||||||
this.error = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
var start, f = this.f, now, i = count;
|
|
||||||
|
|
||||||
// Start the timer
|
|
||||||
start = new Date();
|
|
||||||
|
|
||||||
// Now for the money shot. If this is a looping function ...
|
|
||||||
if (this.loopArg) {
|
|
||||||
// ... let it do the iteration itself
|
|
||||||
f(count);
|
|
||||||
} else {
|
|
||||||
// ... otherwise do the iteration for it
|
|
||||||
while (i--) f();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get time test took (in secs)
|
|
||||||
this.time = Math.max(1,new Date() - start)/1000;
|
|
||||||
|
|
||||||
// Store iteration count and per-operation time taken
|
|
||||||
this.count = count;
|
|
||||||
this.period = this.time/count;
|
|
||||||
|
|
||||||
// Do we need to do another run?
|
|
||||||
this.running = this.time <= this.MIN_TIME;
|
|
||||||
|
|
||||||
// ... if so, compute how many times we should iterate
|
|
||||||
if (this.running) {
|
|
||||||
// Bump the count to the nearest power of 2
|
|
||||||
var x = this.MIN_TIME/this.time;
|
|
||||||
var pow = Math.pow(2, Math.max(1, Math.ceil(Math.log(x)/Math.log(2))));
|
|
||||||
count *= pow;
|
|
||||||
if (count > this.MAX_COUNT) {
|
|
||||||
throw new Error('Max count exceeded. If this test uses a looping function, make sure the iteration loop is working properly.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// Exceptions are caught and displayed in the test UI
|
|
||||||
this.reset();
|
|
||||||
this.error = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Figure out what to do next
|
|
||||||
if (this.running) {
|
|
||||||
me.run(count);
|
|
||||||
} else {
|
|
||||||
jsl.status('');
|
|
||||||
me.onStop(me);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finish up
|
|
||||||
this.onChange(this);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of operations per second for this test.
|
|
||||||
*
|
|
||||||
* @param normalize if true, iteration loop overhead taken into account
|
|
||||||
*/
|
|
||||||
getHz: function(/**Boolean*/ normalize) {
|
|
||||||
var p = this.period;
|
|
||||||
|
|
||||||
// Adjust period based on the calibration test time
|
|
||||||
if (normalize && !this.isCalibration) {
|
|
||||||
var cal = Test.CALIBRATIONS[this.loopArg ? 0 : 1];
|
|
||||||
|
|
||||||
// If the period is within 20% of the calibration time, then zero the
|
|
||||||
// it out
|
|
||||||
p = p < cal.period*1.2 ? 0 : p - cal.period;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Math.round(1/p);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a friendly string describing the test
|
|
||||||
*/
|
|
||||||
toString: function() {
|
|
||||||
return this.name + ' - ' + this.time/this.count + ' secs';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// CSS we need for the UI
|
|
||||||
var STYLESHEET = '<style> \
|
|
||||||
#jslitmus {font-family:sans-serif; font-size: 12px;} \
|
|
||||||
#jslitmus a {text-decoration: none;} \
|
|
||||||
#jslitmus a:hover {text-decoration: underline;} \
|
|
||||||
#jsl_status { \
|
|
||||||
margin-top: 10px; \
|
|
||||||
font-size: 10px; \
|
|
||||||
color: #888; \
|
|
||||||
} \
|
|
||||||
A IMG {border:none} \
|
|
||||||
#test_results { \
|
|
||||||
margin-top: 10px; \
|
|
||||||
font-size: 12px; \
|
|
||||||
font-family: sans-serif; \
|
|
||||||
border-collapse: collapse; \
|
|
||||||
border-spacing: 0px; \
|
|
||||||
} \
|
|
||||||
#test_results th, #test_results td { \
|
|
||||||
border: solid 1px #ccc; \
|
|
||||||
vertical-align: top; \
|
|
||||||
padding: 3px; \
|
|
||||||
} \
|
|
||||||
#test_results th { \
|
|
||||||
vertical-align: bottom; \
|
|
||||||
background-color: #ccc; \
|
|
||||||
padding: 1px; \
|
|
||||||
font-size: 10px; \
|
|
||||||
} \
|
|
||||||
#test_results #test_platform { \
|
|
||||||
color: #444; \
|
|
||||||
text-align:center; \
|
|
||||||
} \
|
|
||||||
#test_results .test_row { \
|
|
||||||
color: #006; \
|
|
||||||
cursor: pointer; \
|
|
||||||
} \
|
|
||||||
#test_results .test_nonlooping { \
|
|
||||||
border-left-style: dotted; \
|
|
||||||
border-left-width: 2px; \
|
|
||||||
} \
|
|
||||||
#test_results .test_looping { \
|
|
||||||
border-left-style: solid; \
|
|
||||||
border-left-width: 2px; \
|
|
||||||
} \
|
|
||||||
#test_results .test_name {white-space: nowrap;} \
|
|
||||||
#test_results .test_pending { \
|
|
||||||
} \
|
|
||||||
#test_results .test_running { \
|
|
||||||
font-style: italic; \
|
|
||||||
} \
|
|
||||||
#test_results .test_done {} \
|
|
||||||
#test_results .test_done { \
|
|
||||||
text-align: right; \
|
|
||||||
font-family: monospace; \
|
|
||||||
} \
|
|
||||||
#test_results .test_error {color: #600;} \
|
|
||||||
#test_results .test_error .error_head {font-weight:bold;} \
|
|
||||||
#test_results .test_error .error_body {font-size:85%;} \
|
|
||||||
#test_results .test_row:hover td { \
|
|
||||||
background-color: #ffc; \
|
|
||||||
text-decoration: underline; \
|
|
||||||
} \
|
|
||||||
#chart { \
|
|
||||||
margin: 10px 0px; \
|
|
||||||
width: 250px; \
|
|
||||||
} \
|
|
||||||
#chart img { \
|
|
||||||
border: solid 1px #ccc; \
|
|
||||||
margin-bottom: 5px; \
|
|
||||||
} \
|
|
||||||
#chart #tiny_url { \
|
|
||||||
height: 40px; \
|
|
||||||
width: 250px; \
|
|
||||||
} \
|
|
||||||
#jslitmus_credit { \
|
|
||||||
font-size: 10px; \
|
|
||||||
color: #888; \
|
|
||||||
margin-top: 8px; \
|
|
||||||
} \
|
|
||||||
</style>';
|
|
||||||
|
|
||||||
// HTML markup for the UI
|
|
||||||
var MARKUP = '<div id="jslitmus"> \
|
|
||||||
<button onclick="JSLitmus.runAll(event)">Run Tests</button> \
|
|
||||||
<button id="stop_button" disabled="disabled" onclick="JSLitmus.stop()">Stop Tests</button> \
|
|
||||||
<br \> \
|
|
||||||
<br \> \
|
|
||||||
<input type="checkbox" style="vertical-align: middle" id="test_normalize" checked="checked" onchange="JSLitmus.renderAll()""> Normalize results \
|
|
||||||
<table id="test_results"> \
|
|
||||||
<colgroup> \
|
|
||||||
<col /> \
|
|
||||||
<col width="100" /> \
|
|
||||||
</colgroup> \
|
|
||||||
<tr><th id="test_platform" colspan="2">' + platform + '</th></tr> \
|
|
||||||
<tr><th>Test</th><th>Ops/sec</th></tr> \
|
|
||||||
<tr id="test_row_template" class="test_row" style="display:none"> \
|
|
||||||
<td class="test_name"></td> \
|
|
||||||
<td class="test_result">Ready</td> \
|
|
||||||
</tr> \
|
|
||||||
</table> \
|
|
||||||
<div id="jsl_status"></div> \
|
|
||||||
<div id="chart" style="display:none"> \
|
|
||||||
<a id="chart_link" target="_blank"><img id="chart_image"></a> \
|
|
||||||
TinyURL (for chart): \
|
|
||||||
<iframe id="tiny_url" frameBorder="0" scrolling="no" src=""></iframe> \
|
|
||||||
</div> \
|
|
||||||
<a id="jslitmus_credit" title="JSLitmus home page" href="http://code.google.com/p/jslitmus" target="_blank">Powered by JSLitmus</a> \
|
|
||||||
</div>';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The public API for creating and running tests
|
|
||||||
*/
|
|
||||||
window.JSLitmus = {
|
|
||||||
/** The list of all tests that have been registered with JSLitmus.test */
|
|
||||||
_tests: [],
|
|
||||||
/** The queue of tests that need to be run */
|
|
||||||
_queue: [],
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The parsed query parameters the current page URL. This is provided as a
|
|
||||||
* convenience for test functions - it's not used by JSLitmus proper
|
|
||||||
*/
|
|
||||||
params: {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize
|
|
||||||
*/
|
|
||||||
_init: function() {
|
|
||||||
// Parse query params into JSLitmus.params[] hash
|
|
||||||
var match = (location + '').match(/([^?#]*)(#.*)?$/);
|
|
||||||
if (match) {
|
|
||||||
var pairs = match[1].split('&');
|
|
||||||
for (var i = 0; i < pairs.length; i++) {
|
|
||||||
var pair = pairs[i].split('=');
|
|
||||||
if (pair.length > 1) {
|
|
||||||
var key = pair.shift();
|
|
||||||
var value = pair.length > 1 ? pair.join('=') : pair[0];
|
|
||||||
this.params[key] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write out the stylesheet. We have to do this here because IE
|
|
||||||
// doesn't honor sheets written after the document has loaded.
|
|
||||||
document.write(STYLESHEET);
|
|
||||||
|
|
||||||
// Setup the rest of the UI once the document is loaded
|
|
||||||
if (window.addEventListener) {
|
|
||||||
window.addEventListener('load', this._setup, false);
|
|
||||||
} else if (document.addEventListener) {
|
|
||||||
document.addEventListener('load', this._setup, false);
|
|
||||||
} else if (window.attachEvent) {
|
|
||||||
window.attachEvent('onload', this._setup);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set up the UI
|
|
||||||
*/
|
|
||||||
_setup: function() {
|
|
||||||
var el = jsl.$('jslitmus_container');
|
|
||||||
if (!el) document.body.appendChild(el = document.createElement('div'));
|
|
||||||
|
|
||||||
el.innerHTML = MARKUP;
|
|
||||||
|
|
||||||
// Render the UI for all our tests
|
|
||||||
for (var i=0; i < JSLitmus._tests.length; i++)
|
|
||||||
JSLitmus.renderTest(JSLitmus._tests[i]);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* (Re)render all the test results
|
|
||||||
*/
|
|
||||||
renderAll: function() {
|
|
||||||
for (var i = 0; i < JSLitmus._tests.length; i++)
|
|
||||||
JSLitmus.renderTest(JSLitmus._tests[i]);
|
|
||||||
JSLitmus.renderChart();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* (Re)render the chart graphics
|
|
||||||
*/
|
|
||||||
renderChart: function() {
|
|
||||||
var url = JSLitmus.chartUrl();
|
|
||||||
jsl.$('chart_link').href = url;
|
|
||||||
jsl.$('chart_image').src = url;
|
|
||||||
jsl.$('chart').style.display = '';
|
|
||||||
|
|
||||||
// Update the tiny URL
|
|
||||||
jsl.$('tiny_url').src = 'http://tinyurl.com/api-create.php?url='+escape(url);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* (Re)render the results for a specific test
|
|
||||||
*/
|
|
||||||
renderTest: function(test) {
|
|
||||||
// Make a new row if needed
|
|
||||||
if (!test._row) {
|
|
||||||
var trow = jsl.$('test_row_template');
|
|
||||||
if (!trow) return;
|
|
||||||
|
|
||||||
test._row = trow.cloneNode(true);
|
|
||||||
test._row.style.display = '';
|
|
||||||
test._row.id = '';
|
|
||||||
test._row.onclick = function() {JSLitmus._queueTest(test);};
|
|
||||||
test._row.title = 'Run ' + test.name + ' test';
|
|
||||||
trow.parentNode.appendChild(test._row);
|
|
||||||
test._row.cells[0].innerHTML = test.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
var cell = test._row.cells[1];
|
|
||||||
var cns = [test.loopArg ? 'test_looping' : 'test_nonlooping'];
|
|
||||||
|
|
||||||
if (test.error) {
|
|
||||||
cns.push('test_error');
|
|
||||||
cell.innerHTML =
|
|
||||||
'<div class="error_head">' + test.error + '</div>' +
|
|
||||||
'<ul class="error_body"><li>' +
|
|
||||||
jsl.join(test.error, ': ', '</li><li>') +
|
|
||||||
'</li></ul>';
|
|
||||||
} else {
|
|
||||||
if (test.running) {
|
|
||||||
cns.push('test_running');
|
|
||||||
cell.innerHTML = 'running';
|
|
||||||
} else if (jsl.indexOf(JSLitmus._queue, test) >= 0) {
|
|
||||||
cns.push('test_pending');
|
|
||||||
cell.innerHTML = 'pending';
|
|
||||||
} else if (test.count) {
|
|
||||||
cns.push('test_done');
|
|
||||||
var hz = test.getHz(jsl.$('test_normalize').checked);
|
|
||||||
cell.innerHTML = hz != Infinity ? hz : '∞';
|
|
||||||
cell.title = 'Looped ' + test.count + ' times in ' + test.time + ' seconds';
|
|
||||||
} else {
|
|
||||||
cell.innerHTML = 'ready';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cell.className = cns.join(' ');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new test
|
|
||||||
*/
|
|
||||||
test: function(name, f) {
|
|
||||||
// Create the Test object
|
|
||||||
var test = new Test(name, f);
|
|
||||||
JSLitmus._tests.push(test);
|
|
||||||
|
|
||||||
// Re-render if the test state changes
|
|
||||||
test.onChange = JSLitmus.renderTest;
|
|
||||||
|
|
||||||
// Run the next test if this one finished
|
|
||||||
test.onStop = function(test) {
|
|
||||||
if (JSLitmus.onTestFinish) JSLitmus.onTestFinish(test);
|
|
||||||
JSLitmus.currentTest = null;
|
|
||||||
JSLitmus._nextTest();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Render the new test
|
|
||||||
this.renderTest(test);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add all tests to the run queue
|
|
||||||
*/
|
|
||||||
runAll: function(e) {
|
|
||||||
e = e || window.event;
|
|
||||||
var reverse = e && e.shiftKey, len = JSLitmus._tests.length;
|
|
||||||
for (var i = 0; i < len; i++) {
|
|
||||||
JSLitmus._queueTest(JSLitmus._tests[!reverse ? i : (len - i - 1)]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove all tests from the run queue. The current test has to finish on
|
|
||||||
* it's own though
|
|
||||||
*/
|
|
||||||
stop: function() {
|
|
||||||
while (JSLitmus._queue.length) {
|
|
||||||
var test = JSLitmus._queue.shift();
|
|
||||||
JSLitmus.renderTest(test);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the next test in the run queue
|
|
||||||
*/
|
|
||||||
_nextTest: function() {
|
|
||||||
if (!JSLitmus.currentTest) {
|
|
||||||
var test = JSLitmus._queue.shift();
|
|
||||||
if (test) {
|
|
||||||
jsl.$('stop_button').disabled = false;
|
|
||||||
JSLitmus.currentTest = test;
|
|
||||||
test.run();
|
|
||||||
JSLitmus.renderTest(test);
|
|
||||||
if (JSLitmus.onTestStart) JSLitmus.onTestStart(test);
|
|
||||||
} else {
|
|
||||||
jsl.$('stop_button').disabled = true;
|
|
||||||
JSLitmus.renderChart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a test to the run queue
|
|
||||||
*/
|
|
||||||
_queueTest: function(test) {
|
|
||||||
if (jsl.indexOf(JSLitmus._queue, test) >= 0) return;
|
|
||||||
JSLitmus._queue.push(test);
|
|
||||||
JSLitmus.renderTest(test);
|
|
||||||
JSLitmus._nextTest();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a Google Chart URL that shows the data for all tests
|
|
||||||
*/
|
|
||||||
chartUrl: function() {
|
|
||||||
var n = JSLitmus._tests.length, markers = [], data = [];
|
|
||||||
var d, min = 0, max = -1e10;
|
|
||||||
var normalize = jsl.$('test_normalize').checked;
|
|
||||||
|
|
||||||
// Gather test data
|
|
||||||
for (var i=0; i < JSLitmus._tests.length; i++) {
|
|
||||||
var test = JSLitmus._tests[i];
|
|
||||||
if (test.count) {
|
|
||||||
var hz = test.getHz(normalize);
|
|
||||||
var v = hz != Infinity ? hz : 0;
|
|
||||||
data.push(v);
|
|
||||||
markers.push('t' + jsl.escape(test.name + '(' + jsl.toLabel(hz)+ ')') + ',000000,0,' +
|
|
||||||
markers.length + ',10');
|
|
||||||
max = Math.max(v, max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (markers.length <= 0) return null;
|
|
||||||
|
|
||||||
// Build chart title
|
|
||||||
var title = document.getElementsByTagName('title');
|
|
||||||
title = (title && title.length) ? title[0].innerHTML : null;
|
|
||||||
var chart_title = [];
|
|
||||||
if (title) chart_title.push(title);
|
|
||||||
chart_title.push('Ops/sec (' + platform + ')');
|
|
||||||
|
|
||||||
// Build labels
|
|
||||||
var labels = [jsl.toLabel(min), jsl.toLabel(max)];
|
|
||||||
|
|
||||||
var w = 250, bw = 15;
|
|
||||||
var bs = 5;
|
|
||||||
var h = markers.length*(bw + bs) + 30 + chart_title.length*20;
|
|
||||||
|
|
||||||
var params = {
|
|
||||||
chtt: escape(chart_title.join('|')),
|
|
||||||
chts: '000000,10',
|
|
||||||
cht: 'bhg', // chart type
|
|
||||||
chd: 't:' + data.join(','), // data set
|
|
||||||
chds: min + ',' + max, // max/min of data
|
|
||||||
chxt: 'x', // label axes
|
|
||||||
chxl: '0:|' + labels.join('|'), // labels
|
|
||||||
chsp: '0,1',
|
|
||||||
chm: markers.join('|'), // test names
|
|
||||||
chbh: [bw, 0, bs].join(','), // bar widths
|
|
||||||
// chf: 'bg,lg,0,eeeeee,0,eeeeee,.5,ffffff,1', // gradient
|
|
||||||
chs: w + 'x' + h
|
|
||||||
};
|
|
||||||
return 'http://chart.apis.google.com/chart?' + jsl.join(params, '=', '&');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
JSLitmus._init();
|
|
||||||
})();
|
|
||||||
236
vendor/backbone/test/vendor/qunit.css
vendored
236
vendor/backbone/test/vendor/qunit.css
vendored
@@ -1,236 +0,0 @@
|
|||||||
/**
|
|
||||||
* QUnit v1.8.0 - A JavaScript Unit Testing Framework
|
|
||||||
*
|
|
||||||
* http://docs.jquery.com/QUnit
|
|
||||||
*
|
|
||||||
* Copyright (c) 2012 John Resig, Jörn Zaefferer
|
|
||||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
|
||||||
* or GPL (GPL-LICENSE.txt) licenses.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Font Family and Sizes */
|
|
||||||
|
|
||||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
|
|
||||||
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
|
|
||||||
#qunit-tests { font-size: smaller; }
|
|
||||||
|
|
||||||
|
|
||||||
/** Resets */
|
|
||||||
|
|
||||||
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Header */
|
|
||||||
|
|
||||||
#qunit-header {
|
|
||||||
padding: 0.5em 0 0.5em 1em;
|
|
||||||
|
|
||||||
color: #8699a4;
|
|
||||||
background-color: #0d3349;
|
|
||||||
|
|
||||||
font-size: 1.5em;
|
|
||||||
line-height: 1em;
|
|
||||||
font-weight: normal;
|
|
||||||
|
|
||||||
border-radius: 15px 15px 0 0;
|
|
||||||
-moz-border-radius: 15px 15px 0 0;
|
|
||||||
-webkit-border-top-right-radius: 15px;
|
|
||||||
-webkit-border-top-left-radius: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-header a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: #c2ccd1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-header a:hover,
|
|
||||||
#qunit-header a:focus {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-header label {
|
|
||||||
display: inline-block;
|
|
||||||
padding-left: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-banner {
|
|
||||||
height: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-testrunner-toolbar {
|
|
||||||
padding: 0.5em 0 0.5em 2em;
|
|
||||||
color: #5E740B;
|
|
||||||
background-color: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-userAgent {
|
|
||||||
padding: 0.5em 0 0.5em 2.5em;
|
|
||||||
background-color: #2b81af;
|
|
||||||
color: #fff;
|
|
||||||
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Tests: Pass/Fail */
|
|
||||||
|
|
||||||
#qunit-tests {
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li {
|
|
||||||
padding: 0.4em 0.5em 0.4em 2.5em;
|
|
||||||
border-bottom: 1px solid #fff;
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li strong {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li a {
|
|
||||||
padding: 0.5em;
|
|
||||||
color: #c2ccd1;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
#qunit-tests li a:hover,
|
|
||||||
#qunit-tests li a:focus {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests ol {
|
|
||||||
margin-top: 0.5em;
|
|
||||||
padding: 0.5em;
|
|
||||||
|
|
||||||
background-color: #fff;
|
|
||||||
|
|
||||||
border-radius: 15px;
|
|
||||||
-moz-border-radius: 15px;
|
|
||||||
-webkit-border-radius: 15px;
|
|
||||||
|
|
||||||
box-shadow: inset 0px 2px 13px #999;
|
|
||||||
-moz-box-shadow: inset 0px 2px 13px #999;
|
|
||||||
-webkit-box-shadow: inset 0px 2px 13px #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
margin-top: .2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests th {
|
|
||||||
text-align: right;
|
|
||||||
vertical-align: top;
|
|
||||||
padding: 0 .5em 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests td {
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests pre {
|
|
||||||
margin: 0;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests del {
|
|
||||||
background-color: #e0f2be;
|
|
||||||
color: #374e0c;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests ins {
|
|
||||||
background-color: #ffcaca;
|
|
||||||
color: #500;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Test Counts */
|
|
||||||
|
|
||||||
#qunit-tests b.counts { color: black; }
|
|
||||||
#qunit-tests b.passed { color: #5E740B; }
|
|
||||||
#qunit-tests b.failed { color: #710909; }
|
|
||||||
|
|
||||||
#qunit-tests li li {
|
|
||||||
margin: 0.5em;
|
|
||||||
padding: 0.4em 0.5em 0.4em 0.5em;
|
|
||||||
background-color: #fff;
|
|
||||||
border-bottom: none;
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Passing Styles */
|
|
||||||
|
|
||||||
#qunit-tests li li.pass {
|
|
||||||
color: #5E740B;
|
|
||||||
background-color: #fff;
|
|
||||||
border-left: 26px solid #C6E746;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
|
|
||||||
#qunit-tests .pass .test-name { color: #366097; }
|
|
||||||
|
|
||||||
#qunit-tests .pass .test-actual,
|
|
||||||
#qunit-tests .pass .test-expected { color: #999999; }
|
|
||||||
|
|
||||||
#qunit-banner.qunit-pass { background-color: #C6E746; }
|
|
||||||
|
|
||||||
/*** Failing Styles */
|
|
||||||
|
|
||||||
#qunit-tests li li.fail {
|
|
||||||
color: #710909;
|
|
||||||
background-color: #fff;
|
|
||||||
border-left: 26px solid #EE5757;
|
|
||||||
white-space: pre;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests > li:last-child {
|
|
||||||
border-radius: 0 0 15px 15px;
|
|
||||||
-moz-border-radius: 0 0 15px 15px;
|
|
||||||
-webkit-border-bottom-right-radius: 15px;
|
|
||||||
-webkit-border-bottom-left-radius: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
|
|
||||||
#qunit-tests .fail .test-name,
|
|
||||||
#qunit-tests .fail .module-name { color: #000000; }
|
|
||||||
|
|
||||||
#qunit-tests .fail .test-actual { color: #EE5757; }
|
|
||||||
#qunit-tests .fail .test-expected { color: green; }
|
|
||||||
|
|
||||||
#qunit-banner.qunit-fail { background-color: #EE5757; }
|
|
||||||
|
|
||||||
|
|
||||||
/** Result */
|
|
||||||
|
|
||||||
#qunit-testresult {
|
|
||||||
padding: 0.5em 0.5em 0.5em 2.5em;
|
|
||||||
|
|
||||||
color: #2b81af;
|
|
||||||
background-color: #D2E0E6;
|
|
||||||
|
|
||||||
border-bottom: 1px solid white;
|
|
||||||
}
|
|
||||||
#qunit-testresult .module-name {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Fixture */
|
|
||||||
|
|
||||||
#qunit-fixture {
|
|
||||||
position: absolute;
|
|
||||||
top: -10000px;
|
|
||||||
left: -10000px;
|
|
||||||
width: 1000px;
|
|
||||||
height: 1000px;
|
|
||||||
}
|
|
||||||
1863
vendor/backbone/test/vendor/qunit.js
vendored
1863
vendor/backbone/test/vendor/qunit.js
vendored
File diff suppressed because it is too large
Load Diff
313
vendor/backbone/test/view.js
vendored
313
vendor/backbone/test/view.js
vendored
@@ -1,4 +1,4 @@
|
|||||||
$(document).ready(function() {
|
(function() {
|
||||||
|
|
||||||
var view;
|
var view;
|
||||||
|
|
||||||
@@ -7,135 +7,139 @@ $(document).ready(function() {
|
|||||||
setup: function() {
|
setup: function() {
|
||||||
view = new Backbone.View({
|
view = new Backbone.View({
|
||||||
id : 'test-view',
|
id : 'test-view',
|
||||||
className : 'test-view'
|
className : 'test-view',
|
||||||
|
other : 'non-special-option'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("View: constructor", 4, function() {
|
test("constructor", 3, function() {
|
||||||
equal(view.el.id, 'test-view');
|
equal(view.el.id, 'test-view');
|
||||||
equal(view.el.className, 'test-view');
|
equal(view.el.className, 'test-view');
|
||||||
equal(view.options.id, 'test-view');
|
equal(view.el.other, void 0);
|
||||||
equal(view.options.className, 'test-view');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("View: jQuery", 2, function() {
|
test("jQuery", 1, function() {
|
||||||
view.setElement(document.body);
|
var view = new Backbone.View;
|
||||||
ok(view.$('#qunit-header a').get(0).innerHTML.match(/Backbone Test Suite/));
|
view.setElement('<p><a><b>test</b></a></p>');
|
||||||
ok(view.$('#qunit-header a').get(1).innerHTML.match(/Backbone Speed Suite/));
|
strictEqual(view.$('a b').html(), 'test');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("View: make", 3, function() {
|
test("initialize", 1, function() {
|
||||||
var div = view.make('div', {id: 'test-div'}, "one two three");
|
|
||||||
equal(div.tagName.toLowerCase(), 'div');
|
|
||||||
equal(div.id, 'test-div');
|
|
||||||
equal($(div).text(), 'one two three');
|
|
||||||
});
|
|
||||||
|
|
||||||
test("View: make can take falsy values for content", 2, function() {
|
|
||||||
var div = view.make('div', {id: 'test-div'}, 0);
|
|
||||||
equal($(div).text(), '0');
|
|
||||||
|
|
||||||
var div = view.make('div', {id: 'test-div'}, '');
|
|
||||||
equal($(div).text(), '');
|
|
||||||
});
|
|
||||||
|
|
||||||
test("View: initialize", 1, function() {
|
|
||||||
var View = Backbone.View.extend({
|
var View = Backbone.View.extend({
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
this.one = 1;
|
this.one = 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var view = new View;
|
|
||||||
equal(view.one, 1);
|
strictEqual(new View().one, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("View: delegateEvents", 6, function() {
|
test("delegateEvents", 6, function() {
|
||||||
var counter = 0;
|
var counter1 = 0, counter2 = 0;
|
||||||
var counter2 = 0;
|
|
||||||
view.setElement(document.body);
|
var view = new Backbone.View({el: '#testElement'});
|
||||||
view.increment = function(){ counter++; };
|
view.increment = function(){ counter1++; };
|
||||||
view.$el.bind('click', function(){ counter2++; });
|
view.$el.on('click', function(){ counter2++; });
|
||||||
var events = {"click #qunit-banner": "increment"};
|
|
||||||
|
var events = {'click h1': 'increment'};
|
||||||
|
|
||||||
view.delegateEvents(events);
|
view.delegateEvents(events);
|
||||||
$('#qunit-banner').trigger('click');
|
view.$('h1').trigger('click');
|
||||||
equal(counter, 1);
|
equal(counter1, 1);
|
||||||
equal(counter2, 1);
|
equal(counter2, 1);
|
||||||
$('#qunit-banner').trigger('click');
|
|
||||||
equal(counter, 2);
|
view.$('h1').trigger('click');
|
||||||
|
equal(counter1, 2);
|
||||||
equal(counter2, 2);
|
equal(counter2, 2);
|
||||||
|
|
||||||
view.delegateEvents(events);
|
view.delegateEvents(events);
|
||||||
$('#qunit-banner').trigger('click');
|
view.$('h1').trigger('click');
|
||||||
equal(counter, 3);
|
equal(counter1, 3);
|
||||||
equal(counter2, 3);
|
equal(counter2, 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("View: delegateEvents allows functions for callbacks", 3, function() {
|
test("delegateEvents allows functions for callbacks", 3, function() {
|
||||||
|
var view = new Backbone.View({el: '<p></p>'});
|
||||||
view.counter = 0;
|
view.counter = 0;
|
||||||
view.setElement("#qunit-banner");
|
|
||||||
var events = {"click": function() { this.counter++; }};
|
var events = {
|
||||||
|
click: function() {
|
||||||
|
this.counter++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
view.delegateEvents(events);
|
view.delegateEvents(events);
|
||||||
$('#qunit-banner').trigger('click');
|
view.$el.trigger('click');
|
||||||
equal(view.counter, 1);
|
equal(view.counter, 1);
|
||||||
$('#qunit-banner').trigger('click');
|
|
||||||
|
view.$el.trigger('click');
|
||||||
equal(view.counter, 2);
|
equal(view.counter, 2);
|
||||||
|
|
||||||
view.delegateEvents(events);
|
view.delegateEvents(events);
|
||||||
$('#qunit-banner').trigger('click');
|
view.$el.trigger('click');
|
||||||
equal(view.counter, 3);
|
equal(view.counter, 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("View: undelegateEvents", 6, function() {
|
|
||||||
var counter = 0;
|
test("delegateEvents ignore undefined methods", 0, function() {
|
||||||
var counter2 = 0;
|
var view = new Backbone.View({el: '<p></p>'});
|
||||||
view.setElement(document.body);
|
view.delegateEvents({'click': 'undefinedMethod'});
|
||||||
view.increment = function(){ counter++; };
|
view.$el.trigger('click');
|
||||||
$(view.el).unbind('click');
|
});
|
||||||
$(view.el).bind('click', function(){ counter2++; });
|
|
||||||
var events = {"click #qunit-userAgent": "increment"};
|
test("undelegateEvents", 6, function() {
|
||||||
|
var counter1 = 0, counter2 = 0;
|
||||||
|
|
||||||
|
var view = new Backbone.View({el: '#testElement'});
|
||||||
|
view.increment = function(){ counter1++; };
|
||||||
|
view.$el.on('click', function(){ counter2++; });
|
||||||
|
|
||||||
|
var events = {'click h1': 'increment'};
|
||||||
|
|
||||||
view.delegateEvents(events);
|
view.delegateEvents(events);
|
||||||
$('#qunit-userAgent').trigger('click');
|
view.$('h1').trigger('click');
|
||||||
equal(counter, 1);
|
equal(counter1, 1);
|
||||||
equal(counter2, 1);
|
equal(counter2, 1);
|
||||||
|
|
||||||
view.undelegateEvents();
|
view.undelegateEvents();
|
||||||
$('#qunit-userAgent').trigger('click');
|
view.$('h1').trigger('click');
|
||||||
equal(counter, 1);
|
equal(counter1, 1);
|
||||||
equal(counter2, 2);
|
equal(counter2, 2);
|
||||||
|
|
||||||
view.delegateEvents(events);
|
view.delegateEvents(events);
|
||||||
$('#qunit-userAgent').trigger('click');
|
view.$('h1').trigger('click');
|
||||||
equal(counter, 2);
|
equal(counter1, 2);
|
||||||
equal(counter2, 3);
|
equal(counter2, 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("View: _ensureElement with DOM node el", 1, function() {
|
test("_ensureElement with DOM node el", 1, function() {
|
||||||
var ViewClass = Backbone.View.extend({
|
var View = Backbone.View.extend({
|
||||||
el: document.body
|
el: document.body
|
||||||
});
|
});
|
||||||
var view = new ViewClass;
|
|
||||||
equal(view.el, document.body);
|
equal(new View().el, document.body);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("View: _ensureElement with string el", 3, function() {
|
test("_ensureElement with string el", 3, function() {
|
||||||
var ViewClass = Backbone.View.extend({
|
var View = Backbone.View.extend({
|
||||||
el: "body"
|
el: "body"
|
||||||
});
|
});
|
||||||
var view = new ViewClass;
|
strictEqual(new View().el, document.body);
|
||||||
strictEqual(view.el, document.body);
|
|
||||||
|
|
||||||
ViewClass = Backbone.View.extend({
|
View = Backbone.View.extend({
|
||||||
el: "#testElement > h1"
|
el: "#testElement > h1"
|
||||||
});
|
});
|
||||||
view = new ViewClass;
|
strictEqual(new View().el, $("#testElement > h1").get(0));
|
||||||
strictEqual(view.el, $("#testElement > h1").get(0));
|
|
||||||
|
|
||||||
ViewClass = Backbone.View.extend({
|
View = Backbone.View.extend({
|
||||||
el: "#nonexistent"
|
el: "#nonexistent"
|
||||||
});
|
});
|
||||||
view = new ViewClass;
|
ok(!new View().el);
|
||||||
ok(!view.el);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("View: with className and id functions", 2, function() {
|
test("with className and id functions", 2, function() {
|
||||||
var View = Backbone.View.extend({
|
var View = Backbone.View.extend({
|
||||||
className: function() {
|
className: function() {
|
||||||
return 'className';
|
return 'className';
|
||||||
@@ -144,53 +148,63 @@ $(document).ready(function() {
|
|||||||
return 'id';
|
return 'id';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var view = new View();
|
|
||||||
strictEqual(view.el.className, 'className');
|
strictEqual(new View().el.className, 'className');
|
||||||
strictEqual(view.el.id, 'id');
|
strictEqual(new View().el.id, 'id');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("View: with attributes", 2, function() {
|
test("with attributes", 2, function() {
|
||||||
var view = new Backbone.View({attributes : {'class': 'one', id: 'two'}});
|
var View = Backbone.View.extend({
|
||||||
equal(view.el.className, 'one');
|
attributes: {
|
||||||
equal(view.el.id, 'two');
|
id: 'id',
|
||||||
|
'class': 'class'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
strictEqual(new View().el.className, 'class');
|
||||||
|
strictEqual(new View().el.id, 'id');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("View: with attributes as a function", 1, function() {
|
test("with attributes as a function", 1, function() {
|
||||||
var viewClass = Backbone.View.extend({
|
var View = Backbone.View.extend({
|
||||||
attributes: function() {
|
attributes: function() {
|
||||||
return {'class': 'dynamic'};
|
return {'class': 'dynamic'};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
equal((new viewClass).el.className, 'dynamic');
|
|
||||||
|
strictEqual(new View().el.className, 'dynamic');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("View: multiple views per element", 3, function() {
|
test("multiple views per element", 3, function() {
|
||||||
var count = 0, ViewClass = Backbone.View.extend({
|
var count = 0;
|
||||||
el: $("body"),
|
var $el = $('<p></p>');
|
||||||
|
|
||||||
|
var View = Backbone.View.extend({
|
||||||
|
el: $el,
|
||||||
events: {
|
events: {
|
||||||
"click": "click"
|
click: function() {
|
||||||
},
|
count++;
|
||||||
click: function() {
|
}
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var view1 = new ViewClass;
|
var view1 = new View;
|
||||||
$("body").trigger("click");
|
$el.trigger("click");
|
||||||
equal(1, count);
|
equal(1, count);
|
||||||
|
|
||||||
var view2 = new ViewClass;
|
var view2 = new View;
|
||||||
$("body").trigger("click");
|
$el.trigger("click");
|
||||||
equal(3, count);
|
equal(3, count);
|
||||||
|
|
||||||
view1.delegateEvents();
|
view1.delegateEvents();
|
||||||
$("body").trigger("click");
|
$el.trigger("click");
|
||||||
equal(5, count);
|
equal(5, count);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("View: custom events, with namespaces", 2, function() {
|
test("custom events, with namespaces", 2, function() {
|
||||||
var count = 0;
|
var count = 0;
|
||||||
var ViewClass = Backbone.View.extend({
|
|
||||||
|
var View = Backbone.View.extend({
|
||||||
el: $('body'),
|
el: $('body'),
|
||||||
events: function() {
|
events: function() {
|
||||||
return {"fake$event.namespaced": "run"};
|
return {"fake$event.namespaced": "run"};
|
||||||
@@ -200,45 +214,114 @@ $(document).ready(function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var view = new ViewClass;
|
var view = new View;
|
||||||
$('body').trigger('fake$event').trigger('fake$event');
|
$('body').trigger('fake$event').trigger('fake$event');
|
||||||
equal(count, 2);
|
equal(count, 2);
|
||||||
$('body').unbind('.namespaced');
|
|
||||||
|
$('body').off('.namespaced');
|
||||||
$('body').trigger('fake$event');
|
$('body').trigger('fake$event');
|
||||||
equal(count, 2);
|
equal(count, 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("#1048 - setElement uses provided object.", 2, function() {
|
test("#1048 - setElement uses provided object.", 2, function() {
|
||||||
var $el = $('body');
|
var $el = $('body');
|
||||||
|
|
||||||
var view = new Backbone.View({el: $el});
|
var view = new Backbone.View({el: $el});
|
||||||
ok(view.$el === $el);
|
ok(view.$el === $el);
|
||||||
|
|
||||||
view.setElement($el = $($el));
|
view.setElement($el = $($el));
|
||||||
ok(view.$el === $el);
|
ok(view.$el === $el);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("#986 - Undelegate before changing element.", 1, function() {
|
test("#986 - Undelegate before changing element.", 1, function() {
|
||||||
var a = $('<button></button>');
|
var button1 = $('<button></button>');
|
||||||
var b = $('<button></button>');
|
var button2 = $('<button></button>');
|
||||||
|
|
||||||
var View = Backbone.View.extend({
|
var View = Backbone.View.extend({
|
||||||
events: {click: function(e) { ok(view.el === e.target); }}
|
events: {
|
||||||
|
click: function(e) {
|
||||||
|
ok(view.el === e.target);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
var view = new View({el: a});
|
|
||||||
view.setElement(b);
|
var view = new View({el: button1});
|
||||||
a.trigger('click');
|
view.setElement(button2);
|
||||||
b.trigger('click');
|
|
||||||
|
button1.trigger('click');
|
||||||
|
button2.trigger('click');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("#1172 - Clone attributes object", 2, function() {
|
test("#1172 - Clone attributes object", 2, function() {
|
||||||
var View = Backbone.View.extend({attributes: {foo: 'bar'}});
|
var View = Backbone.View.extend({
|
||||||
var v1 = new View({id: 'foo'});
|
attributes: {foo: 'bar'}
|
||||||
strictEqual(v1.el.id, 'foo');
|
});
|
||||||
var v2 = new View();
|
|
||||||
ok(!v2.el.id);
|
var view1 = new View({id: 'foo'});
|
||||||
|
strictEqual(view1.el.id, 'foo');
|
||||||
|
|
||||||
|
var view2 = new View();
|
||||||
|
ok(!view2.el.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("#1228 - tagName can be provided as a function", 1, function() {
|
test("#1228 - tagName can be provided as a function", 1, function() {
|
||||||
var View = Backbone.View.extend({tagName: function(){ return 'p'; }});
|
var View = Backbone.View.extend({
|
||||||
|
tagName: function() {
|
||||||
|
return 'p';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ok(new View().$el.is('p'));
|
ok(new View().$el.is('p'));
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
test("views stopListening", 0, function() {
|
||||||
|
var View = Backbone.View.extend({
|
||||||
|
initialize: function() {
|
||||||
|
this.listenTo(this.model, 'all x', function(){ ok(false); }, this);
|
||||||
|
this.listenTo(this.collection, 'all x', function(){ ok(false); }, this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var view = new View({
|
||||||
|
model: new Backbone.Model,
|
||||||
|
collection: new Backbone.Collection
|
||||||
|
});
|
||||||
|
|
||||||
|
view.stopListening();
|
||||||
|
view.model.trigger('x');
|
||||||
|
view.collection.trigger('x');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Provide function for el.", 2, function() {
|
||||||
|
var View = Backbone.View.extend({
|
||||||
|
el: function() {
|
||||||
|
return "<p><a></a></p>";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var view = new View;
|
||||||
|
ok(view.$el.is('p'));
|
||||||
|
ok(view.$el.has('a'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("events passed in options", 1, function() {
|
||||||
|
var counter = 0;
|
||||||
|
|
||||||
|
var View = Backbone.View.extend({
|
||||||
|
el: '#testElement',
|
||||||
|
increment: function() {
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var view = new View({
|
||||||
|
events: {
|
||||||
|
'click h1': 'increment'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
view.$('h1').trigger('click').trigger('click');
|
||||||
|
equal(counter, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
|
|||||||
2
vendor/benchmark.js/LICENSE.txt
vendored
2
vendor/benchmark.js/LICENSE.txt
vendored
@@ -1,4 +1,4 @@
|
|||||||
Copyright 2010-2012 Mathias Bynens <http://mathiasbynens.be/>
|
Copyright 2010-2015 Mathias Bynens <http://mathiasbynens.be/>
|
||||||
Based on JSLitmus.js, copyright Robert Kieffer <http://broofa.com/>
|
Based on JSLitmus.js, copyright Robert Kieffer <http://broofa.com/>
|
||||||
Modified by John-David Dalton <http://allyoucanleet.com/>
|
Modified by John-David Dalton <http://allyoucanleet.com/>
|
||||||
|
|
||||||
|
|||||||
135
vendor/benchmark.js/README.md
vendored
135
vendor/benchmark.js/README.md
vendored
@@ -1,135 +0,0 @@
|
|||||||
# Benchmark.js <sup>v1.0.0</sup>
|
|
||||||
|
|
||||||
A [robust](http://calendar.perfplanet.com/2010/bulletproof-javascript-benchmarks/ "Bulletproof JavaScript benchmarks") benchmarking library that works on nearly all JavaScript platforms<sup><a name="fnref1" href="#fn1">1</a></sup>, supports high-resolution timers, and returns statistically significant results. As seen on [jsPerf](http://jsperf.com/).
|
|
||||||
|
|
||||||
## Download
|
|
||||||
|
|
||||||
* [Development source](https://raw.github.com/bestiejs/benchmark.js/1.0.0/benchmark.js)
|
|
||||||
|
|
||||||
## Dive in
|
|
||||||
|
|
||||||
We’ve got [API docs](http://benchmarkjs.com/docs) and [unit tests](http://benchmarkjs.com/tests).
|
|
||||||
|
|
||||||
For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/benchmark.js/wiki/Roadmap).
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
Benchmark.js has been tested in at least Adobe AIR 3.1, Chrome 5-21, Firefox 1.5-13, IE 6-9, Opera 9.25-12.01, Safari 3-6, Node.js 0.8.6, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
|
|
||||||
|
|
||||||
## Installation and usage
|
|
||||||
|
|
||||||
In a browser or Adobe AIR:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<script src="benchmark.js"></script>
|
|
||||||
```
|
|
||||||
|
|
||||||
Optionally, expose Java’s nanosecond timer by adding the `nano` applet to the `<body>`:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<applet code="nano" archive="nano.jar"></applet>
|
|
||||||
```
|
|
||||||
|
|
||||||
Or enable Chrome’s microsecond timer by using the [command line switch](http://peter.sh/experiments/chromium-command-line-switches/#enable-benchmarking):
|
|
||||||
|
|
||||||
--enable-benchmarking
|
|
||||||
|
|
||||||
Via [npm](http://npmjs.org/):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install benchmark
|
|
||||||
```
|
|
||||||
|
|
||||||
In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/):
|
|
||||||
|
|
||||||
```js
|
|
||||||
var Benchmark = require('benchmark');
|
|
||||||
```
|
|
||||||
|
|
||||||
Optionally, use the [microtime module](https://github.com/wadey/node-microtime) by Wade Simmons:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install microtime
|
|
||||||
```
|
|
||||||
|
|
||||||
In [RingoJS v0.7.0-](http://ringojs.org/):
|
|
||||||
|
|
||||||
```js
|
|
||||||
var Benchmark = require('benchmark').Benchmark;
|
|
||||||
```
|
|
||||||
|
|
||||||
In [Rhino](http://www.mozilla.org/rhino/):
|
|
||||||
|
|
||||||
```js
|
|
||||||
load('benchmark.js');
|
|
||||||
```
|
|
||||||
|
|
||||||
In an AMD loader like [RequireJS](http://requirejs.org/):
|
|
||||||
|
|
||||||
```js
|
|
||||||
require({
|
|
||||||
'paths': {
|
|
||||||
'benchmark': 'path/to/benchmark'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
['benchmark'], function(Benchmark) {
|
|
||||||
console.log(Benchmark.version);
|
|
||||||
});
|
|
||||||
|
|
||||||
// or with platform.js
|
|
||||||
// https://github.com/bestiejs/platform.js
|
|
||||||
require({
|
|
||||||
'paths': {
|
|
||||||
'benchmark': 'path/to/benchmark',
|
|
||||||
'platform': 'path/to/platform'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
['benchmark', 'platform'], function(Benchmark, platform) {
|
|
||||||
Benchmark.platform = platform;
|
|
||||||
console.log(Benchmark.platform.name);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Usage example:
|
|
||||||
|
|
||||||
```js
|
|
||||||
var suite = new Benchmark.Suite;
|
|
||||||
|
|
||||||
// add tests
|
|
||||||
suite.add('RegExp#test', function() {
|
|
||||||
/o/.test('Hello World!');
|
|
||||||
})
|
|
||||||
.add('String#indexOf', function() {
|
|
||||||
'Hello World!'.indexOf('o') > -1;
|
|
||||||
})
|
|
||||||
// add listeners
|
|
||||||
.on('cycle', function(event) {
|
|
||||||
console.log(String(event.target));
|
|
||||||
})
|
|
||||||
.on('complete', function() {
|
|
||||||
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
|
|
||||||
})
|
|
||||||
// run async
|
|
||||||
.run({ 'async': true });
|
|
||||||
|
|
||||||
// logs:
|
|
||||||
// > RegExp#test x 4,161,532 +-0.99% (59 cycles)
|
|
||||||
// > String#indexOf x 6,139,623 +-1.00% (131 cycles)
|
|
||||||
// > Fastest is String#indexOf
|
|
||||||
```
|
|
||||||
|
|
||||||
## BestieJS
|
|
||||||
|
|
||||||
Benchmark.js is part of the BestieJS *"Best in Class"* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation.
|
|
||||||
|
|
||||||
## Authors
|
|
||||||
|
|
||||||
* [Mathias Bynens](http://mathiasbynens.be/)
|
|
||||||
[](https://twitter.com/mathias "Follow @mathias on Twitter")
|
|
||||||
* [John-David Dalton](http://allyoucanleet.com/)
|
|
||||||
[](https://twitter.com/jdalton "Follow @jdalton on Twitter")
|
|
||||||
|
|
||||||
## Contributors
|
|
||||||
|
|
||||||
* [Kit Cambridge](http://kitcambridge.github.com/)
|
|
||||||
[](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter")
|
|
||||||
6129
vendor/benchmark.js/benchmark.js
vendored
6129
vendor/benchmark.js/benchmark.js
vendored
File diff suppressed because it is too large
Load Diff
20
vendor/docdown/LICENSE.txt
vendored
20
vendor/docdown/LICENSE.txt
vendored
@@ -1,20 +0,0 @@
|
|||||||
Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
|
|
||||||
|
|
||||||
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.
|
|
||||||
33
vendor/docdown/README.md
vendored
33
vendor/docdown/README.md
vendored
@@ -1,33 +0,0 @@
|
|||||||
# Docdown <sup>v1.0.0</sup>
|
|
||||||
|
|
||||||
A simple JSDoc to Markdown documentation generator.
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
The documentation for Docdown can be viewed here: [/doc/README.md](https://github.com/jdalton/docdown/blob/master/doc/README.md#readme)
|
|
||||||
|
|
||||||
For a list of upcoming features, check out our [roadmap](https://github.com/jdalton/docdown/wiki/Roadmap).
|
|
||||||
|
|
||||||
## Installation and usage
|
|
||||||
|
|
||||||
Usage example:
|
|
||||||
|
|
||||||
```php
|
|
||||||
require("docdown.php");
|
|
||||||
|
|
||||||
// generate Markdown
|
|
||||||
$markdown = docdown(array(
|
|
||||||
"path" => $filepath,
|
|
||||||
"url" => "https://github.com/username/project/blob/master/my.js"
|
|
||||||
));
|
|
||||||
```
|
|
||||||
|
|
||||||
## Author
|
|
||||||
|
|
||||||
* [John-David Dalton](http://allyoucanleet.com/)
|
|
||||||
[](https://twitter.com/jdalton "Follow @jdalton on Twitter")
|
|
||||||
|
|
||||||
## Contributors
|
|
||||||
|
|
||||||
* [Mathias Bynens](http://mathiasbynens.be/)
|
|
||||||
[](https://twitter.com/mathias "Follow @mathias on Twitter")
|
|
||||||
38
vendor/docdown/docdown.php
vendored
38
vendor/docdown/docdown.php
vendored
@@ -1,38 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*!
|
|
||||||
* Docdown v1.0.0-pre
|
|
||||||
* Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
|
|
||||||
* Available under MIT license <http://mths.be/mit>
|
|
||||||
*/
|
|
||||||
require(dirname(__FILE__) . '/src/DocDown/Generator.php');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates Markdown from JSDoc entries in a given file.
|
|
||||||
*
|
|
||||||
* @param {Array} [$options=array()] The options array.
|
|
||||||
* @returns {String} The generated Markdown.
|
|
||||||
* @example
|
|
||||||
*
|
|
||||||
* // specify a file path
|
|
||||||
* $markdown = docdown(array(
|
|
||||||
* // path to js file
|
|
||||||
* 'path' => $filepath,
|
|
||||||
* // url used to reference line numbers in code
|
|
||||||
* 'url' => 'https://github.com/username/project/blob/master/my.js'
|
|
||||||
* ));
|
|
||||||
*
|
|
||||||
* // or pass raw js
|
|
||||||
* $markdown = docdown(array(
|
|
||||||
* // raw JavaScript source
|
|
||||||
* 'source' => $rawJS,
|
|
||||||
* // documentation title
|
|
||||||
* 'title' => 'My API Documentation',
|
|
||||||
* // url used to reference line numbers in code
|
|
||||||
* 'url' => 'https://github.com/username/project/blob/master/my.js'
|
|
||||||
* ));
|
|
||||||
*/
|
|
||||||
function docdown( $options = array() ) {
|
|
||||||
$gen = new Generator($options);
|
|
||||||
return $gen->generate();
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
304
vendor/docdown/src/DocDown/Entry.php
vendored
304
vendor/docdown/src/DocDown/Entry.php
vendored
@@ -1,304 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class to simplify parsing a single JSDoc entry.
|
|
||||||
*/
|
|
||||||
class Entry {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The documentation entry.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @type String
|
|
||||||
*/
|
|
||||||
public $entry = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The language highlighter used for code examples.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @type String
|
|
||||||
*/
|
|
||||||
public $lang = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The source code.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @type String
|
|
||||||
*/
|
|
||||||
public $source = '';
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Entry constructor.
|
|
||||||
*
|
|
||||||
* @constructor
|
|
||||||
* @param {String} $entry The documentation entry to analyse.
|
|
||||||
* @param {String} $source The source code.
|
|
||||||
* @param {String} $lang The language highlighter used for code examples.
|
|
||||||
*/
|
|
||||||
public function __construct( $entry, $source, $lang = 'js' ) {
|
|
||||||
$this->entry = $entry;
|
|
||||||
$this->lang = $lang;
|
|
||||||
$this->source = str_replace(PHP_EOL, "\n", $source);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the documentation entries from source code.
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
* @memberOf Entry
|
|
||||||
* @param {String} $source The source code.
|
|
||||||
* @returns {Array} The array of entries.
|
|
||||||
*/
|
|
||||||
public static function getEntries( $source ) {
|
|
||||||
preg_match_all('#/\*\*(?![-!])[\s\S]*?\*/\s*[^\n]+#', $source, $result);
|
|
||||||
return array_pop($result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the entry is a function reference.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @memberOf Entry
|
|
||||||
* @returns {Boolean} Returns `true` if the entry is a function reference, else `false`.
|
|
||||||
*/
|
|
||||||
private function isFunction() {
|
|
||||||
return !!(
|
|
||||||
$this->isCtor() ||
|
|
||||||
count($this->getParams()) ||
|
|
||||||
count($this->getReturns()) ||
|
|
||||||
preg_match('/\*\s*@function\b/', $this->entry)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the function call from the entry.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @returns {String} The function call.
|
|
||||||
*/
|
|
||||||
public function getCall() {
|
|
||||||
preg_match('#\*/\s*(?:function ([^(]*)|(.*?)(?=[:=,]|return\b))#', $this->entry, $result);
|
|
||||||
if ($result = array_pop($result)) {
|
|
||||||
$result = array_pop(explode('var ', trim(trim(array_pop(explode('.', $result))), "'")));
|
|
||||||
}
|
|
||||||
// resolve name
|
|
||||||
// avoid $this->getName() because it calls $this->getCall()
|
|
||||||
preg_match('#\*\s*@name\s+([^\n]+)#', $this->entry, $name);
|
|
||||||
if (count($name)) {
|
|
||||||
$name = trim($name[1]);
|
|
||||||
} else {
|
|
||||||
$name = $result;
|
|
||||||
}
|
|
||||||
// compile function call syntax
|
|
||||||
if ($this->isFunction()) {
|
|
||||||
// compose parts
|
|
||||||
$result = array($result);
|
|
||||||
$params = $this->getParams();
|
|
||||||
foreach ($params as $param) {
|
|
||||||
$result[] = $param[1];
|
|
||||||
}
|
|
||||||
// format
|
|
||||||
$result = $name .'('. implode(array_slice($result, 1), ', ') .')';
|
|
||||||
$result = str_replace(', [', ' [, ', str_replace('], [', ', ', $result));
|
|
||||||
}
|
|
||||||
return $result ? $result : $name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the entry description.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @returns {String} The entry description.
|
|
||||||
*/
|
|
||||||
public function getDesc() {
|
|
||||||
preg_match('#/\*\*(?:\s*\*)?([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result);
|
|
||||||
if (count($result)) {
|
|
||||||
$type = $this->getType();
|
|
||||||
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
|
|
||||||
$result = ($type == 'Function' ? '' : '(' . str_replace('|', ', ', trim($type, '{}')) . '): ') . $result;
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the entry `example` data.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @returns {String} The entry `example` data.
|
|
||||||
*/
|
|
||||||
public function getExample() {
|
|
||||||
preg_match('#\*\s*@example\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result);
|
|
||||||
if (count($result)) {
|
|
||||||
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', "\n", $result[1]));
|
|
||||||
$result = '```' . $this->lang . "\n" . $result . "\n```";
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the line number of the entry.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @returns {Number} The line number.
|
|
||||||
*/
|
|
||||||
public function getLineNumber() {
|
|
||||||
preg_match_all('/\n/', substr($this->source, 0, strrpos($this->source, $this->entry) + strlen($this->entry)), $lines);
|
|
||||||
return count(array_pop($lines)) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the entry `member` data.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @param {Number} $index The index of the array value to return.
|
|
||||||
* @returns {Array|String} The entry `member` data.
|
|
||||||
*/
|
|
||||||
public function getMembers( $index = null ) {
|
|
||||||
preg_match('#\*\s*@member(?:Of)?\s+([^\n]+)#', $this->entry, $result);
|
|
||||||
if (count($result)) {
|
|
||||||
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
|
|
||||||
$result = preg_split('/,\s*/', $result);
|
|
||||||
}
|
|
||||||
return $index !== null ? @$result[$index] : $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the entry `name` data.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @returns {String} The entry `name` data.
|
|
||||||
*/
|
|
||||||
public function getName() {
|
|
||||||
preg_match('#\*\s*@name\s+([^\n]+)#', $this->entry, $result);
|
|
||||||
if (count($result)) {
|
|
||||||
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
|
|
||||||
} else {
|
|
||||||
$result = array_shift(explode('(', $this->getCall()));
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the entry `param` data.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @param {Number} $index The index of the array value to return.
|
|
||||||
* @returns {Array} The entry `param` data.
|
|
||||||
*/
|
|
||||||
public function getParams( $index = null ) {
|
|
||||||
preg_match_all('#\*\s*@param\s+\{([^}]+)\}\s+(\[.+\]|[$\w]+)\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#i', $this->entry, $result);
|
|
||||||
if (count($result = array_filter(array_slice($result, 1)))) {
|
|
||||||
// repurpose array
|
|
||||||
foreach ($result as $param) {
|
|
||||||
foreach ($param as $key => $value) {
|
|
||||||
if (!is_array($result[0][$key])) {
|
|
||||||
$result[0][$key] = array();
|
|
||||||
}
|
|
||||||
$result[0][$key][] = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$result = $result[0];
|
|
||||||
}
|
|
||||||
return $index !== null ? @$result[$index] : $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the entry `returns` data.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @returns {String} The entry `returns` data.
|
|
||||||
*/
|
|
||||||
public function getReturns() {
|
|
||||||
preg_match('#\*\s*@returns\s+\{([^}]+)\}\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result);
|
|
||||||
if (count($result)) {
|
|
||||||
$result = array_map('trim', array_slice($result, 1));
|
|
||||||
$result[0] = str_replace('|', ', ', $result[0]);
|
|
||||||
$result[1] = preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]);
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the entry `type` data.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @returns {String} The entry `type` data.
|
|
||||||
*/
|
|
||||||
public function getType() {
|
|
||||||
preg_match('#\*\s*@type\s+([^\n]+)#', $this->entry, $result);
|
|
||||||
if (count($result)) {
|
|
||||||
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
|
|
||||||
} else {
|
|
||||||
$result = $this->isFunction() ? 'Function' : 'Unknown';
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if an entry is a constructor.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @returns {Boolean} Returns true if a constructor, else false.
|
|
||||||
*/
|
|
||||||
public function isCtor() {
|
|
||||||
return !!preg_match('/\*\s*@constructor\b/', $this->entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if an entry *is* assigned to a prototype.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @returns {Boolean} Returns true if assigned to a prototype, else false.
|
|
||||||
*/
|
|
||||||
public function isPlugin() {
|
|
||||||
return !$this->isCtor() && !$this->isPrivate() && !$this->isStatic();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if an entry is private.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @returns {Boolean} Returns true if private, else false.
|
|
||||||
*/
|
|
||||||
public function isPrivate() {
|
|
||||||
return !!preg_match('/\*\s*@private\b/', $this->entry) || strrpos($this->entry, '@') === false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if an entry is *not* assigned to a prototype.
|
|
||||||
*
|
|
||||||
* @memberOf Entry
|
|
||||||
* @returns {Boolean} Returns true if not assigned to a prototype, else false.
|
|
||||||
*/
|
|
||||||
public function isStatic() {
|
|
||||||
$public = !$this->isPrivate();
|
|
||||||
$result = $public && !!preg_match('/\*\s*@static\b/', $this->entry);
|
|
||||||
|
|
||||||
// set in cases where it isn't explicitly stated
|
|
||||||
if ($public && !$result) {
|
|
||||||
if ($parent = array_pop(preg_split('/[#.]/', $this->getMembers(0)))) {
|
|
||||||
foreach (Entry::getEntries($this->source) as $entry) {
|
|
||||||
$entry = new Entry($entry, $this->source);
|
|
||||||
if ($entry->getName() == $parent) {
|
|
||||||
$result = !$entry->isCtor();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
416
vendor/docdown/src/DocDown/Generator.php
vendored
416
vendor/docdown/src/DocDown/Generator.php
vendored
@@ -1,416 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require(dirname(__FILE__) . "/Entry.php");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates Markdown from JSDoc entries.
|
|
||||||
*/
|
|
||||||
class Generator {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An array of JSDoc entries.
|
|
||||||
*
|
|
||||||
* @memberOf Generator
|
|
||||||
* @type Array
|
|
||||||
*/
|
|
||||||
public $entries = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An options array used to configure the generator.
|
|
||||||
*
|
|
||||||
* @memberOf Generator
|
|
||||||
* @type Array
|
|
||||||
*/
|
|
||||||
public $options = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The entire file's source code.
|
|
||||||
*
|
|
||||||
* @memberOf Generator
|
|
||||||
* @type String
|
|
||||||
*/
|
|
||||||
public $source = '';
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Generator constructor.
|
|
||||||
*
|
|
||||||
* @constructor
|
|
||||||
* @param {String} $source The source code to parse.
|
|
||||||
* @param {Array} $options The options array.
|
|
||||||
*/
|
|
||||||
public function __construct( $source, $options = array() ) {
|
|
||||||
// juggle arguments
|
|
||||||
if (is_array($source)) {
|
|
||||||
$options = $source;
|
|
||||||
} else {
|
|
||||||
$options['source'] = $source;
|
|
||||||
}
|
|
||||||
if (isset($options['source']) && realpath($options['source'])) {
|
|
||||||
$options['path'] = $options['source'];
|
|
||||||
}
|
|
||||||
if (isset($options['path'])) {
|
|
||||||
preg_match('/(?<=\.)[a-z]+$/', $options['path'], $ext);
|
|
||||||
$options['source'] = file_get_contents($options['path']);
|
|
||||||
$ext = array_pop($ext);
|
|
||||||
|
|
||||||
if (!isset($options['lang']) && $ext) {
|
|
||||||
$options['lang'] = $ext;
|
|
||||||
}
|
|
||||||
if (!isset($options['title'])) {
|
|
||||||
$options['title'] = ucfirst(basename($options['path'])) . ' API documentation';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isset($options['lang'])) {
|
|
||||||
$options['lang'] = 'js';
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->options = $options;
|
|
||||||
$this->source = str_replace(PHP_EOL, "\n", $options['source']);
|
|
||||||
$this->entries = Entry::getEntries($this->source);
|
|
||||||
|
|
||||||
foreach ($this->entries as $index => $value) {
|
|
||||||
$this->entries[$index] = new Entry($value, $this->source, $options['lang']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs common string formatting operations.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @static
|
|
||||||
* @memberOf Generator
|
|
||||||
* @param {String} $string The string to format.
|
|
||||||
* @returns {String} The formatted string.
|
|
||||||
*/
|
|
||||||
private static function format($string) {
|
|
||||||
$counter = 0;
|
|
||||||
|
|
||||||
// tokenize inline code snippets
|
|
||||||
preg_match_all('/`[^`]+`/', $string, $tokenized);
|
|
||||||
$tokenized = $tokenized[0];
|
|
||||||
foreach ($tokenized as $snippet) {
|
|
||||||
$string = str_replace($snippet, '__token' . ($counter++) .'__', $string);
|
|
||||||
}
|
|
||||||
|
|
||||||
// italicize parentheses
|
|
||||||
$string = preg_replace('/(^|\s)(\([^)]+\))/', '$1*$2*', $string);
|
|
||||||
|
|
||||||
// mark numbers as inline code
|
|
||||||
$string = preg_replace('/ (-?\d+(?:.\d+)?)(?!\.[^\n])/', ' `$1`', $string);
|
|
||||||
|
|
||||||
// detokenize inline code snippets
|
|
||||||
$counter = 0;
|
|
||||||
foreach ($tokenized as $snippet) {
|
|
||||||
$string = str_replace('__token' . ($counter++) . '__', $snippet, $string);
|
|
||||||
}
|
|
||||||
|
|
||||||
return trim($string);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Modify a string by replacing named tokens with matching assoc. array values.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @static
|
|
||||||
* @memberOf Generator
|
|
||||||
* @param {String} $string The string to modify.
|
|
||||||
* @param {Array|Object} $object The template object.
|
|
||||||
* @returns {String} The modified string.
|
|
||||||
*/
|
|
||||||
private static function interpolate($string, $object) {
|
|
||||||
preg_match_all('/#\{([^}]+)\}/', $string, $tokens);
|
|
||||||
$tokens = array_unique(array_pop($tokens));
|
|
||||||
|
|
||||||
foreach ($tokens as $token) {
|
|
||||||
$pattern = '/#\{' . $token . '\}/';
|
|
||||||
$replacement = '';
|
|
||||||
|
|
||||||
if (is_object($object)) {
|
|
||||||
preg_match('/\(([^)]+?)\)$/', $token, $args);
|
|
||||||
$args = preg_split('/,\s*/', array_pop($args));
|
|
||||||
$method = 'get' . ucfirst(str_replace('/\([^)]+?\)$/', '', $token));
|
|
||||||
|
|
||||||
if (method_exists($object, $method)) {
|
|
||||||
$replacement = (string) call_user_func_array(array($object, $method), $args);
|
|
||||||
} else if (isset($object->{$token})) {
|
|
||||||
$replacement = (string) $object->{$token};
|
|
||||||
}
|
|
||||||
} else if (isset($object[$token])) {
|
|
||||||
$replacement = (string) $object[$token];
|
|
||||||
}
|
|
||||||
$string = preg_replace($pattern, trim($replacement), $string);
|
|
||||||
}
|
|
||||||
return Generator::format($string);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the entry's hash used to navigate the documentation.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @memberOf Generator
|
|
||||||
* @param {Number|Object} $entry The entry object.
|
|
||||||
* @param {String} $member The name of the member.
|
|
||||||
* @returns {String} The url hash.
|
|
||||||
*/
|
|
||||||
private function getHash( $entry, $member = '' ) {
|
|
||||||
$entry = is_numeric($entry) ? $this->entries[$entry] : $entry;
|
|
||||||
$member = !$member ? $entry->getMembers(0) : $member;
|
|
||||||
$result = ($member ? $member . ($entry->isPlugin() ? 'prototype' : '') : '') . $entry->getCall();
|
|
||||||
$result = preg_replace('/\(\[|\[\]/', '', $result);
|
|
||||||
$result = preg_replace('/[ =\'"{}.()\]]/', '', $result);
|
|
||||||
$result = preg_replace('/[[#,]/', '-', $result);
|
|
||||||
return strtolower($result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the entry's url for the specific line number.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @memberOf Generator
|
|
||||||
* @param {Number|Object} $entry The entry object.
|
|
||||||
* @returns {String} The url.
|
|
||||||
*/
|
|
||||||
private function getLineUrl( $entry ) {
|
|
||||||
$entry = is_numeric($entry) ? $this->entries($entry) : $entry;
|
|
||||||
return $this->options['url'] . '#L' . $entry->getLineNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the character used to separate the entry's name from its member.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @memberOf Generator
|
|
||||||
* @param {Number|Object} $entry The entry object.
|
|
||||||
* @returns {String} The separator.
|
|
||||||
*/
|
|
||||||
private function getSeparator( $entry ) {
|
|
||||||
$entry = is_numeric($entry) ? $this->entries($entry) : $entry;
|
|
||||||
return $entry->isPlugin() ? '.prototype.' : '.';
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates Markdown from JSDoc entries.
|
|
||||||
*
|
|
||||||
* @memberOf Generator
|
|
||||||
* @returns {String} The rendered Markdown.
|
|
||||||
*/
|
|
||||||
public function generate() {
|
|
||||||
$api = array();
|
|
||||||
$compiling = false;
|
|
||||||
$openTag = "\n<!-- div -->\n";
|
|
||||||
$closeTag = "\n<!-- /div -->\n";
|
|
||||||
$result = array('# ' . $this->options['title']);
|
|
||||||
$toc = 'toc';
|
|
||||||
|
|
||||||
// initialize $api array
|
|
||||||
foreach ($this->entries as $entry) {
|
|
||||||
|
|
||||||
if (!$entry->isPrivate()) {
|
|
||||||
$name = $entry->getName();
|
|
||||||
$members = $entry->getMembers();
|
|
||||||
$members = count($members) ? $members : array('');
|
|
||||||
|
|
||||||
foreach ($members as $member) {
|
|
||||||
// create api category arrays
|
|
||||||
if (!isset($api[$member]) && $member) {
|
|
||||||
$api[$member] = new Entry('', '', $entry->lang);
|
|
||||||
$api[$member]->static = array();
|
|
||||||
$api[$member]->plugin = array();
|
|
||||||
}
|
|
||||||
// append entry to api category
|
|
||||||
if (!$member || $entry->isCtor() || ($entry->getType() == 'Object' &&
|
|
||||||
!preg_match('/[=:]\s*null\s*[,;]?$/', $entry->entry))) {
|
|
||||||
$member = ($member ? $member . ($entry->isPlugin() ? '#' : '.') : '') . $name;
|
|
||||||
$entry->static = @$api[$member] ? $api[$member]->static : array();
|
|
||||||
$entry->plugin = @$api[$member] ? $api[$member]->plugin : array();
|
|
||||||
$api[$member] = $entry;
|
|
||||||
}
|
|
||||||
else if ($entry->isStatic()) {
|
|
||||||
$api[$member]->static[] = $entry;
|
|
||||||
} else if (!$entry->isCtor()) {
|
|
||||||
$api[$member]->plugin[] = $entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
// custom sort for root level entries
|
|
||||||
// TODO: see how well it handles deeper namespace traversal
|
|
||||||
function sortCompare($a, $b) {
|
|
||||||
$score = array( 'a' => 0, 'b' => 0);
|
|
||||||
foreach (array( 'a' => $a, 'b' => $b) as $key => $value) {
|
|
||||||
// capitalized keys that represent constructor properties are last
|
|
||||||
if (preg_match('/[#.][A-Z]/', $value)) {
|
|
||||||
$score[$key] = 0;
|
|
||||||
}
|
|
||||||
// lowercase keys with prototype properties are next to last
|
|
||||||
else if (preg_match('/#[a-z]/', $value)) {
|
|
||||||
$score[$key] = 1;
|
|
||||||
}
|
|
||||||
// lowercase keys with static properties next to first
|
|
||||||
else if (preg_match('/\.[a-z]/', $value)) {
|
|
||||||
$score[$key] = 2;
|
|
||||||
}
|
|
||||||
// lowercase keys with no properties are first
|
|
||||||
else if (preg_match('/^[^#.]+$/', $value)) {
|
|
||||||
$score[$key] = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$score = $score['b'] - $score['a'];
|
|
||||||
return $score ? $score : strcasecmp($a, $b);
|
|
||||||
}
|
|
||||||
|
|
||||||
uksort($api, 'sortCompare');
|
|
||||||
|
|
||||||
// sort static and plugin sub-entries
|
|
||||||
foreach ($api as $entry) {
|
|
||||||
foreach (array('static', 'plugin') as $kind) {
|
|
||||||
$sortBy = array( 'a' => array(), 'b' => array(), 'c' => array() );
|
|
||||||
foreach ($entry->{$kind} as $subentry) {
|
|
||||||
$name = $subentry->getName();
|
|
||||||
// functions w/o ALL-CAPs names are last
|
|
||||||
$sortBy['a'][] = $subentry->getType() == 'Function' && !preg_match('/^[A-Z_]+$/', $name);
|
|
||||||
// ALL-CAPs properties first
|
|
||||||
$sortBy['b'][] = preg_match('/^[A-Z_]+$/', $name);
|
|
||||||
// lowercase alphanumeric sort
|
|
||||||
$sortBy['c'][] = strtolower($name);
|
|
||||||
}
|
|
||||||
array_multisort($sortBy['a'], SORT_ASC, $sortBy['b'], SORT_DESC, $sortBy['c'], SORT_ASC, $entry->{$kind});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
// compile TOC
|
|
||||||
$result[] = $openTag;
|
|
||||||
|
|
||||||
foreach ($api as $key => $entry) {
|
|
||||||
$entry->hash = $this->getHash($entry);
|
|
||||||
$entry->href = $this->getLineUrl($entry);
|
|
||||||
|
|
||||||
$member = $entry->getMembers(0);
|
|
||||||
$member = ($member ? $member . ($entry->isPlugin() ? '.prototype.' : '.') : '') . $entry->getName();
|
|
||||||
|
|
||||||
$entry->member = preg_replace('/' . $entry->getName() . '$/', '', $member);
|
|
||||||
|
|
||||||
$compiling = $compiling ? ($result[] = $closeTag) : true;
|
|
||||||
|
|
||||||
// assign TOC hash
|
|
||||||
if (count($result) == 2) {
|
|
||||||
$toc = $member;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add root entry
|
|
||||||
array_push(
|
|
||||||
$result,
|
|
||||||
$openTag, '## ' . (count($result) == 2 ? '<a id="' . $toc . '"></a>' : '') . '`' . $member . '`',
|
|
||||||
Generator::interpolate('* [`' . $member . '`](##{hash})', $entry)
|
|
||||||
);
|
|
||||||
|
|
||||||
// add static and plugin sub-entries
|
|
||||||
foreach (array('static', 'plugin') as $kind) {
|
|
||||||
if ($kind == 'plugin' && count($entry->plugin)) {
|
|
||||||
array_push(
|
|
||||||
$result,
|
|
||||||
$closeTag,
|
|
||||||
$openTag,
|
|
||||||
'## `' . $member . ($entry->isCtor() ? '.prototype`' : '`')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
foreach ($entry->{$kind} as $subentry) {
|
|
||||||
$subentry->hash = $this->getHash($subentry);
|
|
||||||
$subentry->href = $this->getLineUrl($subentry);
|
|
||||||
$subentry->member = $member;
|
|
||||||
$subentry->separator = $this->getSeparator($subentry);
|
|
||||||
$result[] = Generator::interpolate('* [`#{member}#{separator}#{name}`](##{hash})', $subentry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
array_push($result, $closeTag, $closeTag);
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
// compile content
|
|
||||||
$compiling = false;
|
|
||||||
$result[] = $openTag;
|
|
||||||
|
|
||||||
foreach ($api as $entry) {
|
|
||||||
// add root entry
|
|
||||||
$member = $entry->member . $entry->getName();
|
|
||||||
$compiling = $compiling ? ($result[] = $closeTag) : true;
|
|
||||||
|
|
||||||
array_push($result, $openTag, '## `' . $member . '`');
|
|
||||||
|
|
||||||
foreach (array($entry, 'static', 'plugin') as $kind) {
|
|
||||||
$subentries = is_string($kind) ? $entry->{$kind} : array($kind);
|
|
||||||
|
|
||||||
// title
|
|
||||||
if ($kind != 'static' && $entry->getType() != 'Object' &&
|
|
||||||
count($subentries) && $subentries[0] != $kind) {
|
|
||||||
if ($kind == 'plugin') {
|
|
||||||
$result[] = $closeTag;
|
|
||||||
}
|
|
||||||
array_push(
|
|
||||||
$result,
|
|
||||||
$openTag,
|
|
||||||
'## `' . $member . ($kind == 'plugin' ? '.prototype`' : '`')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// body
|
|
||||||
foreach ($subentries as $subentry) {
|
|
||||||
// description
|
|
||||||
array_push(
|
|
||||||
$result,
|
|
||||||
$openTag,
|
|
||||||
Generator::interpolate("### <a id=\"#{hash}\"></a>`#{member}#{separator}#{call}`\n<a href=\"##{hash}\">#</a> [Ⓢ](#{href} \"View in source\") [Ⓣ][1]\n\n#{desc}", $subentry)
|
|
||||||
);
|
|
||||||
|
|
||||||
// @param
|
|
||||||
if (count($params = $subentry->getParams())) {
|
|
||||||
array_push($result, '', '#### Arguments');
|
|
||||||
foreach ($params as $index => $param) {
|
|
||||||
$result[] = Generator::interpolate('#{num}. `#{name}` (#{type}): #{desc}', array(
|
|
||||||
'desc' => $param[2],
|
|
||||||
'name' => $param[1],
|
|
||||||
'num' => $index + 1,
|
|
||||||
'type' => $param[0]
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// @returns
|
|
||||||
if (count($returns = $subentry->getReturns())) {
|
|
||||||
array_push(
|
|
||||||
$result, '',
|
|
||||||
'#### Returns',
|
|
||||||
Generator::interpolate('(#{type}): #{desc}', array('desc' => $returns[1], 'type' => $returns[0]))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// @example
|
|
||||||
if ($example = $subentry->getExample()) {
|
|
||||||
array_push($result, '', '#### Example', $example);
|
|
||||||
}
|
|
||||||
array_push($result, "\n* * *", $closeTag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// close tags add TOC link reference
|
|
||||||
array_push($result, $closeTag, $closeTag, '', ' [1]: #' . $toc . ' "Jump back to the TOC."');
|
|
||||||
|
|
||||||
// cleanup whitespace
|
|
||||||
return trim(preg_replace('/ +\n/', "\n", join($result, "\n")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
1049
vendor/firebug-lite/changelog.txt
vendored
1049
vendor/firebug-lite/changelog.txt
vendored
File diff suppressed because it is too large
Load Diff
662
vendor/firebug-lite/skin/xp/debugger.css
vendored
662
vendor/firebug-lite/skin/xp/debugger.css
vendored
@@ -1,331 +1,331 @@
|
|||||||
/* See license.txt for terms of usage */
|
/* See license.txt for terms of usage */
|
||||||
|
|
||||||
.panelNode-script {
|
.panelNode-script {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
|
|
||||||
.scriptTooltip {
|
.scriptTooltip {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 2147483647;
|
z-index: 2147483647;
|
||||||
padding: 2px 3px;
|
padding: 2px 3px;
|
||||||
border: 1px solid #CBE087;
|
border: 1px solid #CBE087;
|
||||||
background: LightYellow;
|
background: LightYellow;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
|
|
||||||
.sourceBox {
|
.sourceBox {
|
||||||
/* TODO: xxxpedro problem with sourceBox and scrolling elements */
|
/* TODO: xxxpedro problem with sourceBox and scrolling elements */
|
||||||
/*overflow: scroll; /* see issue 1479 */
|
/*overflow: scroll; /* see issue 1479 */
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sourceRow {
|
.sourceRow {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
-moz-user-select: text;
|
-moz-user-select: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sourceRow.hovered {
|
.sourceRow.hovered {
|
||||||
background-color: #EEEEEE;
|
background-color: #EEEEEE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
|
|
||||||
.sourceLine {
|
.sourceLine {
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
border-right: 1px solid #CCCCCC;
|
border-right: 1px solid #CCCCCC;
|
||||||
padding: 0px 4px 0 20px;
|
padding: 0px 4px 0 20px;
|
||||||
background: #EEEEEE no-repeat 2px 0px;
|
background: #EEEEEE no-repeat 2px 0px;
|
||||||
color: #888888;
|
color: #888888;
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
font-family: monospace; /* see issue 2953 */
|
font-family: monospace; /* see issue 2953 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.noteInToolTip { /* below sourceLine, so it overrides it */
|
.noteInToolTip { /* below sourceLine, so it overrides it */
|
||||||
background-color: #FFD472;
|
background-color: #FFD472;
|
||||||
}
|
}
|
||||||
|
|
||||||
.useA11y .sourceBox .sourceViewport:focus .sourceLine {
|
.useA11y .sourceBox .sourceViewport:focus .sourceLine {
|
||||||
background-color: #FFFFC0;
|
background-color: #FFFFC0;
|
||||||
color: navy;
|
color: navy;
|
||||||
border-right: 1px solid black;
|
border-right: 1px solid black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.useA11y .sourceBox .sourceViewport:focus {
|
.useA11y .sourceBox .sourceViewport:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.a11y1emSize {
|
.a11y1emSize {
|
||||||
width: 1em;
|
width: 1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
.useA11y .panelStatusLabel:focus {
|
.useA11y .panelStatusLabel:focus {
|
||||||
outline-offset: -2px !important;
|
outline-offset: -2px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sourceBox > .sourceRow > .sourceLine {
|
.sourceBox > .sourceRow > .sourceLine {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sourceLine:hover {
|
.sourceLine:hover {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sourceRowText {
|
.sourceRowText {
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sourceRow[exe_line="true"] {
|
.sourceRow[exe_line="true"] {
|
||||||
outline: 1px solid #D9D9B6;
|
outline: 1px solid #D9D9B6;
|
||||||
margin-right: 1px;
|
margin-right: 1px;
|
||||||
background-color: lightgoldenrodyellow;
|
background-color: lightgoldenrodyellow;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sourceRow[executable="true"] > .sourceLine {
|
.sourceRow[executable="true"] > .sourceLine {
|
||||||
content: "-";
|
content: "-";
|
||||||
color: #4AA02C; /* Spring Green */
|
color: #4AA02C; /* Spring Green */
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sourceRow[exe_line="true"] > .sourceLine {
|
.sourceRow[exe_line="true"] > .sourceLine {
|
||||||
background-image: url(chrome://firebug/skin/exe.png);
|
background-image: url(chrome://firebug/skin/exe.png);
|
||||||
color: #000000;
|
color: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sourceRow[breakpoint="true"] > .sourceLine {
|
.sourceRow[breakpoint="true"] > .sourceLine {
|
||||||
background-image: url(chrome://firebug/skin/breakpoint.png);
|
background-image: url(chrome://firebug/skin/breakpoint.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sourceRow[breakpoint="true"][condition="true"] > .sourceLine {
|
.sourceRow[breakpoint="true"][condition="true"] > .sourceLine {
|
||||||
background-image: url(chrome://firebug/skin/breakpointCondition.png);
|
background-image: url(chrome://firebug/skin/breakpointCondition.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sourceRow[breakpoint="true"][disabledBreakpoint="true"] > .sourceLine {
|
.sourceRow[breakpoint="true"][disabledBreakpoint="true"] > .sourceLine {
|
||||||
background-image: url(chrome://firebug/skin/breakpointDisabled.png);
|
background-image: url(chrome://firebug/skin/breakpointDisabled.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sourceRow[breakpoint="true"][exe_line="true"] > .sourceLine {
|
.sourceRow[breakpoint="true"][exe_line="true"] > .sourceLine {
|
||||||
background-image: url(chrome://firebug/skin/breakpointExe.png);
|
background-image: url(chrome://firebug/skin/breakpointExe.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sourceRow[breakpoint="true"][exe_line="true"][disabledBreakpoint="true"] > .sourceLine {
|
.sourceRow[breakpoint="true"][exe_line="true"][disabledBreakpoint="true"] > .sourceLine {
|
||||||
background-image: url(chrome://firebug/skin/breakpointDisabledExe.png);
|
background-image: url(chrome://firebug/skin/breakpointDisabledExe.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sourceLine.editing {
|
.sourceLine.editing {
|
||||||
background-image: url(chrome://firebug/skin/breakpoint.png);
|
background-image: url(chrome://firebug/skin/breakpoint.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
|
|
||||||
.conditionEditor {
|
.conditionEditor {
|
||||||
z-index: 2147483647;
|
z-index: 2147483647;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
left: 2px;
|
left: 2px;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conditionEditorInner {
|
.conditionEditorInner {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: -26px;
|
top: -26px;
|
||||||
height: 0;
|
height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conditionCaption {
|
.conditionCaption {
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
font-family: Lucida Grande, sans-serif;
|
font-family: Lucida Grande, sans-serif;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: #226679;
|
color: #226679;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conditionInput {
|
.conditionInput {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 1px solid #0096C0;
|
border: 1px solid #0096C0;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conditionEditorInner1 {
|
.conditionEditorInner1 {
|
||||||
padding-left: 37px;
|
padding-left: 37px;
|
||||||
background: url(condBorders.png) repeat-y;
|
background: url(condBorders.png) repeat-y;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conditionEditorInner2 {
|
.conditionEditorInner2 {
|
||||||
padding-right: 25px;
|
padding-right: 25px;
|
||||||
background: url(condBorders.png) repeat-y 100% 0;
|
background: url(condBorders.png) repeat-y 100% 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conditionEditorTop1 {
|
.conditionEditorTop1 {
|
||||||
background: url(condCorners.png) no-repeat 100% 0;
|
background: url(condCorners.png) no-repeat 100% 0;
|
||||||
margin-left: 37px;
|
margin-left: 37px;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conditionEditorTop2 {
|
.conditionEditorTop2 {
|
||||||
position: relative;
|
position: relative;
|
||||||
left: -37px;
|
left: -37px;
|
||||||
width: 37px;
|
width: 37px;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
background: url(condCorners.png) no-repeat;
|
background: url(condCorners.png) no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conditionEditorBottom1 {
|
.conditionEditorBottom1 {
|
||||||
background: url(condCorners.png) no-repeat 100% 100%;
|
background: url(condCorners.png) no-repeat 100% 100%;
|
||||||
margin-left: 37px;
|
margin-left: 37px;
|
||||||
height: 33px;
|
height: 33px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conditionEditorBottom2 {
|
.conditionEditorBottom2 {
|
||||||
position: relative; left: -37px;
|
position: relative; left: -37px;
|
||||||
width: 37px;
|
width: 37px;
|
||||||
height: 33px;
|
height: 33px;
|
||||||
background: url(condCorners.png) no-repeat 0 100%;
|
background: url(condCorners.png) no-repeat 0 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
.upsideDown {
|
.upsideDown {
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upsideDown .conditionEditorInner {
|
.upsideDown .conditionEditorInner {
|
||||||
top: -8px;
|
top: -8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upsideDown .conditionEditorInner1 {
|
.upsideDown .conditionEditorInner1 {
|
||||||
padding-left: 33px;
|
padding-left: 33px;
|
||||||
background: url(condBordersUps.png) repeat-y;
|
background: url(condBordersUps.png) repeat-y;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upsideDown .conditionEditorInner2 {
|
.upsideDown .conditionEditorInner2 {
|
||||||
padding-right: 25px;
|
padding-right: 25px;
|
||||||
background: url(condBordersUps.png) repeat-y 100% 0;
|
background: url(condBordersUps.png) repeat-y 100% 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upsideDown .conditionEditorTop1 {
|
.upsideDown .conditionEditorTop1 {
|
||||||
background: url(condCornersUps.png) no-repeat 100% 0;
|
background: url(condCornersUps.png) no-repeat 100% 0;
|
||||||
margin-left: 33px;
|
margin-left: 33px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upsideDown .conditionEditorTop2 {
|
.upsideDown .conditionEditorTop2 {
|
||||||
position: relative;
|
position: relative;
|
||||||
left: -33px;
|
left: -33px;
|
||||||
width: 33px;
|
width: 33px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
background: url(condCornersUps.png) no-repeat;
|
background: url(condCornersUps.png) no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upsideDown .conditionEditorBottom1 {
|
.upsideDown .conditionEditorBottom1 {
|
||||||
background: url(condCornersUps.png) no-repeat 100% 100%;
|
background: url(condCornersUps.png) no-repeat 100% 100%;
|
||||||
margin-left: 33px;
|
margin-left: 33px;
|
||||||
height: 43px;
|
height: 43px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upsideDown .conditionEditorBottom2 {
|
.upsideDown .conditionEditorBottom2 {
|
||||||
position: relative;
|
position: relative;
|
||||||
left: -33px;
|
left: -33px;
|
||||||
width: 33px;
|
width: 33px;
|
||||||
height: 43px;
|
height: 43px;
|
||||||
background: url(condCornersUps.png) no-repeat 0 100%;
|
background: url(condCornersUps.png) no-repeat 0 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
|
|
||||||
.breakpointsGroupListBox {
|
.breakpointsGroupListBox {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointBlockHead {
|
.breakpointBlockHead {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-top: 4px;
|
padding-top: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointBlockHead > .checkbox {
|
.breakpointBlockHead > .checkbox {
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointBlockHead > .objectLink-sourceLink {
|
.breakpointBlockHead > .objectLink-sourceLink {
|
||||||
top: 4px;
|
top: 4px;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
background-color: #FFFFFF; /* issue 3308 */
|
background-color: #FFFFFF; /* issue 3308 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointBlockHead > .closeButton {
|
.breakpointBlockHead > .closeButton {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 2px;
|
top: 2px;
|
||||||
right: 2px;
|
right: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointCheckbox {
|
.breakpointCheckbox {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointName {
|
.breakpointName {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointRow[aria-checked="false"] > .breakpointBlockHead > *,
|
.breakpointRow[aria-checked="false"] > .breakpointBlockHead > *,
|
||||||
.breakpointRow[aria-checked="false"] > .breakpointCode {
|
.breakpointRow[aria-checked="false"] > .breakpointCode {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointRow[aria-checked="false"] .breakpointCheckbox,
|
.breakpointRow[aria-checked="false"] .breakpointCheckbox,
|
||||||
.breakpointRow[aria-checked="false"] .objectLink-sourceLink,
|
.breakpointRow[aria-checked="false"] .objectLink-sourceLink,
|
||||||
.breakpointRow[aria-checked="false"] .closeButton,
|
.breakpointRow[aria-checked="false"] .closeButton,
|
||||||
.breakpointRow[aria-checked="false"] .breakpointMutationType {
|
.breakpointRow[aria-checked="false"] .breakpointMutationType {
|
||||||
opacity: 1.0 !important;
|
opacity: 1.0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointCode {
|
.breakpointCode {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
padding-left: 24px;
|
padding-left: 24px;
|
||||||
padding-bottom: 2px;
|
padding-bottom: 2px;
|
||||||
border-bottom: 1px solid #D7D7D7;
|
border-bottom: 1px solid #D7D7D7;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
color: DarkGreen;
|
color: DarkGreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointCondition {
|
.breakpointCondition {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
padding-left: 24px;
|
padding-left: 24px;
|
||||||
padding-bottom: 2px;
|
padding-bottom: 2px;
|
||||||
border-bottom: 1px solid #D7D7D7;
|
border-bottom: 1px solid #D7D7D7;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
color: Gray;
|
color: Gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointBlock-breakpoints > .groupHeader {
|
.breakpointBlock-breakpoints > .groupHeader {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointBlock-monitors > .breakpointCode {
|
.breakpointBlock-monitors > .breakpointCode {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointBlock-errorBreakpoints .breakpointCheckbox,
|
.breakpointBlock-errorBreakpoints .breakpointCheckbox,
|
||||||
.breakpointBlock-monitors .breakpointCheckbox {
|
.breakpointBlock-monitors .breakpointCheckbox {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointHeader {
|
.breakpointHeader {
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
border-top: none !important;
|
border-top: none !important;
|
||||||
}
|
}
|
||||||
|
|||||||
1634
vendor/firebug-lite/skin/xp/firebug-1.3a2.css
vendored
1634
vendor/firebug-lite/skin/xp/firebug-1.3a2.css
vendored
File diff suppressed because it is too large
Load Diff
40
vendor/firebug-lite/skin/xp/firebug.IE6.css
vendored
40
vendor/firebug-lite/skin/xp/firebug.IE6.css
vendored
@@ -1,20 +1,20 @@
|
|||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
#fbToolbarSearch {
|
#fbToolbarSearch {
|
||||||
background-image: url(search.gif) !important;
|
background-image: url(search.gif) !important;
|
||||||
}
|
}
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
.fbErrors {
|
.fbErrors {
|
||||||
background-image: url(errorIcon.gif) !important;
|
background-image: url(errorIcon.gif) !important;
|
||||||
}
|
}
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
.logRow-info {
|
.logRow-info {
|
||||||
background-image: url(infoIcon.gif) !important;
|
background-image: url(infoIcon.gif) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logRow-warning {
|
.logRow-warning {
|
||||||
background-image: url(warningIcon.gif) !important;
|
background-image: url(warningIcon.gif) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logRow-error {
|
.logRow-error {
|
||||||
background-image: url(errorIcon.gif) !important;
|
background-image: url(errorIcon.gif) !important;
|
||||||
}
|
}
|
||||||
|
|||||||
6294
vendor/firebug-lite/skin/xp/firebug.css
vendored
6294
vendor/firebug-lite/skin/xp/firebug.css
vendored
File diff suppressed because it is too large
Load Diff
428
vendor/firebug-lite/skin/xp/firebug.html
vendored
428
vendor/firebug-lite/skin/xp/firebug.html
vendored
@@ -1,215 +1,215 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/DTD/strict.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/DTD/strict.dtd">
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||||
<title>Firebug Lite</title>
|
<title>Firebug Lite</title>
|
||||||
<!-- An empty script to avoid FOUC when loading the stylesheet -->
|
<!-- An empty script to avoid FOUC when loading the stylesheet -->
|
||||||
<script type="text/javascript"></script>
|
<script type="text/javascript"></script>
|
||||||
<style type="text/css" media="screen">@import "firebug.css";</style>
|
<style type="text/css" media="screen">@import "firebug.css";</style>
|
||||||
<style>html,body{margin:0;padding:0;overflow:hidden;}</style>
|
<style>html,body{margin:0;padding:0;overflow:hidden;}</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="fbBody">
|
<body class="fbBody">
|
||||||
<table id="fbChrome" cellpadding="0" cellspacing="0" border="0">
|
<table id="fbChrome" cellpadding="0" cellspacing="0" border="0">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<!-- Interface - Top Area -->
|
<!-- Interface - Top Area -->
|
||||||
<td id="fbTop" colspan="2">
|
<td id="fbTop" colspan="2">
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
<div>
|
<div>
|
||||||
--><!-- <span id="fbToolbarErrors" class="fbErrors">2 errors</span> --><!--
|
--><!-- <span id="fbToolbarErrors" class="fbErrors">2 errors</span> --><!--
|
||||||
<input type="text" id="fbToolbarSearch" />
|
<input type="text" id="fbToolbarSearch" />
|
||||||
</div>
|
</div>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Window Buttons -->
|
<!-- Window Buttons -->
|
||||||
<div id="fbWindowButtons">
|
<div id="fbWindowButtons">
|
||||||
<a id="fbWindow_btDeactivate" class="fbSmallButton fbHover" title="Deactivate Firebug for this web page"> </a>
|
<a id="fbWindow_btDeactivate" class="fbSmallButton fbHover" title="Deactivate Firebug for this web page"> </a>
|
||||||
<a id="fbWindow_btDetach" class="fbSmallButton fbHover" title="Open Firebug in popup window"> </a>
|
<a id="fbWindow_btDetach" class="fbSmallButton fbHover" title="Open Firebug in popup window"> </a>
|
||||||
<a id="fbWindow_btClose" class="fbSmallButton fbHover" title="Minimize Firebug"> </a>
|
<a id="fbWindow_btClose" class="fbSmallButton fbHover" title="Minimize Firebug"> </a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Toolbar buttons and Status Bar -->
|
<!-- Toolbar buttons and Status Bar -->
|
||||||
<div id="fbToolbar">
|
<div id="fbToolbar">
|
||||||
<div id="fbToolbarContent">
|
<div id="fbToolbarContent">
|
||||||
|
|
||||||
<!-- Firebug Button -->
|
<!-- Firebug Button -->
|
||||||
<span id="fbToolbarIcon">
|
<span id="fbToolbarIcon">
|
||||||
<a id="fbFirebugButton" class="fbIconButton" class="fbHover" target="_blank"> </a>
|
<a id="fbFirebugButton" class="fbIconButton" class="fbHover" target="_blank"> </a>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
<span id="fbLeftToolbarErrors" class="fbErrors">2 errors</span>
|
<span id="fbLeftToolbarErrors" class="fbErrors">2 errors</span>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Toolbar Buttons -->
|
<!-- Toolbar Buttons -->
|
||||||
<span id="fbToolbarButtons">
|
<span id="fbToolbarButtons">
|
||||||
<!-- Fixed Toolbar Buttons -->
|
<!-- Fixed Toolbar Buttons -->
|
||||||
<span id="fbFixedButtons">
|
<span id="fbFixedButtons">
|
||||||
<a id="fbChrome_btInspect" class="fbButton fbHover" title="Click an element in the page to inspect">Inspect</a>
|
<a id="fbChrome_btInspect" class="fbButton fbHover" title="Click an element in the page to inspect">Inspect</a>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<!-- Console Panel Toolbar Buttons -->
|
<!-- Console Panel Toolbar Buttons -->
|
||||||
<span id="fbConsoleButtons" class="fbToolbarButtons">
|
<span id="fbConsoleButtons" class="fbToolbarButtons">
|
||||||
<a id="fbConsole_btClear" class="fbButton fbHover" title="Clear the console">Clear</a>
|
<a id="fbConsole_btClear" class="fbButton fbHover" title="Clear the console">Clear</a>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<!-- HTML Panel Toolbar Buttons -->
|
<!-- HTML Panel Toolbar Buttons -->
|
||||||
<!--
|
<!--
|
||||||
<span id="fbHTMLButtons" class="fbToolbarButtons">
|
<span id="fbHTMLButtons" class="fbToolbarButtons">
|
||||||
<a id="fbHTML_btEdit" class="fbHover" title="Edit this HTML">Edit</a>
|
<a id="fbHTML_btEdit" class="fbHover" title="Edit this HTML">Edit</a>
|
||||||
</span>
|
</span>
|
||||||
-->
|
-->
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<!-- Status Bar -->
|
<!-- Status Bar -->
|
||||||
<span id="fbStatusBarBox">
|
<span id="fbStatusBarBox">
|
||||||
<span class="fbToolbarSeparator"></span>
|
<span class="fbToolbarSeparator"></span>
|
||||||
<!-- HTML Panel Status Bar -->
|
<!-- HTML Panel Status Bar -->
|
||||||
<!--
|
<!--
|
||||||
<span id="fbHTMLStatusBar" class="fbStatusBar fbToolbarButtons">
|
<span id="fbHTMLStatusBar" class="fbStatusBar fbToolbarButtons">
|
||||||
</span>
|
</span>
|
||||||
-->
|
-->
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- PanelBars -->
|
<!-- PanelBars -->
|
||||||
<div id="fbPanelBarBox">
|
<div id="fbPanelBarBox">
|
||||||
|
|
||||||
<!-- Main PanelBar -->
|
<!-- Main PanelBar -->
|
||||||
<div id="fbPanelBar1" class="fbPanelBar">
|
<div id="fbPanelBar1" class="fbPanelBar">
|
||||||
<a id="fbConsoleTab" class="fbTab fbHover">
|
<a id="fbConsoleTab" class="fbTab fbHover">
|
||||||
<span class="fbTabL"></span>
|
<span class="fbTabL"></span>
|
||||||
<span class="fbTabText">Console</span>
|
<span class="fbTabText">Console</span>
|
||||||
<span class="fbTabMenuTarget"></span>
|
<span class="fbTabMenuTarget"></span>
|
||||||
<span class="fbTabR"></span>
|
<span class="fbTabR"></span>
|
||||||
</a>
|
</a>
|
||||||
<a id="fbHTMLTab" class="fbTab fbHover">
|
<a id="fbHTMLTab" class="fbTab fbHover">
|
||||||
<span class="fbTabL"></span>
|
<span class="fbTabL"></span>
|
||||||
<span class="fbTabText">HTML</span>
|
<span class="fbTabText">HTML</span>
|
||||||
<span class="fbTabR"></span>
|
<span class="fbTabR"></span>
|
||||||
</a>
|
</a>
|
||||||
<a class="fbTab fbHover">
|
<a class="fbTab fbHover">
|
||||||
<span class="fbTabL"></span>
|
<span class="fbTabL"></span>
|
||||||
<span class="fbTabText">CSS</span>
|
<span class="fbTabText">CSS</span>
|
||||||
<span class="fbTabR"></span>
|
<span class="fbTabR"></span>
|
||||||
</a>
|
</a>
|
||||||
<a class="fbTab fbHover">
|
<a class="fbTab fbHover">
|
||||||
<span class="fbTabL"></span>
|
<span class="fbTabL"></span>
|
||||||
<span class="fbTabText">Script</span>
|
<span class="fbTabText">Script</span>
|
||||||
<span class="fbTabR"></span>
|
<span class="fbTabR"></span>
|
||||||
</a>
|
</a>
|
||||||
<a class="fbTab fbHover">
|
<a class="fbTab fbHover">
|
||||||
<span class="fbTabL"></span>
|
<span class="fbTabL"></span>
|
||||||
<span class="fbTabText">DOM</span>
|
<span class="fbTabText">DOM</span>
|
||||||
<span class="fbTabR"></span>
|
<span class="fbTabR"></span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Side PanelBars -->
|
<!-- Side PanelBars -->
|
||||||
<div id="fbPanelBar2Box" class="hide">
|
<div id="fbPanelBar2Box" class="hide">
|
||||||
<div id="fbPanelBar2" class="fbPanelBar">
|
<div id="fbPanelBar2" class="fbPanelBar">
|
||||||
<!--
|
<!--
|
||||||
<a class="fbTab fbHover">
|
<a class="fbTab fbHover">
|
||||||
<span class="fbTabL"></span>
|
<span class="fbTabL"></span>
|
||||||
<span class="fbTabText">Style</span>
|
<span class="fbTabText">Style</span>
|
||||||
<span class="fbTabR"></span>
|
<span class="fbTabR"></span>
|
||||||
</a>
|
</a>
|
||||||
<a class="fbTab fbHover">
|
<a class="fbTab fbHover">
|
||||||
<span class="fbTabL"></span>
|
<span class="fbTabL"></span>
|
||||||
<span class="fbTabText">Layout</span>
|
<span class="fbTabText">Layout</span>
|
||||||
<span class="fbTabR"></span>
|
<span class="fbTabR"></span>
|
||||||
</a>
|
</a>
|
||||||
<a class="fbTab fbHover">
|
<a class="fbTab fbHover">
|
||||||
<span class="fbTabL"></span>
|
<span class="fbTabL"></span>
|
||||||
<span class="fbTabText">DOM</span>
|
<span class="fbTabText">DOM</span>
|
||||||
<span class="fbTabR"></span>
|
<span class="fbTabR"></span>
|
||||||
</a>
|
</a>
|
||||||
-->
|
-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Horizontal Splitter -->
|
<!-- Horizontal Splitter -->
|
||||||
<div id="fbHSplitter"> </div>
|
<div id="fbHSplitter"> </div>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<!-- Interface - Main Area -->
|
<!-- Interface - Main Area -->
|
||||||
<tr id="fbContent">
|
<tr id="fbContent">
|
||||||
|
|
||||||
<!-- Panels -->
|
<!-- Panels -->
|
||||||
<td id="fbPanelBox1">
|
<td id="fbPanelBox1">
|
||||||
<div id="fbPanel1" class="fbFitHeight">
|
<div id="fbPanel1" class="fbFitHeight">
|
||||||
<div id="fbConsole" class="fbPanel"></div>
|
<div id="fbConsole" class="fbPanel"></div>
|
||||||
<div id="fbHTML" class="fbPanel"></div>
|
<div id="fbHTML" class="fbPanel"></div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<!-- Side Panel Box -->
|
<!-- Side Panel Box -->
|
||||||
<td id="fbPanelBox2" class="hide">
|
<td id="fbPanelBox2" class="hide">
|
||||||
|
|
||||||
<!-- VerticalSplitter -->
|
<!-- VerticalSplitter -->
|
||||||
<div id="fbVSplitter" class="fbVSplitter"> </div>
|
<div id="fbVSplitter" class="fbVSplitter"> </div>
|
||||||
|
|
||||||
<!-- Side Panels -->
|
<!-- Side Panels -->
|
||||||
<div id="fbPanel2" class="fbFitHeight">
|
<div id="fbPanel2" class="fbFitHeight">
|
||||||
|
|
||||||
<!-- HTML Side Panels -->
|
<!-- HTML Side Panels -->
|
||||||
<div id="fbHTML_Style" class="fbPanel"></div>
|
<div id="fbHTML_Style" class="fbPanel"></div>
|
||||||
<div id="fbHTML_Layout" class="fbPanel"></div>
|
<div id="fbHTML_Layout" class="fbPanel"></div>
|
||||||
<div id="fbHTML_DOM" class="fbPanel"></div>
|
<div id="fbHTML_DOM" class="fbPanel"></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Large Command Line -->
|
<!-- Large Command Line -->
|
||||||
<textarea id="fbLargeCommandLine" class="fbFitHeight"></textarea>
|
<textarea id="fbLargeCommandLine" class="fbFitHeight"></textarea>
|
||||||
|
|
||||||
<!-- Large Command Line Buttons -->
|
<!-- Large Command Line Buttons -->
|
||||||
<div id="fbLargeCommandButtons">
|
<div id="fbLargeCommandButtons">
|
||||||
<a id="fbCommand_btRun" class="fbButton fbHover">Run</a>
|
<a id="fbCommand_btRun" class="fbButton fbHover">Run</a>
|
||||||
<a id="fbCommand_btClear" class="fbButton fbHover">Clear</a>
|
<a id="fbCommand_btClear" class="fbButton fbHover">Clear</a>
|
||||||
|
|
||||||
<a id="fbSmallCommandLineIcon" class="fbSmallButton fbHover"></a>
|
<a id="fbSmallCommandLineIcon" class="fbSmallButton fbHover"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<!-- Interface - Bottom Area -->
|
<!-- Interface - Bottom Area -->
|
||||||
<tr id="fbBottom" class="hide">
|
<tr id="fbBottom" class="hide">
|
||||||
|
|
||||||
<!-- Command Line -->
|
<!-- Command Line -->
|
||||||
<td id="fbCommand" colspan="2">
|
<td id="fbCommand" colspan="2">
|
||||||
<div id="fbCommandBox">
|
<div id="fbCommandBox">
|
||||||
<div id="fbCommandIcon">>>></div>
|
<div id="fbCommandIcon">>>></div>
|
||||||
<input id="fbCommandLine" name="fbCommandLine" type="text" />
|
<input id="fbCommandLine" name="fbCommandLine" type="text" />
|
||||||
<a id="fbLargeCommandLineIcon" class="fbSmallButton fbHover"></a>
|
<a id="fbLargeCommandLineIcon" class="fbSmallButton fbHover"></a>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<span id="fbMiniChrome">
|
<span id="fbMiniChrome">
|
||||||
<span id="fbMiniContent">
|
<span id="fbMiniContent">
|
||||||
<span id="fbMiniIcon" title="Open Firebug Lite"></span>
|
<span id="fbMiniIcon" title="Open Firebug Lite"></span>
|
||||||
<span id="fbMiniErrors" class="fbErrors"><!-- 2 errors --></span>
|
<span id="fbMiniErrors" class="fbErrors"><!-- 2 errors --></span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<!--
|
<!--
|
||||||
<div id="fbErrorPopup">
|
<div id="fbErrorPopup">
|
||||||
<div id="fbErrorPopupContent">
|
<div id="fbErrorPopupContent">
|
||||||
<div id="fbErrorIndicator" class="fbErrors">2 errors</div>
|
<div id="fbErrorIndicator" class="fbErrors">2 errors</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
-->
|
-->
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
542
vendor/firebug-lite/skin/xp/html.css
vendored
542
vendor/firebug-lite/skin/xp/html.css
vendored
@@ -1,272 +1,272 @@
|
|||||||
/* See license.txt for terms of usage */
|
/* See license.txt for terms of usage */
|
||||||
|
|
||||||
.panelNode-html {
|
.panelNode-html {
|
||||||
-moz-box-sizing: padding-box;
|
-moz-box-sizing: padding-box;
|
||||||
padding: 4px 0 0 2px;
|
padding: 4px 0 0 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeBox {
|
.nodeBox {
|
||||||
position: relative;
|
position: relative;
|
||||||
font-family: Monaco, monospace;
|
font-family: Monaco, monospace;
|
||||||
padding-left: 13px;
|
padding-left: 13px;
|
||||||
-moz-user-select: -moz-none;
|
-moz-user-select: -moz-none;
|
||||||
}
|
}
|
||||||
.nodeBox.search-selection {
|
.nodeBox.search-selection {
|
||||||
-moz-user-select: text;
|
-moz-user-select: text;
|
||||||
}
|
}
|
||||||
.twisty {
|
.twisty {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
width: 14px;
|
width: 14px;
|
||||||
height: 14px;
|
height: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeChildBox {
|
.nodeChildBox {
|
||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeLabel,
|
.nodeLabel,
|
||||||
.nodeCloseLabel {
|
.nodeCloseLabel {
|
||||||
margin: -2px 2px 0 2px;
|
margin: -2px 2px 0 2px;
|
||||||
border: 2px solid transparent;
|
border: 2px solid transparent;
|
||||||
-moz-border-radius: 3px;
|
-moz-border-radius: 3px;
|
||||||
padding: 0 2px;
|
padding: 0 2px;
|
||||||
color: #000088;
|
color: #000088;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeCloseLabel {
|
.nodeCloseLabel {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeTag {
|
.nodeTag {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: blue;
|
color: blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeValue {
|
.nodeValue {
|
||||||
color: #FF0000;
|
color: #FF0000;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeText,
|
.nodeText,
|
||||||
.nodeComment {
|
.nodeComment {
|
||||||
margin: 0 2px;
|
margin: 0 2px;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeText {
|
.nodeText {
|
||||||
color: #333333;
|
color: #333333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeWhiteSpace {
|
.nodeWhiteSpace {
|
||||||
border: 1px solid LightGray;
|
border: 1px solid LightGray;
|
||||||
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
|
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
|
||||||
margin-left: 1px;
|
margin-left: 1px;
|
||||||
color: gray;
|
color: gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.nodeWhiteSpace_Space {
|
.nodeWhiteSpace_Space {
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeTextEntity {
|
.nodeTextEntity {
|
||||||
border: 1px solid gray;
|
border: 1px solid gray;
|
||||||
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
|
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
|
||||||
margin-left: 1px;
|
margin-left: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeComment {
|
.nodeComment {
|
||||||
color: DarkGreen;
|
color: DarkGreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
.nodeBox.highlightOpen > .nodeLabel {
|
.nodeBox.highlightOpen > .nodeLabel {
|
||||||
background-color: #EEEEEE;
|
background-color: #EEEEEE;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeBox.highlightOpen > .nodeCloseLabel,
|
.nodeBox.highlightOpen > .nodeCloseLabel,
|
||||||
.nodeBox.highlightOpen > .nodeChildBox,
|
.nodeBox.highlightOpen > .nodeChildBox,
|
||||||
.nodeBox.open > .nodeCloseLabel,
|
.nodeBox.open > .nodeCloseLabel,
|
||||||
.nodeBox.open > .nodeChildBox {
|
.nodeBox.open > .nodeChildBox {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
|
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
|
||||||
.nodeBox.selected > .nodeLabel {
|
.nodeBox.selected > .nodeLabel {
|
||||||
border-color: Highlight;
|
border-color: Highlight;
|
||||||
background-color: Highlight;
|
background-color: Highlight;
|
||||||
color: HighlightText !important;
|
color: HighlightText !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
|
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
|
||||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
|
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
|
||||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
|
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
|
||||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText {
|
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText {
|
||||||
color: inherit !important;
|
color: inherit !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
.nodeBox.highlighted > .nodeLabel {
|
.nodeBox.highlighted > .nodeLabel {
|
||||||
border-color: Highlight !important;
|
border-color: Highlight !important;
|
||||||
background-color: cyan !important;
|
background-color: cyan !important;
|
||||||
color: #000000 !important;
|
color: #000000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox,
|
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox,
|
||||||
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeTag,
|
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeTag,
|
||||||
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
|
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
|
||||||
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeText {
|
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeText {
|
||||||
color: #000000 !important;
|
color: #000000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox,
|
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox,
|
||||||
.nodeBox.nodeHidden .nodeCloseLabel,
|
.nodeBox.nodeHidden .nodeCloseLabel,
|
||||||
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeText,
|
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeText,
|
||||||
.nodeBox.nodeHidden .nodeText {
|
.nodeBox.nodeHidden .nodeText {
|
||||||
color: #888888;
|
color: #888888;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeTag,
|
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeTag,
|
||||||
.nodeBox.nodeHidden .nodeCloseLabel > .nodeCloseLabelBox > .nodeTag {
|
.nodeBox.nodeHidden .nodeCloseLabel > .nodeCloseLabelBox > .nodeTag {
|
||||||
color: #5F82D9;
|
color: #5F82D9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue {
|
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue {
|
||||||
color: #D86060;
|
color: #D86060;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox,
|
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox,
|
||||||
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
|
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
|
||||||
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
|
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
|
||||||
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeText {
|
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeText {
|
||||||
color: SkyBlue !important;
|
color: SkyBlue !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
.nodeBox.mutated > .nodeLabel,
|
.nodeBox.mutated > .nodeLabel,
|
||||||
.nodeAttr.mutated,
|
.nodeAttr.mutated,
|
||||||
.nodeValue.mutated,
|
.nodeValue.mutated,
|
||||||
.nodeText.mutated,
|
.nodeText.mutated,
|
||||||
.nodeBox.mutated > .nodeText {
|
.nodeBox.mutated > .nodeText {
|
||||||
background-color: #EFFF79;
|
background-color: #EFFF79;
|
||||||
color: #FF0000 !important;
|
color: #FF0000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nodeBox.selected.mutated > .nodeLabel,
|
.nodeBox.selected.mutated > .nodeLabel,
|
||||||
.nodeBox.selected.mutated > .nodeLabel > .nodeLabelBox,
|
.nodeBox.selected.mutated > .nodeLabel > .nodeLabelBox,
|
||||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr.mutated > .nodeValue,
|
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr.mutated > .nodeValue,
|
||||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue.mutated,
|
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue.mutated,
|
||||||
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText.mutated {
|
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText.mutated {
|
||||||
background-color: #EFFF79;
|
background-color: #EFFF79;
|
||||||
border-color: #EFFF79;
|
border-color: #EFFF79;
|
||||||
color: #FF0000 !important;
|
color: #FF0000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
|
|
||||||
.logRow-dirxml {
|
.logRow-dirxml {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.soloElement > .nodeBox {
|
.soloElement > .nodeBox {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.useA11y .nodeLabel.focused {
|
.useA11y .nodeLabel.focused {
|
||||||
outline: 2px solid #FF9933;
|
outline: 2px solid #FF9933;
|
||||||
-moz-outline-radius: 3px;
|
-moz-outline-radius: 3px;
|
||||||
outline-offset: -2px;
|
outline-offset: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.useA11y .nodeLabelBox:focus {
|
.useA11y .nodeLabelBox:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
|
|
||||||
.breakpointCode .twisty {
|
.breakpointCode .twisty {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointCode .nodeBox.containerNodeBox,
|
.breakpointCode .nodeBox.containerNodeBox,
|
||||||
.breakpointCode .nodeLabel {
|
.breakpointCode .nodeLabel {
|
||||||
padding-left: 0px;
|
padding-left: 0px;
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
font-family: Monaco, monospace !important;
|
font-family: Monaco, monospace !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointCode .nodeTag,
|
.breakpointCode .nodeTag,
|
||||||
.breakpointCode .nodeAttr,
|
.breakpointCode .nodeAttr,
|
||||||
.breakpointCode .nodeText,
|
.breakpointCode .nodeText,
|
||||||
.breakpointCode .nodeValue,
|
.breakpointCode .nodeValue,
|
||||||
.breakpointCode .nodeLabel {
|
.breakpointCode .nodeLabel {
|
||||||
color: DarkGreen !important;
|
color: DarkGreen !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breakpointMutationType {
|
.breakpointMutationType {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 4px;
|
top: 4px;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
color: gray;
|
color: gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************************************/
|
/************************************************************************************************/
|
||||||
/* Twisties */
|
/* Twisties */
|
||||||
|
|
||||||
.twisty,
|
.twisty,
|
||||||
.logRow-errorMessage > .hasTwisty > .errorTitle,
|
.logRow-errorMessage > .hasTwisty > .errorTitle,
|
||||||
.logRow-log > .objectBox-array.hasTwisty,
|
.logRow-log > .objectBox-array.hasTwisty,
|
||||||
.logRow-spy .spyHead .spyTitle,
|
.logRow-spy .spyHead .spyTitle,
|
||||||
.logGroup > .logRow,
|
.logGroup > .logRow,
|
||||||
.memberRow.hasChildren > .memberLabelCell > .memberLabel,
|
.memberRow.hasChildren > .memberLabelCell > .memberLabel,
|
||||||
.hasHeaders .netHrefLabel,
|
.hasHeaders .netHrefLabel,
|
||||||
.netPageRow > .netCol > .netPageTitle {
|
.netPageRow > .netCol > .netPageTitle {
|
||||||
background-image: url(twistyClosed.png);
|
background-image: url(twistyClosed.png);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 2px 2px;
|
background-position: 2px 2px;
|
||||||
min-height: 12px;
|
min-height: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logRow-errorMessage > .hasTwisty.opened > .errorTitle,
|
.logRow-errorMessage > .hasTwisty.opened > .errorTitle,
|
||||||
.logRow-log > .objectBox-array.hasTwisty.opened,
|
.logRow-log > .objectBox-array.hasTwisty.opened,
|
||||||
.logRow-spy.opened .spyHead .spyTitle,
|
.logRow-spy.opened .spyHead .spyTitle,
|
||||||
.logGroup.opened > .logRow,
|
.logGroup.opened > .logRow,
|
||||||
.memberRow.hasChildren.opened > .memberLabelCell > .memberLabel,
|
.memberRow.hasChildren.opened > .memberLabelCell > .memberLabel,
|
||||||
.nodeBox.highlightOpen > .nodeLabel > .twisty,
|
.nodeBox.highlightOpen > .nodeLabel > .twisty,
|
||||||
.nodeBox.open > .nodeLabel > .twisty,
|
.nodeBox.open > .nodeLabel > .twisty,
|
||||||
.netRow.opened > .netCol > .netHrefLabel,
|
.netRow.opened > .netCol > .netHrefLabel,
|
||||||
.netPageRow.opened > .netCol > .netPageTitle {
|
.netPageRow.opened > .netCol > .netPageTitle {
|
||||||
background-image: url(twistyOpen.png);
|
background-image: url(twistyOpen.png);
|
||||||
}
|
}
|
||||||
|
|
||||||
.twisty {
|
.twisty {
|
||||||
background-position: 4px 4px;
|
background-position: 4px 4px;
|
||||||
}
|
}
|
||||||
12
vendor/firebug-lite/skin/xp/roundCorner.svg
vendored
12
vendor/firebug-lite/skin/xp/roundCorner.svg
vendored
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
<rect fill="white" x="0" y="0" width="100%" height="100%" />
|
<rect fill="white" x="0" y="0" width="100%" height="100%" />
|
||||||
<rect fill="highlight" x="0" y="0" width="100%" height="100%" rx="2px"/>
|
<rect fill="highlight" x="0" y="0" width="100%" height="100%" rx="2px"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 228 B |
@@ -6258,7 +6258,7 @@ FBL.Firebug =
|
|||||||
{
|
{
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
version: "Firebug Lite 1.4.0",
|
version: "Firebug Lite 1.4.0",
|
||||||
revision: "$Revision: 11967 $",
|
revision: "$Revision$",
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
modules: modules,
|
modules: modules,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
http://www.JSON.org/json2.js
|
json2.js
|
||||||
2009-09-29
|
2015-02-25
|
||||||
|
|
||||||
Public Domain.
|
Public Domain.
|
||||||
|
|
||||||
@@ -48,7 +48,9 @@
|
|||||||
Date.prototype.toJSON = function (key) {
|
Date.prototype.toJSON = function (key) {
|
||||||
function f(n) {
|
function f(n) {
|
||||||
// Format integers to have at least two digits.
|
// Format integers to have at least two digits.
|
||||||
return n < 10 ? '0' + n : n;
|
return n < 10
|
||||||
|
? '0' + n
|
||||||
|
: n;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.getUTCFullYear() + '-' +
|
return this.getUTCFullYear() + '-' +
|
||||||
@@ -146,10 +148,12 @@
|
|||||||
redistribute.
|
redistribute.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*jslint evil: true, strict: false */
|
/*jslint
|
||||||
|
eval, for, this
|
||||||
|
*/
|
||||||
|
|
||||||
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
|
/*property
|
||||||
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
|
JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
|
||||||
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
|
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
|
||||||
lastIndex, length, parse, prototype, push, replace, slice, stringify,
|
lastIndex, length, parse, prototype, push, replace, slice, stringify,
|
||||||
test, toJSON, toString, valueOf
|
test, toJSON, toString, valueOf
|
||||||
@@ -159,50 +163,48 @@
|
|||||||
// Create a JSON object only if one does not already exist. We create the
|
// Create a JSON object only if one does not already exist. We create the
|
||||||
// methods in a closure to avoid creating global variables.
|
// methods in a closure to avoid creating global variables.
|
||||||
|
|
||||||
if (!this.JSON) {
|
if (typeof JSON !== 'object') {
|
||||||
this.JSON = {};
|
JSON = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
function f(n) {
|
function f(n) {
|
||||||
// Format integers to have at least two digits.
|
// Format integers to have at least two digits.
|
||||||
return n < 10 ? '0' + n : n;
|
return n < 10
|
||||||
|
? '0' + n
|
||||||
|
: n;
|
||||||
|
}
|
||||||
|
|
||||||
|
function this_value() {
|
||||||
|
return this.valueOf();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof Date.prototype.toJSON !== 'function') {
|
if (typeof Date.prototype.toJSON !== 'function') {
|
||||||
|
|
||||||
Date.prototype.toJSON = function (key) {
|
Date.prototype.toJSON = function () {
|
||||||
|
|
||||||
return isFinite(this.valueOf()) ?
|
return isFinite(this.valueOf())
|
||||||
this.getUTCFullYear() + '-' +
|
? this.getUTCFullYear() + '-' +
|
||||||
f(this.getUTCMonth() + 1) + '-' +
|
f(this.getUTCMonth() + 1) + '-' +
|
||||||
f(this.getUTCDate()) + 'T' +
|
f(this.getUTCDate()) + 'T' +
|
||||||
f(this.getUTCHours()) + ':' +
|
f(this.getUTCHours()) + ':' +
|
||||||
f(this.getUTCMinutes()) + ':' +
|
f(this.getUTCMinutes()) + ':' +
|
||||||
f(this.getUTCSeconds()) + 'Z' : null;
|
f(this.getUTCSeconds()) + 'Z'
|
||||||
|
: null;
|
||||||
};
|
};
|
||||||
|
|
||||||
String.prototype.toJSON =
|
Boolean.prototype.toJSON = this_value;
|
||||||
Number.prototype.toJSON =
|
Number.prototype.toJSON = this_value;
|
||||||
Boolean.prototype.toJSON = function (key) {
|
String.prototype.toJSON = this_value;
|
||||||
return this.valueOf();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
var cx,
|
||||||
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
|
escapable,
|
||||||
gap,
|
gap,
|
||||||
indent,
|
indent,
|
||||||
meta = { // table of character substitutions
|
meta,
|
||||||
'\b': '\\b',
|
|
||||||
'\t': '\\t',
|
|
||||||
'\n': '\\n',
|
|
||||||
'\f': '\\f',
|
|
||||||
'\r': '\\r',
|
|
||||||
'"' : '\\"',
|
|
||||||
'\\': '\\\\'
|
|
||||||
},
|
|
||||||
rep;
|
rep;
|
||||||
|
|
||||||
|
|
||||||
@@ -214,13 +216,14 @@ if (!this.JSON) {
|
|||||||
// sequences.
|
// sequences.
|
||||||
|
|
||||||
escapable.lastIndex = 0;
|
escapable.lastIndex = 0;
|
||||||
return escapable.test(string) ?
|
return escapable.test(string)
|
||||||
'"' + string.replace(escapable, function (a) {
|
? '"' + string.replace(escapable, function (a) {
|
||||||
var c = meta[a];
|
var c = meta[a];
|
||||||
return typeof c === 'string' ? c :
|
return typeof c === 'string'
|
||||||
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
? c
|
||||||
}) + '"' :
|
: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||||
'"' + string + '"';
|
}) + '"'
|
||||||
|
: '"' + string + '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -260,7 +263,9 @@ if (!this.JSON) {
|
|||||||
|
|
||||||
// JSON numbers must be finite. Encode non-finite numbers as null.
|
// JSON numbers must be finite. Encode non-finite numbers as null.
|
||||||
|
|
||||||
return isFinite(value) ? String(value) : 'null';
|
return isFinite(value)
|
||||||
|
? String(value)
|
||||||
|
: 'null';
|
||||||
|
|
||||||
case 'boolean':
|
case 'boolean':
|
||||||
case 'null':
|
case 'null':
|
||||||
@@ -303,11 +308,11 @@ if (!this.JSON) {
|
|||||||
// Join all of the elements together, separated with commas, and wrap them in
|
// Join all of the elements together, separated with commas, and wrap them in
|
||||||
// brackets.
|
// brackets.
|
||||||
|
|
||||||
v = partial.length === 0 ? '[]' :
|
v = partial.length === 0
|
||||||
gap ? '[\n' + gap +
|
? '[]'
|
||||||
partial.join(',\n' + gap) + '\n' +
|
: gap
|
||||||
mind + ']' :
|
? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
|
||||||
'[' + partial.join(',') + ']';
|
: '[' + partial.join(',') + ']';
|
||||||
gap = mind;
|
gap = mind;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
@@ -317,11 +322,15 @@ if (!this.JSON) {
|
|||||||
if (rep && typeof rep === 'object') {
|
if (rep && typeof rep === 'object') {
|
||||||
length = rep.length;
|
length = rep.length;
|
||||||
for (i = 0; i < length; i += 1) {
|
for (i = 0; i < length; i += 1) {
|
||||||
k = rep[i];
|
if (typeof rep[i] === 'string') {
|
||||||
if (typeof k === 'string') {
|
k = rep[i];
|
||||||
v = str(k, value);
|
v = str(k, value);
|
||||||
if (v) {
|
if (v) {
|
||||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
partial.push(quote(k) + (
|
||||||
|
gap
|
||||||
|
? ': '
|
||||||
|
: ':'
|
||||||
|
) + v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -330,10 +339,14 @@ if (!this.JSON) {
|
|||||||
// Otherwise, iterate through all of the keys in the object.
|
// Otherwise, iterate through all of the keys in the object.
|
||||||
|
|
||||||
for (k in value) {
|
for (k in value) {
|
||||||
if (Object.hasOwnProperty.call(value, k)) {
|
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||||
v = str(k, value);
|
v = str(k, value);
|
||||||
if (v) {
|
if (v) {
|
||||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
partial.push(quote(k) + (
|
||||||
|
gap
|
||||||
|
? ': '
|
||||||
|
: ':'
|
||||||
|
) + v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -342,9 +355,11 @@ if (!this.JSON) {
|
|||||||
// Join all of the member texts together, separated with commas,
|
// Join all of the member texts together, separated with commas,
|
||||||
// and wrap them in braces.
|
// and wrap them in braces.
|
||||||
|
|
||||||
v = partial.length === 0 ? '{}' :
|
v = partial.length === 0
|
||||||
gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
|
? '{}'
|
||||||
mind + '}' : '{' + partial.join(',') + '}';
|
: gap
|
||||||
|
? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
|
||||||
|
: '{' + partial.join(',') + '}';
|
||||||
gap = mind;
|
gap = mind;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
@@ -353,6 +368,16 @@ if (!this.JSON) {
|
|||||||
// If the JSON object does not yet have a stringify method, give it one.
|
// If the JSON object does not yet have a stringify method, give it one.
|
||||||
|
|
||||||
if (typeof JSON.stringify !== 'function') {
|
if (typeof JSON.stringify !== 'function') {
|
||||||
|
escapable = /[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
|
||||||
|
meta = { // table of character substitutions
|
||||||
|
'\b': '\\b',
|
||||||
|
'\t': '\\t',
|
||||||
|
'\n': '\\n',
|
||||||
|
'\f': '\\f',
|
||||||
|
'\r': '\\r',
|
||||||
|
'"': '\\"',
|
||||||
|
'\\': '\\\\'
|
||||||
|
};
|
||||||
JSON.stringify = function (value, replacer, space) {
|
JSON.stringify = function (value, replacer, space) {
|
||||||
|
|
||||||
// The stringify method takes a value and an optional replacer, and an optional
|
// The stringify method takes a value and an optional replacer, and an optional
|
||||||
@@ -385,7 +410,7 @@ if (!this.JSON) {
|
|||||||
rep = replacer;
|
rep = replacer;
|
||||||
if (replacer && typeof replacer !== 'function' &&
|
if (replacer && typeof replacer !== 'function' &&
|
||||||
(typeof replacer !== 'object' ||
|
(typeof replacer !== 'object' ||
|
||||||
typeof replacer.length !== 'number')) {
|
typeof replacer.length !== 'number')) {
|
||||||
throw new Error('JSON.stringify');
|
throw new Error('JSON.stringify');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,6 +425,7 @@ if (!this.JSON) {
|
|||||||
// If the JSON object does not yet have a parse method, give it one.
|
// If the JSON object does not yet have a parse method, give it one.
|
||||||
|
|
||||||
if (typeof JSON.parse !== 'function') {
|
if (typeof JSON.parse !== 'function') {
|
||||||
|
cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
|
||||||
JSON.parse = function (text, reviver) {
|
JSON.parse = function (text, reviver) {
|
||||||
|
|
||||||
// The parse method takes a text and an optional reviver function, and returns
|
// The parse method takes a text and an optional reviver function, and returns
|
||||||
@@ -415,7 +441,7 @@ if (!this.JSON) {
|
|||||||
var k, v, value = holder[key];
|
var k, v, value = holder[key];
|
||||||
if (value && typeof value === 'object') {
|
if (value && typeof value === 'object') {
|
||||||
for (k in value) {
|
for (k in value) {
|
||||||
if (Object.hasOwnProperty.call(value, k)) {
|
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||||
v = walk(value, k);
|
v = walk(value, k);
|
||||||
if (v !== undefined) {
|
if (v !== undefined) {
|
||||||
value[k] = v;
|
value[k] = v;
|
||||||
@@ -433,11 +459,12 @@ if (!this.JSON) {
|
|||||||
// Unicode characters with escape sequences. JavaScript handles many characters
|
// Unicode characters with escape sequences. JavaScript handles many characters
|
||||||
// incorrectly, either silently deleting them, or treating them as line endings.
|
// incorrectly, either silently deleting them, or treating them as line endings.
|
||||||
|
|
||||||
|
text = String(text);
|
||||||
cx.lastIndex = 0;
|
cx.lastIndex = 0;
|
||||||
if (cx.test(text)) {
|
if (cx.test(text)) {
|
||||||
text = text.replace(cx, function (a) {
|
text = text.replace(cx, function (a) {
|
||||||
return '\\u' +
|
return '\\u' +
|
||||||
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,10 +481,13 @@ if (!this.JSON) {
|
|||||||
// we look to see that the remaining characters are only whitespace or ']' or
|
// we look to see that the remaining characters are only whitespace or ']' or
|
||||||
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
|
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
|
||||||
|
|
||||||
if (/^[\],:{}\s]*$/.
|
if (
|
||||||
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
|
/^[\],:{}\s]*$/.test(
|
||||||
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
|
text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
|
||||||
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
|
||||||
|
.replace(/(?:^|:|,)(?:\s*\[)+/g, '')
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
|
||||||
// In the third stage we use the eval function to compile the text into a
|
// In the third stage we use the eval function to compile the text into a
|
||||||
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
|
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
|
||||||
@@ -469,8 +499,9 @@ replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
|||||||
// In the optional fourth stage, we recursively walk the new structure, passing
|
// In the optional fourth stage, we recursively walk the new structure, passing
|
||||||
// each name/value pair to a reviver function for possible transformation.
|
// each name/value pair to a reviver function for possible transformation.
|
||||||
|
|
||||||
return typeof reviver === 'function' ?
|
return typeof reviver === 'function'
|
||||||
walk({'': j}, '') : j;
|
? walk({'': j}, '')
|
||||||
|
: j;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
||||||
@@ -478,4 +509,4 @@ replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
|||||||
throw new SyntaxError('JSON.parse');
|
throw new SyntaxError('JSON.parse');
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}());
|
}());
|
||||||
20
vendor/platform.js/LICENSE.txt
vendored
20
vendor/platform.js/LICENSE.txt
vendored
@@ -1,20 +0,0 @@
|
|||||||
Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
|
|
||||||
|
|
||||||
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.
|
|
||||||
98
vendor/platform.js/README.md
vendored
98
vendor/platform.js/README.md
vendored
@@ -1,98 +0,0 @@
|
|||||||
# Platform.js <sup>v1.0.0</sup>
|
|
||||||
|
|
||||||
A platform detection library that works on nearly all JavaScript platforms<sup><a name="fnref1" href="#fn1">1</a></sup>.
|
|
||||||
|
|
||||||
## Disclaimer
|
|
||||||
|
|
||||||
Platform.js is for informational purposes only and **not** intended as a substitution for [feature detection/inference](http://allyoucanleet.com/post/18087210413/feature-testing-costs#screencast2) checks.
|
|
||||||
|
|
||||||
## BestieJS
|
|
||||||
|
|
||||||
Platform.js is part of the BestieJS *"Best in Class"* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation.
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
The documentation for Platform.js can be viewed here: [/doc/README.md](https://github.com/bestiejs/platform.js/blob/master/doc/README.md#readme)
|
|
||||||
|
|
||||||
For a list of upcoming features, check out our [roadmap](https://github.com/bestiejs/platform.js/wiki/Roadmap).
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
Platform.js has been tested in at least Adobe AIR 3.1, Chrome 5-21, Firefox 1.5-13, IE 6-9, Opera 9.25-12.01, Safari 3-6, Node.js 0.8.6, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5.
|
|
||||||
|
|
||||||
## Installation and usage
|
|
||||||
|
|
||||||
In a browser or Adobe AIR:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<script src="platform.js"></script>
|
|
||||||
```
|
|
||||||
|
|
||||||
Via [npm](http://npmjs.org/):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install platform
|
|
||||||
```
|
|
||||||
|
|
||||||
In [Node.js](http://nodejs.org/) and [RingoJS](http://ringojs.org/):
|
|
||||||
|
|
||||||
```js
|
|
||||||
var platform = require('platform');
|
|
||||||
```
|
|
||||||
|
|
||||||
In [Rhino](http://www.mozilla.org/rhino/):
|
|
||||||
|
|
||||||
```js
|
|
||||||
load('platform.js');
|
|
||||||
```
|
|
||||||
|
|
||||||
In an AMD loader like [RequireJS](http://requirejs.org/):
|
|
||||||
|
|
||||||
```js
|
|
||||||
require({
|
|
||||||
'paths': {
|
|
||||||
'platform': 'path/to/platform'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
['platform'], function(platform) {
|
|
||||||
console.log(platform.name);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Usage example:
|
|
||||||
|
|
||||||
```js
|
|
||||||
// on IE10 x86 platform preview running in IE7 compatibility mode on Windows 7 64 bit edition
|
|
||||||
platform.name; // 'IE'
|
|
||||||
platform.version; // '10.0'
|
|
||||||
platform.layout; // 'Trident'
|
|
||||||
platform.os; // 'Windows Server 2008 R2 / 7 x64'
|
|
||||||
platform.description; // 'IE 10.0 x86 (platform preview; running in IE 7 mode) on Windows Server 2008 R2 / 7 x64'
|
|
||||||
|
|
||||||
// or on an iPad
|
|
||||||
platform.name; // 'Safari'
|
|
||||||
platform.version; // '5.1'
|
|
||||||
platform.product; // 'iPad'
|
|
||||||
platform.manufacturer; // 'Apple'
|
|
||||||
platform.layout; // 'WebKit'
|
|
||||||
platform.os; // 'iOS 5.0'
|
|
||||||
platform.description; // 'Safari 5.1 on Apple iPad (iOS 5.0)'
|
|
||||||
|
|
||||||
// or parsing a given UA string
|
|
||||||
var info = platform.parse('Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7.2; en; rv:2.0) Gecko/20100101 Firefox/4.0 Opera 11.52');
|
|
||||||
info.name; // 'Opera'
|
|
||||||
info.version; // '11.52'
|
|
||||||
info.layout; // 'Presto'
|
|
||||||
info.os; // 'Mac OS X 10.7.2'
|
|
||||||
info.description; // 'Opera 11.52 (identifying as Firefox 4.0) on Mac OS X 10.7.2'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Author
|
|
||||||
|
|
||||||
* [John-David Dalton](http://allyoucanleet.com/)
|
|
||||||
[](https://twitter.com/jdalton "Follow @jdalton on Twitter")
|
|
||||||
|
|
||||||
## Contributors
|
|
||||||
|
|
||||||
* [Mathias Bynens](http://mathiasbynens.be/)
|
|
||||||
[](https://twitter.com/mathias "Follow @mathias on Twitter")
|
|
||||||
996
vendor/platform.js/platform.js
vendored
996
vendor/platform.js/platform.js
vendored
@@ -1,996 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Platform.js v1.0.0 <http://mths.be/platform>
|
|
||||||
* Copyright 2010-2012 John-David Dalton <http://allyoucanleet.com/>
|
|
||||||
* Available under MIT license <http://mths.be/mit>
|
|
||||||
*/
|
|
||||||
;(function(window) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/** Backup possible window/global object */
|
|
||||||
var oldWin = window;
|
|
||||||
|
|
||||||
/** Detect free variable `exports` */
|
|
||||||
var freeExports = typeof exports == 'object' && exports;
|
|
||||||
|
|
||||||
/** Detect free variable `global` */
|
|
||||||
var freeGlobal = typeof global == 'object' && global &&
|
|
||||||
(global == global.global ? (window = global) : global);
|
|
||||||
|
|
||||||
/** Opera regexp */
|
|
||||||
var reOpera = /Opera/;
|
|
||||||
|
|
||||||
/** Used to resolve a value's internal [[Class]] */
|
|
||||||
var toString = {}.toString;
|
|
||||||
|
|
||||||
/** Detect Java environment */
|
|
||||||
var java = /Java/.test(getClassOf(window.java)) && window.java;
|
|
||||||
|
|
||||||
/** A character to represent alpha */
|
|
||||||
var alpha = java ? 'a' : '\u03b1';
|
|
||||||
|
|
||||||
/** A character to represent beta */
|
|
||||||
var beta = java ? 'b' : '\u03b2';
|
|
||||||
|
|
||||||
/** Browser document object */
|
|
||||||
var doc = window.document || {};
|
|
||||||
|
|
||||||
/** Used to check for own properties of an object */
|
|
||||||
var hasOwnProperty = {}.hasOwnProperty;
|
|
||||||
|
|
||||||
/** Browser navigator object */
|
|
||||||
var nav = window.navigator || {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detect Opera browser
|
|
||||||
* http://www.howtocreate.co.uk/operaStuff/operaObject.html
|
|
||||||
* http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini
|
|
||||||
*/
|
|
||||||
var opera = window.operamini || window.opera;
|
|
||||||
|
|
||||||
/** Opera [[Class]] */
|
|
||||||
var operaClass = reOpera.test(operaClass = getClassOf(opera)) ? operaClass : (opera = null);
|
|
||||||
|
|
||||||
/** Possible global object */
|
|
||||||
var thisBinding = this;
|
|
||||||
|
|
||||||
/** Browser user agent string */
|
|
||||||
var userAgent = nav.userAgent || '';
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Capitalizes a string value.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {String} string The string to capitalize.
|
|
||||||
* @returns {String} The capitalized string.
|
|
||||||
*/
|
|
||||||
function capitalize(string) {
|
|
||||||
string = String(string);
|
|
||||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An iteration utility for arrays and objects.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Array|Object} object The object to iterate over.
|
|
||||||
* @param {Function} callback The function called per iteration.
|
|
||||||
*/
|
|
||||||
function each(object, callback) {
|
|
||||||
var index = -1,
|
|
||||||
length = object.length;
|
|
||||||
|
|
||||||
if (length == length >>> 0) {
|
|
||||||
while (++index < length) {
|
|
||||||
callback(object[index], index, object);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
forOwn(object, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trim and conditionally capitalize string values.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {String} string The string to format.
|
|
||||||
* @returns {String} The formatted string.
|
|
||||||
*/
|
|
||||||
function format(string) {
|
|
||||||
string = trim(string);
|
|
||||||
return /^(?:webOS|i(?:OS|P))/.test(string)
|
|
||||||
? string
|
|
||||||
: capitalize(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterates over an object's own properties, executing the `callback` for each.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Object} object The object to iterate over.
|
|
||||||
* @param {Function} callback The function executed per own property.
|
|
||||||
*/
|
|
||||||
function forOwn(object, callback) {
|
|
||||||
for (var key in object) {
|
|
||||||
hasKey(object, key) && callback(object[key], key, object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the internal [[Class]] of a value.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Mixed} value The value.
|
|
||||||
* @returns {String} The [[Class]].
|
|
||||||
*/
|
|
||||||
function getClassOf(value) {
|
|
||||||
return value == null
|
|
||||||
? capitalize(value)
|
|
||||||
: toString.call(value).slice(8, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if an object has the specified key as a direct property.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Object} object The object to check.
|
|
||||||
* @param {String} key The key to check for.
|
|
||||||
* @returns {Boolean} Returns `true` if key is a direct property, else `false`.
|
|
||||||
*/
|
|
||||||
function hasKey() {
|
|
||||||
// lazy define for others (not as accurate)
|
|
||||||
hasKey = function(object, key) {
|
|
||||||
var parent = object != null && (object.constructor || Object).prototype;
|
|
||||||
return !!parent && key in Object(object) && !(key in parent && object[key] === parent[key]);
|
|
||||||
};
|
|
||||||
// for modern browsers
|
|
||||||
if (getClassOf(hasOwnProperty) == 'Function') {
|
|
||||||
hasKey = function(object, key) {
|
|
||||||
return object != null && hasOwnProperty.call(object, key);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// for Safari 2
|
|
||||||
else if ({}.__proto__ == Object.prototype) {
|
|
||||||
hasKey = function(object, key) {
|
|
||||||
var result = false;
|
|
||||||
if (object != null) {
|
|
||||||
object = Object(object);
|
|
||||||
object.__proto__ = [object.__proto__, object.__proto__ = null, result = key in object][0];
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return hasKey.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Host objects can return type values that are different from their actual
|
|
||||||
* data type. The objects we are concerned with usually return non-primitive
|
|
||||||
* types of object, function, or unknown.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Mixed} object The owner of the property.
|
|
||||||
* @param {String} property The property to check.
|
|
||||||
* @returns {Boolean} Returns `true` if the property value is a non-primitive, else `false`.
|
|
||||||
*/
|
|
||||||
function isHostType(object, property) {
|
|
||||||
var type = object != null ? typeof object[property] : 'number';
|
|
||||||
return !/^(?:boolean|number|string|undefined)$/.test(type) &&
|
|
||||||
(type == 'object' ? !!object[property] : true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepares a string for use in a RegExp constructor by making hyphens and
|
|
||||||
* spaces optional.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {String} string The string to qualify.
|
|
||||||
* @returns {String} The qualified string.
|
|
||||||
*/
|
|
||||||
function qualify(string) {
|
|
||||||
return String(string).replace(/([ -])(?!$)/g, '$1?');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A bare-bones` Array#reduce` like utility function.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Array} array The array to iterate over.
|
|
||||||
* @param {Function} callback The function called per iteration.
|
|
||||||
* @param {Mixed} accumulator Initial value of the accumulator.
|
|
||||||
* @returns {Mixed} The accumulator.
|
|
||||||
*/
|
|
||||||
function reduce(array, callback) {
|
|
||||||
var accumulator = null;
|
|
||||||
each(array, function(value, index) {
|
|
||||||
accumulator = callback(accumulator, value, index, array);
|
|
||||||
});
|
|
||||||
return accumulator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes leading and trailing whitespace from a string.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {String} string The string to trim.
|
|
||||||
* @returns {String} The trimmed string.
|
|
||||||
*/
|
|
||||||
function trim(string) {
|
|
||||||
return String(string).replace(/^ +| +$/g, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new platform object.
|
|
||||||
*
|
|
||||||
* @memberOf platform
|
|
||||||
* @param {String} [ua = navigator.userAgent] The user agent string.
|
|
||||||
* @returns {Object} A platform object.
|
|
||||||
*/
|
|
||||||
function parse(ua) {
|
|
||||||
|
|
||||||
ua || (ua = userAgent);
|
|
||||||
|
|
||||||
/** Temporary variable used over the script's lifetime */
|
|
||||||
var data;
|
|
||||||
|
|
||||||
/** The CPU architecture */
|
|
||||||
var arch = ua;
|
|
||||||
|
|
||||||
/** Platform description array */
|
|
||||||
var description = [];
|
|
||||||
|
|
||||||
/** Platform alpha/beta indicator */
|
|
||||||
var prerelease = null;
|
|
||||||
|
|
||||||
/** A flag to indicate that environment features should be used to resolve the platform */
|
|
||||||
var useFeatures = ua == userAgent;
|
|
||||||
|
|
||||||
/** The browser/environment version */
|
|
||||||
var version = useFeatures && opera && typeof opera.version == 'function' && opera.version();
|
|
||||||
|
|
||||||
/* Detectable layout engines (order is important) */
|
|
||||||
var layout = getLayout([
|
|
||||||
{ 'label': 'WebKit', 'pattern': 'AppleWebKit' },
|
|
||||||
'iCab',
|
|
||||||
'Presto',
|
|
||||||
'NetFront',
|
|
||||||
'Tasman',
|
|
||||||
'Trident',
|
|
||||||
'KHTML',
|
|
||||||
'Gecko'
|
|
||||||
]);
|
|
||||||
|
|
||||||
/* Detectable browser names (order is important) */
|
|
||||||
var name = getName([
|
|
||||||
'Adobe AIR',
|
|
||||||
'Arora',
|
|
||||||
'Avant Browser',
|
|
||||||
'Camino',
|
|
||||||
'Epiphany',
|
|
||||||
'Fennec',
|
|
||||||
'Flock',
|
|
||||||
'Galeon',
|
|
||||||
'GreenBrowser',
|
|
||||||
'iCab',
|
|
||||||
'Iceweasel',
|
|
||||||
'Iron',
|
|
||||||
'K-Meleon',
|
|
||||||
'Konqueror',
|
|
||||||
'Lunascape',
|
|
||||||
'Maxthon',
|
|
||||||
'Midori',
|
|
||||||
'Nook Browser',
|
|
||||||
'PhantomJS',
|
|
||||||
'Raven',
|
|
||||||
'Rekonq',
|
|
||||||
'RockMelt',
|
|
||||||
'SeaMonkey',
|
|
||||||
{ 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' },
|
|
||||||
'Sleipnir',
|
|
||||||
'SlimBrowser',
|
|
||||||
'Sunrise',
|
|
||||||
'Swiftfox',
|
|
||||||
'WebPositive',
|
|
||||||
'Opera Mini',
|
|
||||||
'Opera',
|
|
||||||
'Chrome',
|
|
||||||
{ 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' },
|
|
||||||
{ 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' },
|
|
||||||
{ 'label': 'IE', 'pattern': 'MSIE' },
|
|
||||||
'Safari'
|
|
||||||
]);
|
|
||||||
|
|
||||||
/* Detectable products (order is important) */
|
|
||||||
var product = getProduct([
|
|
||||||
'BlackBerry',
|
|
||||||
{ 'label': 'Galaxy S', 'pattern': 'GT-I9000' },
|
|
||||||
{ 'label': 'Galaxy S2', 'pattern': 'GT-I9100' },
|
|
||||||
'Google TV',
|
|
||||||
'iPad',
|
|
||||||
'iPod',
|
|
||||||
'iPhone',
|
|
||||||
'Kindle',
|
|
||||||
{ 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' },
|
|
||||||
'Nook',
|
|
||||||
'PlayBook',
|
|
||||||
'PlayStation Vita',
|
|
||||||
'TouchPad',
|
|
||||||
'Transformer',
|
|
||||||
'Xoom'
|
|
||||||
]);
|
|
||||||
|
|
||||||
/* Detectable manufacturers */
|
|
||||||
var manufacturer = getManufacturer({
|
|
||||||
'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 },
|
|
||||||
'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 },
|
|
||||||
'Asus': { 'Transformer': 1 },
|
|
||||||
'Barnes & Noble': { 'Nook': 1 },
|
|
||||||
'BlackBerry': { 'PlayBook': 1 },
|
|
||||||
'Google': { 'Google TV': 1 },
|
|
||||||
'HP': { 'TouchPad': 1 },
|
|
||||||
'LG': { },
|
|
||||||
'Motorola': { 'Xoom': 1 },
|
|
||||||
'Nokia': { },
|
|
||||||
'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1 },
|
|
||||||
'Sony': { 'PlayStation Vita': 1 }
|
|
||||||
});
|
|
||||||
|
|
||||||
/* Detectable OSes (order is important) */
|
|
||||||
var os = getOS([
|
|
||||||
'Android',
|
|
||||||
'CentOS',
|
|
||||||
'Debian',
|
|
||||||
'Fedora',
|
|
||||||
'FreeBSD',
|
|
||||||
'Gentoo',
|
|
||||||
'Haiku',
|
|
||||||
'Kubuntu',
|
|
||||||
'Linux Mint',
|
|
||||||
'Red Hat',
|
|
||||||
'SuSE',
|
|
||||||
'Ubuntu',
|
|
||||||
'Xubuntu',
|
|
||||||
'Cygwin',
|
|
||||||
'Symbian OS',
|
|
||||||
'hpwOS',
|
|
||||||
'webOS ',
|
|
||||||
'webOS',
|
|
||||||
'Tablet OS',
|
|
||||||
'Linux',
|
|
||||||
'Mac OS X',
|
|
||||||
'Macintosh',
|
|
||||||
'Mac',
|
|
||||||
'Windows 98;',
|
|
||||||
'Windows '
|
|
||||||
]);
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Picks the layout engine from an array of guesses.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Array} guesses An array of guesses.
|
|
||||||
* @returns {String|Null} The detected layout engine.
|
|
||||||
*/
|
|
||||||
function getLayout(guesses) {
|
|
||||||
return reduce(guesses, function(result, guess) {
|
|
||||||
return result || RegExp('\\b' + (
|
|
||||||
guess.pattern || qualify(guess)
|
|
||||||
) + '\\b', 'i').exec(ua) && (guess.label || guess);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Picks the manufacturer from an array of guesses.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Array} guesses An array of guesses.
|
|
||||||
* @returns {String|Null} The detected manufacturer.
|
|
||||||
*/
|
|
||||||
function getManufacturer(guesses) {
|
|
||||||
return reduce(guesses, function(result, value, key) {
|
|
||||||
// lookup the manufacturer by product or scan the UA for the manufacturer
|
|
||||||
return result || (
|
|
||||||
value[product] ||
|
|
||||||
value[0/*Opera 9.25 fix*/, /^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] ||
|
|
||||||
RegExp('\\b' + (key.pattern || qualify(key)) + '(?:\\b|\\w*\\d)', 'i').exec(ua)
|
|
||||||
) && (key.label || key);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Picks the browser name from an array of guesses.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Array} guesses An array of guesses.
|
|
||||||
* @returns {String|Null} The detected browser name.
|
|
||||||
*/
|
|
||||||
function getName(guesses) {
|
|
||||||
return reduce(guesses, function(result, guess) {
|
|
||||||
return result || RegExp('\\b' + (
|
|
||||||
guess.pattern || qualify(guess)
|
|
||||||
) + '\\b', 'i').exec(ua) && (guess.label || guess);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Picks the OS name from an array of guesses.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Array} guesses An array of guesses.
|
|
||||||
* @returns {String|Null} The detected OS name.
|
|
||||||
*/
|
|
||||||
function getOS(guesses) {
|
|
||||||
return reduce(guesses, function(result, guess) {
|
|
||||||
var pattern = guess.pattern || qualify(guess);
|
|
||||||
if (!result && (result =
|
|
||||||
RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua))) {
|
|
||||||
// platform tokens defined at
|
|
||||||
// http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
|
|
||||||
// http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
|
|
||||||
data = {
|
|
||||||
'6.2': '8',
|
|
||||||
'6.1': 'Server 2008 R2 / 7',
|
|
||||||
'6.0': 'Server 2008 / Vista',
|
|
||||||
'5.2': 'Server 2003 / XP 64-bit',
|
|
||||||
'5.1': 'XP',
|
|
||||||
'5.01': '2000 SP1',
|
|
||||||
'5.0': '2000',
|
|
||||||
'4.0': 'NT',
|
|
||||||
'4.90': 'ME'
|
|
||||||
};
|
|
||||||
// detect Windows version from platform tokens
|
|
||||||
if (/^Win/i.test(result) &&
|
|
||||||
(data = data[0/*Opera 9.25 fix*/, /[\d.]+$/.exec(result)])) {
|
|
||||||
result = 'Windows ' + data;
|
|
||||||
}
|
|
||||||
// correct character case and cleanup
|
|
||||||
result = format(String(result)
|
|
||||||
.replace(RegExp(pattern, 'i'), guess.label || guess)
|
|
||||||
.replace(/ ce$/i, ' CE')
|
|
||||||
.replace(/hpw/i, 'web')
|
|
||||||
.replace(/Macintosh/, 'Mac OS')
|
|
||||||
.replace(/_PowerPC/i, ' OS')
|
|
||||||
.replace(/(OS X) [^ \d]+/i, '$1')
|
|
||||||
.replace(/\/(\d)/, ' $1')
|
|
||||||
.replace(/_/g, '.')
|
|
||||||
.replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '')
|
|
||||||
.replace(/x86\.64/gi, 'x86_64')
|
|
||||||
.split(' on ')[0]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Picks the product name from an array of guesses.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Array} guesses An array of guesses.
|
|
||||||
* @returns {String|Null} The detected product name.
|
|
||||||
*/
|
|
||||||
function getProduct(guesses) {
|
|
||||||
return reduce(guesses, function(result, guess) {
|
|
||||||
var pattern = guess.pattern || qualify(guess);
|
|
||||||
if (!result && (result =
|
|
||||||
RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) ||
|
|
||||||
RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua)
|
|
||||||
)) {
|
|
||||||
// split by forward slash and append product version if needed
|
|
||||||
if ((result = String(guess.label || result).split('/'))[1] && !/[\d.]+/.test(result[0])) {
|
|
||||||
result[0] += ' ' + result[1];
|
|
||||||
}
|
|
||||||
// correct character case and cleanup
|
|
||||||
guess = guess.label || guess;
|
|
||||||
result = format(result[0]
|
|
||||||
.replace(RegExp(pattern, 'i'), guess)
|
|
||||||
.replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ')
|
|
||||||
.replace(RegExp('(' + guess + ')(\\w)', 'i'), '$1 $2'));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the version using an array of UA patterns.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Array} patterns An array of UA patterns.
|
|
||||||
* @returns {String|Null} The detected version.
|
|
||||||
*/
|
|
||||||
function getVersion(patterns) {
|
|
||||||
return reduce(patterns, function(result, pattern) {
|
|
||||||
return result || (RegExp(pattern +
|
|
||||||
'(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns `platform.description` when the platform object is coerced to a string.
|
|
||||||
*
|
|
||||||
* @name toString
|
|
||||||
* @memberOf platform
|
|
||||||
* @returns {String} Returns `platform.description` if available, else an empty string.
|
|
||||||
*/
|
|
||||||
function toStringPlatform() {
|
|
||||||
return this.description || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
// convert layout to an array so we can add extra details
|
|
||||||
layout && (layout = [layout]);
|
|
||||||
|
|
||||||
// detect product names that contain their manufacturer's name
|
|
||||||
if (manufacturer && !product) {
|
|
||||||
product = getProduct([manufacturer]);
|
|
||||||
}
|
|
||||||
// clean up Google TV
|
|
||||||
if ((data = /Google TV/.exec(product))) {
|
|
||||||
product = data[0];
|
|
||||||
}
|
|
||||||
// detect simulators
|
|
||||||
if (/\bSimulator\b/i.test(ua)) {
|
|
||||||
product = (product ? product + ' ' : '') + 'Simulator';
|
|
||||||
}
|
|
||||||
// detect iOS
|
|
||||||
if (/^iP/.test(product)) {
|
|
||||||
name || (name = 'Safari');
|
|
||||||
os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua))
|
|
||||||
? ' ' + data[1].replace(/_/g, '.')
|
|
||||||
: '');
|
|
||||||
}
|
|
||||||
// detect Kubuntu
|
|
||||||
else if (name == 'Konqueror' && !/buntu/i.test(os)) {
|
|
||||||
os = 'Kubuntu';
|
|
||||||
}
|
|
||||||
// detect Android browsers
|
|
||||||
else if (manufacturer && manufacturer != 'Google' &&
|
|
||||||
/Chrome|Vita/.test(name + ';' + product)) {
|
|
||||||
name = 'Android Browser';
|
|
||||||
os = /Android/.test(os) ? os : 'Android';
|
|
||||||
}
|
|
||||||
// detect false positives for Firefox/Safari
|
|
||||||
else if (!name || (data = !/\bMinefield\b/i.test(ua) && /Firefox|Safari/.exec(name))) {
|
|
||||||
// escape the `/` for Firefox 1
|
|
||||||
if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) {
|
|
||||||
// clear name of false positives
|
|
||||||
name = null;
|
|
||||||
}
|
|
||||||
// reassign a generic name
|
|
||||||
if ((data = product || manufacturer || os) &&
|
|
||||||
(product || manufacturer || /Android|Symbian OS|Tablet OS|webOS/.test(os))) {
|
|
||||||
name = /[a-z]+(?: Hat)?/i.exec(/Android/.test(os) ? os : data) + ' Browser';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// detect non-Opera versions (order is important)
|
|
||||||
if (!version) {
|
|
||||||
version = getVersion([
|
|
||||||
'(?:Cloud9|CriOS|CrMo|Opera ?Mini|Raven|Silk(?!/[\\d.]+$))',
|
|
||||||
'Version',
|
|
||||||
qualify(name),
|
|
||||||
'(?:Firefox|Minefield|NetFront)'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
// detect stubborn layout engines
|
|
||||||
if (layout == 'iCab' && parseFloat(version) > 3) {
|
|
||||||
layout = ['WebKit'];
|
|
||||||
} else if (data =
|
|
||||||
/Opera/.test(name) && 'Presto' ||
|
|
||||||
/\b(?:Midori|Nook|Safari)\b/i.test(ua) && 'WebKit' ||
|
|
||||||
!layout && /\bMSIE\b/i.test(ua) && (/^Mac/.test(os) ? 'Tasman' : 'Trident')) {
|
|
||||||
layout = [data];
|
|
||||||
}
|
|
||||||
// leverage environment features
|
|
||||||
if (useFeatures) {
|
|
||||||
// detect server-side environments
|
|
||||||
// Rhino has a global function while others have a global object
|
|
||||||
if (isHostType(window, 'global')) {
|
|
||||||
if (java) {
|
|
||||||
data = java.lang.System;
|
|
||||||
arch = data.getProperty('os.arch');
|
|
||||||
os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version');
|
|
||||||
}
|
|
||||||
if (typeof exports == 'object' && exports) {
|
|
||||||
// if `thisBinding` is the [ModuleScope]
|
|
||||||
if (thisBinding == oldWin && typeof system == 'object' && (data = [system])[0]) {
|
|
||||||
os || (os = data[0].os || null);
|
|
||||||
try {
|
|
||||||
data[1] = require('ringo/engine').version;
|
|
||||||
version = data[1].join('.');
|
|
||||||
name = 'RingoJS';
|
|
||||||
} catch(e) {
|
|
||||||
if (data[0].global == freeGlobal) {
|
|
||||||
name = 'Narwhal';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (typeof process == 'object' && (data = process)) {
|
|
||||||
name = 'Node.js';
|
|
||||||
arch = data.arch;
|
|
||||||
os = data.platform;
|
|
||||||
version = /[\d.]+/.exec(data.version)[0];
|
|
||||||
}
|
|
||||||
} else if (getClassOf(window.environment) == 'Environment') {
|
|
||||||
name = 'Rhino';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// detect Adobe AIR
|
|
||||||
else if (getClassOf(data = window.runtime) == 'ScriptBridgingProxyObject') {
|
|
||||||
name = 'Adobe AIR';
|
|
||||||
os = data.flash.system.Capabilities.os;
|
|
||||||
}
|
|
||||||
// detect PhantomJS
|
|
||||||
else if (getClassOf(data = window.phantom) == 'RuntimeObject') {
|
|
||||||
name = 'PhantomJS';
|
|
||||||
version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch);
|
|
||||||
}
|
|
||||||
// detect IE compatibility modes
|
|
||||||
else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) {
|
|
||||||
// we're in compatibility mode when the Trident version + 4 doesn't
|
|
||||||
// equal the document mode
|
|
||||||
version = [version, doc.documentMode];
|
|
||||||
if ((data = +data[1] + 4) != version[1]) {
|
|
||||||
description.push('IE ' + version[1] + ' mode');
|
|
||||||
layout[1] = '';
|
|
||||||
version[1] = data;
|
|
||||||
}
|
|
||||||
version = name == 'IE' ? String(version[1].toFixed(1)) : version[0];
|
|
||||||
}
|
|
||||||
os = os && format(os);
|
|
||||||
}
|
|
||||||
// detect prerelease phases
|
|
||||||
if (version && (data =
|
|
||||||
/(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) ||
|
|
||||||
/(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) ||
|
|
||||||
/\bMinefield\b/i.test(ua) && 'a')) {
|
|
||||||
prerelease = /b/i.test(data) ? 'beta' : 'alpha';
|
|
||||||
version = version.replace(RegExp(data + '\\+?$'), '') +
|
|
||||||
(prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || '');
|
|
||||||
}
|
|
||||||
// rename code name "Fennec"
|
|
||||||
if (name == 'Fennec') {
|
|
||||||
name = 'Firefox Mobile';
|
|
||||||
}
|
|
||||||
// obscure Maxthon's unreliable version
|
|
||||||
else if (name == 'Maxthon' && version) {
|
|
||||||
version = version.replace(/\.[\d.]+/, '.x');
|
|
||||||
}
|
|
||||||
// detect Silk desktop/accelerated modes
|
|
||||||
else if (name == 'Silk') {
|
|
||||||
if (!/Mobi/i.test(ua)) {
|
|
||||||
os = 'Android';
|
|
||||||
description.unshift('desktop mode');
|
|
||||||
}
|
|
||||||
if (/Accelerated *= *true/i.test(ua)) {
|
|
||||||
description.unshift('accelerated');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// detect Windows Phone desktop mode
|
|
||||||
else if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) {
|
|
||||||
name += ' Mobile';
|
|
||||||
os = 'Windows Phone OS ' + data + '.x';
|
|
||||||
description.unshift('desktop mode');
|
|
||||||
}
|
|
||||||
// add mobile postfix
|
|
||||||
else if ((name == 'IE' || name && !product && !/Browser|Mobi/.test(name)) &&
|
|
||||||
(os == 'Windows CE' || /Mobi/i.test(ua))) {
|
|
||||||
name += ' Mobile';
|
|
||||||
}
|
|
||||||
// detect IE platform preview
|
|
||||||
else if (name == 'IE' && useFeatures && typeof external == 'object' && !external) {
|
|
||||||
description.unshift('platform preview');
|
|
||||||
}
|
|
||||||
// detect BlackBerry OS version
|
|
||||||
// http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp
|
|
||||||
else if (/BlackBerry/.test(product) && (data =
|
|
||||||
(RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] ||
|
|
||||||
version)) {
|
|
||||||
os = 'Device Software ' + data;
|
|
||||||
version = null;
|
|
||||||
}
|
|
||||||
// detect Opera identifying/masking itself as another browser
|
|
||||||
// http://www.opera.com/support/kb/view/843/
|
|
||||||
else if (this != forOwn && (
|
|
||||||
(useFeatures && opera) ||
|
|
||||||
(/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) ||
|
|
||||||
(name == 'Firefox' && /OS X (?:\d+\.){2,}/.test(os)) ||
|
|
||||||
(name == 'IE' && (
|
|
||||||
(os && !/^Win/.test(os) && version > 5.5) ||
|
|
||||||
/Windows XP/.test(os) && version > 8 ||
|
|
||||||
version == 8 && !/Trident/.test(ua)
|
|
||||||
))
|
|
||||||
) && !reOpera.test(data = parse.call(forOwn, ua.replace(reOpera, '') + ';')) && data.name) {
|
|
||||||
|
|
||||||
// when "indentifying", the UA contains both Opera and the other browser's name
|
|
||||||
data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : '');
|
|
||||||
if (reOpera.test(name)) {
|
|
||||||
if (/IE/.test(data) && os == 'Mac OS') {
|
|
||||||
os = null;
|
|
||||||
}
|
|
||||||
data = 'identify' + data;
|
|
||||||
}
|
|
||||||
// when "masking", the UA contains only the other browser's name
|
|
||||||
else {
|
|
||||||
data = 'mask' + data;
|
|
||||||
if (operaClass) {
|
|
||||||
name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2'));
|
|
||||||
} else {
|
|
||||||
name = 'Opera';
|
|
||||||
}
|
|
||||||
if (/IE/.test(data)) {
|
|
||||||
os = null;
|
|
||||||
}
|
|
||||||
if (!useFeatures) {
|
|
||||||
version = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
layout = ['Presto'];
|
|
||||||
description.push(data);
|
|
||||||
}
|
|
||||||
// detect WebKit Nightly and approximate Chrome/Safari versions
|
|
||||||
if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) {
|
|
||||||
// correct build for numeric comparison
|
|
||||||
// (e.g. "532.5" becomes "532.05")
|
|
||||||
data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data];
|
|
||||||
// nightly builds are postfixed with a `+`
|
|
||||||
if (name == 'Safari' && data[1].slice(-1) == '+') {
|
|
||||||
name = 'WebKit Nightly';
|
|
||||||
prerelease = 'alpha';
|
|
||||||
version = data[1].slice(0, -1);
|
|
||||||
}
|
|
||||||
// clear incorrect browser versions
|
|
||||||
else if (version == data[1] ||
|
|
||||||
version == (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1]) {
|
|
||||||
version = null;
|
|
||||||
}
|
|
||||||
// use the full Chrome version when available
|
|
||||||
data = [data[0], (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]];
|
|
||||||
|
|
||||||
// detect JavaScriptCore
|
|
||||||
// http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi
|
|
||||||
if (!useFeatures || (/internal|\n/i.test(toString.toString()) && !data[1])) {
|
|
||||||
layout[1] = 'like Safari';
|
|
||||||
data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : '5');
|
|
||||||
} else {
|
|
||||||
layout[1] = 'like Chrome';
|
|
||||||
data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : '21');
|
|
||||||
}
|
|
||||||
// add the postfix of ".x" or "+" for approximate versions
|
|
||||||
layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+');
|
|
||||||
// obscure version for some Safari 1-2 releases
|
|
||||||
if (name == 'Safari' && (!version || parseInt(version) > 45)) {
|
|
||||||
version = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// detect Opera desktop modes
|
|
||||||
if (name == 'Opera' && (data = /(?:zbov|zvav)$/.exec(os))) {
|
|
||||||
name += ' ';
|
|
||||||
description.unshift('desktop mode');
|
|
||||||
if (data == 'zvav') {
|
|
||||||
name += 'Mini';
|
|
||||||
version = null;
|
|
||||||
} else {
|
|
||||||
name += 'Mobile';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// detect Chrome desktop mode
|
|
||||||
else if (name == 'Safari' && /Chrome/.exec(layout[1])) {
|
|
||||||
description.unshift('desktop mode');
|
|
||||||
name = 'Chrome Mobile';
|
|
||||||
version = null;
|
|
||||||
|
|
||||||
if (/Mac OS X/.test(os)) {
|
|
||||||
manufacturer = 'Apple';
|
|
||||||
os = 'iOS 4.3+';
|
|
||||||
} else {
|
|
||||||
os = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// strip incorrect OS versions
|
|
||||||
if (version && version.indexOf(data = /[\d.]+$/.exec(os)) == 0 &&
|
|
||||||
ua.indexOf('/' + data + '-') > -1) {
|
|
||||||
os = trim(os.replace(data, ''));
|
|
||||||
}
|
|
||||||
// add layout engine
|
|
||||||
if (layout && !/Avant|Nook/.test(name) && (
|
|
||||||
/Browser|Lunascape|Maxthon/.test(name) ||
|
|
||||||
/^(?:Adobe|Arora|Midori|Phantom|Rekonq|Rock|Sleipnir|Web)/.test(name) && layout[1])) {
|
|
||||||
// don't add layout details to description if they are falsey
|
|
||||||
(data = layout[layout.length - 1]) && description.push(data);
|
|
||||||
}
|
|
||||||
// combine contextual information
|
|
||||||
if (description.length) {
|
|
||||||
description = ['(' + description.join('; ') + ')'];
|
|
||||||
}
|
|
||||||
// append manufacturer
|
|
||||||
if (manufacturer && product && product.indexOf(manufacturer) < 0) {
|
|
||||||
description.push('on ' + manufacturer);
|
|
||||||
}
|
|
||||||
// append product
|
|
||||||
if (product) {
|
|
||||||
description.push((/^on /.test(description[description.length -1]) ? '' : 'on ') + product);
|
|
||||||
}
|
|
||||||
// parse OS into an object
|
|
||||||
if (os) {
|
|
||||||
data = / ([\d.+]+)$/.exec(os);
|
|
||||||
os = {
|
|
||||||
'architecture': 32,
|
|
||||||
'family': data ? os.replace(data[0], '') : os,
|
|
||||||
'version': data ? data[1] : null,
|
|
||||||
'toString': function() {
|
|
||||||
var version = this.version;
|
|
||||||
return this.family + (version ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : '');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// add browser/OS architecture
|
|
||||||
if ((data = / (?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) {
|
|
||||||
if (os) {
|
|
||||||
os.architecture = 64;
|
|
||||||
os.family = os.family.replace(data, '');
|
|
||||||
}
|
|
||||||
if (name && (/WOW64/i.test(ua) ||
|
|
||||||
(useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform)))) {
|
|
||||||
description.unshift('32-bit');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ua || (ua = null);
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The platform object.
|
|
||||||
*
|
|
||||||
* @name platform
|
|
||||||
* @type Object
|
|
||||||
*/
|
|
||||||
return {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The browser/environment version.
|
|
||||||
*
|
|
||||||
* @memberOf platform
|
|
||||||
* @type String|Null
|
|
||||||
*/
|
|
||||||
'version': name && version && (description.unshift(version), version),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the browser/environment.
|
|
||||||
*
|
|
||||||
* @memberOf platform
|
|
||||||
* @type String|Null
|
|
||||||
*/
|
|
||||||
'name': name && (description.unshift(name), name),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the operating system.
|
|
||||||
*
|
|
||||||
* @memberOf platform
|
|
||||||
* @type Object
|
|
||||||
*/
|
|
||||||
'os': os
|
|
||||||
? (name &&
|
|
||||||
!(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product)) &&
|
|
||||||
description.push(product ? '(' + os + ')' : 'on ' + os), os)
|
|
||||||
: {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The CPU architecture the OS is built for.
|
|
||||||
*
|
|
||||||
* @memberOf platform.os
|
|
||||||
* @type String|Null
|
|
||||||
*/
|
|
||||||
'architecture': null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The family of the OS.
|
|
||||||
*
|
|
||||||
* @memberOf platform.os
|
|
||||||
* @type String|Null
|
|
||||||
*/
|
|
||||||
'family': null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The version of the OS.
|
|
||||||
*
|
|
||||||
* @memberOf platform.os
|
|
||||||
* @type String|Null
|
|
||||||
*/
|
|
||||||
'version': null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the OS string.
|
|
||||||
*
|
|
||||||
* @memberOf platform.os
|
|
||||||
* @returns {String} The OS string.
|
|
||||||
*/
|
|
||||||
'toString': function() { return 'null'; }
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The platform description.
|
|
||||||
*
|
|
||||||
* @memberOf platform
|
|
||||||
* @type String|Null
|
|
||||||
*/
|
|
||||||
'description': description.length ? description.join(' ') : ua,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the browser layout engine.
|
|
||||||
*
|
|
||||||
* @memberOf platform
|
|
||||||
* @type String|Null
|
|
||||||
*/
|
|
||||||
'layout': layout && layout[0],
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the product's manufacturer.
|
|
||||||
*
|
|
||||||
* @memberOf platform
|
|
||||||
* @type String|Null
|
|
||||||
*/
|
|
||||||
'manufacturer': manufacturer,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The alpha/beta release indicator.
|
|
||||||
*
|
|
||||||
* @memberOf platform
|
|
||||||
* @type String|Null
|
|
||||||
*/
|
|
||||||
'prerelease': prerelease,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the product hosting the browser.
|
|
||||||
*
|
|
||||||
* @memberOf platform
|
|
||||||
* @type String|Null
|
|
||||||
*/
|
|
||||||
'product': product,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The browser's user agent string.
|
|
||||||
*
|
|
||||||
* @memberOf platform
|
|
||||||
* @type String|Null
|
|
||||||
*/
|
|
||||||
'ua': ua,
|
|
||||||
|
|
||||||
// parses a user agent string into a platform object
|
|
||||||
'parse': parse,
|
|
||||||
|
|
||||||
// returns the platform description
|
|
||||||
'toString': toStringPlatform
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
// expose platform
|
|
||||||
// some AMD build optimizers, like r.js, check for specific condition patterns like the following:
|
|
||||||
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
|
|
||||||
// define as an anonymous module so, through path mapping, it can be aliased
|
|
||||||
define(function() {
|
|
||||||
return parse();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// check for `exports` after `define` in case a build optimizer adds an `exports` object
|
|
||||||
else if (freeExports) {
|
|
||||||
// in Narwhal, Node.js, or RingoJS
|
|
||||||
forOwn(parse(), function(value, key) {
|
|
||||||
freeExports[key] = value;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// in a browser or Rhino
|
|
||||||
else {
|
|
||||||
// use square bracket notation so Closure Compiler won't munge `platform`
|
|
||||||
// http://code.google.com/closure/compiler/docs/api-tutorial3.html#export
|
|
||||||
window['platform'] = parse();
|
|
||||||
}
|
|
||||||
}(this));
|
|
||||||
20
vendor/qunit-clib/LICENSE.txt
vendored
20
vendor/qunit-clib/LICENSE.txt
vendored
@@ -1,20 +0,0 @@
|
|||||||
Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
|
|
||||||
|
|
||||||
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.
|
|
||||||
57
vendor/qunit-clib/README.md
vendored
57
vendor/qunit-clib/README.md
vendored
@@ -1,57 +0,0 @@
|
|||||||
# QUnit CLIB <sup>v1.0.0</sup>
|
|
||||||
## command-line interface boilerplate
|
|
||||||
|
|
||||||
QUnit CLIB helps extend QUnit's CLI support to many common CLI environments.
|
|
||||||
|
|
||||||
## Screenshot
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
QUnit CLIB has been tested in at least Node.js 0.4.8-0.8.6, Narwhal v0.3.2, RingoJS v0.8.0, and Rhino v1.7RC3-RC5.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
(function(window) {
|
|
||||||
|
|
||||||
// use a single load function
|
|
||||||
var load = typeof require == 'function' ? require : window.load;
|
|
||||||
|
|
||||||
// load QUnit and CLIB if needed
|
|
||||||
var QUnit =
|
|
||||||
window.QUnit || (
|
|
||||||
window.setTimeout || (window.addEventListener = window.setTimeout = / /),
|
|
||||||
window.QUnit = load('path/to/qunit.js') || window.QUnit,
|
|
||||||
load('path/to/qunit-clib.js'),
|
|
||||||
(window.addEventListener || 0).test && delete window.addEventListener,
|
|
||||||
window.QUnit
|
|
||||||
);
|
|
||||||
|
|
||||||
// explicitly call `QUnit.module()` instead of `module()`
|
|
||||||
// in case we are in a CLI environment
|
|
||||||
QUnit.module('A Test Module');
|
|
||||||
|
|
||||||
test('A Test', function() {
|
|
||||||
// ...
|
|
||||||
});
|
|
||||||
|
|
||||||
// must call `QUnit.start()` if using QUnit < 1.3.0 with Node.js or any
|
|
||||||
// version of QUnit with Narwhal, Rhino, or RingoJS
|
|
||||||
if (!window.document) {
|
|
||||||
QUnit.start();
|
|
||||||
}
|
|
||||||
}(typeof global == 'object' && global || this));
|
|
||||||
```
|
|
||||||
|
|
||||||
## Footnotes
|
|
||||||
|
|
||||||
1. QUnit v1.3.0 does not work with Narwhal or Ringo < v0.8.0
|
|
||||||
|
|
||||||
2. Rhino v1.7RC4 does not support timeout fallbacks `clearTimeout` and `setTimeout`
|
|
||||||
|
|
||||||
## Author
|
|
||||||
|
|
||||||
* [John-David Dalton](http://allyoucanleet.com/)
|
|
||||||
[](https://twitter.com/jdalton "Follow @jdalton on Twitter")
|
|
||||||
319
vendor/qunit-clib/qunit-clib.js
vendored
319
vendor/qunit-clib/qunit-clib.js
vendored
@@ -1,319 +0,0 @@
|
|||||||
/*!
|
|
||||||
* QUnit CLI Boilerplate v1.0.0
|
|
||||||
* Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
|
|
||||||
* Based on a gist by Jörn Zaefferer <https://gist.github.com/722381>
|
|
||||||
* Available under MIT license <http://mths.be/mit>
|
|
||||||
*/
|
|
||||||
;(function(global) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/** Add `console.log()` support for Narwhal, Rhino, and RingoJS */
|
|
||||||
global.console || (global.console = { 'log': global.print });
|
|
||||||
|
|
||||||
/** Reduce global.QUnit.QUnit -> global.QUnit */
|
|
||||||
global.QUnit && (QUnit = QUnit.QUnit || QUnit);
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/** Used as a horizontal rule in console output */
|
|
||||||
var hr = '----------------------------------------';
|
|
||||||
|
|
||||||
/** Shortcut used to convert array-like objects to arrays */
|
|
||||||
var slice = [].slice;
|
|
||||||
|
|
||||||
/** Used to resolve a value's internal [[Class]] */
|
|
||||||
var toString = {}.toString;
|
|
||||||
|
|
||||||
/** Used by timer methods */
|
|
||||||
var doneCalled,
|
|
||||||
timer,
|
|
||||||
counter = 0,
|
|
||||||
ids = {};
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An iteration utility for arrays.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Array} array The array to iterate over.
|
|
||||||
* @param {Function} callback The function called per iteration.
|
|
||||||
*/
|
|
||||||
function each(array, callback) {
|
|
||||||
var index = -1,
|
|
||||||
length = array.length;
|
|
||||||
|
|
||||||
while (++index < length) {
|
|
||||||
callback(array[index], index, array);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the specified `value` is a function.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Mixed} value The value to check.
|
|
||||||
* @returns {Boolean} Returns `true` if `value` is a function, else `false`.
|
|
||||||
*/
|
|
||||||
function isFunction(value) {
|
|
||||||
return toString.call(value) == '[object Function]';
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Timeout fallbacks based on the work of Andrea Giammarchi and Weston C.
|
|
||||||
* https://github.com/WebReflection/wru/blob/master/src/rhinoTimers.js
|
|
||||||
* http://stackoverflow.com/questions/2261705/how-to-run-a-javascript-function-asynchronously-without-using-settimeout
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears the delay set by `setInterval` or `setTimeout`.
|
|
||||||
*
|
|
||||||
* @memberOf global
|
|
||||||
* @param {Number} id The ID of the timeout to be cleared.
|
|
||||||
*/
|
|
||||||
function clearTimer(id) {
|
|
||||||
if (ids[id]) {
|
|
||||||
ids[id].cancel();
|
|
||||||
timer.purge();
|
|
||||||
delete ids[id];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Schedules timer-based callbacks.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Function} fn The function to call.
|
|
||||||
* @oaram {Number} delay The number of milliseconds to delay the `fn` call.
|
|
||||||
* @param [arg1, arg2, ...] Arguments to invoke `fn` with.
|
|
||||||
* @param {Boolean} repeated A flag to specify whether `fn` is called repeatedly.
|
|
||||||
* @returns {Number} The the ID of the timeout.
|
|
||||||
*/
|
|
||||||
function schedule(fn, delay, args, repeated) {
|
|
||||||
// Rhino 1.7RC4 will error assigning `task` below
|
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=775566
|
|
||||||
var task = ids[++counter] = new JavaAdapter(java.util.TimerTask, {
|
|
||||||
'run': function() {
|
|
||||||
fn.apply(global, args);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// support non-functions
|
|
||||||
if (!isFunction(fn)) {
|
|
||||||
fn = (function(code) {
|
|
||||||
code = String(code);
|
|
||||||
return function() { eval(code); };
|
|
||||||
}(fn));
|
|
||||||
}
|
|
||||||
// used by setInterval
|
|
||||||
if (repeated) {
|
|
||||||
timer.schedule(task, delay, delay);
|
|
||||||
}
|
|
||||||
// used by setTimeout
|
|
||||||
else {
|
|
||||||
timer.schedule(task, delay);
|
|
||||||
}
|
|
||||||
return counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes a code snippet or function repeatedly, with a delay between each call.
|
|
||||||
*
|
|
||||||
* @memberOf global
|
|
||||||
* @param {Function|String} fn The function to call or string to evaluate.
|
|
||||||
* @oaram {Number} delay The number of milliseconds to delay each `fn` call.
|
|
||||||
* @param [arg1, arg2, ...] Arguments to invoke `fn` with.
|
|
||||||
* @returns {Number} The the ID of the timeout.
|
|
||||||
*/
|
|
||||||
function setInterval(fn, delay) {
|
|
||||||
return schedule(fn, delay, slice.call(arguments, 2), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes a code snippet or a function after specified delay.
|
|
||||||
*
|
|
||||||
* @memberOf global
|
|
||||||
* @param {Function|String} fn The function to call or string to evaluate.
|
|
||||||
* @oaram {Number} delay The number of milliseconds to delay the `fn` call.
|
|
||||||
* @param [arg1, arg2, ...] Arguments to invoke `fn` with.
|
|
||||||
* @returns {Number} The the ID of the timeout.
|
|
||||||
*/
|
|
||||||
function setTimeout(fn, delay) {
|
|
||||||
return schedule(fn, delay, slice.call(arguments, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A logging callback triggered when all testing is completed.
|
|
||||||
*
|
|
||||||
* @memberOf QUnit
|
|
||||||
* @param {Object} details An object with properties `failed`, `passed`,
|
|
||||||
* `runtime`, and `total`.
|
|
||||||
*/
|
|
||||||
function done(details) {
|
|
||||||
// stop `asyncTest()` from erroneously calling `done()` twice in
|
|
||||||
// environments w/o timeouts
|
|
||||||
if (doneCalled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
doneCalled = true;
|
|
||||||
console.log(hr);
|
|
||||||
console.log(' PASS: ' + details.passed + ' FAIL: ' + details.failed + ' TOTAL: ' + details.total);
|
|
||||||
console.log(' Finished in ' + details.runtime + ' milliseconds.');
|
|
||||||
console.log(hr);
|
|
||||||
|
|
||||||
// exit out of Rhino
|
|
||||||
try {
|
|
||||||
quit();
|
|
||||||
} catch(e) { }
|
|
||||||
|
|
||||||
// exit out of Node.js
|
|
||||||
try {
|
|
||||||
process.exit();
|
|
||||||
} catch(e) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A logging callback triggered after every assertion.
|
|
||||||
*
|
|
||||||
* @memberOf QUnit
|
|
||||||
* @param {Object} details An object with properties `actual`, `expected`,
|
|
||||||
* `message`, and `result`.
|
|
||||||
*/
|
|
||||||
function log(details) {
|
|
||||||
var expected = details.expected,
|
|
||||||
result = details.result,
|
|
||||||
type = typeof expected != 'undefined' ? 'EQ' : 'OK';
|
|
||||||
|
|
||||||
var assertion = [
|
|
||||||
result ? 'PASS' : 'FAIL',
|
|
||||||
type,
|
|
||||||
details.message || 'ok'
|
|
||||||
];
|
|
||||||
|
|
||||||
if (!result && type == 'EQ') {
|
|
||||||
assertion.push('Expected: ' + expected + ', Actual: ' + details.actual);
|
|
||||||
}
|
|
||||||
QUnit.config.testStats.assertions.push(assertion.join(' | '));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A logging callback triggered at the start of every test module.
|
|
||||||
*
|
|
||||||
* @memberOf QUnit
|
|
||||||
* @param {Object} details An object with property `name`.
|
|
||||||
*/
|
|
||||||
function moduleStart(details) {
|
|
||||||
console.log(hr);
|
|
||||||
console.log(details.name);
|
|
||||||
console.log(hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts an object into a string representation.
|
|
||||||
*
|
|
||||||
* @memberOf QUnit
|
|
||||||
* @type Function
|
|
||||||
* @param {Object} object The object to stringify.
|
|
||||||
* @returns {String} The result string.
|
|
||||||
*/
|
|
||||||
var parseObject = (function() {
|
|
||||||
var func = QUnit.jsDump.parsers.object;
|
|
||||||
return function(object) {
|
|
||||||
// fork to support Rhino's error objects
|
|
||||||
if (typeof object.rhinoException == 'object') {
|
|
||||||
return object.name +
|
|
||||||
' { message: "' + object.message +
|
|
||||||
'", fileName: "' + object.fileName +
|
|
||||||
'", lineNumber: ' + object.lineNumber + ' }';
|
|
||||||
}
|
|
||||||
return func(object);
|
|
||||||
};
|
|
||||||
}());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A logging callback triggered after a test is completed.
|
|
||||||
*
|
|
||||||
* @memberOf QUnit
|
|
||||||
* @param {Object} details An object with properties `failed`, `name`,
|
|
||||||
* `passed`, and `total`.
|
|
||||||
*/
|
|
||||||
function testDone(details) {
|
|
||||||
var assertions = QUnit.config.testStats.assertions,
|
|
||||||
testName = details.name;
|
|
||||||
|
|
||||||
if (details.failed > 0) {
|
|
||||||
console.log(' FAIL - '+ testName);
|
|
||||||
each(assertions, function(value) {
|
|
||||||
console.log(' ' + value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log(' PASS - ' + testName);
|
|
||||||
}
|
|
||||||
assertions.length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An object used to hold information about the current running test.
|
|
||||||
*
|
|
||||||
* @memberOf QUnit.config
|
|
||||||
* @type Object
|
|
||||||
*/
|
|
||||||
QUnit.config.testStats = {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An array of test summaries (pipe separated).
|
|
||||||
*
|
|
||||||
* @memberOf QUnit.config.testStats
|
|
||||||
* @type Array
|
|
||||||
*/
|
|
||||||
'assertions': []
|
|
||||||
};
|
|
||||||
|
|
||||||
// add shortcuts to the global
|
|
||||||
// exclude `module` because some environments have it as a built-in object
|
|
||||||
each(['asyncTest', 'deepEqual', 'equal', 'equals', 'expect', 'notDeepEqual',
|
|
||||||
'notEqual', 'notStrictEqual', 'ok', 'raises', 'same', 'start', 'stop',
|
|
||||||
'strictEqual', 'test', 'throws'], function(funcName) {
|
|
||||||
var func = QUnit[funcName];
|
|
||||||
if (func) {
|
|
||||||
global[funcName] = func;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// expose timer methods to global
|
|
||||||
try {
|
|
||||||
timer = new java.util.Timer;
|
|
||||||
if (!isFunction(global.clearInterval)) {
|
|
||||||
global.clearInterval = clearTimer;
|
|
||||||
}
|
|
||||||
if (!isFunction(global.clearTimeout)) {
|
|
||||||
global.clearTimeout = clearTimer;
|
|
||||||
}
|
|
||||||
if (!isFunction(global.setInterval)) {
|
|
||||||
global.setInterval = setInterval;
|
|
||||||
}
|
|
||||||
if (!isFunction(global.setTimeout)) {
|
|
||||||
global.setTimeout = setTimeout;
|
|
||||||
}
|
|
||||||
} catch(e) { }
|
|
||||||
|
|
||||||
// add callbacks
|
|
||||||
QUnit.done(done);
|
|
||||||
QUnit.log(log);
|
|
||||||
QUnit.moduleStart(moduleStart);
|
|
||||||
QUnit.testDone(testDone);
|
|
||||||
|
|
||||||
// add wrapped function
|
|
||||||
QUnit.jsDump.parsers.object = parseObject;
|
|
||||||
|
|
||||||
// must call `QUnit.start()` in the test file if using QUnit < 1.3.0 with
|
|
||||||
// Node.js or any version of QUnit with Narwhal, Rhino, or RingoJS
|
|
||||||
QUnit.init();
|
|
||||||
|
|
||||||
}(typeof global == 'object' && global || this));
|
|
||||||
49
vendor/qunit/README.md
vendored
49
vendor/qunit/README.md
vendored
@@ -1,49 +0,0 @@
|
|||||||
[QUnit](http://docs.jquery.com/QUnit) - A JavaScript Unit Testing framework.
|
|
||||||
================================
|
|
||||||
|
|
||||||
QUnit is a powerful, easy-to-use, JavaScript test suite. It's used by the jQuery
|
|
||||||
project to test its code and plugins but is capable of testing any generic
|
|
||||||
JavaScript code (and even capable of testing JavaScript code on the server-side).
|
|
||||||
|
|
||||||
QUnit is especially useful for regression testing: Whenever a bug is reported,
|
|
||||||
write a test that asserts the existence of that particular bug. Then fix it and
|
|
||||||
commit both. Every time you work on the code again, run the tests. If the bug
|
|
||||||
comes up again - a regression - you'll spot it immediately and know how to fix
|
|
||||||
it, because you know what code you just changed.
|
|
||||||
|
|
||||||
Having good unit test coverage makes safe refactoring easy and cheap. You can
|
|
||||||
run the tests after each small refactoring step and always know what change
|
|
||||||
broke something.
|
|
||||||
|
|
||||||
QUnit is similar to other unit testing frameworks like JUnit, but makes use of
|
|
||||||
the features JavaScript provides and helps with testing code in the browser, e.g.
|
|
||||||
with its stop/start facilities for testing asynchronous code.
|
|
||||||
|
|
||||||
If you are interested in helping developing QUnit, you are in the right place.
|
|
||||||
For related discussions, visit the
|
|
||||||
[QUnit and Testing forum](http://forum.jquery.com/qunit-and-testing).
|
|
||||||
|
|
||||||
Planning for a qunitjs.com site and other testing tools related work now happens
|
|
||||||
on the [jQuery Testing Team planning wiki](http://jquerytesting.pbworks.com/w/page/41556026/FrontPage).
|
|
||||||
|
|
||||||
Development
|
|
||||||
-----------
|
|
||||||
|
|
||||||
To submit patches, fork the repository, create a branch for the change. Then implement
|
|
||||||
the change, run `grunt` to lint and test it, then commit, push and create a pull request.
|
|
||||||
|
|
||||||
Include some background for the change in the commit message and `Fixes #nnn`, referring
|
|
||||||
to the issue number you're addressing.
|
|
||||||
|
|
||||||
To run `grunt`, you need `node` and `npm`, then `npm install grunt -g`.
|
|
||||||
|
|
||||||
Releases
|
|
||||||
--------
|
|
||||||
|
|
||||||
Install git-extras and run `git changelog` to update History.md.
|
|
||||||
Update qunit/qunit.js|css and package.json to the release version, commit and
|
|
||||||
tag, update them again to the next version, commit and push commits and tags
|
|
||||||
(`git push --tags origin master`).
|
|
||||||
|
|
||||||
Put the 'v' in front of the tag, e.g. `v1.8.0`. Clean up the changelog, removing merge commits
|
|
||||||
or whitespace cleanups.
|
|
||||||
1863
vendor/qunit/qunit/qunit-1.8.0.js
vendored
1863
vendor/qunit/qunit/qunit-1.8.0.js
vendored
File diff suppressed because it is too large
Load Diff
231
vendor/qunit/qunit/qunit.css
vendored
231
vendor/qunit/qunit/qunit.css
vendored
@@ -1,231 +0,0 @@
|
|||||||
/**
|
|
||||||
* QUnit v1.9.0 - A JavaScript Unit Testing Framework
|
|
||||||
*
|
|
||||||
* http://docs.jquery.com/QUnit
|
|
||||||
*
|
|
||||||
* Copyright (c) 2012 John Resig, Jörn Zaefferer
|
|
||||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
|
||||||
* or GPL (GPL-LICENSE.txt) licenses.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Font Family and Sizes */
|
|
||||||
|
|
||||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
|
|
||||||
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
|
|
||||||
#qunit-tests { font-size: smaller; }
|
|
||||||
|
|
||||||
|
|
||||||
/** Resets */
|
|
||||||
|
|
||||||
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Header */
|
|
||||||
|
|
||||||
#qunit-header {
|
|
||||||
padding: 0.5em 0 0.5em 1em;
|
|
||||||
|
|
||||||
color: #8699a4;
|
|
||||||
background-color: #0d3349;
|
|
||||||
|
|
||||||
font-size: 1.5em;
|
|
||||||
line-height: 1em;
|
|
||||||
font-weight: normal;
|
|
||||||
|
|
||||||
border-radius: 5px 5px 0 0;
|
|
||||||
-moz-border-radius: 5px 5px 0 0;
|
|
||||||
-webkit-border-top-right-radius: 5px;
|
|
||||||
-webkit-border-top-left-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-header a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: #c2ccd1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-header a:hover,
|
|
||||||
#qunit-header a:focus {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-testrunner-toolbar label {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0 .5em 0 .1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-banner {
|
|
||||||
height: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-testrunner-toolbar {
|
|
||||||
padding: 0.5em 0 0.5em 2em;
|
|
||||||
color: #5E740B;
|
|
||||||
background-color: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-userAgent {
|
|
||||||
padding: 0.5em 0 0.5em 2.5em;
|
|
||||||
background-color: #2b81af;
|
|
||||||
color: #fff;
|
|
||||||
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Tests: Pass/Fail */
|
|
||||||
|
|
||||||
#qunit-tests {
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li {
|
|
||||||
padding: 0.4em 0.5em 0.4em 2.5em;
|
|
||||||
border-bottom: 1px solid #fff;
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li strong {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li a {
|
|
||||||
padding: 0.5em;
|
|
||||||
color: #c2ccd1;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
#qunit-tests li a:hover,
|
|
||||||
#qunit-tests li a:focus {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests ol {
|
|
||||||
margin-top: 0.5em;
|
|
||||||
padding: 0.5em;
|
|
||||||
|
|
||||||
background-color: #fff;
|
|
||||||
|
|
||||||
border-radius: 5px;
|
|
||||||
-moz-border-radius: 5px;
|
|
||||||
-webkit-border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
margin-top: .2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests th {
|
|
||||||
text-align: right;
|
|
||||||
vertical-align: top;
|
|
||||||
padding: 0 .5em 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests td {
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests pre {
|
|
||||||
margin: 0;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests del {
|
|
||||||
background-color: #e0f2be;
|
|
||||||
color: #374e0c;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests ins {
|
|
||||||
background-color: #ffcaca;
|
|
||||||
color: #500;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Test Counts */
|
|
||||||
|
|
||||||
#qunit-tests b.counts { color: black; }
|
|
||||||
#qunit-tests b.passed { color: #5E740B; }
|
|
||||||
#qunit-tests b.failed { color: #710909; }
|
|
||||||
|
|
||||||
#qunit-tests li li {
|
|
||||||
padding: 5px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-bottom: none;
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Passing Styles */
|
|
||||||
|
|
||||||
#qunit-tests li li.pass {
|
|
||||||
color: #3c510c;
|
|
||||||
background-color: #fff;
|
|
||||||
border-left: 10px solid #C6E746;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
|
|
||||||
#qunit-tests .pass .test-name { color: #366097; }
|
|
||||||
|
|
||||||
#qunit-tests .pass .test-actual,
|
|
||||||
#qunit-tests .pass .test-expected { color: #999999; }
|
|
||||||
|
|
||||||
#qunit-banner.qunit-pass { background-color: #C6E746; }
|
|
||||||
|
|
||||||
/*** Failing Styles */
|
|
||||||
|
|
||||||
#qunit-tests li li.fail {
|
|
||||||
color: #710909;
|
|
||||||
background-color: #fff;
|
|
||||||
border-left: 10px solid #EE5757;
|
|
||||||
white-space: pre;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests > li:last-child {
|
|
||||||
border-radius: 0 0 5px 5px;
|
|
||||||
-moz-border-radius: 0 0 5px 5px;
|
|
||||||
-webkit-border-bottom-right-radius: 5px;
|
|
||||||
-webkit-border-bottom-left-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
|
|
||||||
#qunit-tests .fail .test-name,
|
|
||||||
#qunit-tests .fail .module-name { color: #000000; }
|
|
||||||
|
|
||||||
#qunit-tests .fail .test-actual { color: #EE5757; }
|
|
||||||
#qunit-tests .fail .test-expected { color: green; }
|
|
||||||
|
|
||||||
#qunit-banner.qunit-fail { background-color: #EE5757; }
|
|
||||||
|
|
||||||
|
|
||||||
/** Result */
|
|
||||||
|
|
||||||
#qunit-testresult {
|
|
||||||
padding: 0.5em 0.5em 0.5em 2.5em;
|
|
||||||
|
|
||||||
color: #2b81af;
|
|
||||||
background-color: #D2E0E6;
|
|
||||||
|
|
||||||
border-bottom: 1px solid white;
|
|
||||||
}
|
|
||||||
#qunit-testresult .module-name {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Fixture */
|
|
||||||
|
|
||||||
#qunit-fixture {
|
|
||||||
position: absolute;
|
|
||||||
top: -10000px;
|
|
||||||
left: -10000px;
|
|
||||||
width: 1000px;
|
|
||||||
height: 1000px;
|
|
||||||
}
|
|
||||||
1932
vendor/qunit/qunit/qunit.js
vendored
1932
vendor/qunit/qunit/qunit.js
vendored
File diff suppressed because it is too large
Load Diff
58
vendor/requirejs/LICENSE
vendored
58
vendor/requirejs/LICENSE
vendored
@@ -1,58 +0,0 @@
|
|||||||
RequireJS is released under two licenses: new BSD, and MIT. You may pick the
|
|
||||||
license that best suits your development needs. The text of both licenses are
|
|
||||||
provided below.
|
|
||||||
|
|
||||||
|
|
||||||
The "New" BSD License:
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
Copyright (c) 2010-2011, The Dojo Foundation
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of the Dojo Foundation nor the names of its contributors
|
|
||||||
may be used to endorse or promote products derived from this software
|
|
||||||
without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MIT License
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Copyright (c) 2010-2011, The Dojo Foundation
|
|
||||||
|
|
||||||
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.
|
|
||||||
51
vendor/requirejs/README.md
vendored
51
vendor/requirejs/README.md
vendored
@@ -1,51 +0,0 @@
|
|||||||
# RequireJS
|
|
||||||
|
|
||||||
RequireJS loads plain JavaScript files as well as more defined modules. It is
|
|
||||||
optimized for in-browser use, including in
|
|
||||||
[a Web Worker](http://requirejs.org/docs/api.html#webworker), but it can be used
|
|
||||||
in other JavaScript environments, like Rhino and
|
|
||||||
[Node](http://requirejs.org/docs/node.html). It implements the
|
|
||||||
[Asynchronous Module](https://github.com/amdjs/amdjs-api/wiki/AMD)
|
|
||||||
API.
|
|
||||||
|
|
||||||
RequireJS uses plain script tags to load modules/files, so it should allow for
|
|
||||||
easy debugging. It can be used
|
|
||||||
[simply to load existing JavaScript files](http://requirejs.org/docs/api.html#jsfiles),
|
|
||||||
so you can add it to your existing project without having to re-write your
|
|
||||||
JavaScript files.
|
|
||||||
|
|
||||||
RequireJS includes [an optimization tool](http://requirejs.org/docs/optimization.html)
|
|
||||||
you can run as part of your packaging steps for deploying your code. The
|
|
||||||
optimization tool can combine and minify your JavaScript files to allow for
|
|
||||||
better performance.
|
|
||||||
|
|
||||||
If the JavaScript file defines a JavaScript module via
|
|
||||||
[define()](http://requirejs.org/docs/api.html#define), then there are other benefits
|
|
||||||
RequireJS can offer: [improvements over traditional CommonJS modules](http://requirejs.org/docs/commonjs.html)
|
|
||||||
and [loading multiple versions](http://requirejs.org/docs/api.html#multiversion)
|
|
||||||
of a module in a page. RequireJS also has a plugin system that supports features like
|
|
||||||
[i18n string bundles](http://requirejs.org/docs/api.html#i18n), and
|
|
||||||
[text file dependencies](http://requirejs.org/docs/api.html#text).
|
|
||||||
|
|
||||||
RequireJS does not have any dependencies on a JavaScript framework.
|
|
||||||
It is dual-licensed -- new BSD or MIT.
|
|
||||||
|
|
||||||
The standard require.js file is around 5.5KB when minified via Closure Compiler
|
|
||||||
and gzipped.
|
|
||||||
|
|
||||||
RequireJS works in IE 6+, Firefox 2+, Safari 3.2+, Chrome 3+, and Opera 10+.
|
|
||||||
|
|
||||||
[Latest Release](http://requirejs.org/docs/download.html)
|
|
||||||
|
|
||||||
## Directories
|
|
||||||
|
|
||||||
* **dist**: Scripts and assets to generate the requirejs.org docs, and for
|
|
||||||
generating a require.js release.
|
|
||||||
* **docs**: The raw HTML files for the requirejs.org docs. Only includes the
|
|
||||||
body of each page. Files in **dist** are used to generate a complete HTML page.
|
|
||||||
* **tests**: Tests for require.js.
|
|
||||||
* **testBaseUrl.js**: A file used in the tests inside **tests**. Purposely
|
|
||||||
placed outside the tests directory for testing paths that go outside a baseUrl.
|
|
||||||
* **updatesubs.sh**: Updates projects that depend on require.js Assumes the
|
|
||||||
projects are siblings to this directory and have specific names. Useful to
|
|
||||||
copy require.js to dependent projects easily while in development.
|
|
||||||
2053
vendor/requirejs/require.js
vendored
2053
vendor/requirejs/require.js
vendored
File diff suppressed because it is too large
Load Diff
5
vendor/underscore/LICENSE
vendored
5
vendor/underscore/LICENSE
vendored
@@ -1,4 +1,5 @@
|
|||||||
Copyright (c) 2009-2012 Jeremy Ashkenas, DocumentCloud
|
Copyright (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative
|
||||||
|
Reporters & Editors
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation
|
obtaining a copy of this software and associated documentation
|
||||||
@@ -19,4 +20,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|||||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|||||||
19
vendor/underscore/README.md
vendored
19
vendor/underscore/README.md
vendored
@@ -1,19 +0,0 @@
|
|||||||
__
|
|
||||||
/\ \ __
|
|
||||||
__ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ /\_\ ____
|
|
||||||
/\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ \/\ \ /',__\
|
|
||||||
\ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ \ \ \/\__, `\
|
|
||||||
\ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/
|
|
||||||
\/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_//\ \_\ \/___/
|
|
||||||
\ \____/
|
|
||||||
\/___/
|
|
||||||
|
|
||||||
Underscore.js is a utility-belt library for JavaScript that provides
|
|
||||||
support for the usual functional suspects (each, map, reduce, filter...)
|
|
||||||
without extending any core JavaScript objects.
|
|
||||||
|
|
||||||
For Docs, License, Tests, and pre-packed downloads, see:
|
|
||||||
http://underscorejs.org
|
|
||||||
|
|
||||||
Many thanks to our contributors:
|
|
||||||
https://github.com/documentcloud/underscore/contributors
|
|
||||||
625
vendor/underscore/test/arrays.js
vendored
625
vendor/underscore/test/arrays.js
vendored
@@ -1,143 +1,310 @@
|
|||||||
$(document).ready(function() {
|
(function() {
|
||||||
|
var _ = typeof require == 'function' ? require('..') : window._;
|
||||||
|
|
||||||
module("Arrays");
|
QUnit.module('Arrays');
|
||||||
|
|
||||||
test("arrays: first", function() {
|
test('first', function() {
|
||||||
equal(_.first([1,2,3]), 1, 'can pull out the first element of an array');
|
equal(_.first([1, 2, 3]), 1, 'can pull out the first element of an array');
|
||||||
equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"');
|
equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"');
|
||||||
equal(_.first([1,2,3], 0).join(', '), "", 'can pass an index to first');
|
deepEqual(_.first([1, 2, 3], 0), [], 'can pass an index to first');
|
||||||
equal(_.first([1,2,3], 2).join(', '), '1, 2', 'can pass an index to first');
|
deepEqual(_.first([1, 2, 3], 2), [1, 2], 'can pass an index to first');
|
||||||
equal(_.first([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to first');
|
deepEqual(_.first([1, 2, 3], 5), [1, 2, 3], 'can pass an index to first');
|
||||||
var result = (function(){ return _.first(arguments); })(4, 3, 2, 1);
|
var result = (function(){ return _.first(arguments); }(4, 3, 2, 1));
|
||||||
equal(result, 4, 'works on an arguments object.');
|
equal(result, 4, 'works on an arguments object.');
|
||||||
result = _.map([[1,2,3],[1,2,3]], _.first);
|
result = _.map([[1, 2, 3], [1, 2, 3]], _.first);
|
||||||
equal(result.join(','), '1,1', 'works well with _.map');
|
deepEqual(result, [1, 1], 'works well with _.map');
|
||||||
result = (function() { return _.take([1,2,3], 2); })();
|
result = (function() { return _.first([1, 2, 3], 2); }());
|
||||||
equal(result.join(','), '1,2', 'aliased as take');
|
deepEqual(result, [1, 2]);
|
||||||
|
|
||||||
|
equal(_.first(null), undefined, 'handles nulls');
|
||||||
|
strictEqual(_.first([1, 2, 3], -1).length, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("arrays: rest", function() {
|
test('head', function() {
|
||||||
|
strictEqual(_.first, _.head, 'alias for first');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('take', function() {
|
||||||
|
strictEqual(_.first, _.take, 'alias for first');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('rest', function() {
|
||||||
var numbers = [1, 2, 3, 4];
|
var numbers = [1, 2, 3, 4];
|
||||||
equal(_.rest(numbers).join(", "), "2, 3, 4", 'working rest()');
|
deepEqual(_.rest(numbers), [2, 3, 4], 'working rest()');
|
||||||
equal(_.rest(numbers, 0).join(", "), "1, 2, 3, 4", 'working rest(0)');
|
deepEqual(_.rest(numbers, 0), [1, 2, 3, 4], 'working rest(0)');
|
||||||
equal(_.rest(numbers, 2).join(', '), '3, 4', 'rest can take an index');
|
deepEqual(_.rest(numbers, 2), [3, 4], 'rest can take an index');
|
||||||
var result = (function(){ return _(arguments).tail(); })(1, 2, 3, 4);
|
var result = (function(){ return _(arguments).rest(); }(1, 2, 3, 4));
|
||||||
equal(result.join(', '), '2, 3, 4', 'aliased as tail and works on arguments object');
|
deepEqual(result, [2, 3, 4], 'works on arguments object');
|
||||||
result = _.map([[1,2,3],[1,2,3]], _.rest);
|
result = _.map([[1, 2, 3], [1, 2, 3]], _.rest);
|
||||||
equal(_.flatten(result).join(','), '2,3,2,3', 'works well with _.map');
|
deepEqual(_.flatten(result), [2, 3, 2, 3], 'works well with _.map');
|
||||||
|
result = (function(){ return _(arguments).rest(); }(1, 2, 3, 4));
|
||||||
|
deepEqual(result, [2, 3, 4], 'works on arguments object');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("arrays: initial", function() {
|
test('tail', function() {
|
||||||
equal(_.initial([1,2,3,4,5]).join(", "), "1, 2, 3, 4", 'working initial()');
|
strictEqual(_.rest, _.tail, 'alias for rest');
|
||||||
equal(_.initial([1,2,3,4],2).join(", "), "1, 2", 'initial can take an index');
|
|
||||||
var result = (function(){ return _(arguments).initial(); })(1, 2, 3, 4);
|
|
||||||
equal(result.join(", "), "1, 2, 3", 'initial works on arguments object');
|
|
||||||
result = _.map([[1,2,3],[1,2,3]], _.initial);
|
|
||||||
equal(_.flatten(result).join(','), '1,2,1,2', 'initial works with _.map');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("arrays: last", function() {
|
test('drop', function() {
|
||||||
equal(_.last([1,2,3]), 3, 'can pull out the last element of an array');
|
strictEqual(_.rest, _.drop, 'alias for rest');
|
||||||
equal(_.last([1,2,3], 0).join(', '), "", 'can pass an index to last');
|
});
|
||||||
equal(_.last([1,2,3], 2).join(', '), '2, 3', 'can pass an index to last');
|
|
||||||
equal(_.last([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to last');
|
test('initial', function() {
|
||||||
var result = (function(){ return _(arguments).last(); })(1, 2, 3, 4);
|
deepEqual(_.initial([1, 2, 3, 4, 5]), [1, 2, 3, 4], 'working initial()');
|
||||||
|
deepEqual(_.initial([1, 2, 3, 4], 2), [1, 2], 'initial can take an index');
|
||||||
|
deepEqual(_.initial([1, 2, 3, 4], 6), [], 'initial can take a large index');
|
||||||
|
var result = (function(){ return _(arguments).initial(); }(1, 2, 3, 4));
|
||||||
|
deepEqual(result, [1, 2, 3], 'initial works on arguments object');
|
||||||
|
result = _.map([[1, 2, 3], [1, 2, 3]], _.initial);
|
||||||
|
deepEqual(_.flatten(result), [1, 2, 1, 2], 'initial works with _.map');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('last', function() {
|
||||||
|
equal(_.last([1, 2, 3]), 3, 'can pull out the last element of an array');
|
||||||
|
deepEqual(_.last([1, 2, 3], 0), [], 'can pass an index to last');
|
||||||
|
deepEqual(_.last([1, 2, 3], 2), [2, 3], 'can pass an index to last');
|
||||||
|
deepEqual(_.last([1, 2, 3], 5), [1, 2, 3], 'can pass an index to last');
|
||||||
|
var result = (function(){ return _(arguments).last(); }(1, 2, 3, 4));
|
||||||
equal(result, 4, 'works on an arguments object');
|
equal(result, 4, 'works on an arguments object');
|
||||||
result = _.map([[1,2,3],[1,2,3]], _.last);
|
result = _.map([[1, 2, 3], [1, 2, 3]], _.last);
|
||||||
equal(result.join(','), '3,3', 'works well with _.map');
|
deepEqual(result, [3, 3], 'works well with _.map');
|
||||||
|
|
||||||
|
equal(_.last(null), undefined, 'handles nulls');
|
||||||
|
strictEqual(_.last([1, 2, 3], -1).length, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("arrays: compact", function() {
|
test('compact', function() {
|
||||||
equal(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values');
|
equal(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values');
|
||||||
var result = (function(){ return _(arguments).compact().length; })(0, 1, false, 2, false, 3);
|
var result = (function(){ return _.compact(arguments).length; }(0, 1, false, 2, false, 3));
|
||||||
equal(result, 3, 'works on an arguments object');
|
equal(result, 3, 'works on an arguments object');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("arrays: flatten", function() {
|
test('flatten', function() {
|
||||||
if (window.JSON) {
|
deepEqual(_.flatten(null), [], 'Flattens supports null');
|
||||||
var list = [1, [2], [3, [[[4]]]]];
|
deepEqual(_.flatten(void 0), [], 'Flattens supports undefined');
|
||||||
equal(JSON.stringify(_.flatten(list)), '[1,2,3,4]', 'can flatten nested arrays');
|
|
||||||
equal(JSON.stringify(_.flatten(list, true)), '[1,2,3,[[[4]]]]', 'can shallowly flatten nested arrays');
|
deepEqual(_.flatten([[], [[]], []]), [], 'Flattens empty arrays');
|
||||||
var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]);
|
deepEqual(_.flatten([[], [[]], []], true), [[]], 'Flattens empty arrays');
|
||||||
equal(JSON.stringify(result), '[1,2,3,4]', 'works on an arguments object');
|
|
||||||
}
|
var list = [1, [2], [3, [[[4]]]]];
|
||||||
|
deepEqual(_.flatten(list), [1, 2, 3, 4], 'can flatten nested arrays');
|
||||||
|
deepEqual(_.flatten(list, true), [1, 2, 3, [[[4]]]], 'can shallowly flatten nested arrays');
|
||||||
|
var result = (function(){ return _.flatten(arguments); }(1, [2], [3, [[[4]]]]));
|
||||||
|
deepEqual(result, [1, 2, 3, 4], 'works on an arguments object');
|
||||||
|
list = [[1], [2], [3], [[4]]];
|
||||||
|
deepEqual(_.flatten(list, true), [1, 2, 3, [4]], 'can shallowly flatten arrays containing only other arrays');
|
||||||
|
|
||||||
|
equal(_.flatten([_.range(10), _.range(10), 5, 1, 3], true).length, 23);
|
||||||
|
equal(_.flatten([_.range(10), _.range(10), 5, 1, 3]).length, 23);
|
||||||
|
equal(_.flatten([new Array(1000000), _.range(56000), 5, 1, 3]).length, 1056003, 'Flatten can handle massive collections');
|
||||||
|
equal(_.flatten([new Array(1000000), _.range(56000), 5, 1, 3], true).length, 1056003, 'Flatten can handle massive collections');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("arrays: without", function() {
|
test('without', function() {
|
||||||
var list = [1, 2, 1, 0, 3, 1, 4];
|
var list = [1, 2, 1, 0, 3, 1, 4];
|
||||||
equal(_.without(list, 0, 1).join(', '), '2, 3, 4', 'can remove all instances of an object');
|
deepEqual(_.without(list, 0, 1), [2, 3, 4], 'can remove all instances of an object');
|
||||||
var result = (function(){ return _.without(arguments, 0, 1); })(1, 2, 1, 0, 3, 1, 4);
|
var result = (function(){ return _.without(arguments, 0, 1); }(1, 2, 1, 0, 3, 1, 4));
|
||||||
equal(result.join(', '), '2, 3, 4', 'works on an arguments object');
|
deepEqual(result, [2, 3, 4], 'works on an arguments object');
|
||||||
|
|
||||||
var list = [{one : 1}, {two : 2}];
|
list = [{one : 1}, {two : 2}];
|
||||||
ok(_.without(list, {one : 1}).length == 2, 'uses real object identity for comparisons.');
|
equal(_.without(list, {one : 1}).length, 2, 'uses real object identity for comparisons.');
|
||||||
ok(_.without(list, list[0]).length == 1, 'ditto.');
|
equal(_.without(list, list[0]).length, 1, 'ditto.');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("arrays: uniq", function() {
|
test('sortedIndex', function() {
|
||||||
var list = [1, 2, 1, 3, 1, 4];
|
|
||||||
equal(_.uniq(list).join(', '), '1, 2, 3, 4', 'can find the unique values of an unsorted array');
|
|
||||||
|
|
||||||
var list = [1, 1, 1, 2, 2, 3];
|
|
||||||
equal(_.uniq(list, true).join(', '), '1, 2, 3', 'can find the unique values of a sorted array faster');
|
|
||||||
|
|
||||||
var list = [{name:'moe'}, {name:'curly'}, {name:'larry'}, {name:'curly'}];
|
|
||||||
var iterator = function(value) { return value.name; };
|
|
||||||
equal(_.map(_.uniq(list, false, iterator), iterator).join(', '), 'moe, curly, larry', 'can find the unique values of an array using a custom iterator');
|
|
||||||
|
|
||||||
var iterator = function(value) { return value +1; };
|
|
||||||
var list = [1, 2, 2, 3, 4, 4];
|
|
||||||
equal(_.uniq(list, true, iterator).join(', '), '1, 2, 3, 4', 'iterator works with sorted array');
|
|
||||||
|
|
||||||
var result = (function(){ return _.uniq(arguments); })(1, 2, 1, 3, 1, 4);
|
|
||||||
equal(result.join(', '), '1, 2, 3, 4', 'works on an arguments object');
|
|
||||||
});
|
|
||||||
|
|
||||||
test("arrays: intersection", function() {
|
|
||||||
var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho'];
|
|
||||||
equal(_.intersection(stooges, leaders).join(''), 'moe', 'can take the set intersection of two arrays');
|
|
||||||
equal(_(stooges).intersection(leaders).join(''), 'moe', 'can perform an OO-style intersection');
|
|
||||||
var result = (function(){ return _.intersection(arguments, leaders); })('moe', 'curly', 'larry');
|
|
||||||
equal(result.join(''), 'moe', 'works on an arguments object');
|
|
||||||
});
|
|
||||||
|
|
||||||
test("arrays: union", function() {
|
|
||||||
var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]);
|
|
||||||
equal(result.join(' '), '1 2 3 30 40', 'takes the union of a list of arrays');
|
|
||||||
|
|
||||||
var result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]);
|
|
||||||
equal(result.join(' '), '1 2 3 30 40 1', 'takes the union of a list of nested arrays');
|
|
||||||
});
|
|
||||||
|
|
||||||
test("arrays: difference", function() {
|
|
||||||
var result = _.difference([1, 2, 3], [2, 30, 40]);
|
|
||||||
equal(result.join(' '), '1 3', 'takes the difference of two arrays');
|
|
||||||
|
|
||||||
var result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]);
|
|
||||||
equal(result.join(' '), '3 4', 'takes the difference of three arrays');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('arrays: zip', function() {
|
|
||||||
var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true];
|
|
||||||
var stooges = _.zip(names, ages, leaders);
|
|
||||||
equal(String(stooges), 'moe,30,true,larry,40,,curly,50,', 'zipped together arrays of different lengths');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('arrays: zipObject', function() {
|
|
||||||
var result = _.zipObject(['moe', 'larry', 'curly'], [30, 40, 50]);
|
|
||||||
var shouldBe = {moe: 30, larry: 40, curly: 50};
|
|
||||||
ok(_.isEqual(result, shouldBe), 'two arrays zipped together into an object');
|
|
||||||
});
|
|
||||||
|
|
||||||
test("arrays: indexOf", function() {
|
|
||||||
var numbers = [1, 2, 3];
|
|
||||||
numbers.indexOf = null;
|
|
||||||
equal(_.indexOf(numbers, 2), 1, 'can compute indexOf, even without the native function');
|
|
||||||
var result = (function(){ return _.indexOf(arguments, 2); })(1, 2, 3);
|
|
||||||
equal(result, 1, 'works on an arguments object');
|
|
||||||
equal(_.indexOf(null, 2), -1, 'handles nulls properly');
|
|
||||||
|
|
||||||
var numbers = [10, 20, 30, 40, 50], num = 35;
|
var numbers = [10, 20, 30, 40, 50], num = 35;
|
||||||
|
var indexForNum = _.sortedIndex(numbers, num);
|
||||||
|
equal(indexForNum, 3, '35 should be inserted at index 3');
|
||||||
|
|
||||||
|
var indexFor30 = _.sortedIndex(numbers, 30);
|
||||||
|
equal(indexFor30, 2, '30 should be inserted at index 2');
|
||||||
|
|
||||||
|
var objects = [{x: 10}, {x: 20}, {x: 30}, {x: 40}];
|
||||||
|
var iterator = function(obj){ return obj.x; };
|
||||||
|
strictEqual(_.sortedIndex(objects, {x: 25}, iterator), 2);
|
||||||
|
strictEqual(_.sortedIndex(objects, {x: 35}, 'x'), 3);
|
||||||
|
|
||||||
|
var context = {1: 2, 2: 3, 3: 4};
|
||||||
|
iterator = function(obj){ return this[obj]; };
|
||||||
|
strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1);
|
||||||
|
|
||||||
|
var values = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647];
|
||||||
|
var array = Array(Math.pow(2, 32) - 1);
|
||||||
|
var length = values.length;
|
||||||
|
while (length--) {
|
||||||
|
array[values[length]] = values[length];
|
||||||
|
}
|
||||||
|
equal(_.sortedIndex(array, 2147483648), 2147483648, 'should work with large indexes');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('uniq', function() {
|
||||||
|
var list = [1, 2, 1, 3, 1, 4];
|
||||||
|
deepEqual(_.uniq(list), [1, 2, 3, 4], 'can find the unique values of an unsorted array');
|
||||||
|
|
||||||
|
list = [1, 1, 1, 2, 2, 3];
|
||||||
|
deepEqual(_.uniq(list, true), [1, 2, 3], 'can find the unique values of a sorted array faster');
|
||||||
|
|
||||||
|
list = [{name: 'moe'}, {name: 'curly'}, {name: 'larry'}, {name: 'curly'}];
|
||||||
|
var iterator = function(value) { return value.name; };
|
||||||
|
deepEqual(_.map(_.uniq(list, false, iterator), iterator), ['moe', 'curly', 'larry'], 'can find the unique values of an array using a custom iterator');
|
||||||
|
|
||||||
|
deepEqual(_.map(_.uniq(list, iterator), iterator), ['moe', 'curly', 'larry'], 'can find the unique values of an array using a custom iterator without specifying whether array is sorted');
|
||||||
|
|
||||||
|
iterator = function(value) { return value + 1; };
|
||||||
|
list = [1, 2, 2, 3, 4, 4];
|
||||||
|
deepEqual(_.uniq(list, true, iterator), [1, 2, 3, 4], 'iterator works with sorted array');
|
||||||
|
|
||||||
|
var kittens = [
|
||||||
|
{kitten: 'Celery', cuteness: 8},
|
||||||
|
{kitten: 'Juniper', cuteness: 10},
|
||||||
|
{kitten: 'Spottis', cuteness: 10}
|
||||||
|
];
|
||||||
|
|
||||||
|
var expected = [
|
||||||
|
{kitten: 'Celery', cuteness: 8},
|
||||||
|
{kitten: 'Juniper', cuteness: 10}
|
||||||
|
];
|
||||||
|
|
||||||
|
deepEqual(_.uniq(kittens, true, 'cuteness'), expected, 'string iterator works with sorted array');
|
||||||
|
|
||||||
|
|
||||||
|
var result = (function(){ return _.uniq(arguments); }(1, 2, 1, 3, 1, 4));
|
||||||
|
deepEqual(result, [1, 2, 3, 4], 'works on an arguments object');
|
||||||
|
|
||||||
|
var a = {}, b = {}, c = {};
|
||||||
|
deepEqual(_.uniq([a, b, a, b, c]), [a, b, c], 'works on values that can be tested for equivalency but not ordered');
|
||||||
|
|
||||||
|
deepEqual(_.uniq(null), []);
|
||||||
|
|
||||||
|
var context = {};
|
||||||
|
list = [3];
|
||||||
|
_.uniq(list, function(value, index, array) {
|
||||||
|
strictEqual(this, context);
|
||||||
|
strictEqual(value, 3);
|
||||||
|
strictEqual(index, 0);
|
||||||
|
strictEqual(array, list);
|
||||||
|
}, context);
|
||||||
|
|
||||||
|
deepEqual(_.uniq([{a: 1, b: 1}, {a: 1, b: 2}, {a: 1, b: 3}, {a: 2, b: 1}], 'a'), [{a: 1, b: 1}, {a: 2, b: 1}], 'can use pluck like iterator');
|
||||||
|
deepEqual(_.uniq([{0: 1, b: 1}, {0: 1, b: 2}, {0: 1, b: 3}, {0: 2, b: 1}], 0), [{0: 1, b: 1}, {0: 2, b: 1}], 'can use falsey pluck like iterator');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('unique', function() {
|
||||||
|
strictEqual(_.uniq, _.unique, 'alias for uniq');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('intersection', function() {
|
||||||
|
var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho'];
|
||||||
|
deepEqual(_.intersection(stooges, leaders), ['moe'], 'can take the set intersection of two arrays');
|
||||||
|
deepEqual(_(stooges).intersection(leaders), ['moe'], 'can perform an OO-style intersection');
|
||||||
|
var result = (function(){ return _.intersection(arguments, leaders); }('moe', 'curly', 'larry'));
|
||||||
|
deepEqual(result, ['moe'], 'works on an arguments object');
|
||||||
|
var theSixStooges = ['moe', 'moe', 'curly', 'curly', 'larry', 'larry'];
|
||||||
|
deepEqual(_.intersection(theSixStooges, leaders), ['moe'], 'returns a duplicate-free array');
|
||||||
|
result = _.intersection([2, 4, 3, 1], [1, 2, 3]);
|
||||||
|
deepEqual(result, [2, 3, 1], 'preserves order of first array');
|
||||||
|
result = _.intersection(null, [1, 2, 3]);
|
||||||
|
equal(Object.prototype.toString.call(result), '[object Array]', 'returns an empty array when passed null as first argument');
|
||||||
|
equal(result.length, 0, 'returns an empty array when passed null as first argument');
|
||||||
|
result = _.intersection([1, 2, 3], null);
|
||||||
|
equal(Object.prototype.toString.call(result), '[object Array]', 'returns an empty array when passed null as argument beyond the first');
|
||||||
|
equal(result.length, 0, 'returns an empty array when passed null as argument beyond the first');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('union', function() {
|
||||||
|
var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]);
|
||||||
|
deepEqual(result, [1, 2, 3, 30, 40], 'takes the union of a list of arrays');
|
||||||
|
|
||||||
|
result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]);
|
||||||
|
deepEqual(result, [1, 2, 3, 30, 40, [1]], 'takes the union of a list of nested arrays');
|
||||||
|
|
||||||
|
var args = null;
|
||||||
|
(function(){ args = arguments; }(1, 2, 3));
|
||||||
|
result = _.union(args, [2, 30, 1], [1, 40]);
|
||||||
|
deepEqual(result, [1, 2, 3, 30, 40], 'takes the union of a list of arrays');
|
||||||
|
|
||||||
|
result = _.union([1, 2, 3], 4);
|
||||||
|
deepEqual(result, [1, 2, 3], 'restrict the union to arrays only');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('difference', function() {
|
||||||
|
var result = _.difference([1, 2, 3], [2, 30, 40]);
|
||||||
|
deepEqual(result, [1, 3], 'takes the difference of two arrays');
|
||||||
|
|
||||||
|
result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]);
|
||||||
|
deepEqual(result, [3, 4], 'takes the difference of three arrays');
|
||||||
|
|
||||||
|
result = _.difference([1, 2, 3], 1);
|
||||||
|
deepEqual(result, [1, 2, 3], 'restrict the difference to arrays only');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('zip', function() {
|
||||||
|
var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true];
|
||||||
|
deepEqual(_.zip(names, ages, leaders), [
|
||||||
|
['moe', 30, true],
|
||||||
|
['larry', 40, undefined],
|
||||||
|
['curly', 50, undefined]
|
||||||
|
], 'zipped together arrays of different lengths');
|
||||||
|
|
||||||
|
var stooges = _.zip(['moe', 30, 'stooge 1'], ['larry', 40, 'stooge 2'], ['curly', 50, 'stooge 3']);
|
||||||
|
deepEqual(stooges, [['moe', 'larry', 'curly'], [30, 40, 50], ['stooge 1', 'stooge 2', 'stooge 3']], 'zipped pairs');
|
||||||
|
|
||||||
|
// In the case of difference lengths of the tuples undefineds
|
||||||
|
// should be used as placeholder
|
||||||
|
stooges = _.zip(['moe', 30], ['larry', 40], ['curly', 50, 'extra data']);
|
||||||
|
deepEqual(stooges, [['moe', 'larry', 'curly'], [30, 40, 50], [undefined, undefined, 'extra data']], 'zipped pairs with empties');
|
||||||
|
|
||||||
|
var empty = _.zip([]);
|
||||||
|
deepEqual(empty, [], 'unzipped empty');
|
||||||
|
|
||||||
|
deepEqual(_.zip(null), [], 'handles null');
|
||||||
|
deepEqual(_.zip(), [], '_.zip() returns []');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('unzip', function() {
|
||||||
|
deepEqual(_.unzip(null), [], 'handles null');
|
||||||
|
|
||||||
|
deepEqual(_.unzip([['a', 'b'], [1, 2]]), [['a', 1], ['b', 2]]);
|
||||||
|
|
||||||
|
// complements zip
|
||||||
|
var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
|
||||||
|
deepEqual(_.unzip(zipped), [['fred', 'barney'], [30, 40], [true, false]]);
|
||||||
|
|
||||||
|
zipped = _.zip(['moe', 30], ['larry', 40], ['curly', 50, 'extra data']);
|
||||||
|
deepEqual(_.unzip(zipped), [['moe', 30, void 0], ['larry', 40, void 0], ['curly', 50, 'extra data']], 'Uses length of largest array');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('object', function() {
|
||||||
|
var result = _.object(['moe', 'larry', 'curly'], [30, 40, 50]);
|
||||||
|
var shouldBe = {moe: 30, larry: 40, curly: 50};
|
||||||
|
deepEqual(result, shouldBe, 'two arrays zipped together into an object');
|
||||||
|
|
||||||
|
result = _.object([['one', 1], ['two', 2], ['three', 3]]);
|
||||||
|
shouldBe = {one: 1, two: 2, three: 3};
|
||||||
|
deepEqual(result, shouldBe, 'an array of pairs zipped together into an object');
|
||||||
|
|
||||||
|
var stooges = {moe: 30, larry: 40, curly: 50};
|
||||||
|
deepEqual(_.object(_.pairs(stooges)), stooges, 'an object converted to pairs and back to an object');
|
||||||
|
|
||||||
|
deepEqual(_.object(null), {}, 'handles nulls');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('indexOf', function() {
|
||||||
|
var numbers = [1, 2, 3];
|
||||||
|
equal(_.indexOf(numbers, 2), 1, 'can compute indexOf');
|
||||||
|
var result = (function(){ return _.indexOf(arguments, 2); }(1, 2, 3));
|
||||||
|
equal(result, 1, 'works on an arguments object');
|
||||||
|
|
||||||
|
_.each([null, void 0, [], false], function(val) {
|
||||||
|
var msg = 'Handles: ' + (_.isArray(val) ? '[]' : val);
|
||||||
|
equal(_.indexOf(val, 2), -1, msg);
|
||||||
|
equal(_.indexOf(val, 2, -1), -1, msg);
|
||||||
|
equal(_.indexOf(val, 2, -20), -1, msg);
|
||||||
|
equal(_.indexOf(val, 2, 15), -1, msg);
|
||||||
|
});
|
||||||
|
|
||||||
|
var num = 35;
|
||||||
|
numbers = [10, 20, 30, 40, 50];
|
||||||
var index = _.indexOf(numbers, num, true);
|
var index = _.indexOf(numbers, num, true);
|
||||||
equal(index, -1, '35 is not in the list');
|
equal(index, -1, '35 is not in the list');
|
||||||
|
|
||||||
@@ -146,29 +313,225 @@ $(document).ready(function() {
|
|||||||
equal(index, 3, '40 is in the list');
|
equal(index, 3, '40 is in the list');
|
||||||
|
|
||||||
numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40;
|
numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40;
|
||||||
index = _.indexOf(numbers, num, true);
|
equal(_.indexOf(numbers, num, true), 1, '40 is in the list');
|
||||||
equal(index, 1, '40 is in the list');
|
equal(_.indexOf(numbers, 6, true), -1, '6 isnt in the list');
|
||||||
|
equal(_.indexOf([1, 2, 5, 4, 6, 7], 5, true), -1, 'sorted indexOf doesn\'t uses binary search');
|
||||||
|
ok(_.every(['1', [], {}, null], function() {
|
||||||
|
return _.indexOf(numbers, num, {}) === 1;
|
||||||
|
}), 'non-nums as fromIndex make indexOf assume sorted');
|
||||||
|
|
||||||
|
numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3];
|
||||||
|
index = _.indexOf(numbers, 2, 5);
|
||||||
|
equal(index, 7, 'supports the fromIndex argument');
|
||||||
|
|
||||||
|
index = _.indexOf([,,,], undefined);
|
||||||
|
equal(index, 0, 'treats sparse arrays as if they were dense');
|
||||||
|
|
||||||
|
var array = [1, 2, 3, 1, 2, 3];
|
||||||
|
strictEqual(_.indexOf(array, 1, -3), 3, 'neg `fromIndex` starts at the right index');
|
||||||
|
strictEqual(_.indexOf(array, 1, -2), -1, 'neg `fromIndex` starts at the right index');
|
||||||
|
strictEqual(_.indexOf(array, 2, -3), 4);
|
||||||
|
_.each([-6, -8, -Infinity], function(fromIndex) {
|
||||||
|
strictEqual(_.indexOf(array, 1, fromIndex), 0);
|
||||||
|
});
|
||||||
|
strictEqual(_.indexOf([1, 2, 3], 1, true), 0);
|
||||||
|
|
||||||
|
index = _.indexOf([], undefined, true);
|
||||||
|
equal(index, -1, 'empty array with truthy `isSorted` returns -1');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("arrays: lastIndexOf", function() {
|
test('indexOf with NaN', function() {
|
||||||
var numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0];
|
strictEqual(_.indexOf([1, 2, NaN, NaN], NaN), 2, 'Expected [1, 2, NaN] to contain NaN');
|
||||||
|
strictEqual(_.indexOf([1, 2, Infinity], NaN), -1, 'Expected [1, 2, NaN] to contain NaN');
|
||||||
|
|
||||||
|
strictEqual(_.indexOf([1, 2, NaN, NaN], NaN, 1), 2, 'startIndex does not affect result');
|
||||||
|
strictEqual(_.indexOf([1, 2, NaN, NaN], NaN, -2), 2, 'startIndex does not affect result');
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
strictEqual(_.indexOf(arguments, NaN), 2, 'Expected arguments [1, 2, NaN] to contain NaN');
|
||||||
|
}(1, 2, NaN, NaN));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('indexOf with +- 0', function() {
|
||||||
|
_.each([-0, +0], function(val) {
|
||||||
|
strictEqual(_.indexOf([1, 2, val, val], val), 2);
|
||||||
|
strictEqual(_.indexOf([1, 2, val, val], -val), 2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('lastIndexOf', function() {
|
||||||
|
var numbers = [1, 0, 1];
|
||||||
|
var falsey = [void 0, '', 0, false, NaN, null, undefined];
|
||||||
|
equal(_.lastIndexOf(numbers, 1), 2);
|
||||||
|
|
||||||
|
numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0];
|
||||||
numbers.lastIndexOf = null;
|
numbers.lastIndexOf = null;
|
||||||
equal(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function');
|
equal(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function');
|
||||||
equal(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element');
|
equal(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element');
|
||||||
var result = (function(){ return _.lastIndexOf(arguments, 1); })(1, 0, 1, 0, 0, 1, 0, 0, 0);
|
var result = (function(){ return _.lastIndexOf(arguments, 1); }(1, 0, 1, 0, 0, 1, 0, 0, 0));
|
||||||
equal(result, 5, 'works on an arguments object');
|
equal(result, 5, 'works on an arguments object');
|
||||||
equal(_.indexOf(null, 2), -1, 'handles nulls properly');
|
|
||||||
|
_.each([null, void 0, [], false], function(val) {
|
||||||
|
var msg = 'Handles: ' + (_.isArray(val) ? '[]' : val);
|
||||||
|
equal(_.lastIndexOf(val, 2), -1, msg);
|
||||||
|
equal(_.lastIndexOf(val, 2, -1), -1, msg);
|
||||||
|
equal(_.lastIndexOf(val, 2, -20), -1, msg);
|
||||||
|
equal(_.lastIndexOf(val, 2, 15), -1, msg);
|
||||||
|
});
|
||||||
|
|
||||||
|
numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3];
|
||||||
|
var index = _.lastIndexOf(numbers, 2, 2);
|
||||||
|
equal(index, 1, 'supports the fromIndex argument');
|
||||||
|
|
||||||
|
var array = [1, 2, 3, 1, 2, 3];
|
||||||
|
|
||||||
|
strictEqual(_.lastIndexOf(array, 1, 0), 0, 'starts at the correct from idx');
|
||||||
|
strictEqual(_.lastIndexOf(array, 3), 5, 'should return the index of the last matched value');
|
||||||
|
strictEqual(_.lastIndexOf(array, 4), -1, 'should return `-1` for an unmatched value');
|
||||||
|
|
||||||
|
strictEqual(_.lastIndexOf(array, 1, 2), 0, 'should work with a positive `fromIndex`');
|
||||||
|
|
||||||
|
_.each([6, 8, Math.pow(2, 32), Infinity], function(fromIndex) {
|
||||||
|
strictEqual(_.lastIndexOf(array, undefined, fromIndex), -1);
|
||||||
|
strictEqual(_.lastIndexOf(array, 1, fromIndex), 3);
|
||||||
|
strictEqual(_.lastIndexOf(array, '', fromIndex), -1);
|
||||||
|
});
|
||||||
|
|
||||||
|
var expected = _.map(falsey, function(value) {
|
||||||
|
return typeof value == 'number' ? -1 : 5;
|
||||||
|
});
|
||||||
|
|
||||||
|
var actual = _.map(falsey, function(fromIndex) {
|
||||||
|
return _.lastIndexOf(array, 3, fromIndex);
|
||||||
|
});
|
||||||
|
|
||||||
|
deepEqual(actual, expected, 'should treat falsey `fromIndex` values, except `0` and `NaN`, as `array.length`');
|
||||||
|
strictEqual(_.lastIndexOf(array, 3, '1'), 5, 'should treat non-number `fromIndex` values as `array.length`');
|
||||||
|
strictEqual(_.lastIndexOf(array, 3, true), 5, 'should treat non-number `fromIndex` values as `array.length`');
|
||||||
|
|
||||||
|
strictEqual(_.lastIndexOf(array, 2, -3), 1, 'should work with a negative `fromIndex`');
|
||||||
|
strictEqual(_.lastIndexOf(array, 1, -3), 3, 'neg `fromIndex` starts at the right index');
|
||||||
|
|
||||||
|
deepEqual(_.map([-6, -8, -Infinity], function(fromIndex) {
|
||||||
|
return _.lastIndexOf(array, 1, fromIndex);
|
||||||
|
}), [0, -1, -1]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("arrays: range", function() {
|
test('lastIndexOf with NaN', function() {
|
||||||
equal(_.range(0).join(''), '', 'range with 0 as a first argument generates an empty array');
|
strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN), 3, 'Expected [1, 2, NaN] to contain NaN');
|
||||||
equal(_.range(4).join(' '), '0 1 2 3', 'range with a single positive argument generates an array of elements 0,1,2,...,n-1');
|
strictEqual(_.lastIndexOf([1, 2, Infinity], NaN), -1, 'Expected [1, 2, NaN] to contain NaN');
|
||||||
equal(_.range(5, 8).join(' '), '5 6 7', 'range with two arguments a & b, a<b generates an array of elements a,a+1,a+2,...,b-2,b-1');
|
|
||||||
equal(_.range(8, 5).join(''), '', 'range with two arguments a & b, b<a generates an empty array');
|
strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN, 2), 2, 'fromIndex does not affect result');
|
||||||
equal(_.range(3, 10, 3).join(' '), '3 6 9', 'range with three arguments a & b & c, c < b-a, a < b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) < c');
|
strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN, -2), 2, 'fromIndex does not affect result');
|
||||||
equal(_.range(3, 10, 15).join(''), '3', 'range with three arguments a & b & c, c > b-a, a < b generates an array with a single element, equal to a');
|
|
||||||
equal(_.range(12, 7, -2).join(' '), '12 10 8', 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b');
|
(function() {
|
||||||
equal(_.range(0, -10, -1).join(' '), '0 -1 -2 -3 -4 -5 -6 -7 -8 -9', 'final example in the Python docs');
|
strictEqual(_.lastIndexOf(arguments, NaN), 3, 'Expected arguments [1, 2, NaN] to contain NaN');
|
||||||
|
}(1, 2, NaN, NaN));
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
test('lastIndexOf with +- 0', function() {
|
||||||
|
_.each([-0, +0], function(val) {
|
||||||
|
strictEqual(_.lastIndexOf([1, 2, val, val], val), 3);
|
||||||
|
strictEqual(_.lastIndexOf([1, 2, val, val], -val), 3);
|
||||||
|
strictEqual(_.lastIndexOf([-1, 1, 2], -val), -1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('findIndex', function() {
|
||||||
|
var objects = [
|
||||||
|
{'a': 0, 'b': 0},
|
||||||
|
{'a': 1, 'b': 1},
|
||||||
|
{'a': 2, 'b': 2},
|
||||||
|
{'a': 0, 'b': 0}
|
||||||
|
];
|
||||||
|
|
||||||
|
equal(_.findIndex(objects, function(obj) {
|
||||||
|
return obj.a === 0;
|
||||||
|
}), 0);
|
||||||
|
|
||||||
|
equal(_.findIndex(objects, function(obj) {
|
||||||
|
return obj.b * obj.a === 4;
|
||||||
|
}), 2);
|
||||||
|
|
||||||
|
equal(_.findIndex(objects, 'a'), 1, 'Uses lookupIterator');
|
||||||
|
|
||||||
|
equal(_.findIndex(objects, function(obj) {
|
||||||
|
return obj.b * obj.a === 5;
|
||||||
|
}), -1);
|
||||||
|
|
||||||
|
equal(_.findIndex(null, _.noop), -1);
|
||||||
|
strictEqual(_.findIndex(objects, function(a) {
|
||||||
|
return a.foo === null;
|
||||||
|
}), -1);
|
||||||
|
_.findIndex([{a: 1}], function(a, key, obj) {
|
||||||
|
equal(key, 0);
|
||||||
|
deepEqual(obj, [{a: 1}]);
|
||||||
|
strictEqual(this, objects, 'called with context');
|
||||||
|
}, objects);
|
||||||
|
|
||||||
|
var sparse = [];
|
||||||
|
sparse[20] = {'a': 2, 'b': 2};
|
||||||
|
equal(_.findIndex(sparse, function(obj) {
|
||||||
|
return obj && obj.b * obj.a === 4;
|
||||||
|
}), 20, 'Works with sparse arrays');
|
||||||
|
|
||||||
|
var array = [1, 2, 3, 4];
|
||||||
|
array.match = 55;
|
||||||
|
strictEqual(_.findIndex(array, function(x) { return x === 55; }), -1, 'doesn\'t match array-likes keys');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('findLastIndex', function() {
|
||||||
|
var objects = [
|
||||||
|
{'a': 0, 'b': 0},
|
||||||
|
{'a': 1, 'b': 1},
|
||||||
|
{'a': 2, 'b': 2},
|
||||||
|
{'a': 0, 'b': 0}
|
||||||
|
];
|
||||||
|
|
||||||
|
equal(_.findLastIndex(objects, function(obj) {
|
||||||
|
return obj.a === 0;
|
||||||
|
}), 3);
|
||||||
|
|
||||||
|
equal(_.findLastIndex(objects, function(obj) {
|
||||||
|
return obj.b * obj.a === 4;
|
||||||
|
}), 2);
|
||||||
|
|
||||||
|
equal(_.findLastIndex(objects, 'a'), 2, 'Uses lookupIterator');
|
||||||
|
|
||||||
|
equal(_.findLastIndex(objects, function(obj) {
|
||||||
|
return obj.b * obj.a === 5;
|
||||||
|
}), -1);
|
||||||
|
|
||||||
|
equal(_.findLastIndex(null, _.noop), -1);
|
||||||
|
strictEqual(_.findLastIndex(objects, function(a) {
|
||||||
|
return a.foo === null;
|
||||||
|
}), -1);
|
||||||
|
_.findLastIndex([{a: 1}], function(a, key, obj) {
|
||||||
|
equal(key, 0);
|
||||||
|
deepEqual(obj, [{a: 1}]);
|
||||||
|
strictEqual(this, objects, 'called with context');
|
||||||
|
}, objects);
|
||||||
|
|
||||||
|
var sparse = [];
|
||||||
|
sparse[20] = {'a': 2, 'b': 2};
|
||||||
|
equal(_.findLastIndex(sparse, function(obj) {
|
||||||
|
return obj && obj.b * obj.a === 4;
|
||||||
|
}), 20, 'Works with sparse arrays');
|
||||||
|
|
||||||
|
var array = [1, 2, 3, 4];
|
||||||
|
array.match = 55;
|
||||||
|
strictEqual(_.findLastIndex(array, function(x) { return x === 55; }), -1, 'doesn\'t match array-likes keys');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('range', function() {
|
||||||
|
deepEqual(_.range(0), [], 'range with 0 as a first argument generates an empty array');
|
||||||
|
deepEqual(_.range(4), [0, 1, 2, 3], 'range with a single positive argument generates an array of elements 0,1,2,...,n-1');
|
||||||
|
deepEqual(_.range(5, 8), [5, 6, 7], 'range with two arguments a & b, a<b generates an array of elements a,a+1,a+2,...,b-2,b-1');
|
||||||
|
deepEqual(_.range(8, 5), [], 'range with two arguments a & b, b<a generates an empty array');
|
||||||
|
deepEqual(_.range(3, 10, 3), [3, 6, 9], 'range with three arguments a & b & c, c < b-a, a < b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) < c');
|
||||||
|
deepEqual(_.range(3, 10, 15), [3], 'range with three arguments a & b & c, c > b-a, a < b generates an array with a single element, equal to a');
|
||||||
|
deepEqual(_.range(12, 7, -2), [12, 10, 8], 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b');
|
||||||
|
deepEqual(_.range(0, -10, -1), [0, -1, -2, -3, -4, -5, -6, -7, -8, -9], 'final example in the Python docs');
|
||||||
|
});
|
||||||
|
|
||||||
|
}());
|
||||||
|
|||||||
83
vendor/underscore/test/chaining.js
vendored
83
vendor/underscore/test/chaining.js
vendored
@@ -1,13 +1,14 @@
|
|||||||
$(document).ready(function() {
|
(function() {
|
||||||
|
var _ = typeof require == 'function' ? require('..') : window._;
|
||||||
|
|
||||||
module("Chaining");
|
QUnit.module('Chaining');
|
||||||
|
|
||||||
test("chaining: map/flatten/reduce", function() {
|
test('map/flatten/reduce', function() {
|
||||||
var lyrics = [
|
var lyrics = [
|
||||||
"I'm a lumberjack and I'm okay",
|
'I\'m a lumberjack and I\'m okay',
|
||||||
"I sleep all night and I work all day",
|
'I sleep all night and I work all day',
|
||||||
"He's a lumberjack and he's okay",
|
'He\'s a lumberjack and he\'s okay',
|
||||||
"He sleeps all night and he works all day"
|
'He sleeps all night and he works all day'
|
||||||
];
|
];
|
||||||
var counts = _(lyrics).chain()
|
var counts = _(lyrics).chain()
|
||||||
.map(function(line) { return line.split(''); })
|
.map(function(line) { return line.split(''); })
|
||||||
@@ -17,35 +18,36 @@ $(document).ready(function() {
|
|||||||
hash[l]++;
|
hash[l]++;
|
||||||
return hash;
|
return hash;
|
||||||
}, {}).value();
|
}, {}).value();
|
||||||
ok(counts['a'] == 16 && counts['e'] == 10, 'counted all the letters in the song');
|
equal(counts.a, 16, 'counted all the letters in the song');
|
||||||
|
equal(counts.e, 10, 'counted all the letters in the song');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("chaining: select/reject/sortBy", function() {
|
test('select/reject/sortBy', function() {
|
||||||
var numbers = [1,2,3,4,5,6,7,8,9,10];
|
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||||
numbers = _(numbers).chain().select(function(n) {
|
numbers = _(numbers).chain().select(function(n) {
|
||||||
return n % 2 == 0;
|
return n % 2 === 0;
|
||||||
}).reject(function(n) {
|
}).reject(function(n) {
|
||||||
return n % 4 == 0;
|
return n % 4 === 0;
|
||||||
}).sortBy(function(n) {
|
}).sortBy(function(n) {
|
||||||
return -n;
|
return -n;
|
||||||
}).value();
|
}).value();
|
||||||
equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers");
|
deepEqual(numbers, [10, 6, 2], 'filtered and reversed the numbers');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("chaining: select/reject/sortBy in functional style", function() {
|
test('select/reject/sortBy in functional style', function() {
|
||||||
var numbers = [1,2,3,4,5,6,7,8,9,10];
|
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||||
numbers = _.chain(numbers).select(function(n) {
|
numbers = _.chain(numbers).select(function(n) {
|
||||||
return n % 2 == 0;
|
return n % 2 === 0;
|
||||||
}).reject(function(n) {
|
}).reject(function(n) {
|
||||||
return n % 4 == 0;
|
return n % 4 === 0;
|
||||||
}).sortBy(function(n) {
|
}).sortBy(function(n) {
|
||||||
return -n;
|
return -n;
|
||||||
}).value();
|
}).value();
|
||||||
equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers");
|
deepEqual(numbers, [10, 6, 2], 'filtered and reversed the numbers');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("chaining: reverse/concat/unshift/pop/map", function() {
|
test('reverse/concat/unshift/pop/map', function() {
|
||||||
var numbers = [1,2,3,4,5];
|
var numbers = [1, 2, 3, 4, 5];
|
||||||
numbers = _(numbers).chain()
|
numbers = _(numbers).chain()
|
||||||
.reverse()
|
.reverse()
|
||||||
.concat([5, 5, 5])
|
.concat([5, 5, 5])
|
||||||
@@ -53,7 +55,44 @@ $(document).ready(function() {
|
|||||||
.pop()
|
.pop()
|
||||||
.map(function(n){ return n * 2; })
|
.map(function(n){ return n * 2; })
|
||||||
.value();
|
.value();
|
||||||
equal(numbers.join(', '), "34, 10, 8, 6, 4, 2, 10, 10", 'can chain together array functions.');
|
deepEqual(numbers, [34, 10, 8, 6, 4, 2, 10, 10], 'can chain together array functions.');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
test('splice', function() {
|
||||||
|
var instance = _([1, 2, 3, 4, 5]).chain();
|
||||||
|
deepEqual(instance.splice(1, 3).value(), [1, 5]);
|
||||||
|
deepEqual(instance.splice(1, 0).value(), [1, 5]);
|
||||||
|
deepEqual(instance.splice(1, 1).value(), [1]);
|
||||||
|
deepEqual(instance.splice(0, 1).value(), [], '#397 Can create empty array');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('shift', function() {
|
||||||
|
var instance = _([1, 2, 3]).chain();
|
||||||
|
deepEqual(instance.shift().value(), [2, 3]);
|
||||||
|
deepEqual(instance.shift().value(), [3]);
|
||||||
|
deepEqual(instance.shift().value(), [], '#397 Can create empty array');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('pop', function() {
|
||||||
|
var instance = _([1, 2, 3]).chain();
|
||||||
|
deepEqual(instance.pop().value(), [1, 2]);
|
||||||
|
deepEqual(instance.pop().value(), [1]);
|
||||||
|
deepEqual(instance.pop().value(), [], '#397 Can create empty array');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('chaining works in small stages', function() {
|
||||||
|
var o = _([1, 2, 3, 4]).chain();
|
||||||
|
deepEqual(o.filter(function(i) { return i < 3; }).value(), [1, 2]);
|
||||||
|
deepEqual(o.filter(function(i) { return i > 2; }).value(), [3, 4]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('#1562: Engine proxies for chained functions', function() {
|
||||||
|
var wrapped = _(512);
|
||||||
|
strictEqual(wrapped.toJSON(), 512);
|
||||||
|
strictEqual(wrapped.valueOf(), 512);
|
||||||
|
strictEqual(+wrapped, 512);
|
||||||
|
strictEqual(wrapped.toString(), '512');
|
||||||
|
strictEqual('' + wrapped, '512');
|
||||||
|
});
|
||||||
|
|
||||||
|
}());
|
||||||
|
|||||||
847
vendor/underscore/test/collections.js
vendored
847
vendor/underscore/test/collections.js
vendored
@@ -1,60 +1,181 @@
|
|||||||
$(document).ready(function() {
|
(function() {
|
||||||
|
var _ = typeof require == 'function' ? require('..') : window._;
|
||||||
|
|
||||||
module("Collections");
|
QUnit.module('Collections');
|
||||||
|
|
||||||
test("collections: each", function() {
|
test('each', function() {
|
||||||
_.each([1, 2, 3], function(num, i) {
|
_.each([1, 2, 3], function(num, i) {
|
||||||
equal(num, i + 1, 'each iterators provide value and iteration count');
|
equal(num, i + 1, 'each iterators provide value and iteration count');
|
||||||
});
|
});
|
||||||
|
|
||||||
var answers = [];
|
var answers = [];
|
||||||
_.each([1, 2, 3], function(num){ answers.push(num * this.multiplier);}, {multiplier : 5});
|
_.each([1, 2, 3], function(num){ answers.push(num * this.multiplier);}, {multiplier : 5});
|
||||||
equal(answers.join(', '), '5, 10, 15', 'context object property accessed');
|
deepEqual(answers, [5, 10, 15], 'context object property accessed');
|
||||||
|
|
||||||
answers = [];
|
answers = [];
|
||||||
_.forEach([1, 2, 3], function(num){ answers.push(num); });
|
_.each([1, 2, 3], function(num){ answers.push(num); });
|
||||||
equal(answers.join(', '), '1, 2, 3', 'aliased as "forEach"');
|
deepEqual(answers, [1, 2, 3], 'aliased as "forEach"');
|
||||||
|
|
||||||
answers = [];
|
answers = [];
|
||||||
var obj = {one : 1, two : 2, three : 3};
|
var obj = {one : 1, two : 2, three : 3};
|
||||||
obj.constructor.prototype.four = 4;
|
obj.constructor.prototype.four = 4;
|
||||||
_.each(obj, function(value, key){ answers.push(key); });
|
_.each(obj, function(value, key){ answers.push(key); });
|
||||||
equal(answers.join(", "), 'one, two, three', 'iterating over objects works, and ignores the object prototype.');
|
deepEqual(answers, ['one', 'two', 'three'], 'iterating over objects works, and ignores the object prototype.');
|
||||||
delete obj.constructor.prototype.four;
|
delete obj.constructor.prototype.four;
|
||||||
|
|
||||||
answer = null;
|
// ensure the each function is JITed
|
||||||
|
_(1000).times(function() { _.each([], function(){}); });
|
||||||
|
var count = 0;
|
||||||
|
obj = {1 : 'foo', 2 : 'bar', 3 : 'baz'};
|
||||||
|
_.each(obj, function(value, key){ count++; });
|
||||||
|
equal(count, 3, 'the fun should be called only 3 times');
|
||||||
|
|
||||||
|
var answer = null;
|
||||||
_.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; });
|
_.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; });
|
||||||
ok(answer, 'can reference the original collection from inside the iterator');
|
ok(answer, 'can reference the original collection from inside the iterator');
|
||||||
|
|
||||||
answers = 0;
|
answers = 0;
|
||||||
_.each(null, function(){ ++answers; });
|
_.each(null, function(){ ++answers; });
|
||||||
equal(answers, 0, 'handles a null properly');
|
equal(answers, 0, 'handles a null properly');
|
||||||
|
|
||||||
|
_.each(false, function(){});
|
||||||
|
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
strictEqual(_.each(a, function(){}), a);
|
||||||
|
strictEqual(_.each(null, function(){}), null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: map', function() {
|
test('forEach', function() {
|
||||||
var doubled = _.map([1, 2, 3], function(num){ return num * 2; });
|
strictEqual(_.each, _.forEach, 'alias for each');
|
||||||
equal(doubled.join(', '), '2, 4, 6', 'doubled numbers');
|
});
|
||||||
|
|
||||||
doubled = _.collect([1, 2, 3], function(num){ return num * 2; });
|
test('lookupIterator with contexts', function() {
|
||||||
equal(doubled.join(', '), '2, 4, 6', 'aliased as "collect"');
|
_.each([true, false, 'yes', '', 0, 1, {}], function(context) {
|
||||||
|
_.each([1], function() {
|
||||||
|
equal(this, context);
|
||||||
|
}, context);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Iterating objects with sketchy length properties', function() {
|
||||||
|
var functions = [
|
||||||
|
'each', 'map', 'filter', 'find',
|
||||||
|
'some', 'every', 'max', 'min',
|
||||||
|
'groupBy', 'countBy', 'partition', 'indexBy'
|
||||||
|
];
|
||||||
|
var reducers = ['reduce', 'reduceRight'];
|
||||||
|
|
||||||
|
var tricks = [
|
||||||
|
{length: '5'},
|
||||||
|
{
|
||||||
|
length: {
|
||||||
|
valueOf: _.constant(5)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{length: Math.pow(2, 53) + 1},
|
||||||
|
{length: Math.pow(2, 53)},
|
||||||
|
{length: null},
|
||||||
|
{length: -2},
|
||||||
|
{length: new Number(15)}
|
||||||
|
];
|
||||||
|
|
||||||
|
expect(tricks.length * (functions.length + reducers.length + 4));
|
||||||
|
|
||||||
|
_.each(tricks, function(trick) {
|
||||||
|
var length = trick.length;
|
||||||
|
strictEqual(_.size(trick), 1, 'size on obj with length: ' + length);
|
||||||
|
deepEqual(_.toArray(trick), [length], 'toArray on obj with length: ' + length);
|
||||||
|
deepEqual(_.shuffle(trick), [length], 'shuffle on obj with length: ' + length);
|
||||||
|
deepEqual(_.sample(trick), length, 'sample on obj with length: ' + length);
|
||||||
|
|
||||||
|
|
||||||
|
_.each(functions, function(method) {
|
||||||
|
_[method](trick, function(val, key) {
|
||||||
|
strictEqual(key, 'length', method + ': ran with length = ' + val);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
_.each(reducers, function(method) {
|
||||||
|
strictEqual(_[method](trick), trick.length, method);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Resistant to collection length and properties changing while iterating', function() {
|
||||||
|
|
||||||
|
var collection = [
|
||||||
|
'each', 'map', 'filter', 'find',
|
||||||
|
'some', 'every', 'max', 'min', 'reject',
|
||||||
|
'groupBy', 'countBy', 'partition', 'indexBy',
|
||||||
|
'reduce', 'reduceRight'
|
||||||
|
];
|
||||||
|
var array = [
|
||||||
|
'findIndex', 'findLastIndex'
|
||||||
|
];
|
||||||
|
var object = [
|
||||||
|
'mapObject', 'findKey', 'pick', 'omit'
|
||||||
|
];
|
||||||
|
|
||||||
|
_.each(collection.concat(array), function(method) {
|
||||||
|
var sparseArray = [1, 2, 3];
|
||||||
|
sparseArray.length = 100;
|
||||||
|
var answers = 0;
|
||||||
|
_[method](sparseArray, function(){
|
||||||
|
++answers;
|
||||||
|
return method === 'every' ? true : null;
|
||||||
|
}, {});
|
||||||
|
equal(answers, 100, method + ' enumerates [0, length)');
|
||||||
|
|
||||||
|
var growingCollection = [1, 2, 3], count = 0;
|
||||||
|
_[method](growingCollection, function() {
|
||||||
|
if (count < 10) growingCollection.push(count++);
|
||||||
|
return method === 'every' ? true : null;
|
||||||
|
}, {});
|
||||||
|
equal(count, 3, method + ' is resistant to length changes');
|
||||||
|
});
|
||||||
|
|
||||||
|
_.each(collection.concat(object), function(method) {
|
||||||
|
var changingObject = {0: 0, 1: 1}, count = 0;
|
||||||
|
_[method](changingObject, function(val) {
|
||||||
|
if (count < 10) changingObject[++count] = val + 1;
|
||||||
|
return method === 'every' ? true : null;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
equal(count, 2, method + ' is resistant to property changes');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('map', function() {
|
||||||
|
var doubled = _.map([1, 2, 3], function(num){ return num * 2; });
|
||||||
|
deepEqual(doubled, [2, 4, 6], 'doubled numbers');
|
||||||
|
|
||||||
var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier : 3});
|
var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier : 3});
|
||||||
equal(tripled.join(', '), '3, 6, 9', 'tripled numbers with context');
|
deepEqual(tripled, [3, 6, 9], 'tripled numbers with context');
|
||||||
|
|
||||||
var doubled = _([1, 2, 3]).map(function(num){ return num * 2; });
|
doubled = _([1, 2, 3]).map(function(num){ return num * 2; });
|
||||||
equal(doubled.join(', '), '2, 4, 6', 'OO-style doubled numbers');
|
deepEqual(doubled, [2, 4, 6], 'OO-style doubled numbers');
|
||||||
|
|
||||||
var ids = _.map($('#map-test').children(), function(n){ return n.id; });
|
var ids = _.map({length: 2, 0: {id: '1'}, 1: {id: '2'}}, function(n){
|
||||||
deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on NodeLists.');
|
return n.id;
|
||||||
|
});
|
||||||
|
deepEqual(ids, ['1', '2'], 'Can use collection methods on Array-likes.');
|
||||||
|
|
||||||
var ids = _.map(document.images, function(n){ return n.id; });
|
deepEqual(_.map(null, _.noop), [], 'handles a null properly');
|
||||||
ok(ids[0] == 'chart_image', 'can use collection methods on HTMLCollections');
|
|
||||||
|
|
||||||
var ifnull = _.map(null, function(){});
|
deepEqual(_.map([1], function() {
|
||||||
ok(_.isArray(ifnull) && ifnull.length === 0, 'handles a null properly');
|
return this.length;
|
||||||
|
}, [5]), [1], 'called with context');
|
||||||
|
|
||||||
|
// Passing a property name like _.pluck.
|
||||||
|
var people = [{name : 'moe', age : 30}, {name : 'curly', age : 50}];
|
||||||
|
deepEqual(_.map(people, 'name'), ['moe', 'curly'], 'predicate string map to object properties');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: reduce', function() {
|
test('collect', function() {
|
||||||
|
strictEqual(_.map, _.collect, 'alias for map');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('reduce', function() {
|
||||||
var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }, 0);
|
var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }, 0);
|
||||||
equal(sum, 6, 'can sum up an array');
|
equal(sum, 6, 'can sum up an array');
|
||||||
|
|
||||||
@@ -68,139 +189,367 @@ $(document).ready(function() {
|
|||||||
sum = _([1, 2, 3]).reduce(function(sum, num){ return sum + num; }, 0);
|
sum = _([1, 2, 3]).reduce(function(sum, num){ return sum + num; }, 0);
|
||||||
equal(sum, 6, 'OO-style reduce');
|
equal(sum, 6, 'OO-style reduce');
|
||||||
|
|
||||||
var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; });
|
sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; });
|
||||||
equal(sum, 6, 'default initial value');
|
equal(sum, 6, 'default initial value');
|
||||||
|
|
||||||
var ifnull;
|
var prod = _.reduce([1, 2, 3, 4], function(prod, num){ return prod * num; });
|
||||||
try {
|
equal(prod, 24, 'can reduce via multiplication');
|
||||||
_.reduce(null, function(){});
|
|
||||||
} catch (ex) {
|
|
||||||
ifnull = ex;
|
|
||||||
}
|
|
||||||
ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly');
|
|
||||||
|
|
||||||
ok(_.reduce(null, function(){}, 138) === 138, 'handles a null (with initial value) properly');
|
ok(_.reduce(null, _.noop, 138) === 138, 'handles a null (with initial value) properly');
|
||||||
equal(_.reduce([], function(){}, undefined), undefined, 'undefined can be passed as a special case');
|
equal(_.reduce([], _.noop, undefined), undefined, 'undefined can be passed as a special case');
|
||||||
raises(function() { _.reduce([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value');
|
equal(_.reduce([_], _.noop), _, 'collection of length one with no initial value returns the first item');
|
||||||
|
equal(_.reduce([], _.noop), undefined, 'returns undefined when collection is empty and no initial value');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: reduceRight', function() {
|
test('foldl', function() {
|
||||||
var list = _.reduceRight(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, '');
|
strictEqual(_.reduce, _.foldl, 'alias for reduce');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('reduceRight', function() {
|
||||||
|
var list = _.reduceRight(['foo', 'bar', 'baz'], function(memo, str){ return memo + str; }, '');
|
||||||
equal(list, 'bazbarfoo', 'can perform right folds');
|
equal(list, 'bazbarfoo', 'can perform right folds');
|
||||||
|
|
||||||
var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, '');
|
list = _.reduceRight(['foo', 'bar', 'baz'], function(memo, str){ return memo + str; });
|
||||||
equal(list, 'bazbarfoo', 'aliased as "foldr"');
|
|
||||||
|
|
||||||
var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; });
|
|
||||||
equal(list, 'bazbarfoo', 'default initial value');
|
equal(list, 'bazbarfoo', 'default initial value');
|
||||||
|
|
||||||
var ifnull;
|
var sum = _.reduceRight({a: 1, b: 2, c: 3}, function(sum, num){ return sum + num; });
|
||||||
try {
|
equal(sum, 6, 'default initial value on object');
|
||||||
_.reduceRight(null, function(){});
|
|
||||||
} catch (ex) {
|
|
||||||
ifnull = ex;
|
|
||||||
}
|
|
||||||
ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly');
|
|
||||||
|
|
||||||
ok(_.reduceRight(null, function(){}, 138) === 138, 'handles a null (with initial value) properly');
|
ok(_.reduceRight(null, _.noop, 138) === 138, 'handles a null (with initial value) properly');
|
||||||
|
equal(_.reduceRight([_], _.noop), _, 'collection of length one with no initial value returns the first item');
|
||||||
|
|
||||||
equal(_.reduceRight([], function(){}, undefined), undefined, 'undefined can be passed as a special case');
|
equal(_.reduceRight([], _.noop, undefined), undefined, 'undefined can be passed as a special case');
|
||||||
raises(function() { _.reduceRight([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value');
|
equal(_.reduceRight([], _.noop), undefined, 'returns undefined when collection is empty and no initial value');
|
||||||
|
|
||||||
|
// Assert that the correct arguments are being passed.
|
||||||
|
|
||||||
|
var args,
|
||||||
|
memo = {},
|
||||||
|
object = {a: 1, b: 2},
|
||||||
|
lastKey = _.keys(object).pop();
|
||||||
|
|
||||||
|
var expected = lastKey === 'a'
|
||||||
|
? [memo, 1, 'a', object]
|
||||||
|
: [memo, 2, 'b', object];
|
||||||
|
|
||||||
|
_.reduceRight(object, function() {
|
||||||
|
if (!args) args = _.toArray(arguments);
|
||||||
|
}, memo);
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
|
||||||
|
// And again, with numeric keys.
|
||||||
|
|
||||||
|
object = {'2': 'a', '1': 'b'};
|
||||||
|
lastKey = _.keys(object).pop();
|
||||||
|
args = null;
|
||||||
|
|
||||||
|
expected = lastKey === '2'
|
||||||
|
? [memo, 'a', '2', object]
|
||||||
|
: [memo, 'b', '1', object];
|
||||||
|
|
||||||
|
_.reduceRight(object, function() {
|
||||||
|
if (!args) args = _.toArray(arguments);
|
||||||
|
}, memo);
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: find', function() {
|
test('foldr', function() {
|
||||||
|
strictEqual(_.reduceRight, _.foldr, 'alias for reduceRight');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('find', function() {
|
||||||
var array = [1, 2, 3, 4];
|
var array = [1, 2, 3, 4];
|
||||||
strictEqual(_.find(array, function(n) { return n > 2; }), 3, 'should return first found `value`');
|
strictEqual(_.find(array, function(n) { return n > 2; }), 3, 'should return first found `value`');
|
||||||
strictEqual(_.find(array, function() { return false; }), void 0, 'should return `undefined` if `value` is not found');
|
strictEqual(_.find(array, function() { return false; }), void 0, 'should return `undefined` if `value` is not found');
|
||||||
});
|
|
||||||
|
|
||||||
test('collections: detect', function() {
|
array.dontmatch = 55;
|
||||||
var result = _.detect([1, 2, 3], function(num){ return num * 2 == 4; });
|
strictEqual(_.find(array, function(x) { return x === 55; }), void 0, 'iterates array-likes correctly');
|
||||||
|
|
||||||
|
// Matching an object like _.findWhere.
|
||||||
|
var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}, {a: 2, b: 4}];
|
||||||
|
deepEqual(_.find(list, {a: 1}), {a: 1, b: 2}, 'can be used as findWhere');
|
||||||
|
deepEqual(_.find(list, {b: 4}), {a: 1, b: 4});
|
||||||
|
ok(!_.find(list, {c: 1}), 'undefined when not found');
|
||||||
|
ok(!_.find([], {c: 1}), 'undefined when searching empty list');
|
||||||
|
|
||||||
|
var result = _.find([1, 2, 3], function(num){ return num * 2 === 4; });
|
||||||
equal(result, 2, 'found the first "2" and broke the loop');
|
equal(result, 2, 'found the first "2" and broke the loop');
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
a: {x: 1, z: 3},
|
||||||
|
b: {x: 2, z: 2},
|
||||||
|
c: {x: 3, z: 4},
|
||||||
|
d: {x: 4, z: 1}
|
||||||
|
};
|
||||||
|
|
||||||
|
deepEqual(_.find(obj, {x: 2}), {x: 2, z: 2}, 'works on objects');
|
||||||
|
deepEqual(_.find(obj, {x: 2, z: 1}), void 0);
|
||||||
|
deepEqual(_.find(obj, function(x) {
|
||||||
|
return x.x === 4;
|
||||||
|
}), {x: 4, z: 1});
|
||||||
|
|
||||||
|
_.findIndex([{a: 1}], function(a, key, obj) {
|
||||||
|
equal(key, 0);
|
||||||
|
deepEqual(obj, [{a: 1}]);
|
||||||
|
strictEqual(this, _, 'called with context');
|
||||||
|
}, _);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: select', function() {
|
test('detect', function() {
|
||||||
var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
|
strictEqual(_.detect, _.find, 'alias for detect');
|
||||||
equal(evens.join(', '), '2, 4, 6', 'selected each even number');
|
|
||||||
|
|
||||||
evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
|
|
||||||
equal(evens.join(', '), '2, 4, 6', 'aliased as "filter"');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: reject', function() {
|
test('filter', function() {
|
||||||
var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
|
var evenArray = [1, 2, 3, 4, 5, 6];
|
||||||
equal(odds.join(', '), '1, 3, 5', 'rejected each even number');
|
var evenObject = {one: 1, two: 2, three: 3};
|
||||||
|
var isEven = function(num){ return num % 2 === 0; };
|
||||||
|
|
||||||
|
deepEqual(_.filter(evenArray, isEven), [2, 4, 6]);
|
||||||
|
deepEqual(_.filter(evenObject, isEven), [2], 'can filter objects');
|
||||||
|
deepEqual(_.filter([{}, evenObject, []], 'two'), [evenObject], 'predicate string map to object properties');
|
||||||
|
|
||||||
|
_.filter([1], function() {
|
||||||
|
equal(this, evenObject, 'given context');
|
||||||
|
}, evenObject);
|
||||||
|
|
||||||
|
// Can be used like _.where.
|
||||||
|
var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
|
||||||
|
deepEqual(_.filter(list, {a: 1}), [{a: 1, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}]);
|
||||||
|
deepEqual(_.filter(list, {b: 2}), [{a: 1, b: 2}, {a: 2, b: 2}]);
|
||||||
|
deepEqual(_.filter(list, {}), list, 'Empty object accepts all items');
|
||||||
|
deepEqual(_(list).filter({}), list, 'OO-filter');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: all', function() {
|
test('select', function() {
|
||||||
ok(_.all([], _.identity), 'the empty set');
|
strictEqual(_.filter, _.select, 'alias for filter');
|
||||||
ok(_.all([true, true, true], _.identity), 'all true values');
|
|
||||||
ok(!_.all([true, false, true], _.identity), 'one false value');
|
|
||||||
ok(_.all([0, 10, 28], function(num){ return num % 2 == 0; }), 'even numbers');
|
|
||||||
ok(!_.all([0, 11, 28], function(num){ return num % 2 == 0; }), 'an odd number');
|
|
||||||
ok(_.all([1], _.identity) === true, 'cast to boolean - true');
|
|
||||||
ok(_.all([0], _.identity) === false, 'cast to boolean - false');
|
|
||||||
ok(_.every([true, true, true], _.identity), 'aliased as "every"');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: any', function() {
|
test('reject', function() {
|
||||||
var nativeSome = Array.prototype.some;
|
var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 === 0; });
|
||||||
Array.prototype.some = null;
|
deepEqual(odds, [1, 3, 5], 'rejected each even number');
|
||||||
ok(!_.any([]), 'the empty set');
|
|
||||||
ok(!_.any([false, false, false]), 'all false values');
|
var context = 'obj';
|
||||||
ok(_.any([false, false, true]), 'one true value');
|
|
||||||
ok(_.any([null, 0, 'yes', false]), 'a string');
|
var evens = _.reject([1, 2, 3, 4, 5, 6], function(num){
|
||||||
ok(!_.any([null, 0, '', false]), 'falsy values');
|
equal(context, 'obj');
|
||||||
ok(!_.any([1, 11, 29], function(num){ return num % 2 == 0; }), 'all odd numbers');
|
return num % 2 !== 0;
|
||||||
ok(_.any([1, 10, 29], function(num){ return num % 2 == 0; }), 'an even number');
|
}, context);
|
||||||
ok(_.any([1], _.identity) === true, 'cast to boolean - true');
|
deepEqual(evens, [2, 4, 6], 'rejected each odd number');
|
||||||
ok(_.any([0], _.identity) === false, 'cast to boolean - false');
|
|
||||||
ok(_.some([false, false, true]), 'aliased as "some"');
|
deepEqual(_.reject([odds, {one: 1, two: 2, three: 3}], 'two'), [odds], 'predicate string map to object properties');
|
||||||
Array.prototype.some = nativeSome;
|
|
||||||
|
// Can be used like _.where.
|
||||||
|
var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
|
||||||
|
deepEqual(_.reject(list, {a: 1}), [{a: 2, b: 2}]);
|
||||||
|
deepEqual(_.reject(list, {b: 2}), [{a: 1, b: 3}, {a: 1, b: 4}]);
|
||||||
|
deepEqual(_.reject(list, {}), [], 'Returns empty list given empty object');
|
||||||
|
deepEqual(_.reject(list, []), [], 'Returns empty list given empty array');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: include', function() {
|
test('every', function() {
|
||||||
ok(_.include([1,2,3], 2), 'two is in the array');
|
ok(_.every([], _.identity), 'the empty set');
|
||||||
ok(!_.include([1,3,9], 2), 'two is not in the array');
|
ok(_.every([true, true, true], _.identity), 'every true values');
|
||||||
ok(_.contains({moe:1, larry:3, curly:9}, 3) === true, '_.include on objects checks their values');
|
ok(!_.every([true, false, true], _.identity), 'one false value');
|
||||||
ok(_([1,2,3]).include(2), 'OO-style include');
|
ok(_.every([0, 10, 28], function(num){ return num % 2 === 0; }), 'even numbers');
|
||||||
|
ok(!_.every([0, 11, 28], function(num){ return num % 2 === 0; }), 'an odd number');
|
||||||
|
ok(_.every([1], _.identity) === true, 'cast to boolean - true');
|
||||||
|
ok(_.every([0], _.identity) === false, 'cast to boolean - false');
|
||||||
|
ok(!_.every([undefined, undefined, undefined], _.identity), 'works with arrays of undefined');
|
||||||
|
|
||||||
|
var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
|
||||||
|
ok(!_.every(list, {a: 1, b: 2}), 'Can be called with object');
|
||||||
|
ok(_.every(list, 'a'), 'String mapped to object property');
|
||||||
|
|
||||||
|
list = [{a: 1, b: 2}, {a: 2, b: 2, c: true}];
|
||||||
|
ok(_.every(list, {b: 2}), 'Can be called with object');
|
||||||
|
ok(!_.every(list, 'c'), 'String mapped to object property');
|
||||||
|
|
||||||
|
ok(_.every({a: 1, b: 2, c: 3, d: 4}, _.isNumber), 'takes objects');
|
||||||
|
ok(!_.every({a: 1, b: 2, c: 3, d: 4}, _.isObject), 'takes objects');
|
||||||
|
ok(_.every(['a', 'b', 'c', 'd'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works');
|
||||||
|
ok(!_.every(['a', 'b', 'c', 'd', 'f'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: invoke', function() {
|
test('all', function() {
|
||||||
|
strictEqual(_.all, _.every, 'alias for all');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('some', function() {
|
||||||
|
ok(!_.some([]), 'the empty set');
|
||||||
|
ok(!_.some([false, false, false]), 'all false values');
|
||||||
|
ok(_.some([false, false, true]), 'one true value');
|
||||||
|
ok(_.some([null, 0, 'yes', false]), 'a string');
|
||||||
|
ok(!_.some([null, 0, '', false]), 'falsy values');
|
||||||
|
ok(!_.some([1, 11, 29], function(num){ return num % 2 === 0; }), 'all odd numbers');
|
||||||
|
ok(_.some([1, 10, 29], function(num){ return num % 2 === 0; }), 'an even number');
|
||||||
|
ok(_.some([1], _.identity) === true, 'cast to boolean - true');
|
||||||
|
ok(_.some([0], _.identity) === false, 'cast to boolean - false');
|
||||||
|
ok(_.some([false, false, true]));
|
||||||
|
|
||||||
|
var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
|
||||||
|
ok(!_.some(list, {a: 5, b: 2}), 'Can be called with object');
|
||||||
|
ok(_.some(list, 'a'), 'String mapped to object property');
|
||||||
|
|
||||||
|
list = [{a: 1, b: 2}, {a: 2, b: 2, c: true}];
|
||||||
|
ok(_.some(list, {b: 2}), 'Can be called with object');
|
||||||
|
ok(!_.some(list, 'd'), 'String mapped to object property');
|
||||||
|
|
||||||
|
ok(_.some({a: '1', b: '2', c: '3', d: '4', e: 6}, _.isNumber), 'takes objects');
|
||||||
|
ok(!_.some({a: 1, b: 2, c: 3, d: 4}, _.isObject), 'takes objects');
|
||||||
|
ok(_.some(['a', 'b', 'c', 'd'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works');
|
||||||
|
ok(!_.some(['x', 'y', 'z'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('any', function() {
|
||||||
|
strictEqual(_.any, _.some, 'alias for any');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('includes', function() {
|
||||||
|
_.each([null, void 0, 0, 1, NaN, {}, []], function(val) {
|
||||||
|
strictEqual(_.includes(val, 'hasOwnProperty'), false);
|
||||||
|
});
|
||||||
|
strictEqual(_.includes([1, 2, 3], 2), true, 'two is in the array');
|
||||||
|
ok(!_.includes([1, 3, 9], 2), 'two is not in the array');
|
||||||
|
|
||||||
|
strictEqual(_.includes([5, 4, 3, 2, 1], 5, true), true, 'doesn\'t delegate to binary search');
|
||||||
|
|
||||||
|
ok(_.includes({moe: 1, larry: 3, curly: 9}, 3) === true, '_.includes on objects checks their values');
|
||||||
|
ok(_([1, 2, 3]).includes(2), 'OO-style includes');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('include', function() {
|
||||||
|
strictEqual(_.includes, _.include, 'alias for includes');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('contains', function() {
|
||||||
|
strictEqual(_.includes, _.contains, 'alias for includes');
|
||||||
|
|
||||||
|
var numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3];
|
||||||
|
strictEqual(_.includes(numbers, 1, 1), true, 'contains takes a fromIndex');
|
||||||
|
strictEqual(_.includes(numbers, 1, -1), false, 'contains takes a fromIndex');
|
||||||
|
strictEqual(_.includes(numbers, 1, -2), false, 'contains takes a fromIndex');
|
||||||
|
strictEqual(_.includes(numbers, 1, -3), true, 'contains takes a fromIndex');
|
||||||
|
strictEqual(_.includes(numbers, 1, 6), true, 'contains takes a fromIndex');
|
||||||
|
strictEqual(_.includes(numbers, 1, 7), false, 'contains takes a fromIndex');
|
||||||
|
|
||||||
|
ok(_.every([1, 2, 3], _.partial(_.contains, numbers)), 'fromIndex is guarded');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('includes with NaN', function() {
|
||||||
|
strictEqual(_.includes([1, 2, NaN, NaN], NaN), true, 'Expected [1, 2, NaN] to contain NaN');
|
||||||
|
strictEqual(_.includes([1, 2, Infinity], NaN), false, 'Expected [1, 2, NaN] to contain NaN');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('includes with +- 0', function() {
|
||||||
|
_.each([-0, +0], function(val) {
|
||||||
|
strictEqual(_.includes([1, 2, val, val], val), true);
|
||||||
|
strictEqual(_.includes([1, 2, val, val], -val), true);
|
||||||
|
strictEqual(_.includes([-1, 1, 2], -val), false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
test('invoke', 5, function() {
|
||||||
var list = [[5, 1, 7], [3, 2, 1]];
|
var list = [[5, 1, 7], [3, 2, 1]];
|
||||||
var result = _.invoke(list, 'sort');
|
var result = _.invoke(list, 'sort');
|
||||||
equal(result[0].join(', '), '1, 5, 7', 'first array sorted');
|
deepEqual(result[0], [1, 5, 7], 'first array sorted');
|
||||||
equal(result[1].join(', '), '1, 2, 3', 'second array sorted');
|
deepEqual(result[1], [1, 2, 3], 'second array sorted');
|
||||||
|
|
||||||
|
_.invoke([{
|
||||||
|
method: function() {
|
||||||
|
deepEqual(_.toArray(arguments), [1, 2, 3], 'called with arguments');
|
||||||
|
}
|
||||||
|
}], 'method', 1, 2, 3);
|
||||||
|
|
||||||
|
deepEqual(_.invoke([{a: null}, {}, {a: _.constant(1)}], 'a'), [null, void 0, 1], 'handles null & undefined');
|
||||||
|
|
||||||
|
throws(function() {
|
||||||
|
_.invoke([{a: 1}], 'a');
|
||||||
|
}, TypeError, 'throws for non-functions');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: invoke w/ function reference', function() {
|
test('invoke w/ function reference', function() {
|
||||||
var list = [[5, 1, 7], [3, 2, 1]];
|
var list = [[5, 1, 7], [3, 2, 1]];
|
||||||
var result = _.invoke(list, Array.prototype.sort);
|
var result = _.invoke(list, Array.prototype.sort);
|
||||||
equal(result[0].join(', '), '1, 5, 7', 'first array sorted');
|
deepEqual(result[0], [1, 5, 7], 'first array sorted');
|
||||||
equal(result[1].join(', '), '1, 2, 3', 'second array sorted');
|
deepEqual(result[1], [1, 2, 3], 'second array sorted');
|
||||||
|
|
||||||
|
deepEqual(_.invoke([1, 2, 3], function(a) {
|
||||||
|
return a + this;
|
||||||
|
}, 5), [6, 7, 8], 'receives params from invoke');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Relevant when using ClojureScript
|
// Relevant when using ClojureScript
|
||||||
test('collections: invoke when strings have a call method', function() {
|
test('invoke when strings have a call method', function() {
|
||||||
String.prototype.call = function() {
|
String.prototype.call = function() {
|
||||||
return 42;
|
return 42;
|
||||||
};
|
};
|
||||||
var list = [[5, 1, 7], [3, 2, 1]];
|
var list = [[5, 1, 7], [3, 2, 1]];
|
||||||
var s = "foo";
|
var s = 'foo';
|
||||||
equal(s.call(), 42, "call function exists");
|
equal(s.call(), 42, 'call function exists');
|
||||||
var result = _.invoke(list, 'sort');
|
var result = _.invoke(list, 'sort');
|
||||||
equal(result[0].join(', '), '1, 5, 7', 'first array sorted');
|
deepEqual(result[0], [1, 5, 7], 'first array sorted');
|
||||||
equal(result[1].join(', '), '1, 2, 3', 'second array sorted');
|
deepEqual(result[1], [1, 2, 3], 'second array sorted');
|
||||||
delete String.prototype.call;
|
delete String.prototype.call;
|
||||||
equal(s.call, undefined, "call function removed");
|
equal(s.call, undefined, 'call function removed');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: pluck', function() {
|
test('pluck', function() {
|
||||||
var people = [{name : 'moe', age : 30}, {name : 'curly', age : 50}];
|
var people = [{name: 'moe', age: 30}, {name: 'curly', age: 50}];
|
||||||
equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'pulls names out of objects');
|
deepEqual(_.pluck(people, 'name'), ['moe', 'curly'], 'pulls names out of objects');
|
||||||
|
deepEqual(_.pluck(people, 'address'), [undefined, undefined], 'missing properties are returned as undefined');
|
||||||
|
//compat: most flexible handling of edge cases
|
||||||
|
deepEqual(_.pluck([{'[object Object]': 1}], {}), [1]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: max', function() {
|
test('where', function() {
|
||||||
|
var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
|
||||||
|
var result = _.where(list, {a: 1});
|
||||||
|
equal(result.length, 3);
|
||||||
|
equal(result[result.length - 1].b, 4);
|
||||||
|
result = _.where(list, {b: 2});
|
||||||
|
equal(result.length, 2);
|
||||||
|
equal(result[0].a, 1);
|
||||||
|
result = _.where(list, {});
|
||||||
|
equal(result.length, list.length);
|
||||||
|
|
||||||
|
function test() {}
|
||||||
|
test.map = _.map;
|
||||||
|
deepEqual(_.where([_, {a: 1, b: 2}, _], test), [_, _], 'checks properties given function');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('findWhere', function() {
|
||||||
|
var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}, {a: 2, b: 4}];
|
||||||
|
var result = _.findWhere(list, {a: 1});
|
||||||
|
deepEqual(result, {a: 1, b: 2});
|
||||||
|
result = _.findWhere(list, {b: 4});
|
||||||
|
deepEqual(result, {a: 1, b: 4});
|
||||||
|
|
||||||
|
result = _.findWhere(list, {c: 1});
|
||||||
|
ok(_.isUndefined(result), 'undefined when not found');
|
||||||
|
|
||||||
|
result = _.findWhere([], {c: 1});
|
||||||
|
ok(_.isUndefined(result), 'undefined when searching empty list');
|
||||||
|
|
||||||
|
function test() {}
|
||||||
|
test.map = _.map;
|
||||||
|
equal(_.findWhere([_, {a: 1, b: 2}, _], test), _, 'checks properties given function');
|
||||||
|
|
||||||
|
function TestClass() {
|
||||||
|
this.y = 5;
|
||||||
|
this.x = 'foo';
|
||||||
|
}
|
||||||
|
var expect = {c: 1, x: 'foo', y: 5};
|
||||||
|
deepEqual(_.findWhere([{y: 5, b: 6}, expect], new TestClass()), expect, 'uses class instance properties');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('max', function() {
|
||||||
|
equal(-Infinity, _.max(null), 'can handle null/undefined');
|
||||||
|
equal(-Infinity, _.max(undefined), 'can handle null/undefined');
|
||||||
|
equal(-Infinity, _.max(null, _.identity), 'can handle null/undefined');
|
||||||
|
|
||||||
equal(3, _.max([1, 2, 3]), 'can perform a regular Math.max');
|
equal(3, _.max([1, 2, 3]), 'can perform a regular Math.max');
|
||||||
|
|
||||||
var neg = _.max([1, 2, 3], function(num){ return -num; });
|
var neg = _.max([1, 2, 3], function(num){ return -num; });
|
||||||
@@ -208,11 +557,30 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
equal(-Infinity, _.max({}), 'Maximum value of an empty object');
|
equal(-Infinity, _.max({}), 'Maximum value of an empty object');
|
||||||
equal(-Infinity, _.max([]), 'Maximum value of an empty array');
|
equal(-Infinity, _.max([]), 'Maximum value of an empty array');
|
||||||
|
equal(_.max({'a': 'a'}), -Infinity, 'Maximum value of a non-numeric collection');
|
||||||
|
|
||||||
equal(299999, _.max(_.range(1,300000)), "Maximum value of a too-big array");
|
equal(299999, _.max(_.range(1, 300000)), 'Maximum value of a too-big array');
|
||||||
|
|
||||||
|
equal(3, _.max([1, 2, 3, 'test']), 'Finds correct max in array starting with num and containing a NaN');
|
||||||
|
equal(3, _.max(['test', 1, 2, 3]), 'Finds correct max in array starting with NaN');
|
||||||
|
|
||||||
|
var a = {x: -Infinity};
|
||||||
|
var b = {x: -Infinity};
|
||||||
|
var iterator = function(o){ return o.x; };
|
||||||
|
equal(_.max([a, b], iterator), a, 'Respects iterator return value of -Infinity');
|
||||||
|
|
||||||
|
deepEqual(_.max([{'a': 1}, {'a': 0, 'b': 3}, {'a': 4}, {'a': 2}], 'a'), {'a': 4}, 'String keys use property iterator');
|
||||||
|
|
||||||
|
deepEqual(_.max([0, 2], function(a){ return a * this.x; }, {x: 1}), 2, 'Iterator context');
|
||||||
|
deepEqual(_.max([[1], [2, 3], [-1, 4], [5]], 0), [5], 'Lookup falsy iterator');
|
||||||
|
deepEqual(_.max([{0: 1}, {0: 2}, {0: -1}, {a: 1}], 0), {0: 2}, 'Lookup falsy iterator');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: min', function() {
|
test('min', function() {
|
||||||
|
equal(Infinity, _.min(null), 'can handle null/undefined');
|
||||||
|
equal(Infinity, _.min(undefined), 'can handle null/undefined');
|
||||||
|
equal(Infinity, _.min(null, _.identity), 'can handle null/undefined');
|
||||||
|
|
||||||
equal(1, _.min([1, 2, 3]), 'can perform a regular Math.min');
|
equal(1, _.min([1, 2, 3]), 'can perform a regular Math.min');
|
||||||
|
|
||||||
var neg = _.min([1, 2, 3], function(num){ return -num; });
|
var neg = _.min([1, 2, 3], function(num){ return -num; });
|
||||||
@@ -220,89 +588,270 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
equal(Infinity, _.min({}), 'Minimum value of an empty object');
|
equal(Infinity, _.min({}), 'Minimum value of an empty object');
|
||||||
equal(Infinity, _.min([]), 'Minimum value of an empty array');
|
equal(Infinity, _.min([]), 'Minimum value of an empty array');
|
||||||
|
equal(_.min({'a': 'a'}), Infinity, 'Minimum value of a non-numeric collection');
|
||||||
|
|
||||||
var now = new Date(9999999999);
|
var now = new Date(9999999999);
|
||||||
var then = new Date(0);
|
var then = new Date(0);
|
||||||
equal(_.min([now, then]), then);
|
equal(_.min([now, then]), then);
|
||||||
|
|
||||||
equal(1, _.min(_.range(1,300000)), "Minimum value of a too-big array");
|
equal(1, _.min(_.range(1, 300000)), 'Minimum value of a too-big array');
|
||||||
|
|
||||||
|
equal(1, _.min([1, 2, 3, 'test']), 'Finds correct min in array starting with num and containing a NaN');
|
||||||
|
equal(1, _.min(['test', 1, 2, 3]), 'Finds correct min in array starting with NaN');
|
||||||
|
|
||||||
|
var a = {x: Infinity};
|
||||||
|
var b = {x: Infinity};
|
||||||
|
var iterator = function(o){ return o.x; };
|
||||||
|
equal(_.min([a, b], iterator), a, 'Respects iterator return value of Infinity');
|
||||||
|
|
||||||
|
deepEqual(_.min([{'a': 1}, {'a': 0, 'b': 3}, {'a': 4}, {'a': 2}], 'a'), {'a': 0, 'b': 3}, 'String keys use property iterator');
|
||||||
|
|
||||||
|
deepEqual(_.min([0, 2], function(a){ return a * this.x; }, {x: -1}), 2, 'Iterator context');
|
||||||
|
deepEqual(_.min([[1], [2, 3], [-1, 4], [5]], 0), [-1, 4], 'Lookup falsy iterator');
|
||||||
|
deepEqual(_.min([{0: 1}, {0: 2}, {0: -1}, {a: 1}], 0), {0: -1}, 'Lookup falsy iterator');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: sortBy', function() {
|
test('sortBy', function() {
|
||||||
var people = [{name : 'curly', age : 50}, {name : 'moe', age : 30}];
|
var people = [{name : 'curly', age : 50}, {name : 'moe', age : 30}];
|
||||||
people = _.sortBy(people, function(person){ return person.age; });
|
people = _.sortBy(people, function(person){ return person.age; });
|
||||||
equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'stooges sorted by age');
|
deepEqual(_.pluck(people, 'name'), ['moe', 'curly'], 'stooges sorted by age');
|
||||||
|
|
||||||
var list = [undefined, 4, 1, undefined, 3, 2];
|
var list = [undefined, 4, 1, undefined, 3, 2];
|
||||||
equal(_.sortBy(list, _.identity).join(','), '1,2,3,4,,', 'sortBy with undefined values');
|
deepEqual(_.sortBy(list, _.identity), [1, 2, 3, 4, undefined, undefined], 'sortBy with undefined values');
|
||||||
|
|
||||||
var list = ["one", "two", "three", "four", "five"];
|
list = ['one', 'two', 'three', 'four', 'five'];
|
||||||
var sorted = _.sortBy(list, 'length');
|
var sorted = _.sortBy(list, 'length');
|
||||||
equal(sorted.join(' '), 'one two four five three', 'sorted by length');
|
deepEqual(sorted, ['one', 'two', 'four', 'five', 'three'], 'sorted by length');
|
||||||
|
|
||||||
|
function Pair(x, y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
var collection = [
|
||||||
|
new Pair(1, 1), new Pair(1, 2),
|
||||||
|
new Pair(1, 3), new Pair(1, 4),
|
||||||
|
new Pair(1, 5), new Pair(1, 6),
|
||||||
|
new Pair(2, 1), new Pair(2, 2),
|
||||||
|
new Pair(2, 3), new Pair(2, 4),
|
||||||
|
new Pair(2, 5), new Pair(2, 6),
|
||||||
|
new Pair(undefined, 1), new Pair(undefined, 2),
|
||||||
|
new Pair(undefined, 3), new Pair(undefined, 4),
|
||||||
|
new Pair(undefined, 5), new Pair(undefined, 6)
|
||||||
|
];
|
||||||
|
|
||||||
|
var actual = _.sortBy(collection, function(pair) {
|
||||||
|
return pair.x;
|
||||||
|
});
|
||||||
|
|
||||||
|
deepEqual(actual, collection, 'sortBy should be stable');
|
||||||
|
|
||||||
|
deepEqual(_.sortBy(collection, 'x'), collection, 'sortBy accepts property string');
|
||||||
|
|
||||||
|
list = ['q', 'w', 'e', 'r', 't', 'y'];
|
||||||
|
deepEqual(_.sortBy(list), ['e', 'q', 'r', 't', 'w', 'y'], 'uses _.identity if iterator is not specified');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: groupBy', function() {
|
test('groupBy', function() {
|
||||||
var parity = _.groupBy([1, 2, 3, 4, 5, 6], function(num){ return num % 2; });
|
var parity = _.groupBy([1, 2, 3, 4, 5, 6], function(num){ return num % 2; });
|
||||||
ok('0' in parity && '1' in parity, 'created a group for each value');
|
ok('0' in parity && '1' in parity, 'created a group for each value');
|
||||||
equal(parity[0].join(', '), '2, 4, 6', 'put each even number in the right group');
|
deepEqual(parity[0], [2, 4, 6], 'put each even number in the right group');
|
||||||
|
|
||||||
var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
|
var list = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'];
|
||||||
var grouped = _.groupBy(list, 'length');
|
var grouped = _.groupBy(list, 'length');
|
||||||
equal(grouped['3'].join(' '), 'one two six ten');
|
deepEqual(grouped['3'], ['one', 'two', 'six', 'ten']);
|
||||||
equal(grouped['4'].join(' '), 'four five nine');
|
deepEqual(grouped['4'], ['four', 'five', 'nine']);
|
||||||
equal(grouped['5'].join(' '), 'three seven eight');
|
deepEqual(grouped['5'], ['three', 'seven', 'eight']);
|
||||||
|
|
||||||
|
var context = {};
|
||||||
|
_.groupBy([{}], function(){ ok(this === context); }, context);
|
||||||
|
|
||||||
|
grouped = _.groupBy([4.2, 6.1, 6.4], function(num) {
|
||||||
|
return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor';
|
||||||
|
});
|
||||||
|
equal(grouped.constructor.length, 1);
|
||||||
|
equal(grouped.hasOwnProperty.length, 2);
|
||||||
|
|
||||||
|
var array = [{}];
|
||||||
|
_.groupBy(array, function(value, index, obj){ ok(obj === array); });
|
||||||
|
|
||||||
|
array = [1, 2, 1, 2, 3];
|
||||||
|
grouped = _.groupBy(array);
|
||||||
|
equal(grouped['1'].length, 2);
|
||||||
|
equal(grouped['3'].length, 1);
|
||||||
|
|
||||||
|
var matrix = [
|
||||||
|
[1, 2],
|
||||||
|
[1, 3],
|
||||||
|
[2, 3]
|
||||||
|
];
|
||||||
|
deepEqual(_.groupBy(matrix, 0), {1: [[1, 2], [1, 3]], 2: [[2, 3]]});
|
||||||
|
deepEqual(_.groupBy(matrix, 1), {2: [[1, 2]], 3: [[1, 3], [2, 3]]});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: countBy', function() {
|
test('indexBy', function() {
|
||||||
var parity = _.countBy([1, 2, 3, 4, 5], function(num){ return num % 2 == 0; });
|
var parity = _.indexBy([1, 2, 3, 4, 5], function(num){ return num % 2 === 0; });
|
||||||
|
equal(parity['true'], 4);
|
||||||
|
equal(parity['false'], 5);
|
||||||
|
|
||||||
|
var list = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'];
|
||||||
|
var grouped = _.indexBy(list, 'length');
|
||||||
|
equal(grouped['3'], 'ten');
|
||||||
|
equal(grouped['4'], 'nine');
|
||||||
|
equal(grouped['5'], 'eight');
|
||||||
|
|
||||||
|
var array = [1, 2, 1, 2, 3];
|
||||||
|
grouped = _.indexBy(array);
|
||||||
|
equal(grouped['1'], 1);
|
||||||
|
equal(grouped['2'], 2);
|
||||||
|
equal(grouped['3'], 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('countBy', function() {
|
||||||
|
var parity = _.countBy([1, 2, 3, 4, 5], function(num){ return num % 2 === 0; });
|
||||||
equal(parity['true'], 2);
|
equal(parity['true'], 2);
|
||||||
equal(parity['false'], 3);
|
equal(parity['false'], 3);
|
||||||
|
|
||||||
var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
|
var list = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'];
|
||||||
var grouped = _.countBy(list, 'length');
|
var grouped = _.countBy(list, 'length');
|
||||||
equal(grouped['3'], 4);
|
equal(grouped['3'], 4);
|
||||||
equal(grouped['4'], 3);
|
equal(grouped['4'], 3);
|
||||||
equal(grouped['5'], 3);
|
equal(grouped['5'], 3);
|
||||||
|
|
||||||
|
var context = {};
|
||||||
|
_.countBy([{}], function(){ ok(this === context); }, context);
|
||||||
|
|
||||||
|
grouped = _.countBy([4.2, 6.1, 6.4], function(num) {
|
||||||
|
return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor';
|
||||||
|
});
|
||||||
|
equal(grouped.constructor, 1);
|
||||||
|
equal(grouped.hasOwnProperty, 2);
|
||||||
|
|
||||||
|
var array = [{}];
|
||||||
|
_.countBy(array, function(value, index, obj){ ok(obj === array); });
|
||||||
|
|
||||||
|
array = [1, 2, 1, 2, 3];
|
||||||
|
grouped = _.countBy(array);
|
||||||
|
equal(grouped['1'], 2);
|
||||||
|
equal(grouped['3'], 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: sortedIndex', function() {
|
test('shuffle', function() {
|
||||||
var numbers = [10, 20, 30, 40, 50], num = 35;
|
|
||||||
var indexForNum = _.sortedIndex(numbers, num);
|
|
||||||
equal(indexForNum, 3, '35 should be inserted at index 3');
|
|
||||||
|
|
||||||
var indexFor30 = _.sortedIndex(numbers, 30);
|
|
||||||
equal(indexFor30, 2, '30 should be inserted at index 2');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('collections: shuffle', function() {
|
|
||||||
var numbers = _.range(10);
|
var numbers = _.range(10);
|
||||||
var shuffled = _.shuffle(numbers).sort();
|
var shuffled = _.shuffle(numbers);
|
||||||
notStrictEqual(numbers, shuffled, 'original object is unmodified');
|
notStrictEqual(numbers, shuffled, 'original object is unmodified');
|
||||||
equal(shuffled.join(','), numbers.join(','), 'contains the same members before and after shuffle');
|
ok(_.every(_.range(10), function() { //appears consistent?
|
||||||
|
return _.every(numbers, _.partial(_.contains, numbers));
|
||||||
|
}), 'contains the same members before and after shuffle');
|
||||||
|
|
||||||
|
shuffled = _.shuffle({a: 1, b: 2, c: 3, d: 4});
|
||||||
|
equal(shuffled.length, 4);
|
||||||
|
deepEqual(shuffled.sort(), [1, 2, 3, 4], 'works on objects');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: toArray', function() {
|
test('sample', function() {
|
||||||
|
var numbers = _.range(10);
|
||||||
|
var allSampled = _.sample(numbers, 10).sort();
|
||||||
|
deepEqual(allSampled, numbers, 'contains the same members before and after sample');
|
||||||
|
allSampled = _.sample(numbers, 20).sort();
|
||||||
|
deepEqual(allSampled, numbers, 'also works when sampling more objects than are present');
|
||||||
|
ok(_.contains(numbers, _.sample(numbers)), 'sampling a single element returns something from the array');
|
||||||
|
strictEqual(_.sample([]), undefined, 'sampling empty array with no number returns undefined');
|
||||||
|
notStrictEqual(_.sample([], 5), [], 'sampling empty array with a number returns an empty array');
|
||||||
|
notStrictEqual(_.sample([1, 2, 3], 0), [], 'sampling an array with 0 picks returns an empty array');
|
||||||
|
deepEqual(_.sample([1, 2], -1), [], 'sampling a negative number of picks returns an empty array');
|
||||||
|
ok(_.contains([1, 2, 3], _.sample({a: 1, b: 2, c: 3})), 'sample one value from an object');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('toArray', function() {
|
||||||
ok(!_.isArray(arguments), 'arguments object is not an array');
|
ok(!_.isArray(arguments), 'arguments object is not an array');
|
||||||
ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array');
|
ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array');
|
||||||
var a = [1,2,3];
|
var a = [1, 2, 3];
|
||||||
ok(_.toArray(a) !== a, 'array is cloned');
|
ok(_.toArray(a) !== a, 'array is cloned');
|
||||||
equal(_.toArray(a).join(', '), '1, 2, 3', 'cloned array contains same elements');
|
deepEqual(_.toArray(a), [1, 2, 3], 'cloned array contains same elements');
|
||||||
|
|
||||||
var numbers = _.toArray({one : 1, two : 2, three : 3});
|
var numbers = _.toArray({one : 1, two : 2, three : 3});
|
||||||
equal(numbers.join(', '), '1, 2, 3', 'object flattened into array');
|
deepEqual(numbers, [1, 2, 3], 'object flattened into array');
|
||||||
|
|
||||||
var objectWithToArrayFunction = {toArray: function() {
|
if (typeof document != 'undefined') {
|
||||||
return [1, 2, 3];
|
// test in IE < 9
|
||||||
}};
|
var actual;
|
||||||
equal(_.toArray(objectWithToArrayFunction).join(', '), '1, 2, 3', 'toArray method used if present');
|
try {
|
||||||
|
actual = _.toArray(document.childNodes);
|
||||||
var objectWithToArrayValue = {toArray: 1};
|
} catch(ex) { }
|
||||||
equal(_.toArray(objectWithToArrayValue).join(', '), '1', 'toArray property ignored if not a function');
|
deepEqual(actual, _.map(document.childNodes, _.identity), 'works on NodeList');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('collections: size', function() {
|
test('size', function() {
|
||||||
equal(_.size({one : 1, two : 2, three : 3}), 3, 'can compute the size of an object');
|
equal(_.size({one : 1, two : 2, three : 3}), 3, 'can compute the size of an object');
|
||||||
equal(_.size([1, 2, 3]), 3, 'can compute the size of an array');
|
equal(_.size([1, 2, 3]), 3, 'can compute the size of an array');
|
||||||
|
equal(_.size({length: 3, 0: 0, 1: 0, 2: 0}), 3, 'can compute the size of Array-likes');
|
||||||
|
|
||||||
|
var func = function() {
|
||||||
|
return _.size(arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
equal(func(1, 2, 3, 4), 4, 'can test the size of the arguments object');
|
||||||
|
|
||||||
|
equal(_.size('hello'), 5, 'can compute the size of a string literal');
|
||||||
|
equal(_.size(new String('hello')), 5, 'can compute the size of string object');
|
||||||
|
|
||||||
|
equal(_.size(null), 0, 'handles nulls');
|
||||||
|
equal(_.size(0), 0, 'handles numbers');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
test('partition', function() {
|
||||||
|
var list = [0, 1, 2, 3, 4, 5];
|
||||||
|
deepEqual(_.partition(list, function(x) { return x < 4; }), [[0, 1, 2, 3], [4, 5]], 'handles bool return values');
|
||||||
|
deepEqual(_.partition(list, function(x) { return x & 1; }), [[1, 3, 5], [0, 2, 4]], 'handles 0 and 1 return values');
|
||||||
|
deepEqual(_.partition(list, function(x) { return x - 3; }), [[0, 1, 2, 4, 5], [3]], 'handles other numeric return values');
|
||||||
|
deepEqual(_.partition(list, function(x) { return x > 1 ? null : true; }), [[0, 1], [2, 3, 4, 5]], 'handles null return values');
|
||||||
|
deepEqual(_.partition(list, function(x) { if (x < 2) return true; }), [[0, 1], [2, 3, 4, 5]], 'handles undefined return values');
|
||||||
|
deepEqual(_.partition({a: 1, b: 2, c: 3}, function(x) { return x > 1; }), [[2, 3], [1]], 'handles objects');
|
||||||
|
|
||||||
|
deepEqual(_.partition(list, function(x, index) { return index % 2; }), [[1, 3, 5], [0, 2, 4]], 'can reference the array index');
|
||||||
|
deepEqual(_.partition(list, function(x, index, arr) { return x === arr.length - 1; }), [[5], [0, 1, 2, 3, 4]], 'can reference the collection');
|
||||||
|
|
||||||
|
// Default iterator
|
||||||
|
deepEqual(_.partition([1, false, true, '']), [[1, true], [false, '']], 'Default iterator');
|
||||||
|
deepEqual(_.partition([{x: 1}, {x: 0}, {x: 1}], 'x'), [[{x: 1}, {x: 1}], [{x: 0}]], 'Takes a string');
|
||||||
|
|
||||||
|
// Context
|
||||||
|
var predicate = function(x){ return x === this.x; };
|
||||||
|
deepEqual(_.partition([1, 2, 3], predicate, {x: 2}), [[2], [1, 3]], 'partition takes a context argument');
|
||||||
|
|
||||||
|
deepEqual(_.partition([{a: 1}, {b: 2}, {a: 1, b: 2}], {a: 1}), [[{a: 1}, {a: 1, b: 2}], [{b: 2}]], 'predicate can be object');
|
||||||
|
|
||||||
|
var object = {a: 1};
|
||||||
|
_.partition(object, function(val, key, obj) {
|
||||||
|
equal(val, 1);
|
||||||
|
equal(key, 'a');
|
||||||
|
equal(obj, object);
|
||||||
|
equal(this, predicate);
|
||||||
|
}, predicate);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (typeof document != 'undefined') {
|
||||||
|
test('Can use various collection methods on NodeLists', function() {
|
||||||
|
var parent = document.createElement('div');
|
||||||
|
parent.innerHTML = '<span id=id1></span>textnode<span id=id2></span>';
|
||||||
|
|
||||||
|
var elementChildren = _.filter(parent.childNodes, _.isElement);
|
||||||
|
equal(elementChildren.length, 2);
|
||||||
|
|
||||||
|
deepEqual(_.map(elementChildren, 'id'), ['id1', 'id2']);
|
||||||
|
deepEqual(_.map(parent.childNodes, 'nodeType'), [1, 3, 1]);
|
||||||
|
|
||||||
|
ok(!_.every(parent.childNodes, _.isElement));
|
||||||
|
ok(_.some(parent.childNodes, _.isElement));
|
||||||
|
|
||||||
|
function compareNode(node) {
|
||||||
|
return _.isElement(node) ? node.id.charAt(2) : void 0;
|
||||||
|
}
|
||||||
|
equal(_.max(parent.childNodes, compareNode), _.last(parent.childNodes));
|
||||||
|
equal(_.min(parent.childNodes, compareNode), _.first(parent.childNodes));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}());
|
||||||
|
|||||||
533
vendor/underscore/test/functions.js
vendored
533
vendor/underscore/test/functions.js
vendored
@@ -1,10 +1,12 @@
|
|||||||
$(document).ready(function() {
|
(function() {
|
||||||
|
var _ = typeof require == 'function' ? require('..') : window._;
|
||||||
|
|
||||||
module("Functions");
|
QUnit.module('Functions');
|
||||||
|
QUnit.config.asyncRetries = 3;
|
||||||
|
|
||||||
test("functions: bind", function() {
|
test('bind', function() {
|
||||||
var context = {name : 'moe'};
|
var context = {name : 'moe'};
|
||||||
var func = function(arg) { return "name: " + (this.name || arg); };
|
var func = function(arg) { return 'name: ' + (this.name || arg); };
|
||||||
var bound = _.bind(func, context);
|
var bound = _.bind(func, context);
|
||||||
equal(bound(), 'name: moe', 'can bind a function to a context');
|
equal(bound(), 'name: moe', 'can bind a function to a context');
|
||||||
|
|
||||||
@@ -12,16 +14,18 @@ $(document).ready(function() {
|
|||||||
equal(bound(), 'name: moe', 'can do OO-style binding');
|
equal(bound(), 'name: moe', 'can do OO-style binding');
|
||||||
|
|
||||||
bound = _.bind(func, null, 'curly');
|
bound = _.bind(func, null, 'curly');
|
||||||
equal(bound(), 'name: curly', 'can bind without specifying a context');
|
var result = bound();
|
||||||
|
// Work around a PhantomJS bug when applying a function with null|undefined.
|
||||||
|
ok(result === 'name: curly' || result === 'name: ' + window.name, 'can bind without specifying a context');
|
||||||
|
|
||||||
func = function(salutation, name) { return salutation + ': ' + name; };
|
func = function(salutation, name) { return salutation + ': ' + name; };
|
||||||
func = _.bind(func, this, 'hello');
|
func = _.bind(func, this, 'hello');
|
||||||
equal(func('moe'), 'hello: moe', 'the function was partially applied in advance');
|
equal(func('moe'), 'hello: moe', 'the function was partially applied in advance');
|
||||||
|
|
||||||
var func = _.bind(func, this, 'curly');
|
func = _.bind(func, this, 'curly');
|
||||||
equal(func(), 'hello: curly', 'the function was completely applied in advance');
|
equal(func(), 'hello: curly', 'the function was completely applied in advance');
|
||||||
|
|
||||||
var func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; };
|
func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; };
|
||||||
func = _.bind(func, this, 'hello', 'moe', 'curly');
|
func = _.bind(func, this, 'hello', 'moe', 'curly');
|
||||||
equal(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments');
|
equal(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments');
|
||||||
|
|
||||||
@@ -33,12 +37,49 @@ $(document).ready(function() {
|
|||||||
// These tests are only meaningful when using a browser without a native bind function
|
// These tests are only meaningful when using a browser without a native bind function
|
||||||
// To test this with a modern browser, set underscore's nativeBind to undefined
|
// To test this with a modern browser, set underscore's nativeBind to undefined
|
||||||
var F = function () { return this; };
|
var F = function () { return this; };
|
||||||
var Boundf = _.bind(F, {hello: "moe curly"});
|
var boundf = _.bind(F, {hello: 'moe curly'});
|
||||||
equal(new Boundf().hello, undefined, "function should not be bound to the context, to comply with ECMAScript 5");
|
var Boundf = boundf; // make eslint happy.
|
||||||
equal(Boundf().hello, "moe curly", "When called without the new operator, it's OK to be bound to the context");
|
var newBoundf = new Boundf();
|
||||||
|
equal(newBoundf.hello, undefined, 'function should not be bound to the context, to comply with ECMAScript 5');
|
||||||
|
equal(boundf().hello, 'moe curly', "When called without the new operator, it's OK to be bound to the context");
|
||||||
|
ok(newBoundf instanceof F, 'a bound instance is an instance of the original function');
|
||||||
|
|
||||||
|
throws(function() { _.bind('notafunction'); }, TypeError, 'throws an error when binding to a non-function');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("functions: bindAll", function() {
|
test('partial', function() {
|
||||||
|
var obj = {name: 'moe'};
|
||||||
|
var func = function() { return this.name + ' ' + _.toArray(arguments).join(' '); };
|
||||||
|
|
||||||
|
obj.func = _.partial(func, 'a', 'b');
|
||||||
|
equal(obj.func('c', 'd'), 'moe a b c d', 'can partially apply');
|
||||||
|
|
||||||
|
obj.func = _.partial(func, _, 'b', _, 'd');
|
||||||
|
equal(obj.func('a', 'c'), 'moe a b c d', 'can partially apply with placeholders');
|
||||||
|
|
||||||
|
func = _.partial(function() { return arguments.length; }, _, 'b', _, 'd');
|
||||||
|
equal(func('a', 'c', 'e'), 5, 'accepts more arguments than the number of placeholders');
|
||||||
|
equal(func('a'), 4, 'accepts fewer arguments than the number of placeholders');
|
||||||
|
|
||||||
|
func = _.partial(function() { return typeof arguments[2]; }, _, 'b', _, 'd');
|
||||||
|
equal(func('a'), 'undefined', 'unfilled placeholders are undefined');
|
||||||
|
|
||||||
|
// passes context
|
||||||
|
function MyWidget(name, options) {
|
||||||
|
this.name = name;
|
||||||
|
this.options = options;
|
||||||
|
}
|
||||||
|
MyWidget.prototype.get = function() {
|
||||||
|
return this.name;
|
||||||
|
};
|
||||||
|
var MyWidgetWithCoolOpts = _.partial(MyWidget, _, {a: 1});
|
||||||
|
var widget = new MyWidgetWithCoolOpts('foo');
|
||||||
|
ok(widget instanceof MyWidget, 'Can partially bind a constructor');
|
||||||
|
equal(widget.get(), 'foo', 'keeps prototype');
|
||||||
|
deepEqual(widget.options, {a: 1});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('bindAll', function() {
|
||||||
var curly = {name : 'curly'}, moe = {
|
var curly = {name : 'curly'}, moe = {
|
||||||
name : 'moe',
|
name : 'moe',
|
||||||
getName : function() { return 'name: ' + this.name; },
|
getName : function() { return 'name: ' + this.name; },
|
||||||
@@ -54,20 +95,29 @@ $(document).ready(function() {
|
|||||||
moe = {
|
moe = {
|
||||||
name : 'moe',
|
name : 'moe',
|
||||||
getName : function() { return 'name: ' + this.name; },
|
getName : function() { return 'name: ' + this.name; },
|
||||||
sayHi : function() { return 'hi: ' + this.name; }
|
sayHi : function() { return 'hi: ' + this.name; },
|
||||||
|
sayLast : function() { return this.sayHi(_.last(arguments)); }
|
||||||
};
|
};
|
||||||
_.bindAll(moe);
|
|
||||||
|
throws(function() { _.bindAll(moe); }, Error, 'throws an error for bindAll with no functions named');
|
||||||
|
throws(function() { _.bindAll(moe, 'sayBye'); }, TypeError, 'throws an error for bindAll if the given key is undefined');
|
||||||
|
throws(function() { _.bindAll(moe, 'name'); }, TypeError, 'throws an error for bindAll if the given key is not a function');
|
||||||
|
|
||||||
|
_.bindAll(moe, 'sayHi', 'sayLast');
|
||||||
curly.sayHi = moe.sayHi;
|
curly.sayHi = moe.sayHi;
|
||||||
equal(curly.sayHi(), 'hi: moe', 'calling bindAll with no arguments binds all functions to the object');
|
equal(curly.sayHi(), 'hi: moe');
|
||||||
|
|
||||||
|
var sayLast = moe.sayLast;
|
||||||
|
equal(sayLast(1, 2, 3, 4, 5, 6, 7, 'Tom'), 'hi: moe', 'createCallback works with any number of arguments');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("functions: memoize", function() {
|
test('memoize', function() {
|
||||||
var fib = function(n) {
|
var fib = function(n) {
|
||||||
return n < 2 ? n : fib(n - 1) + fib(n - 2);
|
return n < 2 ? n : fib(n - 1) + fib(n - 2);
|
||||||
};
|
};
|
||||||
var fastFib = _.memoize(fib);
|
|
||||||
equal(fib(10), 55, 'a memoized version of fibonacci produces identical results');
|
equal(fib(10), 55, 'a memoized version of fibonacci produces identical results');
|
||||||
equal(fastFib(10), 55, 'a memoized version of fibonacci produces identical results');
|
fib = _.memoize(fib); // Redefine `fib` for memoization
|
||||||
|
equal(fib(10), 55, 'a memoized version of fibonacci produces identical results');
|
||||||
|
|
||||||
var o = function(str) {
|
var o = function(str) {
|
||||||
return str;
|
return str;
|
||||||
@@ -75,140 +125,409 @@ $(document).ready(function() {
|
|||||||
var fastO = _.memoize(o);
|
var fastO = _.memoize(o);
|
||||||
equal(o('toString'), 'toString', 'checks hasOwnProperty');
|
equal(o('toString'), 'toString', 'checks hasOwnProperty');
|
||||||
equal(fastO('toString'), 'toString', 'checks hasOwnProperty');
|
equal(fastO('toString'), 'toString', 'checks hasOwnProperty');
|
||||||
|
|
||||||
|
// Expose the cache.
|
||||||
|
var upper = _.memoize(function(s) {
|
||||||
|
return s.toUpperCase();
|
||||||
|
});
|
||||||
|
equal(upper('foo'), 'FOO');
|
||||||
|
equal(upper('bar'), 'BAR');
|
||||||
|
deepEqual(upper.cache, {foo: 'FOO', bar: 'BAR'});
|
||||||
|
upper.cache = {foo: 'BAR', bar: 'FOO'};
|
||||||
|
equal(upper('foo'), 'BAR');
|
||||||
|
equal(upper('bar'), 'FOO');
|
||||||
|
|
||||||
|
var hashed = _.memoize(function(key) {
|
||||||
|
//https://github.com/jashkenas/underscore/pull/1679#discussion_r13736209
|
||||||
|
ok(/[a-z]+/.test(key), 'hasher doesn\'t change keys');
|
||||||
|
return key;
|
||||||
|
}, function(key) {
|
||||||
|
return key.toUpperCase();
|
||||||
|
});
|
||||||
|
hashed('yep');
|
||||||
|
deepEqual(hashed.cache, {'YEP': 'yep'}, 'takes a hasher');
|
||||||
|
|
||||||
|
// Test that the hash function can be used to swizzle the key.
|
||||||
|
var objCacher = _.memoize(function(value, key) {
|
||||||
|
return {key: key, value: value};
|
||||||
|
}, function(value, key) {
|
||||||
|
return key;
|
||||||
|
});
|
||||||
|
var myObj = objCacher('a', 'alpha');
|
||||||
|
var myObjAlias = objCacher('b', 'alpha');
|
||||||
|
notStrictEqual(myObj, undefined, 'object is created if second argument used as key');
|
||||||
|
strictEqual(myObj, myObjAlias, 'object is cached if second argument used as key');
|
||||||
|
strictEqual(myObj.value, 'a', 'object is not modified if second argument used as key');
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest("functions: delay", 2, function() {
|
asyncTest('delay', 2, function() {
|
||||||
var delayed = false;
|
var delayed = false;
|
||||||
_.delay(function(){ delayed = true; }, 100);
|
_.delay(function(){ delayed = true; }, 100);
|
||||||
setTimeout(function(){ ok(!delayed, "didn't delay the function quite yet"); }, 50);
|
setTimeout(function(){ ok(!delayed, "didn't delay the function quite yet"); }, 50);
|
||||||
setTimeout(function(){ ok(delayed, 'delayed the function'); start(); }, 150);
|
setTimeout(function(){ ok(delayed, 'delayed the function'); start(); }, 150);
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest("functions: defer", 1, function() {
|
asyncTest('defer', 1, function() {
|
||||||
var deferred = false;
|
var deferred = false;
|
||||||
_.defer(function(bool){ deferred = bool; }, true);
|
_.defer(function(bool){ deferred = bool; }, true);
|
||||||
_.delay(function(){ ok(deferred, "deferred the function"); start(); }, 50);
|
_.delay(function(){ ok(deferred, 'deferred the function'); start(); }, 50);
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest("functions: throttle", 2, function() {
|
asyncTest('throttle', 2, function() {
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
var incr = function(){ counter++; };
|
var incr = function(){ counter++; };
|
||||||
var throttledIncr = _.throttle(incr, 100);
|
var throttledIncr = _.throttle(incr, 32);
|
||||||
throttledIncr(); throttledIncr(); throttledIncr();
|
throttledIncr(); throttledIncr();
|
||||||
setTimeout(throttledIncr, 70);
|
|
||||||
setTimeout(throttledIncr, 120);
|
equal(counter, 1, 'incr was called immediately');
|
||||||
setTimeout(throttledIncr, 140);
|
_.delay(function(){ equal(counter, 2, 'incr was throttled'); start(); }, 64);
|
||||||
setTimeout(throttledIncr, 190);
|
|
||||||
setTimeout(throttledIncr, 220);
|
|
||||||
setTimeout(throttledIncr, 240);
|
|
||||||
_.delay(function(){ equal(counter, 1, "incr was called immediately"); }, 30);
|
|
||||||
_.delay(function(){ equal(counter, 4, "incr was throttled"); start(); }, 400);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest("functions: throttle arguments", 2, function() {
|
asyncTest('throttle arguments', 2, function() {
|
||||||
var value = 0;
|
var value = 0;
|
||||||
var update = function(val){ value = val; };
|
var update = function(val){ value = val; };
|
||||||
var throttledUpdate = _.throttle(update, 100);
|
var throttledUpdate = _.throttle(update, 32);
|
||||||
throttledUpdate(1); throttledUpdate(2); throttledUpdate(3);
|
throttledUpdate(1); throttledUpdate(2);
|
||||||
setTimeout(function(){ throttledUpdate(4); }, 120);
|
_.delay(function(){ throttledUpdate(3); }, 64);
|
||||||
setTimeout(function(){ throttledUpdate(5); }, 140);
|
equal(value, 1, 'updated to latest value');
|
||||||
setTimeout(function(){ throttledUpdate(6); }, 250);
|
_.delay(function(){ equal(value, 3, 'updated to latest value'); start(); }, 96);
|
||||||
_.delay(function(){ equal(value, 1, "updated to latest value"); }, 40);
|
|
||||||
_.delay(function(){ equal(value, 6, "updated to latest value"); start(); }, 400);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest("functions: throttle once", 2, function() {
|
asyncTest('throttle once', 2, function() {
|
||||||
|
var counter = 0;
|
||||||
|
var incr = function(){ return ++counter; };
|
||||||
|
var throttledIncr = _.throttle(incr, 32);
|
||||||
|
var result = throttledIncr();
|
||||||
|
_.delay(function(){
|
||||||
|
equal(result, 1, 'throttled functions return their value');
|
||||||
|
equal(counter, 1, 'incr was called once'); start();
|
||||||
|
}, 64);
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest('throttle twice', 1, function() {
|
||||||
|
var counter = 0;
|
||||||
|
var incr = function(){ counter++; };
|
||||||
|
var throttledIncr = _.throttle(incr, 32);
|
||||||
|
throttledIncr(); throttledIncr();
|
||||||
|
_.delay(function(){ equal(counter, 2, 'incr was called twice'); start(); }, 64);
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest('more throttling', 3, function() {
|
||||||
|
var counter = 0;
|
||||||
|
var incr = function(){ counter++; };
|
||||||
|
var throttledIncr = _.throttle(incr, 30);
|
||||||
|
throttledIncr(); throttledIncr();
|
||||||
|
equal(counter, 1);
|
||||||
|
_.delay(function(){
|
||||||
|
equal(counter, 2);
|
||||||
|
throttledIncr();
|
||||||
|
equal(counter, 3);
|
||||||
|
start();
|
||||||
|
}, 85);
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest('throttle repeatedly with results', 6, function() {
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
var incr = function(){ return ++counter; };
|
var incr = function(){ return ++counter; };
|
||||||
var throttledIncr = _.throttle(incr, 100);
|
var throttledIncr = _.throttle(incr, 100);
|
||||||
var result = throttledIncr();
|
var results = [];
|
||||||
_.delay(function(){
|
var saveResult = function() { results.push(throttledIncr()); };
|
||||||
equal(result, 1, "throttled functions return their value");
|
saveResult(); saveResult();
|
||||||
equal(counter, 1, "incr was called once"); start();
|
_.delay(saveResult, 50);
|
||||||
}, 220);
|
_.delay(saveResult, 150);
|
||||||
|
_.delay(saveResult, 160);
|
||||||
|
_.delay(saveResult, 230);
|
||||||
|
_.delay(function() {
|
||||||
|
equal(results[0], 1, 'incr was called once');
|
||||||
|
equal(results[1], 1, 'incr was throttled');
|
||||||
|
equal(results[2], 1, 'incr was throttled');
|
||||||
|
equal(results[3], 2, 'incr was called twice');
|
||||||
|
equal(results[4], 2, 'incr was throttled');
|
||||||
|
equal(results[5], 3, 'incr was called trailing');
|
||||||
|
start();
|
||||||
|
}, 300);
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest("functions: throttle twice", 1, function() {
|
asyncTest('throttle triggers trailing call when invoked repeatedly', 2, function() {
|
||||||
|
var counter = 0;
|
||||||
|
var limit = 48;
|
||||||
|
var incr = function(){ counter++; };
|
||||||
|
var throttledIncr = _.throttle(incr, 32);
|
||||||
|
|
||||||
|
var stamp = new Date;
|
||||||
|
while (new Date - stamp < limit) {
|
||||||
|
throttledIncr();
|
||||||
|
}
|
||||||
|
var lastCount = counter;
|
||||||
|
ok(counter > 1);
|
||||||
|
|
||||||
|
_.delay(function() {
|
||||||
|
ok(counter > lastCount);
|
||||||
|
start();
|
||||||
|
}, 96);
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest('throttle does not trigger leading call when leading is set to false', 2, function() {
|
||||||
|
var counter = 0;
|
||||||
|
var incr = function(){ counter++; };
|
||||||
|
var throttledIncr = _.throttle(incr, 60, {leading: false});
|
||||||
|
|
||||||
|
throttledIncr(); throttledIncr();
|
||||||
|
equal(counter, 0);
|
||||||
|
|
||||||
|
_.delay(function() {
|
||||||
|
equal(counter, 1);
|
||||||
|
start();
|
||||||
|
}, 96);
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest('more throttle does not trigger leading call when leading is set to false', 3, function() {
|
||||||
|
var counter = 0;
|
||||||
|
var incr = function(){ counter++; };
|
||||||
|
var throttledIncr = _.throttle(incr, 100, {leading: false});
|
||||||
|
|
||||||
|
throttledIncr();
|
||||||
|
_.delay(throttledIncr, 50);
|
||||||
|
_.delay(throttledIncr, 60);
|
||||||
|
_.delay(throttledIncr, 200);
|
||||||
|
equal(counter, 0);
|
||||||
|
|
||||||
|
_.delay(function() {
|
||||||
|
equal(counter, 1);
|
||||||
|
}, 250);
|
||||||
|
|
||||||
|
_.delay(function() {
|
||||||
|
equal(counter, 2);
|
||||||
|
start();
|
||||||
|
}, 350);
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest('one more throttle with leading: false test', 2, function() {
|
||||||
|
var counter = 0;
|
||||||
|
var incr = function(){ counter++; };
|
||||||
|
var throttledIncr = _.throttle(incr, 100, {leading: false});
|
||||||
|
|
||||||
|
var time = new Date;
|
||||||
|
while (new Date - time < 350) throttledIncr();
|
||||||
|
ok(counter <= 3);
|
||||||
|
|
||||||
|
_.delay(function() {
|
||||||
|
ok(counter <= 4);
|
||||||
|
start();
|
||||||
|
}, 200);
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest('throttle does not trigger trailing call when trailing is set to false', 4, function() {
|
||||||
|
var counter = 0;
|
||||||
|
var incr = function(){ counter++; };
|
||||||
|
var throttledIncr = _.throttle(incr, 60, {trailing: false});
|
||||||
|
|
||||||
|
throttledIncr(); throttledIncr(); throttledIncr();
|
||||||
|
equal(counter, 1);
|
||||||
|
|
||||||
|
_.delay(function() {
|
||||||
|
equal(counter, 1);
|
||||||
|
|
||||||
|
throttledIncr(); throttledIncr();
|
||||||
|
equal(counter, 2);
|
||||||
|
|
||||||
|
_.delay(function() {
|
||||||
|
equal(counter, 2);
|
||||||
|
start();
|
||||||
|
}, 96);
|
||||||
|
}, 96);
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest('throttle continues to function after system time is set backwards', 2, function() {
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
var incr = function(){ counter++; };
|
var incr = function(){ counter++; };
|
||||||
var throttledIncr = _.throttle(incr, 100);
|
var throttledIncr = _.throttle(incr, 100);
|
||||||
throttledIncr(); throttledIncr();
|
var origNowFunc = _.now;
|
||||||
_.delay(function(){ equal(counter, 2, "incr was called twice"); start(); }, 220);
|
|
||||||
|
throttledIncr();
|
||||||
|
equal(counter, 1);
|
||||||
|
_.now = function () {
|
||||||
|
return new Date(2013, 0, 1, 1, 1, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
_.delay(function() {
|
||||||
|
throttledIncr();
|
||||||
|
equal(counter, 2);
|
||||||
|
start();
|
||||||
|
_.now = origNowFunc;
|
||||||
|
}, 200);
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest("functions: debounce", 1, function() {
|
asyncTest('throttle re-entrant', 2, function() {
|
||||||
var counter = 0;
|
var sequence = [
|
||||||
var incr = function(){ counter++; };
|
['b1', 'b2'],
|
||||||
var debouncedIncr = _.debounce(incr, 50);
|
['c1', 'c2']
|
||||||
debouncedIncr(); debouncedIncr(); debouncedIncr();
|
];
|
||||||
setTimeout(debouncedIncr, 30);
|
var value = '';
|
||||||
setTimeout(debouncedIncr, 60);
|
var throttledAppend;
|
||||||
setTimeout(debouncedIncr, 90);
|
var append = function(arg){
|
||||||
setTimeout(debouncedIncr, 120);
|
value += this + arg;
|
||||||
setTimeout(debouncedIncr, 150);
|
var args = sequence.pop();
|
||||||
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220);
|
if (args) {
|
||||||
|
throttledAppend.call(args[0], args[1]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
throttledAppend = _.throttle(append, 32);
|
||||||
|
throttledAppend.call('a1', 'a2');
|
||||||
|
equal(value, 'a1a2');
|
||||||
|
_.delay(function(){
|
||||||
|
equal(value, 'a1a2c1c2b1b2', 'append was throttled successfully');
|
||||||
|
start();
|
||||||
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest("functions: debounce asap", 2, function() {
|
asyncTest('debounce', 1, function() {
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
var incr = function(){ counter++; };
|
var incr = function(){ counter++; };
|
||||||
var debouncedIncr = _.debounce(incr, 50, true);
|
var debouncedIncr = _.debounce(incr, 32);
|
||||||
debouncedIncr(); debouncedIncr(); debouncedIncr();
|
debouncedIncr(); debouncedIncr();
|
||||||
|
_.delay(debouncedIncr, 16);
|
||||||
|
_.delay(function(){ equal(counter, 1, 'incr was debounced'); start(); }, 96);
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest('debounce asap', 4, function() {
|
||||||
|
var a, b;
|
||||||
|
var counter = 0;
|
||||||
|
var incr = function(){ return ++counter; };
|
||||||
|
var debouncedIncr = _.debounce(incr, 64, true);
|
||||||
|
a = debouncedIncr();
|
||||||
|
b = debouncedIncr();
|
||||||
|
equal(a, 1);
|
||||||
|
equal(b, 1);
|
||||||
equal(counter, 1, 'incr was called immediately');
|
equal(counter, 1, 'incr was called immediately');
|
||||||
setTimeout(debouncedIncr, 30);
|
_.delay(debouncedIncr, 16);
|
||||||
setTimeout(debouncedIncr, 60);
|
_.delay(debouncedIncr, 32);
|
||||||
setTimeout(debouncedIncr, 90);
|
_.delay(debouncedIncr, 48);
|
||||||
setTimeout(debouncedIncr, 120);
|
_.delay(function(){ equal(counter, 1, 'incr was debounced'); start(); }, 128);
|
||||||
setTimeout(debouncedIncr, 150);
|
|
||||||
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest("functions: debounce asap recursively", 2, function() {
|
asyncTest('debounce asap recursively', 2, function() {
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
var debouncedIncr = _.debounce(function(){
|
var debouncedIncr = _.debounce(function(){
|
||||||
counter++;
|
counter++;
|
||||||
if (counter < 5) debouncedIncr();
|
if (counter < 10) debouncedIncr();
|
||||||
}, 50, true);
|
}, 32, true);
|
||||||
debouncedIncr();
|
debouncedIncr();
|
||||||
equal(counter, 1, 'incr was called immediately');
|
equal(counter, 1, 'incr was called immediately');
|
||||||
_.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 70);
|
_.delay(function(){ equal(counter, 1, 'incr was debounced'); start(); }, 96);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("functions: once", function() {
|
asyncTest('debounce after system time is set backwards', 2, function() {
|
||||||
|
var counter = 0;
|
||||||
|
var origNowFunc = _.now;
|
||||||
|
var debouncedIncr = _.debounce(function(){
|
||||||
|
counter++;
|
||||||
|
}, 100, true);
|
||||||
|
|
||||||
|
debouncedIncr();
|
||||||
|
equal(counter, 1, 'incr was called immediately');
|
||||||
|
|
||||||
|
_.now = function () {
|
||||||
|
return new Date(2013, 0, 1, 1, 1, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
_.delay(function() {
|
||||||
|
debouncedIncr();
|
||||||
|
equal(counter, 2, 'incr was debounced successfully');
|
||||||
|
start();
|
||||||
|
_.now = origNowFunc;
|
||||||
|
}, 200);
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest('debounce re-entrant', 2, function() {
|
||||||
|
var sequence = [
|
||||||
|
['b1', 'b2']
|
||||||
|
];
|
||||||
|
var value = '';
|
||||||
|
var debouncedAppend;
|
||||||
|
var append = function(arg){
|
||||||
|
value += this + arg;
|
||||||
|
var args = sequence.pop();
|
||||||
|
if (args) {
|
||||||
|
debouncedAppend.call(args[0], args[1]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
debouncedAppend = _.debounce(append, 32);
|
||||||
|
debouncedAppend.call('a1', 'a2');
|
||||||
|
equal(value, '');
|
||||||
|
_.delay(function(){
|
||||||
|
equal(value, 'a1a2b1b2', 'append was debounced successfully');
|
||||||
|
start();
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('once', function() {
|
||||||
var num = 0;
|
var num = 0;
|
||||||
var increment = _.once(function(){ num++; });
|
var increment = _.once(function(){ return ++num; });
|
||||||
increment();
|
increment();
|
||||||
increment();
|
increment();
|
||||||
equal(num, 1);
|
equal(num, 1);
|
||||||
|
|
||||||
|
equal(increment(), 1, 'stores a memo to the last value');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("functions: wrap", function() {
|
test('Recursive onced function.', 1, function() {
|
||||||
var greet = function(name){ return "hi: " + name; };
|
var f = _.once(function(){
|
||||||
var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); });
|
ok(true);
|
||||||
equal(backwards('moe'), 'hi: moe eom', 'wrapped the saluation function');
|
f();
|
||||||
|
});
|
||||||
|
f();
|
||||||
|
});
|
||||||
|
|
||||||
var inner = function(){ return "Hello "; };
|
test('wrap', function() {
|
||||||
var obj = {name : "Moe"};
|
var greet = function(name){ return 'hi: ' + name; };
|
||||||
|
var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); });
|
||||||
|
equal(backwards('moe'), 'hi: moe eom', 'wrapped the salutation function');
|
||||||
|
|
||||||
|
var inner = function(){ return 'Hello '; };
|
||||||
|
var obj = {name : 'Moe'};
|
||||||
obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; });
|
obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; });
|
||||||
equal(obj.hi(), "Hello Moe");
|
equal(obj.hi(), 'Hello Moe');
|
||||||
|
|
||||||
var noop = function(){};
|
var noop = function(){};
|
||||||
var wrapped = _.wrap(noop, function(fn){ return Array.prototype.slice.call(arguments, 0); });
|
var wrapped = _.wrap(noop, function(){ return Array.prototype.slice.call(arguments, 0); });
|
||||||
var ret = wrapped(['whats', 'your'], 'vector', 'victor');
|
var ret = wrapped(['whats', 'your'], 'vector', 'victor');
|
||||||
deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']);
|
deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("functions: compose", function() {
|
test('negate', function() {
|
||||||
var greet = function(name){ return "hi: " + name; };
|
var isOdd = function(n){ return n & 1; };
|
||||||
|
equal(_.negate(isOdd)(2), true, 'should return the complement of the given function');
|
||||||
|
equal(_.negate(isOdd)(3), false, 'should return the complement of the given function');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('compose', function() {
|
||||||
|
var greet = function(name){ return 'hi: ' + name; };
|
||||||
var exclaim = function(sentence){ return sentence + '!'; };
|
var exclaim = function(sentence){ return sentence + '!'; };
|
||||||
var composed = _.compose(exclaim, greet);
|
var composed = _.compose(exclaim, greet);
|
||||||
equal(composed('moe'), 'hi: moe!', 'can compose a function that takes another');
|
equal(composed('moe'), 'hi: moe!', 'can compose a function that takes another');
|
||||||
|
|
||||||
composed = _.compose(greet, exclaim);
|
composed = _.compose(greet, exclaim);
|
||||||
equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative');
|
equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative');
|
||||||
|
|
||||||
|
// f(g(h(x, y, z)))
|
||||||
|
function h(x, y, z) {
|
||||||
|
equal(arguments.length, 3, 'First function called with multiple args');
|
||||||
|
return z * y;
|
||||||
|
}
|
||||||
|
function g(x) {
|
||||||
|
equal(arguments.length, 1, 'Composed function is called with 1 argument');
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
function f(x) {
|
||||||
|
equal(arguments.length, 1, 'Composed function is called with 1 argument');
|
||||||
|
return x * 2;
|
||||||
|
}
|
||||||
|
composed = _.compose(f, g, h);
|
||||||
|
equal(composed(1, 2, 3), 12);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("functions: after", function() {
|
test('after', function() {
|
||||||
var testAfter = function(afterAmount, timesCalled) {
|
var testAfter = function(afterAmount, timesCalled) {
|
||||||
var afterCalled = 0;
|
var afterCalled = 0;
|
||||||
var after = _.after(afterAmount, function() {
|
var after = _.after(afterAmount, function() {
|
||||||
@@ -218,9 +537,45 @@ $(document).ready(function() {
|
|||||||
return afterCalled;
|
return afterCalled;
|
||||||
};
|
};
|
||||||
|
|
||||||
equal(testAfter(5, 5), 1, "after(N) should fire after being called N times");
|
equal(testAfter(5, 5), 1, 'after(N) should fire after being called N times');
|
||||||
equal(testAfter(5, 4), 0, "after(N) should not fire unless called N times");
|
equal(testAfter(5, 4), 0, 'after(N) should not fire unless called N times');
|
||||||
equal(testAfter(0, 0), 1, "after(0) should fire immediately");
|
equal(testAfter(0, 0), 0, 'after(0) should not fire immediately');
|
||||||
|
equal(testAfter(0, 1), 1, 'after(0) should fire when first invoked');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
test('before', function() {
|
||||||
|
var testBefore = function(beforeAmount, timesCalled) {
|
||||||
|
var beforeCalled = 0;
|
||||||
|
var before = _.before(beforeAmount, function() { beforeCalled++; });
|
||||||
|
while (timesCalled--) before();
|
||||||
|
return beforeCalled;
|
||||||
|
};
|
||||||
|
|
||||||
|
equal(testBefore(5, 5), 4, 'before(N) should not fire after being called N times');
|
||||||
|
equal(testBefore(5, 4), 4, 'before(N) should fire before being called N times');
|
||||||
|
equal(testBefore(0, 0), 0, 'before(0) should not fire immediately');
|
||||||
|
equal(testBefore(0, 1), 0, 'before(0) should not fire when first invoked');
|
||||||
|
|
||||||
|
var context = {num: 0};
|
||||||
|
var increment = _.before(3, function(){ return ++this.num; });
|
||||||
|
_.times(10, increment, context);
|
||||||
|
equal(increment(), 2, 'stores a memo to the last value');
|
||||||
|
equal(context.num, 2, 'provides context');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('iteratee', function() {
|
||||||
|
var identity = _.iteratee();
|
||||||
|
equal(identity, _.identity, '_.iteratee is exposed as an external function.');
|
||||||
|
|
||||||
|
function fn() {
|
||||||
|
return arguments;
|
||||||
|
}
|
||||||
|
_.each([_.iteratee(fn), _.iteratee(fn, {})], function(cb) {
|
||||||
|
equal(cb().length, 0);
|
||||||
|
deepEqual(_.toArray(cb(1, 2, 3)), _.range(1, 4));
|
||||||
|
deepEqual(_.toArray(cb(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), _.range(1, 11));
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}());
|
||||||
|
|||||||
1062
vendor/underscore/test/objects.js
vendored
1062
vendor/underscore/test/objects.js
vendored
File diff suppressed because it is too large
Load Diff
305
vendor/underscore/test/utility.js
vendored
305
vendor/underscore/test/utility.js
vendored
@@ -1,8 +1,8 @@
|
|||||||
$(document).ready(function() {
|
(function() {
|
||||||
|
var _ = typeof require == 'function' ? require('..') : window._;
|
||||||
var templateSettings;
|
var templateSettings;
|
||||||
|
|
||||||
module("Utility", {
|
QUnit.module('Utility', {
|
||||||
|
|
||||||
setup: function() {
|
setup: function() {
|
||||||
templateSettings = _.clone(_.templateSettings);
|
templateSettings = _.clone(_.templateSettings);
|
||||||
@@ -14,28 +14,93 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("utility: identity", function() {
|
test('#750 - Return _ instance.', 2, function() {
|
||||||
var moe = {name : 'moe'};
|
var instance = _([]);
|
||||||
equal(_.identity(moe), moe, 'moe is the same as his identity');
|
ok(_(instance) === instance);
|
||||||
|
ok(new _(instance) === instance);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("utility: uniqueId", function() {
|
test('identity', function() {
|
||||||
|
var stooge = {name : 'moe'};
|
||||||
|
equal(_.identity(stooge), stooge, 'stooge is the same as his identity');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('constant', function() {
|
||||||
|
var stooge = {name : 'moe'};
|
||||||
|
equal(_.constant(stooge)(), stooge, 'should create a function that returns stooge');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('noop', function() {
|
||||||
|
strictEqual(_.noop('curly', 'larry', 'moe'), undefined, 'should always return undefined');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('property', function() {
|
||||||
|
var stooge = {name : 'moe'};
|
||||||
|
equal(_.property('name')(stooge), 'moe', 'should return the property with the given name');
|
||||||
|
equal(_.property('name')(null), undefined, 'should return undefined for null values');
|
||||||
|
equal(_.property('name')(undefined), undefined, 'should return undefined for undefined values');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('propertyOf', function() {
|
||||||
|
var stoogeRanks = _.propertyOf({curly: 2, moe: 1, larry: 3});
|
||||||
|
equal(stoogeRanks('curly'), 2, 'should return the property with the given name');
|
||||||
|
equal(stoogeRanks(null), undefined, 'should return undefined for null values');
|
||||||
|
equal(stoogeRanks(undefined), undefined, 'should return undefined for undefined values');
|
||||||
|
|
||||||
|
function MoreStooges() { this.shemp = 87; }
|
||||||
|
MoreStooges.prototype = {curly: 2, moe: 1, larry: 3};
|
||||||
|
var moreStoogeRanks = _.propertyOf(new MoreStooges());
|
||||||
|
equal(moreStoogeRanks('curly'), 2, 'should return properties from further up the prototype chain');
|
||||||
|
|
||||||
|
var nullPropertyOf = _.propertyOf(null);
|
||||||
|
equal(nullPropertyOf('curly'), undefined, 'should return undefined when obj is null');
|
||||||
|
|
||||||
|
var undefPropertyOf = _.propertyOf(undefined);
|
||||||
|
equal(undefPropertyOf('curly'), undefined, 'should return undefined when obj is undefined');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('random', function() {
|
||||||
|
var array = _.range(1000);
|
||||||
|
var min = Math.pow(2, 31);
|
||||||
|
var max = Math.pow(2, 62);
|
||||||
|
|
||||||
|
ok(_.every(array, function() {
|
||||||
|
return _.random(min, max) >= min;
|
||||||
|
}), 'should produce a random number greater than or equal to the minimum number');
|
||||||
|
|
||||||
|
ok(_.some(array, function() {
|
||||||
|
return _.random(Number.MAX_VALUE) > 0;
|
||||||
|
}), 'should produce a random number when passed `Number.MAX_VALUE`');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('now', function() {
|
||||||
|
var diff = _.now() - new Date().getTime();
|
||||||
|
ok(diff <= 0 && diff > -5, 'Produces the correct time in milliseconds');//within 5ms
|
||||||
|
});
|
||||||
|
|
||||||
|
test('uniqueId', function() {
|
||||||
var ids = [], i = 0;
|
var ids = [], i = 0;
|
||||||
while(i++ < 100) ids.push(_.uniqueId());
|
while (i++ < 100) ids.push(_.uniqueId());
|
||||||
equal(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids');
|
equal(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("utility: times", function() {
|
test('times', function() {
|
||||||
var vals = [];
|
var vals = [];
|
||||||
_.times(3, function (i) { vals.push(i); });
|
_.times(3, function (i) { vals.push(i); });
|
||||||
ok(_.isEqual(vals, [0,1,2]), "is 0 indexed");
|
deepEqual(vals, [0, 1, 2], 'is 0 indexed');
|
||||||
//
|
//
|
||||||
vals = [];
|
vals = [];
|
||||||
_(3).times(function (i) { vals.push(i); });
|
_(3).times(function(i) { vals.push(i); });
|
||||||
ok(_.isEqual(vals, [0,1,2]), "works as a wrapper");
|
deepEqual(vals, [0, 1, 2], 'works as a wrapper');
|
||||||
|
// collects return values
|
||||||
|
deepEqual([0, 1, 2], _.times(3, function(i) { return i; }), 'collects return values');
|
||||||
|
|
||||||
|
deepEqual(_.times(0, _.identity), []);
|
||||||
|
deepEqual(_.times(-1, _.identity), []);
|
||||||
|
deepEqual(_.times(parseFloat('-Infinity'), _.identity), []);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("utility: mixin", function() {
|
test('mixin', function() {
|
||||||
_.mixin({
|
_.mixin({
|
||||||
myReverse: function(string) {
|
myReverse: function(string) {
|
||||||
return string.split('').reverse().join('');
|
return string.split('').reverse().join('');
|
||||||
@@ -45,115 +110,168 @@ $(document).ready(function() {
|
|||||||
equal(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper');
|
equal(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("utility: _.escape", function() {
|
test('_.escape', function() {
|
||||||
equal(_.escape("Curly & Moe"), "Curly & Moe");
|
equal(_.escape(null), '');
|
||||||
equal(_.escape("Curly & Moe"), "Curly &amp; Moe");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("utility: template", function() {
|
test('_.unescape', function() {
|
||||||
|
var string = 'Curly & Moe';
|
||||||
|
equal(_.unescape(null), '');
|
||||||
|
equal(_.unescape(_.escape(string)), string);
|
||||||
|
equal(_.unescape(string), string, 'don\'t unescape unnecessarily');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Don't care what they escape them to just that they're escaped and can be unescaped
|
||||||
|
test('_.escape & unescape', function() {
|
||||||
|
// test & (&) seperately obviously
|
||||||
|
var escapeCharacters = ['<', '>', '"', '\'', '`'];
|
||||||
|
|
||||||
|
_.each(escapeCharacters, function(escapeChar) {
|
||||||
|
var str = 'a ' + escapeChar + ' string escaped';
|
||||||
|
var escaped = _.escape(str);
|
||||||
|
notEqual(str, escaped, escapeChar + ' is escaped');
|
||||||
|
equal(str, _.unescape(escaped), escapeChar + ' can be unescaped');
|
||||||
|
|
||||||
|
str = 'a ' + escapeChar + escapeChar + escapeChar + 'some more string' + escapeChar;
|
||||||
|
escaped = _.escape(str);
|
||||||
|
|
||||||
|
equal(escaped.indexOf(escapeChar), -1, 'can escape multiple occurances of ' + escapeChar);
|
||||||
|
equal(_.unescape(escaped), str, 'multiple occurrences of ' + escapeChar + ' can be unescaped');
|
||||||
|
});
|
||||||
|
|
||||||
|
// handles multiple escape characters at once
|
||||||
|
var joiner = ' other stuff ';
|
||||||
|
var allEscaped = escapeCharacters.join(joiner);
|
||||||
|
allEscaped += allEscaped;
|
||||||
|
ok(_.every(escapeCharacters, function(escapeChar) {
|
||||||
|
return allEscaped.indexOf(escapeChar) !== -1;
|
||||||
|
}), 'handles multiple characters');
|
||||||
|
ok(allEscaped.indexOf(joiner) >= 0, 'can escape multiple escape characters at the same time');
|
||||||
|
|
||||||
|
// test & -> &
|
||||||
|
var str = 'some string & another string & yet another';
|
||||||
|
var escaped = _.escape(str);
|
||||||
|
|
||||||
|
ok(escaped.indexOf('&') !== -1, 'handles & aka &');
|
||||||
|
equal(_.unescape(str), str, 'can unescape &');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('template', function() {
|
||||||
var basicTemplate = _.template("<%= thing %> is gettin' on my noives!");
|
var basicTemplate = _.template("<%= thing %> is gettin' on my noives!");
|
||||||
var result = basicTemplate({thing : 'This'});
|
var result = basicTemplate({thing : 'This'});
|
||||||
equal(result, "This is gettin' on my noives!", 'can do basic attribute interpolation');
|
equal(result, "This is gettin' on my noives!", 'can do basic attribute interpolation');
|
||||||
|
|
||||||
var sansSemicolonTemplate = _.template("A <% this %> B");
|
var sansSemicolonTemplate = _.template('A <% this %> B');
|
||||||
equal(sansSemicolonTemplate(), "A B");
|
equal(sansSemicolonTemplate(), 'A B');
|
||||||
|
|
||||||
var backslashTemplate = _.template("<%= thing %> is \\ridanculous");
|
var backslashTemplate = _.template('<%= thing %> is \\ridanculous');
|
||||||
equal(backslashTemplate({thing: 'This'}), "This is \\ridanculous");
|
equal(backslashTemplate({thing: 'This'}), 'This is \\ridanculous');
|
||||||
|
|
||||||
var escapeTemplate = _.template('<%= a ? "checked=\\"checked\\"" : "" %>');
|
var escapeTemplate = _.template('<%= a ? "checked=\\"checked\\"" : "" %>');
|
||||||
equal(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.');
|
equal(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.');
|
||||||
|
|
||||||
var fancyTemplate = _.template("<ul><% \
|
var fancyTemplate = _.template('<ul><% ' +
|
||||||
for (key in people) { \
|
' for (var key in people) { ' +
|
||||||
%><li><%= people[key] %></li><% } %></ul>");
|
'%><li><%= people[key] %></li><% } %></ul>');
|
||||||
result = fancyTemplate({people : {moe : "Moe", larry : "Larry", curly : "Curly"}});
|
result = fancyTemplate({people : {moe : 'Moe', larry : 'Larry', curly : 'Curly'}});
|
||||||
equal(result, "<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>", 'can run arbitrary javascript in templates');
|
equal(result, '<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>', 'can run arbitrary javascript in templates');
|
||||||
|
|
||||||
var escapedCharsInJavascriptTemplate = _.template("<ul><% _.each(numbers.split('\\n'), function(item) { %><li><%= item %></li><% }) %></ul>");
|
var escapedCharsInJavascriptTemplate = _.template('<ul><% _.each(numbers.split("\\n"), function(item) { %><li><%= item %></li><% }) %></ul>');
|
||||||
result = escapedCharsInJavascriptTemplate({numbers: "one\ntwo\nthree\nfour"});
|
result = escapedCharsInJavascriptTemplate({numbers: 'one\ntwo\nthree\nfour'});
|
||||||
equal(result, "<ul><li>one</li><li>two</li><li>three</li><li>four</li></ul>", 'Can use escaped characters (e.g. \\n) in Javascript');
|
equal(result, '<ul><li>one</li><li>two</li><li>three</li><li>four</li></ul>', 'Can use escaped characters (e.g. \\n) in JavaScript');
|
||||||
|
|
||||||
var namespaceCollisionTemplate = _.template("<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %><div class=\"thumbnail\" rel=\"<%= p %>\"></div><% }); %>");
|
var namespaceCollisionTemplate = _.template('<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %><div class="thumbnail" rel="<%= p %>"></div><% }); %>');
|
||||||
result = namespaceCollisionTemplate({
|
result = namespaceCollisionTemplate({
|
||||||
pageCount: 3,
|
pageCount: 3,
|
||||||
thumbnails: {
|
thumbnails: {
|
||||||
1: "p1-thumbnail.gif",
|
1: 'p1-thumbnail.gif',
|
||||||
2: "p2-thumbnail.gif",
|
2: 'p2-thumbnail.gif',
|
||||||
3: "p3-thumbnail.gif"
|
3: 'p3-thumbnail.gif'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
equal(result, "3 p3-thumbnail.gif <div class=\"thumbnail\" rel=\"p1-thumbnail.gif\"></div><div class=\"thumbnail\" rel=\"p2-thumbnail.gif\"></div><div class=\"thumbnail\" rel=\"p3-thumbnail.gif\"></div>");
|
equal(result, '3 p3-thumbnail.gif <div class="thumbnail" rel="p1-thumbnail.gif"></div><div class="thumbnail" rel="p2-thumbnail.gif"></div><div class="thumbnail" rel="p3-thumbnail.gif"></div>');
|
||||||
|
|
||||||
var noInterpolateTemplate = _.template("<div><p>Just some text. Hey, I know this is silly but it aids consistency.</p></div>");
|
var noInterpolateTemplate = _.template('<div><p>Just some text. Hey, I know this is silly but it aids consistency.</p></div>');
|
||||||
result = noInterpolateTemplate();
|
result = noInterpolateTemplate();
|
||||||
equal(result, "<div><p>Just some text. Hey, I know this is silly but it aids consistency.</p></div>");
|
equal(result, '<div><p>Just some text. Hey, I know this is silly but it aids consistency.</p></div>');
|
||||||
|
|
||||||
var quoteTemplate = _.template("It's its, not it's");
|
var quoteTemplate = _.template("It's its, not it's");
|
||||||
equal(quoteTemplate({}), "It's its, not it's");
|
equal(quoteTemplate({}), "It's its, not it's");
|
||||||
|
|
||||||
var quoteInStatementAndBody = _.template("<%\
|
var quoteInStatementAndBody = _.template('<% ' +
|
||||||
if(foo == 'bar'){ \
|
" if(foo == 'bar'){ " +
|
||||||
%>Statement quotes and 'quotes'.<% } %>");
|
"%>Statement quotes and 'quotes'.<% } %>");
|
||||||
equal(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'.");
|
equal(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'.");
|
||||||
|
|
||||||
var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.');
|
var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.');
|
||||||
equal(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.');
|
equal(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.');
|
||||||
|
|
||||||
var template = _.template("<i><%- value %></i>");
|
var template = _.template('<i><%- value %></i>');
|
||||||
var result = template({value: "<script>"});
|
result = template({value: '<script>'});
|
||||||
equal(result, '<i><script></i>');
|
equal(result, '<i><script></i>');
|
||||||
|
|
||||||
var stooge = {
|
var stooge = {
|
||||||
name: "Moe",
|
name: 'Moe',
|
||||||
template: _.template("I'm <%= this.name %>")
|
template: _.template("I'm <%= this.name %>")
|
||||||
};
|
};
|
||||||
equal(stooge.template(), "I'm Moe");
|
equal(stooge.template(), "I'm Moe");
|
||||||
|
|
||||||
if (!$.browser.msie) {
|
template = _.template('\n ' +
|
||||||
var fromHTML = _.template($('#template').html());
|
' <%\n ' +
|
||||||
equal(fromHTML({data : 12345}).replace(/\s/g, ''), '<li>24690</li>');
|
' // a comment\n ' +
|
||||||
}
|
' if (data) { data += 12345; }; %>\n ' +
|
||||||
|
' <li><%= data %></li>\n '
|
||||||
|
);
|
||||||
|
equal(template({data : 12345}).replace(/\s/g, ''), '<li>24690</li>');
|
||||||
|
|
||||||
_.templateSettings = {
|
_.templateSettings = {
|
||||||
evaluate : /\{\{([\s\S]+?)\}\}/g,
|
evaluate : /\{\{([\s\S]+?)\}\}/g,
|
||||||
interpolate : /\{\{=([\s\S]+?)\}\}/g
|
interpolate : /\{\{=([\s\S]+?)\}\}/g
|
||||||
};
|
};
|
||||||
|
|
||||||
var custom = _.template("<ul>{{ for (key in people) { }}<li>{{= people[key] }}</li>{{ } }}</ul>");
|
var custom = _.template('<ul>{{ for (var key in people) { }}<li>{{= people[key] }}</li>{{ } }}</ul>');
|
||||||
result = custom({people : {moe : "Moe", larry : "Larry", curly : "Curly"}});
|
result = custom({people : {moe : 'Moe', larry : 'Larry', curly : 'Curly'}});
|
||||||
equal(result, "<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>", 'can run arbitrary javascript in templates');
|
equal(result, '<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>', 'can run arbitrary javascript in templates');
|
||||||
|
|
||||||
var customQuote = _.template("It's its, not it's");
|
var customQuote = _.template("It's its, not it's");
|
||||||
equal(customQuote({}), "It's its, not it's");
|
equal(customQuote({}), "It's its, not it's");
|
||||||
|
|
||||||
var quoteInStatementAndBody = _.template("{{ if(foo == 'bar'){ }}Statement quotes and 'quotes'.{{ } }}");
|
quoteInStatementAndBody = _.template("{{ if(foo == 'bar'){ }}Statement quotes and 'quotes'.{{ } }}");
|
||||||
equal(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'.");
|
equal(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'.");
|
||||||
|
|
||||||
_.templateSettings = {
|
_.templateSettings = {
|
||||||
evaluate : /<\?([\s\S]+?)\?>/g,
|
evaluate : /<\?([\s\S]+?)\?>/g,
|
||||||
interpolate : /<\?=([\s\S]+?)\?>/g
|
interpolate : /<\?=([\s\S]+?)\?>/g
|
||||||
};
|
};
|
||||||
|
|
||||||
var customWithSpecialChars = _.template("<ul><? for (key in people) { ?><li><?= people[key] ?></li><? } ?></ul>");
|
var customWithSpecialChars = _.template('<ul><? for (var key in people) { ?><li><?= people[key] ?></li><? } ?></ul>');
|
||||||
result = customWithSpecialChars({people : {moe : "Moe", larry : "Larry", curly : "Curly"}});
|
result = customWithSpecialChars({people : {moe : 'Moe', larry : 'Larry', curly : 'Curly'}});
|
||||||
equal(result, "<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>", 'can run arbitrary javascript in templates');
|
equal(result, '<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>', 'can run arbitrary javascript in templates');
|
||||||
|
|
||||||
var customWithSpecialCharsQuote = _.template("It's its, not it's");
|
var customWithSpecialCharsQuote = _.template("It's its, not it's");
|
||||||
equal(customWithSpecialCharsQuote({}), "It's its, not it's");
|
equal(customWithSpecialCharsQuote({}), "It's its, not it's");
|
||||||
|
|
||||||
var quoteInStatementAndBody = _.template("<? if(foo == 'bar'){ ?>Statement quotes and 'quotes'.<? } ?>");
|
quoteInStatementAndBody = _.template("<? if(foo == 'bar'){ ?>Statement quotes and 'quotes'.<? } ?>");
|
||||||
equal(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'.");
|
equal(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'.");
|
||||||
|
|
||||||
_.templateSettings = {
|
_.templateSettings = {
|
||||||
interpolate : /\{\{(.+?)\}\}/g
|
interpolate : /\{\{(.+?)\}\}/g
|
||||||
};
|
};
|
||||||
|
|
||||||
var mustache = _.template("Hello {{planet}}!");
|
var mustache = _.template('Hello {{planet}}!');
|
||||||
equal(mustache({planet : "World"}), "Hello World!", "can mimic mustache.js");
|
equal(mustache({planet : 'World'}), 'Hello World!', 'can mimic mustache.js');
|
||||||
|
|
||||||
var templateWithNull = _.template("a null undefined {{planet}}");
|
var templateWithNull = _.template('a null undefined {{planet}}');
|
||||||
equal(templateWithNull({planet : "world"}), "a null undefined world", "can handle missing escape and evaluate settings");
|
equal(templateWithNull({planet : 'world'}), 'a null undefined world', 'can handle missing escape and evaluate settings');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('_.template provides the generated function source, when a SyntaxError occurs', function() {
|
||||||
|
try {
|
||||||
|
_.template('<b><%= if x %></b>');
|
||||||
|
} catch (ex) {
|
||||||
|
var source = ex.source;
|
||||||
|
}
|
||||||
|
ok(/__p/.test(source));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('_.template handles \\u2028 & \\u2029', function() {
|
test('_.template handles \\u2028 & \\u2029', function() {
|
||||||
@@ -167,13 +285,49 @@ $(document).ready(function() {
|
|||||||
strictEqual(_.result(obj, 'x'), 'x');
|
strictEqual(_.result(obj, 'x'), 'x');
|
||||||
strictEqual(_.result(obj, 'y'), 'x');
|
strictEqual(_.result(obj, 'y'), 'x');
|
||||||
strictEqual(_.result(obj, 'z'), undefined);
|
strictEqual(_.result(obj, 'z'), undefined);
|
||||||
strictEqual(_.result(null, 'x'), null);
|
strictEqual(_.result(null, 'x'), undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('result returns a default value if object is null or undefined', function() {
|
||||||
|
strictEqual(_.result(null, 'b', 'default'), 'default');
|
||||||
|
strictEqual(_.result(undefined, 'c', 'default'), 'default');
|
||||||
|
strictEqual(_.result(''.match('missing'), 1, 'default'), 'default');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('result returns a default value if property of object is missing', function() {
|
||||||
|
strictEqual(_.result({d: null}, 'd', 'default'), null);
|
||||||
|
strictEqual(_.result({e: false}, 'e', 'default'), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('result only returns the default value if the object does not have the property or is undefined', function() {
|
||||||
|
strictEqual(_.result({}, 'b', 'default'), 'default');
|
||||||
|
strictEqual(_.result({d: undefined}, 'd', 'default'), 'default');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('result does not return the default if the property of an object is found in the prototype', function() {
|
||||||
|
var Foo = function(){};
|
||||||
|
Foo.prototype.bar = 1;
|
||||||
|
strictEqual(_.result(new Foo, 'bar', 2), 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('result does use the fallback when the result of invoking the property is undefined', function() {
|
||||||
|
var obj = {a: function() {}};
|
||||||
|
strictEqual(_.result(obj, 'a', 'failed'), undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('result fallback can use a function', function() {
|
||||||
|
var obj = {a: [1, 2, 3]};
|
||||||
|
strictEqual(_.result(obj, 'b', _.constant(5)), 5);
|
||||||
|
strictEqual(_.result(obj, 'b', function() {
|
||||||
|
return this.a;
|
||||||
|
}), obj.a, 'called with context');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('_.templateSettings.variable', function() {
|
test('_.templateSettings.variable', function() {
|
||||||
var s = '<%=data.x%>';
|
var s = '<%=data.x%>';
|
||||||
var data = {x: 'x'};
|
var data = {x: 'x'};
|
||||||
strictEqual(_.template(s, data, {variable: 'data'}), 'x');
|
var tmp = _.template(s, {variable: 'data'});
|
||||||
|
strictEqual(tmp(data), 'x');
|
||||||
_.templateSettings.variable = 'data';
|
_.templateSettings.variable = 'data';
|
||||||
strictEqual(_.template(s)(data), 'x');
|
strictEqual(_.template(s)(data), 'x');
|
||||||
});
|
});
|
||||||
@@ -194,22 +348,33 @@ $(document).ready(function() {
|
|||||||
strictEqual(templateEscaped({x: undefined}), '');
|
strictEqual(templateEscaped({x: undefined}), '');
|
||||||
|
|
||||||
var templateWithProperty = _.template('<%=x.foo%>');
|
var templateWithProperty = _.template('<%=x.foo%>');
|
||||||
strictEqual(templateWithProperty({x: {} }), '');
|
strictEqual(templateWithProperty({x: {}}), '');
|
||||||
strictEqual(templateWithProperty({x: {} }), '');
|
strictEqual(templateWithProperty({x: {}}), '');
|
||||||
|
|
||||||
var templateWithPropertyEscaped = _.template('<%-x.foo%>');
|
var templateWithPropertyEscaped = _.template('<%-x.foo%>');
|
||||||
strictEqual(templateWithPropertyEscaped({x: {} }), '');
|
strictEqual(templateWithPropertyEscaped({x: {}}), '');
|
||||||
strictEqual(templateWithPropertyEscaped({x: {} }), '');
|
strictEqual(templateWithPropertyEscaped({x: {}}), '');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('interpolate evaluates code only once.', 2, function() {
|
test('interpolate evaluates code only once.', 2, function() {
|
||||||
var count = 0;
|
var count = 0;
|
||||||
var template = _.template('<%= f() %>');
|
var template = _.template('<%= f() %>');
|
||||||
template({f: function(){ ok(!(count++)); }});
|
template({f: function(){ ok(!count++); }});
|
||||||
|
|
||||||
var countEscaped = 0;
|
var countEscaped = 0;
|
||||||
var templateEscaped = _.template('<%- f() %>');
|
var templateEscaped = _.template('<%- f() %>');
|
||||||
templateEscaped({f: function(){ ok(!(countEscaped++)); }});
|
templateEscaped({f: function(){ ok(!countEscaped++); }});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
test('#746 - _.template settings are not modified.', 1, function() {
|
||||||
|
var settings = {};
|
||||||
|
_.template('', null, settings);
|
||||||
|
deepEqual(settings, {});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('#779 - delimeters are applied to unescaped text.', 1, function() {
|
||||||
|
var template = _.template('<<\nx\n>>', null, {evaluate: /<<(.*?)>>/g});
|
||||||
|
strictEqual(template(), '<<\nx\n>>');
|
||||||
|
});
|
||||||
|
|
||||||
|
}());
|
||||||
|
|||||||
9404
vendor/underscore/test/vendor/jquery.js
vendored
9404
vendor/underscore/test/vendor/jquery.js
vendored
File diff suppressed because it is too large
Load Diff
670
vendor/underscore/test/vendor/jslitmus.js
vendored
670
vendor/underscore/test/vendor/jslitmus.js
vendored
@@ -1,670 +0,0 @@
|
|||||||
// JSLitmus.js
|
|
||||||
//
|
|
||||||
// History:
|
|
||||||
// 2008-10-27: Initial release
|
|
||||||
// 2008-11-09: Account for iteration loop overhead
|
|
||||||
// 2008-11-13: Added OS detection
|
|
||||||
// 2009-02-25: Create tinyURL automatically, shift-click runs tests in reverse
|
|
||||||
//
|
|
||||||
// Copyright (c) 2008-2009, Robert Kieffer
|
|
||||||
// All Rights Reserved
|
|
||||||
//
|
|
||||||
// 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 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.
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
// Private methods and state
|
|
||||||
|
|
||||||
// Get platform info but don't go crazy trying to recognize everything
|
|
||||||
// that's out there. This is just for the major platforms and OSes.
|
|
||||||
var platform = 'unknown platform', ua = navigator.userAgent;
|
|
||||||
|
|
||||||
// Detect OS
|
|
||||||
var oses = ['Windows','iPhone OS','(Intel |PPC )?Mac OS X','Linux'].join('|');
|
|
||||||
var pOS = new RegExp('((' + oses + ') [^ \);]*)').test(ua) ? RegExp.$1 : null;
|
|
||||||
if (!pOS) pOS = new RegExp('((' + oses + ')[^ \);]*)').test(ua) ? RegExp.$1 : null;
|
|
||||||
|
|
||||||
// Detect browser
|
|
||||||
var pName = /(Chrome|MSIE|Safari|Opera|Firefox)/.test(ua) ? RegExp.$1 : null;
|
|
||||||
|
|
||||||
// Detect version
|
|
||||||
var vre = new RegExp('(Version|' + pName + ')[ \/]([^ ;]*)');
|
|
||||||
var pVersion = (pName && vre.test(ua)) ? RegExp.$2 : null;
|
|
||||||
var platform = (pOS && pName && pVersion) ? pName + ' ' + pVersion + ' on ' + pOS : 'unknown platform';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A smattering of methods that are needed to implement the JSLitmus testbed.
|
|
||||||
*/
|
|
||||||
var jsl = {
|
|
||||||
/**
|
|
||||||
* Enhanced version of escape()
|
|
||||||
*/
|
|
||||||
escape: function(s) {
|
|
||||||
s = s.replace(/,/g, '\\,');
|
|
||||||
s = escape(s);
|
|
||||||
s = s.replace(/\+/g, '%2b');
|
|
||||||
s = s.replace(/ /g, '+');
|
|
||||||
return s;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an element by ID.
|
|
||||||
*/
|
|
||||||
$: function(id) {
|
|
||||||
return document.getElementById(id);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Null function
|
|
||||||
*/
|
|
||||||
F: function() {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the status shown in the UI
|
|
||||||
*/
|
|
||||||
status: function(msg) {
|
|
||||||
var el = jsl.$('jsl_status');
|
|
||||||
if (el) el.innerHTML = msg || '';
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a number to an abbreviated string like, "15K" or "10M"
|
|
||||||
*/
|
|
||||||
toLabel: function(n) {
|
|
||||||
if (n == Infinity) {
|
|
||||||
return 'Infinity';
|
|
||||||
} else if (n > 1e9) {
|
|
||||||
n = Math.round(n/1e8);
|
|
||||||
return n/10 + 'B';
|
|
||||||
} else if (n > 1e6) {
|
|
||||||
n = Math.round(n/1e5);
|
|
||||||
return n/10 + 'M';
|
|
||||||
} else if (n > 1e3) {
|
|
||||||
n = Math.round(n/1e2);
|
|
||||||
return n/10 + 'K';
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy properties from src to dst
|
|
||||||
*/
|
|
||||||
extend: function(dst, src) {
|
|
||||||
for (var k in src) dst[k] = src[k]; return dst;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Like Array.join(), but for the key-value pairs in an object
|
|
||||||
*/
|
|
||||||
join: function(o, delimit1, delimit2) {
|
|
||||||
if (o.join) return o.join(delimit1); // If it's an array
|
|
||||||
var pairs = [];
|
|
||||||
for (var k in o) pairs.push(k + delimit1 + o[k]);
|
|
||||||
return pairs.join(delimit2);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Array#indexOf isn't supported in IE, so we use this as a cross-browser solution
|
|
||||||
*/
|
|
||||||
indexOf: function(arr, o) {
|
|
||||||
if (arr.indexOf) return arr.indexOf(o);
|
|
||||||
for (var i = 0; i < this.length; i++) if (arr[i] === o) return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test manages a single test (created with
|
|
||||||
* JSLitmus.test())
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
var Test = function (name, f) {
|
|
||||||
if (!f) throw new Error('Undefined test function');
|
|
||||||
if (!(/function[^\(]*\(([^,\)]*)/).test(f.toString())) {
|
|
||||||
throw new Error('"' + name + '" test: Test is not a valid Function object');
|
|
||||||
}
|
|
||||||
this.loopArg = RegExp.$1;
|
|
||||||
this.name = name;
|
|
||||||
this.f = f;
|
|
||||||
};
|
|
||||||
|
|
||||||
jsl.extend(Test, /** @lends Test */ {
|
|
||||||
/** Calibration tests for establishing iteration loop overhead */
|
|
||||||
CALIBRATIONS: [
|
|
||||||
new Test('calibrating loop', function(count) {while (count--);}),
|
|
||||||
new Test('calibrating function', jsl.F)
|
|
||||||
],
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run calibration tests. Returns true if calibrations are not yet
|
|
||||||
* complete (in which case calling code should run the tests yet again).
|
|
||||||
* onCalibrated - Callback to invoke when calibrations have finished
|
|
||||||
*/
|
|
||||||
calibrate: function(onCalibrated) {
|
|
||||||
for (var i = 0; i < Test.CALIBRATIONS.length; i++) {
|
|
||||||
var cal = Test.CALIBRATIONS[i];
|
|
||||||
if (cal.running) return true;
|
|
||||||
if (!cal.count) {
|
|
||||||
cal.isCalibration = true;
|
|
||||||
cal.onStop = onCalibrated;
|
|
||||||
//cal.MIN_TIME = .1; // Do calibrations quickly
|
|
||||||
cal.run(2e4);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
jsl.extend(Test.prototype, {/** @lends Test.prototype */
|
|
||||||
/** Initial number of iterations */
|
|
||||||
INIT_COUNT: 10,
|
|
||||||
/** Max iterations allowed (i.e. used to detect bad looping functions) */
|
|
||||||
MAX_COUNT: 1e9,
|
|
||||||
/** Minimum time a test should take to get valid results (secs) */
|
|
||||||
MIN_TIME: .5,
|
|
||||||
|
|
||||||
/** Callback invoked when test state changes */
|
|
||||||
onChange: jsl.F,
|
|
||||||
|
|
||||||
/** Callback invoked when test is finished */
|
|
||||||
onStop: jsl.F,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset test state
|
|
||||||
*/
|
|
||||||
reset: function() {
|
|
||||||
delete this.count;
|
|
||||||
delete this.time;
|
|
||||||
delete this.running;
|
|
||||||
delete this.error;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the test (in a timeout). We use a timeout to make sure the browser
|
|
||||||
* has a chance to finish rendering any UI changes we've made, like
|
|
||||||
* updating the status message.
|
|
||||||
*/
|
|
||||||
run: function(count) {
|
|
||||||
count = count || this.INIT_COUNT;
|
|
||||||
jsl.status(this.name + ' x ' + count);
|
|
||||||
this.running = true;
|
|
||||||
var me = this;
|
|
||||||
setTimeout(function() {me._run(count);}, 200);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The nuts and bolts code that actually runs a test
|
|
||||||
*/
|
|
||||||
_run: function(count) {
|
|
||||||
var me = this;
|
|
||||||
|
|
||||||
// Make sure calibration tests have run
|
|
||||||
if (!me.isCalibration && Test.calibrate(function() {me.run(count);})) return;
|
|
||||||
this.error = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
var start, f = this.f, now, i = count;
|
|
||||||
|
|
||||||
// Start the timer
|
|
||||||
start = new Date();
|
|
||||||
|
|
||||||
// Now for the money shot. If this is a looping function ...
|
|
||||||
if (this.loopArg) {
|
|
||||||
// ... let it do the iteration itself
|
|
||||||
f(count);
|
|
||||||
} else {
|
|
||||||
// ... otherwise do the iteration for it
|
|
||||||
while (i--) f();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get time test took (in secs)
|
|
||||||
this.time = Math.max(1,new Date() - start)/1000;
|
|
||||||
|
|
||||||
// Store iteration count and per-operation time taken
|
|
||||||
this.count = count;
|
|
||||||
this.period = this.time/count;
|
|
||||||
|
|
||||||
// Do we need to do another run?
|
|
||||||
this.running = this.time <= this.MIN_TIME;
|
|
||||||
|
|
||||||
// ... if so, compute how many times we should iterate
|
|
||||||
if (this.running) {
|
|
||||||
// Bump the count to the nearest power of 2
|
|
||||||
var x = this.MIN_TIME/this.time;
|
|
||||||
var pow = Math.pow(2, Math.max(1, Math.ceil(Math.log(x)/Math.log(2))));
|
|
||||||
count *= pow;
|
|
||||||
if (count > this.MAX_COUNT) {
|
|
||||||
throw new Error('Max count exceeded. If this test uses a looping function, make sure the iteration loop is working properly.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// Exceptions are caught and displayed in the test UI
|
|
||||||
this.reset();
|
|
||||||
this.error = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Figure out what to do next
|
|
||||||
if (this.running) {
|
|
||||||
me.run(count);
|
|
||||||
} else {
|
|
||||||
jsl.status('');
|
|
||||||
me.onStop(me);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finish up
|
|
||||||
this.onChange(this);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of operations per second for this test.
|
|
||||||
*
|
|
||||||
* @param normalize if true, iteration loop overhead taken into account
|
|
||||||
*/
|
|
||||||
getHz: function(/**Boolean*/ normalize) {
|
|
||||||
var p = this.period;
|
|
||||||
|
|
||||||
// Adjust period based on the calibration test time
|
|
||||||
if (normalize && !this.isCalibration) {
|
|
||||||
var cal = Test.CALIBRATIONS[this.loopArg ? 0 : 1];
|
|
||||||
|
|
||||||
// If the period is within 20% of the calibration time, then zero the
|
|
||||||
// it out
|
|
||||||
p = p < cal.period*1.2 ? 0 : p - cal.period;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Math.round(1/p);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a friendly string describing the test
|
|
||||||
*/
|
|
||||||
toString: function() {
|
|
||||||
return this.name + ' - ' + this.time/this.count + ' secs';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// CSS we need for the UI
|
|
||||||
var STYLESHEET = '<style> \
|
|
||||||
#jslitmus {font-family:sans-serif; font-size: 12px;} \
|
|
||||||
#jslitmus a {text-decoration: none;} \
|
|
||||||
#jslitmus a:hover {text-decoration: underline;} \
|
|
||||||
#jsl_status { \
|
|
||||||
margin-top: 10px; \
|
|
||||||
font-size: 10px; \
|
|
||||||
color: #888; \
|
|
||||||
} \
|
|
||||||
A IMG {border:none} \
|
|
||||||
#test_results { \
|
|
||||||
margin-top: 10px; \
|
|
||||||
font-size: 12px; \
|
|
||||||
font-family: sans-serif; \
|
|
||||||
border-collapse: collapse; \
|
|
||||||
border-spacing: 0px; \
|
|
||||||
} \
|
|
||||||
#test_results th, #test_results td { \
|
|
||||||
border: solid 1px #ccc; \
|
|
||||||
vertical-align: top; \
|
|
||||||
padding: 3px; \
|
|
||||||
} \
|
|
||||||
#test_results th { \
|
|
||||||
vertical-align: bottom; \
|
|
||||||
background-color: #ccc; \
|
|
||||||
padding: 1px; \
|
|
||||||
font-size: 10px; \
|
|
||||||
} \
|
|
||||||
#test_results #test_platform { \
|
|
||||||
color: #444; \
|
|
||||||
text-align:center; \
|
|
||||||
} \
|
|
||||||
#test_results .test_row { \
|
|
||||||
color: #006; \
|
|
||||||
cursor: pointer; \
|
|
||||||
} \
|
|
||||||
#test_results .test_nonlooping { \
|
|
||||||
border-left-style: dotted; \
|
|
||||||
border-left-width: 2px; \
|
|
||||||
} \
|
|
||||||
#test_results .test_looping { \
|
|
||||||
border-left-style: solid; \
|
|
||||||
border-left-width: 2px; \
|
|
||||||
} \
|
|
||||||
#test_results .test_name {white-space: nowrap;} \
|
|
||||||
#test_results .test_pending { \
|
|
||||||
} \
|
|
||||||
#test_results .test_running { \
|
|
||||||
font-style: italic; \
|
|
||||||
} \
|
|
||||||
#test_results .test_done {} \
|
|
||||||
#test_results .test_done { \
|
|
||||||
text-align: right; \
|
|
||||||
font-family: monospace; \
|
|
||||||
} \
|
|
||||||
#test_results .test_error {color: #600;} \
|
|
||||||
#test_results .test_error .error_head {font-weight:bold;} \
|
|
||||||
#test_results .test_error .error_body {font-size:85%;} \
|
|
||||||
#test_results .test_row:hover td { \
|
|
||||||
background-color: #ffc; \
|
|
||||||
text-decoration: underline; \
|
|
||||||
} \
|
|
||||||
#chart { \
|
|
||||||
margin: 10px 0px; \
|
|
||||||
width: 250px; \
|
|
||||||
} \
|
|
||||||
#chart img { \
|
|
||||||
border: solid 1px #ccc; \
|
|
||||||
margin-bottom: 5px; \
|
|
||||||
} \
|
|
||||||
#chart #tiny_url { \
|
|
||||||
height: 40px; \
|
|
||||||
width: 250px; \
|
|
||||||
} \
|
|
||||||
#jslitmus_credit { \
|
|
||||||
font-size: 10px; \
|
|
||||||
color: #888; \
|
|
||||||
margin-top: 8px; \
|
|
||||||
} \
|
|
||||||
</style>';
|
|
||||||
|
|
||||||
// HTML markup for the UI
|
|
||||||
var MARKUP = '<div id="jslitmus"> \
|
|
||||||
<button onclick="JSLitmus.runAll(event)">Run Tests</button> \
|
|
||||||
<button id="stop_button" disabled="disabled" onclick="JSLitmus.stop()">Stop Tests</button> \
|
|
||||||
<br \> \
|
|
||||||
<br \> \
|
|
||||||
<input type="checkbox" style="vertical-align: middle" id="test_normalize" checked="checked" onchange="JSLitmus.renderAll()""> Normalize results \
|
|
||||||
<table id="test_results"> \
|
|
||||||
<colgroup> \
|
|
||||||
<col /> \
|
|
||||||
<col width="100" /> \
|
|
||||||
</colgroup> \
|
|
||||||
<tr><th id="test_platform" colspan="2">' + platform + '</th></tr> \
|
|
||||||
<tr><th>Test</th><th>Ops/sec</th></tr> \
|
|
||||||
<tr id="test_row_template" class="test_row" style="display:none"> \
|
|
||||||
<td class="test_name"></td> \
|
|
||||||
<td class="test_result">Ready</td> \
|
|
||||||
</tr> \
|
|
||||||
</table> \
|
|
||||||
<div id="jsl_status"></div> \
|
|
||||||
<div id="chart" style="display:none"> \
|
|
||||||
<a id="chart_link" target="_blank"><img id="chart_image"></a> \
|
|
||||||
TinyURL (for chart): \
|
|
||||||
<iframe id="tiny_url" frameBorder="0" scrolling="no" src=""></iframe> \
|
|
||||||
</div> \
|
|
||||||
<a id="jslitmus_credit" title="JSLitmus home page" href="http://code.google.com/p/jslitmus" target="_blank">Powered by JSLitmus</a> \
|
|
||||||
</div>';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The public API for creating and running tests
|
|
||||||
*/
|
|
||||||
window.JSLitmus = {
|
|
||||||
/** The list of all tests that have been registered with JSLitmus.test */
|
|
||||||
_tests: [],
|
|
||||||
/** The queue of tests that need to be run */
|
|
||||||
_queue: [],
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The parsed query parameters the current page URL. This is provided as a
|
|
||||||
* convenience for test functions - it's not used by JSLitmus proper
|
|
||||||
*/
|
|
||||||
params: {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize
|
|
||||||
*/
|
|
||||||
_init: function() {
|
|
||||||
// Parse query params into JSLitmus.params[] hash
|
|
||||||
var match = (location + '').match(/([^?#]*)(#.*)?$/);
|
|
||||||
if (match) {
|
|
||||||
var pairs = match[1].split('&');
|
|
||||||
for (var i = 0; i < pairs.length; i++) {
|
|
||||||
var pair = pairs[i].split('=');
|
|
||||||
if (pair.length > 1) {
|
|
||||||
var key = pair.shift();
|
|
||||||
var value = pair.length > 1 ? pair.join('=') : pair[0];
|
|
||||||
this.params[key] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write out the stylesheet. We have to do this here because IE
|
|
||||||
// doesn't honor sheets written after the document has loaded.
|
|
||||||
document.write(STYLESHEET);
|
|
||||||
|
|
||||||
// Setup the rest of the UI once the document is loaded
|
|
||||||
if (window.addEventListener) {
|
|
||||||
window.addEventListener('load', this._setup, false);
|
|
||||||
} else if (document.addEventListener) {
|
|
||||||
document.addEventListener('load', this._setup, false);
|
|
||||||
} else if (window.attachEvent) {
|
|
||||||
window.attachEvent('onload', this._setup);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set up the UI
|
|
||||||
*/
|
|
||||||
_setup: function() {
|
|
||||||
var el = jsl.$('jslitmus_container');
|
|
||||||
if (!el) document.body.appendChild(el = document.createElement('div'));
|
|
||||||
|
|
||||||
el.innerHTML = MARKUP;
|
|
||||||
|
|
||||||
// Render the UI for all our tests
|
|
||||||
for (var i=0; i < JSLitmus._tests.length; i++)
|
|
||||||
JSLitmus.renderTest(JSLitmus._tests[i]);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* (Re)render all the test results
|
|
||||||
*/
|
|
||||||
renderAll: function() {
|
|
||||||
for (var i = 0; i < JSLitmus._tests.length; i++)
|
|
||||||
JSLitmus.renderTest(JSLitmus._tests[i]);
|
|
||||||
JSLitmus.renderChart();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* (Re)render the chart graphics
|
|
||||||
*/
|
|
||||||
renderChart: function() {
|
|
||||||
var url = JSLitmus.chartUrl();
|
|
||||||
jsl.$('chart_link').href = url;
|
|
||||||
jsl.$('chart_image').src = url;
|
|
||||||
jsl.$('chart').style.display = '';
|
|
||||||
|
|
||||||
// Update the tiny URL
|
|
||||||
jsl.$('tiny_url').src = 'http://tinyurl.com/api-create.php?url='+escape(url);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* (Re)render the results for a specific test
|
|
||||||
*/
|
|
||||||
renderTest: function(test) {
|
|
||||||
// Make a new row if needed
|
|
||||||
if (!test._row) {
|
|
||||||
var trow = jsl.$('test_row_template');
|
|
||||||
if (!trow) return;
|
|
||||||
|
|
||||||
test._row = trow.cloneNode(true);
|
|
||||||
test._row.style.display = '';
|
|
||||||
test._row.id = '';
|
|
||||||
test._row.onclick = function() {JSLitmus._queueTest(test);};
|
|
||||||
test._row.title = 'Run ' + test.name + ' test';
|
|
||||||
trow.parentNode.appendChild(test._row);
|
|
||||||
test._row.cells[0].innerHTML = test.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
var cell = test._row.cells[1];
|
|
||||||
var cns = [test.loopArg ? 'test_looping' : 'test_nonlooping'];
|
|
||||||
|
|
||||||
if (test.error) {
|
|
||||||
cns.push('test_error');
|
|
||||||
cell.innerHTML =
|
|
||||||
'<div class="error_head">' + test.error + '</div>' +
|
|
||||||
'<ul class="error_body"><li>' +
|
|
||||||
jsl.join(test.error, ': ', '</li><li>') +
|
|
||||||
'</li></ul>';
|
|
||||||
} else {
|
|
||||||
if (test.running) {
|
|
||||||
cns.push('test_running');
|
|
||||||
cell.innerHTML = 'running';
|
|
||||||
} else if (jsl.indexOf(JSLitmus._queue, test) >= 0) {
|
|
||||||
cns.push('test_pending');
|
|
||||||
cell.innerHTML = 'pending';
|
|
||||||
} else if (test.count) {
|
|
||||||
cns.push('test_done');
|
|
||||||
var hz = test.getHz(jsl.$('test_normalize').checked);
|
|
||||||
cell.innerHTML = hz != Infinity ? hz : '∞';
|
|
||||||
} else {
|
|
||||||
cell.innerHTML = 'ready';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cell.className = cns.join(' ');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new test
|
|
||||||
*/
|
|
||||||
test: function(name, f) {
|
|
||||||
// Create the Test object
|
|
||||||
var test = new Test(name, f);
|
|
||||||
JSLitmus._tests.push(test);
|
|
||||||
|
|
||||||
// Re-render if the test state changes
|
|
||||||
test.onChange = JSLitmus.renderTest;
|
|
||||||
|
|
||||||
// Run the next test if this one finished
|
|
||||||
test.onStop = function(test) {
|
|
||||||
if (JSLitmus.onTestFinish) JSLitmus.onTestFinish(test);
|
|
||||||
JSLitmus.currentTest = null;
|
|
||||||
JSLitmus._nextTest();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Render the new test
|
|
||||||
this.renderTest(test);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add all tests to the run queue
|
|
||||||
*/
|
|
||||||
runAll: function(e) {
|
|
||||||
e = e || window.event;
|
|
||||||
var reverse = e && e.shiftKey, len = JSLitmus._tests.length;
|
|
||||||
for (var i = 0; i < len; i++) {
|
|
||||||
JSLitmus._queueTest(JSLitmus._tests[!reverse ? i : (len - i - 1)]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove all tests from the run queue. The current test has to finish on
|
|
||||||
* it's own though
|
|
||||||
*/
|
|
||||||
stop: function() {
|
|
||||||
while (JSLitmus._queue.length) {
|
|
||||||
var test = JSLitmus._queue.shift();
|
|
||||||
JSLitmus.renderTest(test);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the next test in the run queue
|
|
||||||
*/
|
|
||||||
_nextTest: function() {
|
|
||||||
if (!JSLitmus.currentTest) {
|
|
||||||
var test = JSLitmus._queue.shift();
|
|
||||||
if (test) {
|
|
||||||
jsl.$('stop_button').disabled = false;
|
|
||||||
JSLitmus.currentTest = test;
|
|
||||||
test.run();
|
|
||||||
JSLitmus.renderTest(test);
|
|
||||||
if (JSLitmus.onTestStart) JSLitmus.onTestStart(test);
|
|
||||||
} else {
|
|
||||||
jsl.$('stop_button').disabled = true;
|
|
||||||
JSLitmus.renderChart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a test to the run queue
|
|
||||||
*/
|
|
||||||
_queueTest: function(test) {
|
|
||||||
if (jsl.indexOf(JSLitmus._queue, test) >= 0) return;
|
|
||||||
JSLitmus._queue.push(test);
|
|
||||||
JSLitmus.renderTest(test);
|
|
||||||
JSLitmus._nextTest();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a Google Chart URL that shows the data for all tests
|
|
||||||
*/
|
|
||||||
chartUrl: function() {
|
|
||||||
var n = JSLitmus._tests.length, markers = [], data = [];
|
|
||||||
var d, min = 0, max = -1e10;
|
|
||||||
var normalize = jsl.$('test_normalize').checked;
|
|
||||||
|
|
||||||
// Gather test data
|
|
||||||
for (var i=0; i < JSLitmus._tests.length; i++) {
|
|
||||||
var test = JSLitmus._tests[i];
|
|
||||||
if (test.count) {
|
|
||||||
var hz = test.getHz(normalize);
|
|
||||||
var v = hz != Infinity ? hz : 0;
|
|
||||||
data.push(v);
|
|
||||||
markers.push('t' + jsl.escape(test.name + '(' + jsl.toLabel(hz)+ ')') + ',000000,0,' +
|
|
||||||
markers.length + ',10');
|
|
||||||
max = Math.max(v, max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (markers.length <= 0) return null;
|
|
||||||
|
|
||||||
// Build chart title
|
|
||||||
var title = document.getElementsByTagName('title');
|
|
||||||
title = (title && title.length) ? title[0].innerHTML : null;
|
|
||||||
var chart_title = [];
|
|
||||||
if (title) chart_title.push(title);
|
|
||||||
chart_title.push('Ops/sec (' + platform + ')');
|
|
||||||
|
|
||||||
// Build labels
|
|
||||||
var labels = [jsl.toLabel(min), jsl.toLabel(max)];
|
|
||||||
|
|
||||||
var w = 250, bw = 15;
|
|
||||||
var bs = 5;
|
|
||||||
var h = markers.length*(bw + bs) + 30 + chart_title.length*20;
|
|
||||||
|
|
||||||
var params = {
|
|
||||||
chtt: escape(chart_title.join('|')),
|
|
||||||
chts: '000000,10',
|
|
||||||
cht: 'bhg', // chart type
|
|
||||||
chd: 't:' + data.join(','), // data set
|
|
||||||
chds: min + ',' + max, // max/min of data
|
|
||||||
chxt: 'x', // label axes
|
|
||||||
chxl: '0:|' + labels.join('|'), // labels
|
|
||||||
chsp: '0,1',
|
|
||||||
chm: markers.join('|'), // test names
|
|
||||||
chbh: [bw, 0, bs].join(','), // bar widths
|
|
||||||
// chf: 'bg,lg,0,eeeeee,0,eeeeee,.5,ffffff,1', // gradient
|
|
||||||
chs: w + 'x' + h
|
|
||||||
};
|
|
||||||
return 'http://chart.apis.google.com/chart?' + jsl.join(params, '=', '&');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
JSLitmus._init();
|
|
||||||
})();
|
|
||||||
236
vendor/underscore/test/vendor/qunit.css
vendored
236
vendor/underscore/test/vendor/qunit.css
vendored
@@ -1,236 +0,0 @@
|
|||||||
/**
|
|
||||||
* QUnit v1.8.0 - A JavaScript Unit Testing Framework
|
|
||||||
*
|
|
||||||
* http://docs.jquery.com/QUnit
|
|
||||||
*
|
|
||||||
* Copyright (c) 2012 John Resig, Jörn Zaefferer
|
|
||||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
|
||||||
* or GPL (GPL-LICENSE.txt) licenses.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Font Family and Sizes */
|
|
||||||
|
|
||||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
|
|
||||||
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
|
|
||||||
#qunit-tests { font-size: smaller; }
|
|
||||||
|
|
||||||
|
|
||||||
/** Resets */
|
|
||||||
|
|
||||||
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Header */
|
|
||||||
|
|
||||||
#qunit-header {
|
|
||||||
padding: 0.5em 0 0.5em 1em;
|
|
||||||
|
|
||||||
color: #8699a4;
|
|
||||||
background-color: #0d3349;
|
|
||||||
|
|
||||||
font-size: 1.5em;
|
|
||||||
line-height: 1em;
|
|
||||||
font-weight: normal;
|
|
||||||
|
|
||||||
border-radius: 15px 15px 0 0;
|
|
||||||
-moz-border-radius: 15px 15px 0 0;
|
|
||||||
-webkit-border-top-right-radius: 15px;
|
|
||||||
-webkit-border-top-left-radius: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-header a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: #c2ccd1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-header a:hover,
|
|
||||||
#qunit-header a:focus {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-header label {
|
|
||||||
display: inline-block;
|
|
||||||
padding-left: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-banner {
|
|
||||||
height: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-testrunner-toolbar {
|
|
||||||
padding: 0.5em 0 0.5em 2em;
|
|
||||||
color: #5E740B;
|
|
||||||
background-color: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-userAgent {
|
|
||||||
padding: 0.5em 0 0.5em 2.5em;
|
|
||||||
background-color: #2b81af;
|
|
||||||
color: #fff;
|
|
||||||
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Tests: Pass/Fail */
|
|
||||||
|
|
||||||
#qunit-tests {
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li {
|
|
||||||
padding: 0.4em 0.5em 0.4em 2.5em;
|
|
||||||
border-bottom: 1px solid #fff;
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li strong {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li a {
|
|
||||||
padding: 0.5em;
|
|
||||||
color: #c2ccd1;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
#qunit-tests li a:hover,
|
|
||||||
#qunit-tests li a:focus {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests ol {
|
|
||||||
margin-top: 0.5em;
|
|
||||||
padding: 0.5em;
|
|
||||||
|
|
||||||
background-color: #fff;
|
|
||||||
|
|
||||||
border-radius: 15px;
|
|
||||||
-moz-border-radius: 15px;
|
|
||||||
-webkit-border-radius: 15px;
|
|
||||||
|
|
||||||
box-shadow: inset 0px 2px 13px #999;
|
|
||||||
-moz-box-shadow: inset 0px 2px 13px #999;
|
|
||||||
-webkit-box-shadow: inset 0px 2px 13px #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
margin-top: .2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests th {
|
|
||||||
text-align: right;
|
|
||||||
vertical-align: top;
|
|
||||||
padding: 0 .5em 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests td {
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests pre {
|
|
||||||
margin: 0;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests del {
|
|
||||||
background-color: #e0f2be;
|
|
||||||
color: #374e0c;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests ins {
|
|
||||||
background-color: #ffcaca;
|
|
||||||
color: #500;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Test Counts */
|
|
||||||
|
|
||||||
#qunit-tests b.counts { color: black; }
|
|
||||||
#qunit-tests b.passed { color: #5E740B; }
|
|
||||||
#qunit-tests b.failed { color: #710909; }
|
|
||||||
|
|
||||||
#qunit-tests li li {
|
|
||||||
margin: 0.5em;
|
|
||||||
padding: 0.4em 0.5em 0.4em 0.5em;
|
|
||||||
background-color: #fff;
|
|
||||||
border-bottom: none;
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Passing Styles */
|
|
||||||
|
|
||||||
#qunit-tests li li.pass {
|
|
||||||
color: #5E740B;
|
|
||||||
background-color: #fff;
|
|
||||||
border-left: 26px solid #C6E746;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
|
|
||||||
#qunit-tests .pass .test-name { color: #366097; }
|
|
||||||
|
|
||||||
#qunit-tests .pass .test-actual,
|
|
||||||
#qunit-tests .pass .test-expected { color: #999999; }
|
|
||||||
|
|
||||||
#qunit-banner.qunit-pass { background-color: #C6E746; }
|
|
||||||
|
|
||||||
/*** Failing Styles */
|
|
||||||
|
|
||||||
#qunit-tests li li.fail {
|
|
||||||
color: #710909;
|
|
||||||
background-color: #fff;
|
|
||||||
border-left: 26px solid #EE5757;
|
|
||||||
white-space: pre;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests > li:last-child {
|
|
||||||
border-radius: 0 0 15px 15px;
|
|
||||||
-moz-border-radius: 0 0 15px 15px;
|
|
||||||
-webkit-border-bottom-right-radius: 15px;
|
|
||||||
-webkit-border-bottom-left-radius: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
|
|
||||||
#qunit-tests .fail .test-name,
|
|
||||||
#qunit-tests .fail .module-name { color: #000000; }
|
|
||||||
|
|
||||||
#qunit-tests .fail .test-actual { color: #EE5757; }
|
|
||||||
#qunit-tests .fail .test-expected { color: green; }
|
|
||||||
|
|
||||||
#qunit-banner.qunit-fail { background-color: #EE5757; }
|
|
||||||
|
|
||||||
|
|
||||||
/** Result */
|
|
||||||
|
|
||||||
#qunit-testresult {
|
|
||||||
padding: 0.5em 0.5em 0.5em 2.5em;
|
|
||||||
|
|
||||||
color: #2b81af;
|
|
||||||
background-color: #D2E0E6;
|
|
||||||
|
|
||||||
border-bottom: 1px solid white;
|
|
||||||
}
|
|
||||||
#qunit-testresult .module-name {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Fixture */
|
|
||||||
|
|
||||||
#qunit-fixture {
|
|
||||||
position: absolute;
|
|
||||||
top: -10000px;
|
|
||||||
left: -10000px;
|
|
||||||
width: 1000px;
|
|
||||||
height: 1000px;
|
|
||||||
}
|
|
||||||
1863
vendor/underscore/test/vendor/qunit.js
vendored
1863
vendor/underscore/test/vendor/qunit.js
vendored
File diff suppressed because it is too large
Load Diff
38
vendor/underscore/underscore-min.js
vendored
38
vendor/underscore/underscore-min.js
vendored
File diff suppressed because one or more lines are too long
1616
vendor/underscore/underscore.js
vendored
1616
vendor/underscore/underscore.js
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user