Compare commits
1100 Commits
20181121.1
...
20190801.0
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1f13c00937 | ||
![]() |
2fda2ee742 | ||
![]() |
17a3affb6f | ||
![]() |
f6be398fb9 | ||
![]() |
87e24d658b | ||
![]() |
abf70c3a3e | ||
![]() |
b9afa69ee5 | ||
![]() |
d9628fd9a2 | ||
![]() |
a617eac284 | ||
![]() |
7d90429fa9 | ||
![]() |
fa6d0949a2 | ||
![]() |
aab967798a | ||
![]() |
c523bae2c8 | ||
![]() |
b77372fc9a | ||
![]() |
70b06861d1 | ||
![]() |
b158f15d93 | ||
![]() |
4edcd5f2ef | ||
![]() |
689e37782e | ||
![]() |
dcfed5d7e1 | ||
![]() |
54ea6176aa | ||
![]() |
a91bb3cdbb | ||
![]() |
6abbe72e4d | ||
![]() |
dae0ecce6a | ||
![]() |
c3118eada9 | ||
![]() |
0f6d0b164f | ||
![]() |
87293e4b15 | ||
![]() |
ff80eef25d | ||
![]() |
973c190bb6 | ||
![]() |
0cd263c532 | ||
![]() |
3c366b2b85 | ||
![]() |
a59f0086b5 | ||
![]() |
1f1a3acc03 | ||
![]() |
d09cf9c8ab | ||
![]() |
f32eb971a4 | ||
![]() |
56c08a1d07 | ||
![]() |
a44b1d01ed | ||
![]() |
2fd75742f1 | ||
![]() |
70b18344b6 | ||
![]() |
5ec58a723e | ||
![]() |
8dd44bca32 | ||
![]() |
dcb975c8ce | ||
![]() |
ea0a0f510d | ||
![]() |
9476557aee | ||
![]() |
4555bd4240 | ||
![]() |
75c7445dd9 | ||
![]() |
da741238d2 | ||
![]() |
3d0c994b9a | ||
![]() |
ab4b4796c0 | ||
![]() |
a7077dbcb4 | ||
![]() |
a66013ecd7 | ||
![]() |
8265a55838 | ||
![]() |
95d6cbd130 | ||
![]() |
1ee9811644 | ||
![]() |
99c5f2a88a | ||
![]() |
cdfd9cea5c | ||
![]() |
4f2b82d787 | ||
![]() |
3fd0ee9d75 | ||
![]() |
c7f7e72340 | ||
![]() |
1205322342 | ||
![]() |
4cefb9715c | ||
![]() |
35b38db57f | ||
![]() |
4f72eb5416 | ||
![]() |
f3d1a421f4 | ||
![]() |
f3c24dc0b3 | ||
![]() |
e4cbdc29a2 | ||
![]() |
c985977efc | ||
![]() |
8fb991c5ce | ||
![]() |
210c63ad14 | ||
![]() |
8167b05cad | ||
![]() |
e5a916032a | ||
![]() |
56745b3723 | ||
![]() |
ddf2c6cc0f | ||
![]() |
84df2bd531 | ||
![]() |
42c3e3e46c | ||
![]() |
5141e0e923 | ||
![]() |
b87c94e395 | ||
![]() |
55aa5a0d12 | ||
![]() |
eaaeb10c6d | ||
![]() |
567769be5a | ||
![]() |
3ebb30bd48 | ||
![]() |
09a19d2e7f | ||
![]() |
fabc49d17e | ||
![]() |
00e9155546 | ||
![]() |
8238b700b0 | ||
![]() |
5ff33224ed | ||
![]() |
07dee9c5bb | ||
![]() |
9eaeafdd6a | ||
![]() |
beb1fe1e64 | ||
![]() |
cdb2a1a424 | ||
![]() |
8bbc442b7e | ||
![]() |
7a12cbf96e | ||
![]() |
e36454f08f | ||
![]() |
3865c1943c | ||
![]() |
e7e3edfd97 | ||
![]() |
4bdc82f0ed | ||
![]() |
8e3b41885d | ||
![]() |
8f3d5fdb7d | ||
![]() |
f258aa2818 | ||
![]() |
b4dd971829 | ||
![]() |
e99d6f8e6a | ||
![]() |
cc969e547c | ||
![]() |
0e1ae3926b | ||
![]() |
60c2bcc483 | ||
![]() |
5d8e34e8be | ||
![]() |
14a430a059 | ||
![]() |
4ae347949a | ||
![]() |
cdd007cc54 | ||
![]() |
2929db5ba4 | ||
![]() |
628692b2e9 | ||
![]() |
7cfdc24a8c | ||
![]() |
1c69aa122b | ||
![]() |
25afb73ed7 | ||
![]() |
5b5384032d | ||
![]() |
a9d221147f | ||
![]() |
4fdbec93b3 | ||
![]() |
0a8703ad0a | ||
![]() |
ddc11c1b12 | ||
![]() |
317f43277e | ||
![]() |
bf90642c9b | ||
![]() |
6f77992387 | ||
![]() |
deaccd6cd4 | ||
![]() |
d7371ace6a | ||
![]() |
453b1000c1 | ||
![]() |
8c1aff7505 | ||
![]() |
adf002c154 | ||
![]() |
ed7b81e7a4 | ||
![]() |
c0f6ee6a32 | ||
![]() |
9408df6099 | ||
![]() |
157bfd6f80 | ||
![]() |
99da7ebfe6 | ||
![]() |
6911df9ac4 | ||
![]() |
8daeaab40b | ||
![]() |
45c3c78b31 | ||
![]() |
a64a35b861 | ||
![]() |
5a25627219 | ||
![]() |
203b14613f | ||
![]() |
0a7cb39500 | ||
![]() |
42e75e7cdf | ||
![]() |
58e6be12af | ||
![]() |
618d25ce48 | ||
![]() |
9974510067 | ||
![]() |
2faa0c5979 | ||
![]() |
1479647062 | ||
![]() |
3becefaf8b | ||
![]() |
e804e62e66 | ||
![]() |
2c3cc1fbc7 | ||
![]() |
58cc76ab5a | ||
![]() |
5783cdb0d2 | ||
![]() |
4f07caebc6 | ||
![]() |
c4b75b4534 | ||
![]() |
ae82eabaec | ||
![]() |
f8d3e55fe0 | ||
![]() |
1462db0a76 | ||
![]() |
86b36fb76b | ||
![]() |
c6194622b1 | ||
![]() |
be5c3efb23 | ||
![]() |
999c243c94 | ||
![]() |
483f82e554 | ||
![]() |
e91f4567c2 | ||
![]() |
029467139d | ||
![]() |
29649abe3d | ||
![]() |
266c80320b | ||
![]() |
ae51300446 | ||
![]() |
cbdb222f72 | ||
![]() |
98c419ff03 | ||
![]() |
88b9348a81 | ||
![]() |
3e8606781e | ||
![]() |
875afbd7ae | ||
![]() |
3139b914d7 | ||
![]() |
212a44b6ae | ||
![]() |
60551168a2 | ||
![]() |
32d9a6884f | ||
![]() |
7002ab27c0 | ||
![]() |
15c101109e | ||
![]() |
316fed953a | ||
![]() |
93934449c0 | ||
![]() |
894a25c98e | ||
![]() |
90f0d9fa00 | ||
![]() |
83889a8fd7 | ||
![]() |
4cfc429e75 | ||
![]() |
2df829b79d | ||
![]() |
7baf6382ac | ||
![]() |
7d1f689ed9 | ||
![]() |
4f448553f6 | ||
![]() |
dd56671974 | ||
![]() |
d8e0fd0ba5 | ||
![]() |
a9320d4baf | ||
![]() |
42475becf1 | ||
![]() |
c30aca8484 | ||
![]() |
25bdf50737 | ||
![]() |
4a60479b74 | ||
![]() |
f6d651304c | ||
![]() |
85990c20ed | ||
![]() |
8ea98023a5 | ||
![]() |
acceaea410 | ||
![]() |
d609155022 | ||
![]() |
1add5077af | ||
![]() |
a9cac343b0 | ||
![]() |
1b441a752e | ||
![]() |
03fee95f68 | ||
![]() |
7fa4b18843 | ||
![]() |
7b0fb949fd | ||
![]() |
df10cff842 | ||
![]() |
8b93af1b56 | ||
![]() |
a396a4e666 | ||
![]() |
8f278ec4bc | ||
![]() |
032ebce0bc | ||
![]() |
bb60b42f98 | ||
![]() |
21ed717287 | ||
![]() |
2d056bad81 | ||
![]() |
8297e9e215 | ||
![]() |
4ccf450ad4 | ||
![]() |
fc056869a7 | ||
![]() |
0bd5ff34d4 | ||
![]() |
ffd272d3fe | ||
![]() |
1eee186e79 | ||
![]() |
3a05b1124a | ||
![]() |
d14c6125da | ||
![]() |
3ee357178e | ||
![]() |
8f6fdea4eb | ||
![]() |
be6b25f5be | ||
![]() |
be4dd5b20b | ||
![]() |
fe4811b278 | ||
![]() |
d376457cec | ||
![]() |
35e82a8e26 | ||
![]() |
03735f0539 | ||
![]() |
4cc812c1bf | ||
![]() |
bdacd05fab | ||
![]() |
ab157fdbff | ||
![]() |
d94223a61e | ||
![]() |
ebe3198c27 | ||
![]() |
2b2d2effd2 | ||
![]() |
8092e24af8 | ||
![]() |
f019bb095d | ||
![]() |
1ad9d2e54c | ||
![]() |
b2b18cb814 | ||
![]() |
e595637a10 | ||
![]() |
d10a0b3b6c | ||
![]() |
c24f8a2115 | ||
![]() |
7691e3f2c2 | ||
![]() |
6bbe8ff39f | ||
![]() |
a1e9b4938f | ||
![]() |
c826596529 | ||
![]() |
7f47079750 | ||
![]() |
642ba1adc3 | ||
![]() |
fe80c7fe0e | ||
![]() |
9309c5a1b6 | ||
![]() |
575eb22608 | ||
![]() |
be0bef3f1b | ||
![]() |
970286bbba | ||
![]() |
087c3b9c0e | ||
![]() |
b12d1b13ca | ||
![]() |
d0410e0884 | ||
![]() |
a1bf06ceb2 | ||
![]() |
d99744e054 | ||
![]() |
e02d11a51f | ||
![]() |
1b50100b6c | ||
![]() |
309fecc9f3 | ||
![]() |
46f3add520 | ||
![]() |
a89f0bd1cd | ||
![]() |
8408b8d41f | ||
![]() |
13761a20c5 | ||
![]() |
03d17a9761 | ||
![]() |
5501cccc67 | ||
![]() |
9340d9068e | ||
![]() |
bbdaa4b7c1 | ||
![]() |
c87c782b2c | ||
![]() |
f0b1cd9032 | ||
![]() |
2ed532e055 | ||
![]() |
f70dafa192 | ||
![]() |
af6ade8eb6 | ||
![]() |
d77ae840d8 | ||
![]() |
968eae7727 | ||
![]() |
97d8a68455 | ||
![]() |
7827cec212 | ||
![]() |
746ad588ef | ||
![]() |
95e918b6ac | ||
![]() |
1e82cc22e4 | ||
![]() |
fb2e1e5ebb | ||
![]() |
fe2ae965b3 | ||
![]() |
8924a5f043 | ||
![]() |
32e68c1a4b | ||
![]() |
89a35a0062 | ||
![]() |
484b1c8444 | ||
![]() |
cd5e274ffa | ||
![]() |
f466a53ed4 | ||
![]() |
1d40d94774 | ||
![]() |
82e8ca2754 | ||
![]() |
8c904fb012 | ||
![]() |
fa13b95498 | ||
![]() |
289611363e | ||
![]() |
cb7048db23 | ||
![]() |
b9f86f735b | ||
![]() |
0e044acaa9 | ||
![]() |
1223766523 | ||
![]() |
db65af9c22 | ||
![]() |
fcdb1b48a2 | ||
![]() |
8729410dce | ||
![]() |
adb92e1708 | ||
![]() |
81088e0d07 | ||
![]() |
34129cc7cb | ||
![]() |
530be9155b | ||
![]() |
aa33b00a1f | ||
![]() |
57b917f297 | ||
![]() |
aad7dc5d7d | ||
![]() |
6c41c7b1ab | ||
![]() |
8b98f375c2 | ||
![]() |
8a86dd8426 | ||
![]() |
5b12ca94e9 | ||
![]() |
652cd10483 | ||
![]() |
ca0ded8587 | ||
![]() |
f943393ade | ||
![]() |
d8f21d99af | ||
![]() |
73ef03e33f | ||
![]() |
c34dde815c | ||
![]() |
1e85880d7b | ||
![]() |
57abd4ae07 | ||
![]() |
2624c1544b | ||
![]() |
1e72ffc0c2 | ||
![]() |
8ca70ace4c | ||
![]() |
d66cf3f787 | ||
![]() |
44df0f698c | ||
![]() |
981dd5df63 | ||
![]() |
cd6250c495 | ||
![]() |
2f36304f06 | ||
![]() |
30471b7cfb | ||
![]() |
ff2f573dd0 | ||
![]() |
38ddbf45c2 | ||
![]() |
d79bf5e07e | ||
![]() |
d05b1ef9cc | ||
![]() |
c260591d4d | ||
![]() |
87a7e63e31 | ||
![]() |
a5dd3755e1 | ||
![]() |
ad40d9927b | ||
![]() |
f4cfbc6678 | ||
![]() |
b3c1bead39 | ||
![]() |
d220e56239 | ||
![]() |
f967b4940a | ||
![]() |
f44d5dca1c | ||
![]() |
a9ed4e7943 | ||
![]() |
a404acbf44 | ||
![]() |
eaa2ce1462 | ||
![]() |
bdd8699709 | ||
![]() |
9f0b20634a | ||
![]() |
a70d9195db | ||
![]() |
d86253d582 | ||
![]() |
d5a313445f | ||
![]() |
f979febb76 | ||
![]() |
a1a2a78531 | ||
![]() |
6ed2d288e6 | ||
![]() |
5c8e5d3539 | ||
![]() |
bbae3291e1 | ||
![]() |
5dbd5c7395 | ||
![]() |
038f7b43d5 | ||
![]() |
671e564037 | ||
![]() |
8298d810a8 | ||
![]() |
7428479f6b | ||
![]() |
6b85910cdb | ||
![]() |
4d7bb0df7d | ||
![]() |
26a39b1bb8 | ||
![]() |
e23f046c4d | ||
![]() |
fe73213643 | ||
![]() |
cbe5355d38 | ||
![]() |
81b232f01e | ||
![]() |
3e6be45f1f | ||
![]() |
d26ed6fdb6 | ||
![]() |
eda168247c | ||
![]() |
4d2390daf4 | ||
![]() |
5b861bb4c6 | ||
![]() |
be6d89bb7a | ||
![]() |
1c17210948 | ||
![]() |
5257715145 | ||
![]() |
8df9ac9dfa | ||
![]() |
559164e159 | ||
![]() |
70072786a1 | ||
![]() |
cda29fcd07 | ||
![]() |
31e351c75c | ||
![]() |
cadcd845cc | ||
![]() |
b07f95f956 | ||
![]() |
7f99f1d9be | ||
![]() |
8c7cdda3d3 | ||
![]() |
8c222bb467 | ||
![]() |
4dfdebb00a | ||
![]() |
3947adbab4 | ||
![]() |
81eab0bf1b | ||
![]() |
0c406335f5 | ||
![]() |
109c40b2d3 | ||
![]() |
a362b08113 | ||
![]() |
438d155c45 | ||
![]() |
75f5325048 | ||
![]() |
8f5f14fada | ||
![]() |
8e290be9e7 | ||
![]() |
9f97b583a8 | ||
![]() |
8993e39c38 | ||
![]() |
dc61a62149 | ||
![]() |
22fdac4189 | ||
![]() |
c52f437ee6 | ||
![]() |
549db23ff5 | ||
![]() |
6775a094c9 | ||
![]() |
74a255add1 | ||
![]() |
a77c951d55 | ||
![]() |
e3896c359a | ||
![]() |
56e3514e40 | ||
![]() |
f4319d9b13 | ||
![]() |
c134464f6a | ||
![]() |
7b821aa363 | ||
![]() |
4e6d00cf5c | ||
![]() |
22e5792a8f | ||
![]() |
e3e0d4618e | ||
![]() |
aa1ac8f339 | ||
![]() |
40863db138 | ||
![]() |
eac37af18c | ||
![]() |
7f8f99a414 | ||
![]() |
a743a2c46b | ||
![]() |
adc63e1e5a | ||
![]() |
1d24b83e5c | ||
![]() |
b3f9432ae1 | ||
![]() |
c95a44c570 | ||
![]() |
5080f4c2db | ||
![]() |
44eaa3abad | ||
![]() |
9a4215b5d5 | ||
![]() |
004892e11a | ||
![]() |
669358bf1a | ||
![]() |
435b7d9cee | ||
![]() |
9a2207b5cb | ||
![]() |
324f0bb8a2 | ||
![]() |
3b8f8f8189 | ||
![]() |
702c17d658 | ||
![]() |
e2a9cf0d3c | ||
![]() |
8aa501b7bd | ||
![]() |
45189c9163 | ||
![]() |
86940f4d42 | ||
![]() |
812c1362a6 | ||
![]() |
6bf9ea5699 | ||
![]() |
20ee3452dc | ||
![]() |
ef18f9eac9 | ||
![]() |
47faf2768c | ||
![]() |
a2bed3dd90 | ||
![]() |
4fab0b9717 | ||
![]() |
06b70e2653 | ||
![]() |
48aa9a2ad7 | ||
![]() |
93d971f72b | ||
![]() |
7e69df44d7 | ||
![]() |
c743a48cf9 | ||
![]() |
b82a1c75c4 | ||
![]() |
be9402bd05 | ||
![]() |
ebae469e7d | ||
![]() |
d0d293fe21 | ||
![]() |
bd6d082555 | ||
![]() |
39190dda20 | ||
![]() |
89a8e3da36 | ||
![]() |
49f90671fb | ||
![]() |
c4ece5e451 | ||
![]() |
799bd973ca | ||
![]() |
03dffa9905 | ||
![]() |
1d1c981601 | ||
![]() |
40025d44c2 | ||
![]() |
42117fcba0 | ||
![]() |
dc16abd637 | ||
![]() |
8c71746952 | ||
![]() |
6e504020bf | ||
![]() |
7caf37275d | ||
![]() |
c3f094eb9e | ||
![]() |
feb3be1d17 | ||
![]() |
2fe0398f37 | ||
![]() |
42c7879c4d | ||
![]() |
2586590bd9 | ||
![]() |
59ee160f96 | ||
![]() |
d4bc4bf7bc | ||
![]() |
e2a182acee | ||
![]() |
88131ade23 | ||
![]() |
fb16156f8d | ||
![]() |
6ba77b4fa5 | ||
![]() |
c55291dd18 | ||
![]() |
27b61776e8 | ||
![]() |
baa13a1b6c | ||
![]() |
23ca1b972d | ||
![]() |
2d75e797c7 | ||
![]() |
117ea32586 | ||
![]() |
68909c80ff | ||
![]() |
7aa296e774 | ||
![]() |
18df636573 | ||
![]() |
e1540e45f9 | ||
![]() |
d0b0284200 | ||
![]() |
915c441a94 | ||
![]() |
2aec877310 | ||
![]() |
1e291e80b7 | ||
![]() |
7d92eede1f | ||
![]() |
9fc8c0764c | ||
![]() |
4ff2d941c3 | ||
![]() |
2349e2f251 | ||
![]() |
8785b03fd8 | ||
![]() |
92e6c5adfd | ||
![]() |
6015eff8a2 | ||
![]() |
1451a78dd3 | ||
![]() |
094f558556 | ||
![]() |
cd466df42c | ||
![]() |
a626961ae5 | ||
![]() |
bbc32278d8 | ||
![]() |
e2ed1a9fd9 | ||
![]() |
cd94442455 | ||
![]() |
c9eea4acc1 | ||
![]() |
e55ca54509 | ||
![]() |
4118497978 | ||
![]() |
882dc38b12 | ||
![]() |
bcade77075 | ||
![]() |
8c13e524b9 | ||
![]() |
ffa47ccf34 | ||
![]() |
1e22d13588 | ||
![]() |
19804a713d | ||
![]() |
eeaaecd5b7 | ||
![]() |
9a00c65e3b | ||
![]() |
c026c65d53 | ||
![]() |
e9c245015c | ||
![]() |
cdde6f6f4c | ||
![]() |
262537c287 | ||
![]() |
ec04c80413 | ||
![]() |
86548052e5 | ||
![]() |
1890dd8683 | ||
![]() |
2908eb693a | ||
![]() |
7fe4084073 | ||
![]() |
ee948302ed | ||
![]() |
f809bf0550 | ||
![]() |
ed9dff99d3 | ||
![]() |
f5d0162aec | ||
![]() |
32682a2be0 | ||
![]() |
836844a312 | ||
![]() |
8b82fa940e | ||
![]() |
d4be171df9 | ||
![]() |
57be7ac873 | ||
![]() |
a9cecb55ac | ||
![]() |
1c6bf8b94a | ||
![]() |
1c6235546a | ||
![]() |
daaaef96b0 | ||
![]() |
aa3b6343ed | ||
![]() |
3e5d372bbe | ||
![]() |
3bab8686c8 | ||
![]() |
8c0af2c140 | ||
![]() |
f008f8f41a | ||
![]() |
587a7c3b66 | ||
![]() |
b25fff9852 | ||
![]() |
45e5f7d0ff | ||
![]() |
19c44f7c7b | ||
![]() |
241d7345d0 | ||
![]() |
34c6356a47 | ||
![]() |
9383d80354 | ||
![]() |
178e4de452 | ||
![]() |
787abc4611 | ||
![]() |
c2948638d6 | ||
![]() |
1db93a4f7b | ||
![]() |
8f4d24b6da | ||
![]() |
03d4a648f5 | ||
![]() |
8dba463dd4 | ||
![]() |
7c21a07a66 | ||
![]() |
82189ab3c6 | ||
![]() |
c0896d173d | ||
![]() |
5032b6e63b | ||
![]() |
9bf06ca0af | ||
![]() |
4fa1c3e883 | ||
![]() |
339be43eea | ||
![]() |
00c08a09db | ||
![]() |
bed257a4eb | ||
![]() |
b73a2e838a | ||
![]() |
6580d4ce92 | ||
![]() |
8c23674683 | ||
![]() |
3e28b6f2e2 | ||
![]() |
6d2e480ed5 | ||
![]() |
90a1f7e51c | ||
![]() |
63e6506510 | ||
![]() |
220fec6dc9 | ||
![]() |
534b18ee30 | ||
![]() |
e406a50b50 | ||
![]() |
b764e87a00 | ||
![]() |
b7f62c5822 | ||
![]() |
dede819a12 | ||
![]() |
083f0d16ef | ||
![]() |
c7500a504d | ||
![]() |
3348405518 | ||
![]() |
70b2ff3365 | ||
![]() |
a259a12eab | ||
![]() |
979025539e | ||
![]() |
6da311078a | ||
![]() |
7d1991ac78 | ||
![]() |
2c2199fb84 | ||
![]() |
e12da05d4e | ||
![]() |
25d10cf092 | ||
![]() |
1cdaebd92f | ||
![]() |
f5d3f1c042 | ||
![]() |
4073238103 | ||
![]() |
513eaea4f4 | ||
![]() |
b4ac3ddfbd | ||
![]() |
0a269c9e26 | ||
![]() |
1f2371641e | ||
![]() |
8b582f3fcf | ||
![]() |
1afb8f109e | ||
![]() |
5824e0b706 | ||
![]() |
97deed9299 | ||
![]() |
9efcca002d | ||
![]() |
7904483272 | ||
![]() |
8a9594d918 | ||
![]() |
90c09e967a | ||
![]() |
5ba1cc5075 | ||
![]() |
12064a086b | ||
![]() |
32d0e8bf1d | ||
![]() |
79a5947587 | ||
![]() |
c8cda3c817 | ||
![]() |
197cf0f8cc | ||
![]() |
392af26503 | ||
![]() |
41343c9774 | ||
![]() |
4afce7600b | ||
![]() |
e4b4a94a5f | ||
![]() |
3db79607b7 | ||
![]() |
2ada32be02 | ||
![]() |
a4ec8719f9 | ||
![]() |
5e6b28d965 | ||
![]() |
7d8f790708 | ||
![]() |
b6b224be77 | ||
![]() |
3b008b6359 | ||
![]() |
da80bfa3c7 | ||
![]() |
fcd06a9000 | ||
![]() |
762908207f | ||
![]() |
b40b5b95f1 | ||
![]() |
fe176f2752 | ||
![]() |
c7796e9557 | ||
![]() |
679457e36a | ||
![]() |
2d3d4db4dd | ||
![]() |
f127bbc64d | ||
![]() |
bdaf96b114 | ||
![]() |
ad55bae212 | ||
![]() |
ea8958adae | ||
![]() |
e7b664a2ff | ||
![]() |
541d1a5380 | ||
![]() |
ac179f5b45 | ||
![]() |
34f36c6179 | ||
![]() |
56c1920cc1 | ||
![]() |
456880c7cf | ||
![]() |
08222dfbec | ||
![]() |
e8d84e8ba5 | ||
![]() |
c570ce9720 | ||
![]() |
f8b66a78fa | ||
![]() |
e2fc98526b | ||
![]() |
856a393531 | ||
![]() |
8bf2a2f8db | ||
![]() |
3f6bbffcd6 | ||
![]() |
4d5087bd8d | ||
![]() |
f9663143a6 | ||
![]() |
c4aac72e68 | ||
![]() |
f4048bf4ba | ||
![]() |
b384d17fd3 | ||
![]() |
2ae30ac024 | ||
![]() |
9b9b2f0710 | ||
![]() |
5d58dfab3e | ||
![]() |
38ba6058be | ||
![]() |
0f779dd7f8 | ||
![]() |
3ca842187a | ||
![]() |
e36dada843 | ||
![]() |
1b8c567fd7 | ||
![]() |
e1c2cf770a | ||
![]() |
ab6cd578e8 | ||
![]() |
4058a0c8d0 | ||
![]() |
421e5bb169 | ||
![]() |
6faea73c9f | ||
![]() |
3a644621fe | ||
![]() |
abbfea0b6a | ||
![]() |
2f2cdad16b | ||
![]() |
aae3c26a64 | ||
![]() |
0f680bcfd6 | ||
![]() |
f71612d6cf | ||
![]() |
5cc23ab084 | ||
![]() |
9d6c0773c5 | ||
![]() |
44dca3b86d | ||
![]() |
310b81de04 | ||
![]() |
f23258eb8c | ||
![]() |
039bc587cc | ||
![]() |
46e1139946 | ||
![]() |
8938ad8f8d | ||
![]() |
102cb06d28 | ||
![]() |
17d0ae003a | ||
![]() |
7a16961387 | ||
![]() |
d3bdbce0d0 | ||
![]() |
504e4987b7 | ||
![]() |
f00de454d1 | ||
![]() |
ce35416284 | ||
![]() |
7773589e2c | ||
![]() |
5d900f9ced | ||
![]() |
7a344c865f | ||
![]() |
bd0bc2047d | ||
![]() |
2482d78a06 | ||
![]() |
18fc0d0342 | ||
![]() |
024ce5c379 | ||
![]() |
f74fe5718e | ||
![]() |
ef395d4c9f | ||
![]() |
5d42e4f68d | ||
![]() |
acce6f0b2f | ||
![]() |
dadb5f92ee | ||
![]() |
69aff1e204 | ||
![]() |
810fd802b5 | ||
![]() |
cf1b9e5067 | ||
![]() |
83aaf4699c | ||
![]() |
72aa98fe5c | ||
![]() |
86b353e627 | ||
![]() |
79183bb6ea | ||
![]() |
4921686bdf | ||
![]() |
a5bdf096dc | ||
![]() |
bfee69e7ff | ||
![]() |
db53d37493 | ||
![]() |
c294124b8d | ||
![]() |
2afc8607c6 | ||
![]() |
e2ff51f425 | ||
![]() |
25a579f7ed | ||
![]() |
ecd33fd93c | ||
![]() |
960707b804 | ||
![]() |
4cd3b683a7 | ||
![]() |
d0b507561d | ||
![]() |
d8d3149558 | ||
![]() |
41b086cd3c | ||
![]() |
6fc20450b4 | ||
![]() |
c00930f45e | ||
![]() |
77935b7c7a | ||
![]() |
03f7a23540 | ||
![]() |
f1f1623d2f | ||
![]() |
b86bfa0395 | ||
![]() |
75235ec544 | ||
![]() |
7cb2b743fa | ||
![]() |
175693ba4e | ||
![]() |
c7d1417f48 | ||
![]() |
db92abad66 | ||
![]() |
e42e59871e | ||
![]() |
f97b5c48d0 | ||
![]() |
f22510fd74 | ||
![]() |
e789380126 | ||
![]() |
9086051608 | ||
![]() |
a0f0d49f45 | ||
![]() |
bc87e05e2d | ||
![]() |
b0958f589b | ||
![]() |
b37eee56c0 | ||
![]() |
2ad27f7400 | ||
![]() |
95e9d6164d | ||
![]() |
43bc9abb46 | ||
![]() |
ab816ad529 | ||
![]() |
c964ea30e0 | ||
![]() |
73b500db64 | ||
![]() |
633fc1372f | ||
![]() |
dedb36cecf | ||
![]() |
13aa0568a6 | ||
![]() |
a090b291aa | ||
![]() |
30ab056aa4 | ||
![]() |
5a797a6dec | ||
![]() |
d76ffd343e | ||
![]() |
20ecfffb9c | ||
![]() |
d2bfd5ce62 | ||
![]() |
0cdb96f917 | ||
![]() |
fd4ede39ba | ||
![]() |
fa3889b549 | ||
![]() |
d71d5aa855 | ||
![]() |
644af4d009 | ||
![]() |
9f4ae5d932 | ||
![]() |
7a8c9d7c12 | ||
![]() |
89630a5c7f | ||
![]() |
13adee09da | ||
![]() |
c3f473c3e7 | ||
![]() |
0a09eabce3 | ||
![]() |
3e1c22edcd | ||
![]() |
ccb12996f8 | ||
![]() |
d6887758a9 | ||
![]() |
9299d548ba | ||
![]() |
7dda98f139 | ||
![]() |
6b8e90ce67 | ||
![]() |
c20fae289c | ||
![]() |
8db111c2fb | ||
![]() |
5a6d537d43 | ||
![]() |
1ffeace8f9 | ||
![]() |
7bf8ea9d0a | ||
![]() |
85e900bf68 | ||
![]() |
6f9b7a1f60 | ||
![]() |
cad4fa408e | ||
![]() |
dc334844ed | ||
![]() |
4e86cf01b8 | ||
![]() |
2bfd7ff33b | ||
![]() |
b1d5517864 | ||
![]() |
334c4fe90f | ||
![]() |
77f6016701 | ||
![]() |
a2816800e8 | ||
![]() |
e3d32c9dd0 | ||
![]() |
37b2154638 | ||
![]() |
28d3f445f6 | ||
![]() |
45e50ea948 | ||
![]() |
f3eaba4b23 | ||
![]() |
96f7f842cd | ||
![]() |
bc6debc6c9 | ||
![]() |
a9df5ea6a9 | ||
![]() |
c972d039bc | ||
![]() |
d130471a99 | ||
![]() |
52e31648bf | ||
![]() |
40d12fa870 | ||
![]() |
d5728579e0 | ||
![]() |
257ff7707b | ||
![]() |
b8851a7f3e | ||
![]() |
a4680feb92 | ||
![]() |
ca02080cf1 | ||
![]() |
08824b5796 | ||
![]() |
99ded45bb0 | ||
![]() |
bc8cc32445 | ||
![]() |
5cc75c294e | ||
![]() |
035e6752eb | ||
![]() |
c1913799f2 | ||
![]() |
ceb86df0fa | ||
![]() |
24b0eb8ce4 | ||
![]() |
547f829f5b | ||
![]() |
16c9303ae9 | ||
![]() |
6d329bdd1f | ||
![]() |
1c6f7d32cf | ||
![]() |
9a86b06092 | ||
![]() |
0e1eaa18df | ||
![]() |
ad98534195 | ||
![]() |
b261e779e5 | ||
![]() |
f9e97c0577 | ||
![]() |
5276db5d23 | ||
![]() |
6bf954ccb2 | ||
![]() |
26dbef8d4c | ||
![]() |
1d1e85e1d7 | ||
![]() |
755a3d5cf1 | ||
![]() |
e9c5011a6d | ||
![]() |
871ee33229 | ||
![]() |
3b66d58f91 | ||
![]() |
69c10256ef | ||
![]() |
480b92c960 | ||
![]() |
6098b433be | ||
![]() |
d91bf4c2a9 | ||
![]() |
bad9369ce6 | ||
![]() |
3ba9189612 | ||
![]() |
bb71fe0bec | ||
![]() |
65359aabe3 | ||
![]() |
233b646917 | ||
![]() |
3263d84def | ||
![]() |
faee6a7163 | ||
![]() |
00ad91af9a | ||
![]() |
4081fea5f2 | ||
![]() |
97f7da198c | ||
![]() |
f6be8153bb | ||
![]() |
d67e035198 | ||
![]() |
f7a67af71b | ||
![]() |
41554ab14d | ||
![]() |
1b2e052f05 | ||
![]() |
427f0f5e66 | ||
![]() |
86502c5cd8 | ||
![]() |
edf7485578 | ||
![]() |
01c5b64c63 | ||
![]() |
690188b4a3 | ||
![]() |
42e60beb0d | ||
![]() |
0ddc82601a | ||
![]() |
f943366ecd | ||
![]() |
732237d4e1 | ||
![]() |
d8d77d0238 | ||
![]() |
f98fff9ffd | ||
![]() |
9565b5490b | ||
![]() |
8b19ea8e87 | ||
![]() |
2e6d79a60f | ||
![]() |
07f624fd1c | ||
![]() |
3408392aea | ||
![]() |
864f2619a2 | ||
![]() |
bd2c57169b | ||
![]() |
8f1c75c57b | ||
![]() |
1c86fbd52c | ||
![]() |
937a939907 | ||
![]() |
7173b16ef3 | ||
![]() |
d738f6e2f6 | ||
![]() |
b0d32b5674 | ||
![]() |
0f53b7c832 | ||
![]() |
668d4e82ba | ||
![]() |
963bdcc53c | ||
![]() |
d34dada9d8 | ||
![]() |
5ae599b1b2 | ||
![]() |
ebbd308be6 | ||
![]() |
6d43c9e86a | ||
![]() |
339a0f70e3 | ||
![]() |
94df67a7cb | ||
![]() |
1d4f74cda3 | ||
![]() |
07a4505f1e | ||
![]() |
e96c9daad6 | ||
![]() |
08f3496818 | ||
![]() |
326931277e | ||
![]() |
a2ef8bbe70 | ||
![]() |
4bcb51bf5a | ||
![]() |
bda5c3a0c9 | ||
![]() |
e228f60c39 | ||
![]() |
67c032c85a | ||
![]() |
417ffde3e8 | ||
![]() |
f3064f0071 | ||
![]() |
e9d912cc87 | ||
![]() |
2517e5ba60 | ||
![]() |
64b405dd4d | ||
![]() |
ddb050d1fd | ||
![]() |
3f6a8cac80 | ||
![]() |
ad113367e6 | ||
![]() |
f4f08ab0d1 | ||
![]() |
c2a57099d3 | ||
![]() |
adf0c6d891 | ||
![]() |
38a2627227 | ||
![]() |
5a90edc893 | ||
![]() |
88473581c2 | ||
![]() |
88d23eb9dd | ||
![]() |
25c788871f | ||
![]() |
f272801253 | ||
![]() |
2e750dc1e2 | ||
![]() |
3c5fb6d1ad | ||
![]() |
32cd683b8a | ||
![]() |
6c029b39e0 | ||
![]() |
7efad04e42 | ||
![]() |
b6f7781a87 | ||
![]() |
16a147f389 | ||
![]() |
79b71ed753 | ||
![]() |
49fa74cc07 | ||
![]() |
0a2eaec884 | ||
![]() |
4c5d3138c1 | ||
![]() |
5e1cd389b3 | ||
![]() |
7ced08a899 | ||
![]() |
603cf7ba0f | ||
![]() |
c47ba65c3b | ||
![]() |
849ed80e78 | ||
![]() |
b78c48ecec | ||
![]() |
8d2da9c5a6 | ||
![]() |
9664e8258c | ||
![]() |
5f5bf17df0 | ||
![]() |
ca7674cd15 | ||
![]() |
3f5f5bb1ee | ||
![]() |
e7ee9c7054 | ||
![]() |
4f6ecf5c21 | ||
![]() |
87eac4cdee | ||
![]() |
d267196bff | ||
![]() |
f683337cbe | ||
![]() |
1a6226270f | ||
![]() |
64714c64c7 | ||
![]() |
b7c34c483a | ||
![]() |
e5bf842801 | ||
![]() |
d1a56d6acc | ||
![]() |
cac7f8d1ab | ||
![]() |
9d2b37c9f2 | ||
![]() |
e20a02c52c | ||
![]() |
c46d04eaa6 | ||
![]() |
2ec8b97378 | ||
![]() |
b3b9ca9c3f | ||
![]() |
71ed83ef07 | ||
![]() |
47635055d0 | ||
![]() |
0dfca2f33b | ||
![]() |
18de427145 | ||
![]() |
118f28285e | ||
![]() |
6a9cfbfa1c | ||
![]() |
8c61624a9c | ||
![]() |
d277571735 | ||
![]() |
a6f3684846 | ||
![]() |
edef4ba2f5 | ||
![]() |
7cd6619a79 | ||
![]() |
2059e36dd6 | ||
![]() |
4a455e9147 | ||
![]() |
fe0b131480 | ||
![]() |
b1b78c2bb7 | ||
![]() |
99395360c7 | ||
![]() |
bd46e3b8e0 | ||
![]() |
80dd15306e | ||
![]() |
88f0ebf75d | ||
![]() |
8679f10f10 | ||
![]() |
db4c1e45f5 | ||
![]() |
65cf2feb7a | ||
![]() |
97da26eba7 | ||
![]() |
8e7d7c5188 | ||
![]() |
767307ef47 | ||
![]() |
ccc6262026 | ||
![]() |
2cdb542112 | ||
![]() |
4e232e58ce | ||
![]() |
27bb175624 | ||
![]() |
5a5a7dad1e | ||
![]() |
2d1cf421ef | ||
![]() |
8be25f2020 | ||
![]() |
0a8f853a8e | ||
![]() |
a46f5e3d4e | ||
![]() |
5de36f9579 | ||
![]() |
9b5e79f42a | ||
![]() |
a824599a37 | ||
![]() |
884b24da0e | ||
![]() |
76325a384c | ||
![]() |
e2218f1e6e | ||
![]() |
758b686684 | ||
![]() |
3a50d47dd2 | ||
![]() |
b4d4591273 | ||
![]() |
432fdd628c | ||
![]() |
bc23dd37be | ||
![]() |
0319fd23c5 | ||
![]() |
d7e5993501 | ||
![]() |
46a9b90ed0 | ||
![]() |
b0c68e58c5 | ||
![]() |
7063ced7fd | ||
![]() |
7d2444868d | ||
![]() |
0899d42967 | ||
![]() |
d57bcc2701 | ||
![]() |
d9d92c8766 | ||
![]() |
7a16ed5400 | ||
![]() |
07e35ff81a | ||
![]() |
0398944cab | ||
![]() |
a33ff7479a | ||
![]() |
f9182e5453 | ||
![]() |
4f0a965573 | ||
![]() |
2a23487163 | ||
![]() |
6b9ba7367d | ||
![]() |
a17ae5546f | ||
![]() |
47de0e9156 | ||
![]() |
baeda622de | ||
![]() |
48220b67ed | ||
![]() |
9ba232249b | ||
![]() |
b0580e70d2 | ||
![]() |
6c5b274792 | ||
![]() |
3094b08c5f | ||
![]() |
181539baac | ||
![]() |
2289773e36 | ||
![]() |
1ecb138ec5 | ||
![]() |
3d67d9eba3 | ||
![]() |
0fd3c03764 | ||
![]() |
6aca1d0d54 | ||
![]() |
601bbfd88e | ||
![]() |
f600b0522c | ||
![]() |
647a33ea61 | ||
![]() |
64d59fedc8 | ||
![]() |
51d592ba0d | ||
![]() |
eaaf841a87 | ||
![]() |
c6542e383c | ||
![]() |
6e3c2bfd6a | ||
![]() |
be3bfc7aa4 | ||
![]() |
bbe90c1683 | ||
![]() |
2fe1d04eb0 | ||
![]() |
f5022f4e1e | ||
![]() |
fdbb06de19 | ||
![]() |
0cd4980f44 | ||
![]() |
2d0f14d078 | ||
![]() |
9711068f8b | ||
![]() |
fb180c7b9b | ||
![]() |
5947bd6d74 | ||
![]() |
7e584402ea | ||
![]() |
3f113da056 | ||
![]() |
bfef3a96c8 | ||
![]() |
de3a467697 | ||
![]() |
0f895fd3a1 | ||
![]() |
16cc3adcff | ||
![]() |
e2e002b9a9 | ||
![]() |
8274284294 | ||
![]() |
1d7f574b9b | ||
![]() |
f680832f78 | ||
![]() |
77711ea711 | ||
![]() |
f1a6122699 | ||
![]() |
5fec881c39 | ||
![]() |
5dc05129ef | ||
![]() |
f461ad6d31 | ||
![]() |
57b5db4f43 | ||
![]() |
d015fe5160 | ||
![]() |
f7e3f4a828 | ||
![]() |
f3b8d66f4f | ||
![]() |
8ae03dd1ff | ||
![]() |
0e6f6ddbda | ||
![]() |
882c503fa9 | ||
![]() |
22eb6c6a8d | ||
![]() |
8e9ff46bab | ||
![]() |
023d8ad893 | ||
![]() |
6b730b7c40 | ||
![]() |
90cea56a1e | ||
![]() |
5e43d9b6b7 | ||
![]() |
e4cac86690 | ||
![]() |
a249289211 | ||
![]() |
8ecfd9780f | ||
![]() |
913cd2b3d4 | ||
![]() |
c02b7a33fe | ||
![]() |
7a0b2060d4 | ||
![]() |
afe9056725 | ||
![]() |
49be2ad013 | ||
![]() |
230ec51de5 | ||
![]() |
b37ea482d3 | ||
![]() |
bf69c8ce46 | ||
![]() |
d2741af24b | ||
![]() |
f04f58ac88 | ||
![]() |
8757dbb664 | ||
![]() |
ffc7f9706d | ||
![]() |
4487c3dc1a | ||
![]() |
97f5d8e7e2 | ||
![]() |
1cc6e09953 | ||
![]() |
3752530f96 | ||
![]() |
21be35bc46 | ||
![]() |
bb8ec4b2ef | ||
![]() |
278ea184cc | ||
![]() |
5ab419534c | ||
![]() |
07b65f37db | ||
![]() |
8ad5280501 | ||
![]() |
69df6179bb | ||
![]() |
b939ae6ab4 | ||
![]() |
101a364a83 | ||
![]() |
412b7595d2 | ||
![]() |
a7ab652dd3 | ||
![]() |
d41a4cf78b | ||
![]() |
785ed6f9db | ||
![]() |
6885abd234 | ||
![]() |
3497cb892e | ||
![]() |
a82561355c | ||
![]() |
f054cdc9ef |
@@ -8,7 +8,8 @@
|
||||
},
|
||||
"settings": {
|
||||
"react": {
|
||||
"pragma": "h"
|
||||
"pragma": "h",
|
||||
"version": "15.0"
|
||||
},
|
||||
"import/resolver": {
|
||||
"webpack": {
|
||||
@@ -18,6 +19,7 @@
|
||||
},
|
||||
"globals": {
|
||||
"__DEV__": false,
|
||||
"__DEMO__": false,
|
||||
"__BUILD__": false,
|
||||
"__VERSION__": false,
|
||||
"__STATIC_PATH__": false,
|
||||
|
2
.gitattributes
vendored
@@ -9,3 +9,5 @@
|
||||
*.png binary
|
||||
*.zip binary
|
||||
*.mp3 binary
|
||||
|
||||
demo/public/api/camera_proxy_stream/* binary
|
||||
|
4
.github/ISSUE_TEMPLATE.md
vendored
@@ -13,6 +13,10 @@
|
||||
|
||||
**Last working Home Assistant release (if known):**
|
||||
|
||||
**UI (States or Lovelace UI?):**
|
||||
<!--
|
||||
- Frontend -> Developer tools -> Info
|
||||
-->
|
||||
|
||||
**Browser and Operating System:**
|
||||
<!--
|
||||
|
2
.gitignore
vendored
@@ -4,8 +4,8 @@ node_modules/*
|
||||
npm-debug.log
|
||||
.DS_Store
|
||||
hass_frontend/*
|
||||
hass_frontend_es5/*
|
||||
.reify-cache
|
||||
demo/hademo-icons.html
|
||||
|
||||
# Python stuff
|
||||
*.py[cod]
|
||||
|
14
.vscode/extensions.json
vendored
@@ -1,7 +1,9 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"eg2.tslint",
|
||||
"esbenp.prettier-vscode"
|
||||
]
|
||||
}
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"ms-vscode.vscode-typescript-tslint-plugin",
|
||||
"esbenp.prettier-vscode",
|
||||
"bierner.lit-html",
|
||||
"runem.lit-plugin"
|
||||
]
|
||||
}
|
||||
|
57
azure-pipelines-release.yml
Normal file
@@ -0,0 +1,57 @@
|
||||
# https://dev.azure.com/home-assistant
|
||||
|
||||
trigger:
|
||||
batch: true
|
||||
tags:
|
||||
include:
|
||||
- "*"
|
||||
pr: none
|
||||
variables:
|
||||
- name: versionBuilder
|
||||
value: "5.2"
|
||||
- group: github
|
||||
- group: twine
|
||||
|
||||
stages:
|
||||
- stage: "Validate"
|
||||
jobs:
|
||||
- job: "VersionValidate"
|
||||
pool:
|
||||
vmImage: "ubuntu-latest"
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
displayName: "Use Python 3.7"
|
||||
inputs:
|
||||
versionSpec: "3.7"
|
||||
- script: |
|
||||
setup_version="$(python setup.py -V)"
|
||||
branch_version="$(Build.SourceBranchName)"
|
||||
|
||||
if [ "${setup_version}" != "${branch_version}" ]; then
|
||||
echo "Version of tag ${branch_version} don't match with ${setup_version}!"
|
||||
exit 1
|
||||
fi
|
||||
displayName: "Check version of branch/tag"
|
||||
|
||||
- stage: "Build"
|
||||
jobs:
|
||||
- job: "ReleasePython"
|
||||
pool:
|
||||
vmImage: "ubuntu-latest"
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
displayName: "Use Python 3.7"
|
||||
inputs:
|
||||
versionSpec: "3.7"
|
||||
- task: NodeTool@0
|
||||
displayName: "Use Node 12.1"
|
||||
inputs:
|
||||
versionSpec: "12.1"
|
||||
- script: pip install twine wheel
|
||||
displayName: "Install tools"
|
||||
- script: |
|
||||
export TWINE_USERNAME="$(twineUser)"
|
||||
export TWINE_PASSWORD="$(twinePassword)"
|
||||
|
||||
script/release
|
||||
displayName: "Build and release package"
|
7
build-scripts/.eslintrc.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../.eslintrc.json",
|
||||
"rules": {
|
||||
"import/no-extraneous-dependencies": 0,
|
||||
"global-require": 0
|
||||
}
|
||||
}
|
@@ -3,7 +3,7 @@ module.exports.babelLoaderConfig = ({ latestBuild }) => {
|
||||
throw Error("latestBuild not defined for babel loader config");
|
||||
}
|
||||
return {
|
||||
test: /\.m?js$|\.ts$/,
|
||||
test: /\.m?js$|\.tsx?$/,
|
||||
use: {
|
||||
loader: "babel-loader",
|
||||
options: {
|
||||
@@ -12,7 +12,12 @@ module.exports.babelLoaderConfig = ({ latestBuild }) => {
|
||||
require("@babel/preset-env").default,
|
||||
{ modules: false },
|
||||
],
|
||||
require("@babel/preset-typescript").default,
|
||||
[
|
||||
require("@babel/preset-typescript").default,
|
||||
{
|
||||
jsxPragma: "h",
|
||||
},
|
||||
],
|
||||
].filter(Boolean),
|
||||
plugins: [
|
||||
// Part of ES2018. Converts {...a, b: 2} to Object.assign({}, a, {b: 2})
|
||||
@@ -28,6 +33,14 @@ module.exports.babelLoaderConfig = ({ latestBuild }) => {
|
||||
pragma: "h",
|
||||
},
|
||||
],
|
||||
[
|
||||
require("@babel/plugin-proposal-decorators").default,
|
||||
{ decoratorsBeforeExport: true },
|
||||
],
|
||||
[
|
||||
require("@babel/plugin-proposal-class-properties").default,
|
||||
{ loose: true },
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
51
build-scripts/gulp/app.js
Normal file
@@ -0,0 +1,51 @@
|
||||
// Run HA develop mode
|
||||
const gulp = require("gulp");
|
||||
|
||||
require("./clean.js");
|
||||
require("./translations.js");
|
||||
require("./gen-icons.js");
|
||||
require("./gather-static.js");
|
||||
require("./webpack.js");
|
||||
require("./service-worker.js");
|
||||
require("./entry-html.js");
|
||||
|
||||
gulp.task(
|
||||
"develop-app",
|
||||
gulp.series(
|
||||
async function setEnv() {
|
||||
process.env.NODE_ENV = "development";
|
||||
},
|
||||
"clean",
|
||||
gulp.parallel(
|
||||
"gen-service-worker-dev",
|
||||
"gen-icons",
|
||||
"gen-pages-dev",
|
||||
"gen-index-app-dev",
|
||||
gulp.series("create-test-translation", "build-translations")
|
||||
),
|
||||
"copy-static",
|
||||
"webpack-watch-app"
|
||||
)
|
||||
);
|
||||
|
||||
gulp.task(
|
||||
"build-app",
|
||||
gulp.series(
|
||||
async function setEnv() {
|
||||
process.env.NODE_ENV = "production";
|
||||
},
|
||||
"clean",
|
||||
gulp.parallel("gen-icons", "build-translations"),
|
||||
"copy-static",
|
||||
gulp.parallel(
|
||||
"webpack-prod-app",
|
||||
// Do not compress static files in CI, it's SLOW.
|
||||
...(process.env.CI === "true" ? [] : ["compress-static"])
|
||||
),
|
||||
gulp.parallel(
|
||||
"gen-pages-prod",
|
||||
"gen-index-app-prod",
|
||||
"gen-service-worker-prod"
|
||||
)
|
||||
)
|
||||
);
|
17
build-scripts/gulp/clean.js
Normal file
@@ -0,0 +1,17 @@
|
||||
const del = require("del");
|
||||
const gulp = require("gulp");
|
||||
const config = require("../paths");
|
||||
require("./translations");
|
||||
|
||||
gulp.task(
|
||||
"clean",
|
||||
gulp.parallel("clean-translations", function cleanOutputAndBuildDir() {
|
||||
return del([config.root, config.build_dir]);
|
||||
})
|
||||
);
|
||||
gulp.task(
|
||||
"clean-demo",
|
||||
gulp.parallel("clean-translations", function cleanOutputAndBuildDir() {
|
||||
return del([config.demo_root, config.build_dir]);
|
||||
})
|
||||
);
|
42
build-scripts/gulp/demo.js
Normal file
@@ -0,0 +1,42 @@
|
||||
// Run demo develop mode
|
||||
const gulp = require("gulp");
|
||||
|
||||
require("./clean.js");
|
||||
require("./translations.js");
|
||||
require("./gen-icons.js");
|
||||
require("./gather-static.js");
|
||||
require("./webpack.js");
|
||||
require("./service-worker.js");
|
||||
require("./entry-html.js");
|
||||
|
||||
gulp.task(
|
||||
"develop-demo",
|
||||
gulp.series(
|
||||
async function setEnv() {
|
||||
process.env.NODE_ENV = "development";
|
||||
},
|
||||
"clean-demo",
|
||||
gulp.parallel(
|
||||
"gen-icons",
|
||||
"gen-icons-demo",
|
||||
"gen-index-demo-dev",
|
||||
"build-translations"
|
||||
),
|
||||
"copy-static-demo",
|
||||
"webpack-dev-server-demo"
|
||||
)
|
||||
);
|
||||
|
||||
gulp.task(
|
||||
"build-demo",
|
||||
gulp.series(
|
||||
async function setEnv() {
|
||||
process.env.NODE_ENV = "production";
|
||||
},
|
||||
"clean-demo",
|
||||
gulp.parallel("gen-icons", "gen-icons-demo", "build-translations"),
|
||||
"copy-static-demo",
|
||||
"webpack-prod-demo",
|
||||
"gen-index-demo-prod"
|
||||
)
|
||||
);
|
163
build-scripts/gulp/entry-html.js
Normal file
@@ -0,0 +1,163 @@
|
||||
// Tasks to generate entry HTML
|
||||
/* eslint-disable import/no-dynamic-require */
|
||||
/* eslint-disable global-require */
|
||||
const gulp = require("gulp");
|
||||
const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
const template = require("lodash.template");
|
||||
const minify = require("html-minifier").minify;
|
||||
const config = require("../paths.js");
|
||||
|
||||
const templatePath = (tpl) =>
|
||||
path.resolve(config.polymer_dir, "src/html/", `${tpl}.html.template`);
|
||||
|
||||
const demoTemplatePath = (tpl) =>
|
||||
path.resolve(config.demo_dir, "src/html/", `${tpl}.html.template`);
|
||||
|
||||
const readFile = (pth) => fs.readFileSync(pth).toString();
|
||||
|
||||
const renderTemplate = (pth, data = {}, pathFunc = templatePath) => {
|
||||
const compiled = template(readFile(pathFunc(pth)));
|
||||
return compiled({ ...data, renderTemplate });
|
||||
};
|
||||
|
||||
const renderDemoTemplate = (pth, data = {}) =>
|
||||
renderTemplate(pth, data, demoTemplatePath);
|
||||
|
||||
const minifyHtml = (content) =>
|
||||
minify(content, {
|
||||
collapseWhitespace: true,
|
||||
minifyJS: true,
|
||||
minifyCSS: true,
|
||||
removeComments: true,
|
||||
});
|
||||
|
||||
const PAGES = ["onboarding", "authorize"];
|
||||
|
||||
gulp.task("gen-pages-dev", (done) => {
|
||||
for (const page of PAGES) {
|
||||
const content = renderTemplate(page, {
|
||||
latestPageJS: `/frontend_latest/${page}.js`,
|
||||
latestHassIconsJS: "/frontend_latest/hass-icons.js",
|
||||
|
||||
es5Compatibility: "/frontend_es5/compatibility.js",
|
||||
es5PageJS: `/frontend_es5/${page}.js`,
|
||||
es5HassIconsJS: "/frontend_es5/hass-icons.js",
|
||||
});
|
||||
|
||||
fs.outputFileSync(path.resolve(config.root, `${page}.html`), content);
|
||||
}
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task("gen-pages-prod", (done) => {
|
||||
const latestManifest = require(path.resolve(config.output, "manifest.json"));
|
||||
const es5Manifest = require(path.resolve(config.output_es5, "manifest.json"));
|
||||
|
||||
for (const page of PAGES) {
|
||||
const content = renderTemplate(page, {
|
||||
latestPageJS: latestManifest[`${page}.js`],
|
||||
latestHassIconsJS: latestManifest["hass-icons.js"],
|
||||
|
||||
es5Compatibility: es5Manifest["compatibility.js"],
|
||||
es5PageJS: es5Manifest[`${page}.js`],
|
||||
es5HassIconsJS: es5Manifest["hass-icons.js"],
|
||||
});
|
||||
|
||||
fs.outputFileSync(
|
||||
path.resolve(config.root, `${page}.html`),
|
||||
minifyHtml(content)
|
||||
);
|
||||
}
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task("gen-index-app-dev", (done) => {
|
||||
// In dev mode we don't mangle names, so we hardcode urls. That way we can
|
||||
// run webpack as last in watch mode, which blocks output.
|
||||
const content = renderTemplate("index", {
|
||||
latestAppJS: "/frontend_latest/app.js",
|
||||
latestCoreJS: "/frontend_latest/core.js",
|
||||
latestCustomPanelJS: "/frontend_latest/custom-panel.js",
|
||||
latestHassIconsJS: "/frontend_latest/hass-icons.js",
|
||||
|
||||
es5Compatibility: "/frontend_es5/compatibility.js",
|
||||
es5AppJS: "/frontend_es5/app.js",
|
||||
es5CoreJS: "/frontend_es5/core.js",
|
||||
es5CustomPanelJS: "/frontend_es5/custom-panel.js",
|
||||
es5HassIconsJS: "/frontend_es5/hass-icons.js",
|
||||
}).replace(/#THEMEC/g, "{{ theme_color }}");
|
||||
|
||||
fs.outputFileSync(path.resolve(config.root, "index.html"), content);
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task("gen-index-app-prod", (done) => {
|
||||
const latestManifest = require(path.resolve(config.output, "manifest.json"));
|
||||
const es5Manifest = require(path.resolve(config.output_es5, "manifest.json"));
|
||||
const content = renderTemplate("index", {
|
||||
latestAppJS: latestManifest["app.js"],
|
||||
latestCoreJS: latestManifest["core.js"],
|
||||
latestCustomPanelJS: latestManifest["custom-panel.js"],
|
||||
latestHassIconsJS: latestManifest["hass-icons.js"],
|
||||
|
||||
es5Compatibility: es5Manifest["compatibility.js"],
|
||||
es5AppJS: es5Manifest["app.js"],
|
||||
es5CoreJS: es5Manifest["core.js"],
|
||||
es5CustomPanelJS: es5Manifest["custom-panel.js"],
|
||||
es5HassIconsJS: es5Manifest["hass-icons.js"],
|
||||
});
|
||||
const minified = minifyHtml(content).replace(/#THEMEC/g, "{{ theme_color }}");
|
||||
|
||||
fs.outputFileSync(path.resolve(config.root, "index.html"), minified);
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task("gen-index-demo-dev", (done) => {
|
||||
// In dev mode we don't mangle names, so we hardcode urls. That way we can
|
||||
// run webpack as last in watch mode, which blocks output.
|
||||
const content = renderDemoTemplate("index", {
|
||||
latestDemoJS: "/frontend_latest/main.js",
|
||||
|
||||
es5Compatibility: "/frontend_es5/compatibility.js",
|
||||
es5DemoJS: "/frontend_es5/main.js",
|
||||
});
|
||||
|
||||
fs.outputFileSync(path.resolve(config.demo_root, "index.html"), content);
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task("gen-index-demo-dev", (done) => {
|
||||
// In dev mode we don't mangle names, so we hardcode urls. That way we can
|
||||
// run webpack as last in watch mode, which blocks output.
|
||||
const content = renderDemoTemplate("index", {
|
||||
latestDemoJS: "/frontend_latest/main.js",
|
||||
|
||||
es5Compatibility: "/frontend_es5/compatibility.js",
|
||||
es5DemoJS: "/frontend_es5/main.js",
|
||||
});
|
||||
|
||||
fs.outputFileSync(path.resolve(config.demo_root, "index.html"), content);
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task("gen-index-demo-prod", (done) => {
|
||||
const latestManifest = require(path.resolve(
|
||||
config.demo_output,
|
||||
"manifest.json"
|
||||
));
|
||||
const es5Manifest = require(path.resolve(
|
||||
config.demo_output_es5,
|
||||
"manifest.json"
|
||||
));
|
||||
const content = renderDemoTemplate("index", {
|
||||
latestDemoJS: latestManifest["main.js"],
|
||||
|
||||
es5Compatibility: es5Manifest["compatibility.js"],
|
||||
es5DemoJS: es5Manifest["main.js"],
|
||||
});
|
||||
const minified = minifyHtml(content).replace(/#THEMEC/g, "{{ theme_color }}");
|
||||
|
||||
fs.outputFileSync(path.resolve(config.demo_root, "index.html"), minified);
|
||||
done();
|
||||
});
|
116
build-scripts/gulp/gather-static.js
Normal file
@@ -0,0 +1,116 @@
|
||||
// Gulp task to gather all static files.
|
||||
|
||||
const gulp = require("gulp");
|
||||
const path = require("path");
|
||||
const cpx = require("cpx");
|
||||
const fs = require("fs-extra");
|
||||
const zopfli = require("gulp-zopfli-green");
|
||||
const merge = require("merge-stream");
|
||||
const paths = require("../paths");
|
||||
|
||||
const npmPath = (...parts) =>
|
||||
path.resolve(paths.polymer_dir, "node_modules", ...parts);
|
||||
const polyPath = (...parts) => path.resolve(paths.polymer_dir, ...parts);
|
||||
|
||||
const copyFileDir = (fromFile, toDir) =>
|
||||
fs.copySync(fromFile, path.join(toDir, path.basename(fromFile)));
|
||||
|
||||
const genStaticPath = (staticDir) => (...parts) =>
|
||||
path.resolve(staticDir, ...parts);
|
||||
|
||||
function copyTranslations(staticDir) {
|
||||
const staticPath = genStaticPath(staticDir);
|
||||
|
||||
// Translation output
|
||||
fs.copySync(
|
||||
polyPath("build-translations/output"),
|
||||
staticPath("translations")
|
||||
);
|
||||
}
|
||||
|
||||
function copyPolyfills(staticDir) {
|
||||
const staticPath = genStaticPath(staticDir);
|
||||
|
||||
// Web Component polyfills and adapters
|
||||
copyFileDir(
|
||||
npmPath("@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"),
|
||||
staticPath("polyfills/")
|
||||
);
|
||||
copyFileDir(
|
||||
npmPath("@webcomponents/webcomponentsjs/webcomponents-bundle.js"),
|
||||
staticPath("polyfills/")
|
||||
);
|
||||
copyFileDir(
|
||||
npmPath("@webcomponents/webcomponentsjs/webcomponents-bundle.js.map"),
|
||||
staticPath("polyfills/")
|
||||
);
|
||||
}
|
||||
|
||||
function copyFonts(staticDir) {
|
||||
const staticPath = genStaticPath(staticDir);
|
||||
// Local fonts
|
||||
cpx.copySync(
|
||||
npmPath("roboto-fontface/fonts/roboto/*.woff2"),
|
||||
staticPath("fonts/roboto")
|
||||
);
|
||||
}
|
||||
|
||||
function copyMapPanel(staticDir) {
|
||||
const staticPath = genStaticPath(staticDir);
|
||||
copyFileDir(
|
||||
npmPath("leaflet/dist/leaflet.css"),
|
||||
staticPath("images/leaflet/")
|
||||
);
|
||||
fs.copySync(
|
||||
npmPath("leaflet/dist/images"),
|
||||
staticPath("images/leaflet/images/")
|
||||
);
|
||||
}
|
||||
|
||||
function compressStatic(staticDir) {
|
||||
const staticPath = genStaticPath(staticDir);
|
||||
const polyfills = gulp
|
||||
.src(staticPath("polyfills/*.js"))
|
||||
.pipe(zopfli())
|
||||
.pipe(gulp.dest(staticPath("polyfills")));
|
||||
const translations = gulp
|
||||
.src(staticPath("translations/*.json"))
|
||||
.pipe(zopfli())
|
||||
.pipe(gulp.dest(staticPath("translations")));
|
||||
|
||||
return merge(polyfills, translations);
|
||||
}
|
||||
|
||||
gulp.task("copy-static", (done) => {
|
||||
const staticDir = paths.static;
|
||||
const staticPath = genStaticPath(paths.static);
|
||||
// Basic static files
|
||||
fs.copySync(polyPath("public"), paths.root);
|
||||
|
||||
copyPolyfills(staticDir);
|
||||
copyFonts(staticDir);
|
||||
copyTranslations(staticDir);
|
||||
|
||||
// Panel assets
|
||||
copyFileDir(
|
||||
npmPath("react-big-calendar/lib/css/react-big-calendar.css"),
|
||||
staticPath("panels/calendar/")
|
||||
);
|
||||
copyMapPanel(staticDir);
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task("compress-static", () => compressStatic(paths.static));
|
||||
|
||||
gulp.task("copy-static-demo", (done) => {
|
||||
// Copy app static files
|
||||
fs.copySync(polyPath("public"), paths.demo_root);
|
||||
// Copy demo static files
|
||||
fs.copySync(path.resolve(paths.demo_dir, "public"), paths.demo_root);
|
||||
|
||||
copyPolyfills(paths.demo_static);
|
||||
copyMapPanel(paths.demo_static);
|
||||
copyFonts(paths.demo_static);
|
||||
copyTranslations(paths.demo_static);
|
||||
done();
|
||||
});
|
@@ -1,7 +1,7 @@
|
||||
const gulp = require("gulp");
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const config = require("../config");
|
||||
const paths = require("../paths");
|
||||
|
||||
const ICON_PACKAGE_PATH = path.resolve(
|
||||
__dirname,
|
||||
@@ -20,8 +20,9 @@ const BUILT_IN_PANEL_ICONS = [
|
||||
"poll-box", // History panel
|
||||
"format-list-bulleted-type", // Logbook
|
||||
"mailbox", // Mailbox
|
||||
"account-location", // Map
|
||||
"tooltip-account", // Map
|
||||
"cart", // Shopping List
|
||||
"hammer", // developer-tools
|
||||
];
|
||||
|
||||
// Given an icon name, load the SVG file
|
||||
@@ -38,13 +39,13 @@ function loadIcon(name) {
|
||||
function transformXMLtoPolymer(name, xml) {
|
||||
const start = xml.indexOf("><path") + 1;
|
||||
const end = xml.length - start - 6;
|
||||
const path = xml.substr(start, end);
|
||||
return `<g id="${name}">${path}</g>`;
|
||||
const pth = xml.substr(start, end);
|
||||
return `<g id="${name}">${pth}</g>`;
|
||||
}
|
||||
|
||||
// Given an iconset name and icon names, generate a polymer iconset
|
||||
function generateIconset(name, iconNames) {
|
||||
const iconDefs = iconNames
|
||||
function generateIconset(iconsetName, iconNames) {
|
||||
const iconDefs = Array.from(iconNames)
|
||||
.map((name) => {
|
||||
const iconDef = loadIcon(name);
|
||||
if (!iconDef) {
|
||||
@@ -53,7 +54,7 @@ function generateIconset(name, iconNames) {
|
||||
return transformXMLtoPolymer(name, iconDef);
|
||||
})
|
||||
.join("");
|
||||
return `<ha-iconset-svg name="${name}" size="24"><svg><defs>${iconDefs}</defs></svg></ha-iconset-svg>`;
|
||||
return `<ha-iconset-svg name="${iconsetName}" size="24"><svg><defs>${iconDefs}</defs></svg></ha-iconset-svg>`;
|
||||
}
|
||||
|
||||
// Generate the full MDI iconset
|
||||
@@ -62,7 +63,9 @@ function genMDIIcons() {
|
||||
fs.readFileSync(path.resolve(ICON_PACKAGE_PATH, META_PATH), "UTF-8")
|
||||
);
|
||||
const iconNames = meta.map((iconInfo) => iconInfo.name);
|
||||
fs.existsSync(OUTPUT_DIR) || fs.mkdirSync(OUTPUT_DIR);
|
||||
if (!fs.existsSync(OUTPUT_DIR)) {
|
||||
fs.mkdirSync(OUTPUT_DIR);
|
||||
}
|
||||
fs.writeFileSync(MDI_OUTPUT_PATH, generateIconset("mdi", iconNames));
|
||||
}
|
||||
|
||||
@@ -81,7 +84,7 @@ function mapFiles(startPath, filter, mapFunc) {
|
||||
}
|
||||
|
||||
// Find all icons used by the project.
|
||||
function findIcons(path, iconsetName) {
|
||||
function findIcons(searchPath, iconsetName) {
|
||||
const iconRegex = new RegExp(`${iconsetName}:[\\w-]+`, "g");
|
||||
const icons = new Set();
|
||||
function processFile(filename) {
|
||||
@@ -93,20 +96,38 @@ function findIcons(path, iconsetName) {
|
||||
icons.add(match[0].substr(iconsetName.length + 1));
|
||||
}
|
||||
}
|
||||
mapFiles(path, ".js", processFile);
|
||||
mapFiles(path, ".ts", processFile);
|
||||
return Array.from(icons);
|
||||
mapFiles(searchPath, ".js", processFile);
|
||||
mapFiles(searchPath, ".ts", processFile);
|
||||
return icons;
|
||||
}
|
||||
|
||||
function genHassIcons() {
|
||||
const iconNames = findIcons("./src", "hass").concat(BUILT_IN_PANEL_ICONS);
|
||||
fs.existsSync(OUTPUT_DIR) || fs.mkdirSync(OUTPUT_DIR);
|
||||
const iconNames = findIcons("./src", "hass");
|
||||
BUILT_IN_PANEL_ICONS.forEach((name) => iconNames.add(name));
|
||||
if (!fs.existsSync(OUTPUT_DIR)) {
|
||||
fs.mkdirSync(OUTPUT_DIR);
|
||||
}
|
||||
fs.writeFileSync(HASS_OUTPUT_PATH, generateIconset("hass", iconNames));
|
||||
}
|
||||
|
||||
gulp.task("gen-icons-mdi", () => genMDIIcons());
|
||||
gulp.task("gen-icons-hass", () => genHassIcons());
|
||||
gulp.task("gen-icons", ["gen-icons-hass", "gen-icons-mdi"], () => {});
|
||||
gulp.task("gen-icons-mdi", (done) => {
|
||||
genMDIIcons();
|
||||
done();
|
||||
});
|
||||
gulp.task("gen-icons-hass", (done) => {
|
||||
genHassIcons();
|
||||
done();
|
||||
});
|
||||
gulp.task("gen-icons", gulp.series("gen-icons-hass", "gen-icons-mdi"));
|
||||
|
||||
gulp.task("gen-icons-demo", (done) => {
|
||||
const iconNames = findIcons(path.resolve(paths.demo_dir, "./src"), "hademo");
|
||||
fs.writeFileSync(
|
||||
path.resolve(paths.demo_dir, "hademo-icons.html"),
|
||||
generateIconset("hademo", iconNames)
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
findIcons,
|
33
build-scripts/gulp/service-worker.js
Normal file
@@ -0,0 +1,33 @@
|
||||
// Generate service worker.
|
||||
// Based on manifest, create a file with the content as service_worker.js
|
||||
/* eslint-disable import/no-dynamic-require */
|
||||
/* eslint-disable global-require */
|
||||
const gulp = require("gulp");
|
||||
const path = require("path");
|
||||
const fs = require("fs-extra");
|
||||
const config = require("../paths.js");
|
||||
|
||||
const swPath = path.resolve(config.root, "service_worker.js");
|
||||
|
||||
const writeSW = (content) => fs.outputFileSync(swPath, content.trim() + "\n");
|
||||
|
||||
gulp.task("gen-service-worker-dev", (done) => {
|
||||
writeSW(
|
||||
`
|
||||
console.debug('Service worker disabled in development');
|
||||
|
||||
self.addEventListener('install', (event) => {
|
||||
self.skipWaiting();
|
||||
});
|
||||
`
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task("gen-service-worker-prod", (done) => {
|
||||
fs.copySync(
|
||||
path.resolve(config.output, "service_worker.js"),
|
||||
path.resolve(config.root, "service_worker.js")
|
||||
);
|
||||
done();
|
||||
});
|
404
build-scripts/gulp/translations.js
Executable file
@@ -0,0 +1,404 @@
|
||||
const del = require("del");
|
||||
const path = require("path");
|
||||
const gulp = require("gulp");
|
||||
const fs = require("fs");
|
||||
const foreach = require("gulp-foreach");
|
||||
const hash = require("gulp-hash");
|
||||
const hashFilename = require("gulp-hash-filename");
|
||||
const merge = require("gulp-merge-json");
|
||||
const minify = require("gulp-jsonminify");
|
||||
const rename = require("gulp-rename");
|
||||
const transform = require("gulp-json-transform");
|
||||
|
||||
const inDir = "translations";
|
||||
const workDir = "build-translations";
|
||||
const fullDir = workDir + "/full";
|
||||
const coreDir = workDir + "/core";
|
||||
const outDir = workDir + "/output";
|
||||
|
||||
String.prototype.rsplit = function(sep, maxsplit) {
|
||||
var split = this.split(sep);
|
||||
return maxsplit
|
||||
? [split.slice(0, -maxsplit).join(sep)].concat(split.slice(-maxsplit))
|
||||
: split;
|
||||
};
|
||||
|
||||
// Panel translations which should be split from the core translations. These
|
||||
// should mirror the fragment definitions in polymer.json, so that we load
|
||||
// additional resources at equivalent points.
|
||||
const TRANSLATION_FRAGMENTS = [
|
||||
"config",
|
||||
"history",
|
||||
"logbook",
|
||||
"mailbox",
|
||||
"profile",
|
||||
"shopping-list",
|
||||
"page-authorize",
|
||||
"page-demo",
|
||||
"page-onboarding",
|
||||
"developer-tools",
|
||||
];
|
||||
|
||||
const tasks = [];
|
||||
|
||||
function recursiveFlatten(prefix, data) {
|
||||
let output = {};
|
||||
Object.keys(data).forEach(function(key) {
|
||||
if (typeof data[key] === "object") {
|
||||
output = Object.assign(
|
||||
{},
|
||||
output,
|
||||
recursiveFlatten(prefix + key + ".", data[key])
|
||||
);
|
||||
} else {
|
||||
output[prefix + key] = data[key];
|
||||
}
|
||||
});
|
||||
return output;
|
||||
}
|
||||
|
||||
function flatten(data) {
|
||||
return recursiveFlatten("", data);
|
||||
}
|
||||
|
||||
function emptyFilter(data) {
|
||||
const newData = {};
|
||||
Object.keys(data).forEach((key) => {
|
||||
if (data[key]) {
|
||||
if (typeof data[key] === "object") {
|
||||
newData[key] = emptyFilter(data[key]);
|
||||
} else {
|
||||
newData[key] = data[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
return newData;
|
||||
}
|
||||
|
||||
function recursiveEmpty(data) {
|
||||
const newData = {};
|
||||
Object.keys(data).forEach((key) => {
|
||||
if (data[key]) {
|
||||
if (typeof data[key] === "object") {
|
||||
newData[key] = recursiveEmpty(data[key]);
|
||||
} else {
|
||||
newData[key] = "TRANSLATED";
|
||||
}
|
||||
}
|
||||
});
|
||||
return newData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace Lokalise key placeholders with their actual values.
|
||||
*
|
||||
* We duplicate the behavior of Lokalise here so that placeholders can
|
||||
* be included in src/translations/en.json, but still be usable while
|
||||
* developing locally.
|
||||
*
|
||||
* @link https://docs.lokalise.co/article/KO5SZWLLsy-key-referencing
|
||||
*/
|
||||
const re_key_reference = /\[%key:([^%]+)%\]/;
|
||||
function lokalise_transform(data, original) {
|
||||
const output = {};
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
if (value instanceof Object) {
|
||||
output[key] = lokalise_transform(value, original);
|
||||
} else {
|
||||
output[key] = value.replace(re_key_reference, (match, key) => {
|
||||
const replace = key.split("::").reduce((tr, k) => tr[k], original);
|
||||
if (typeof replace !== "string") {
|
||||
throw Error(
|
||||
`Invalid key placeholder ${key} in src/translations/en.json`
|
||||
);
|
||||
}
|
||||
return replace;
|
||||
});
|
||||
}
|
||||
});
|
||||
return output;
|
||||
}
|
||||
|
||||
let taskName = "clean-translations";
|
||||
gulp.task(taskName, function() {
|
||||
return del([`${outDir}/**/*.json`]);
|
||||
});
|
||||
tasks.push(taskName);
|
||||
|
||||
gulp.task("ensure-translations-build-dir", (done) => {
|
||||
if (!fs.existsSync(workDir)) {
|
||||
fs.mkdirSync(workDir);
|
||||
}
|
||||
done();
|
||||
});
|
||||
|
||||
taskName = "create-test-metadata";
|
||||
gulp.task(
|
||||
taskName,
|
||||
gulp.series("ensure-translations-build-dir", function writeTestMetaData(cb) {
|
||||
fs.writeFile(
|
||||
workDir + "/testMetadata.json",
|
||||
JSON.stringify({
|
||||
test: {
|
||||
nativeName: "Test",
|
||||
},
|
||||
}),
|
||||
cb
|
||||
);
|
||||
})
|
||||
);
|
||||
tasks.push(taskName);
|
||||
|
||||
taskName = "create-test-translation";
|
||||
gulp.task(
|
||||
taskName,
|
||||
gulp.series("create-test-metadata", function() {
|
||||
return gulp
|
||||
.src("src/translations/en.json")
|
||||
.pipe(
|
||||
transform(function(data, file) {
|
||||
return recursiveEmpty(data);
|
||||
})
|
||||
)
|
||||
.pipe(rename("test.json"))
|
||||
.pipe(gulp.dest(workDir));
|
||||
})
|
||||
);
|
||||
tasks.push(taskName);
|
||||
|
||||
/**
|
||||
* This task will build a master translation file, to be used as the base for
|
||||
* all languages. This starts with src/translations/en.json, and replaces all
|
||||
* Lokalise key placeholders with their target values. Under normal circumstances,
|
||||
* this will be the same as translations/en.json However, we build it here to
|
||||
* facilitate both making changes in development mode, and to ensure that the
|
||||
* project is buildable immediately after merging new translation keys, since
|
||||
* the Lokalise update to translations/en.json will not happen immediately.
|
||||
*/
|
||||
taskName = "build-master-translation";
|
||||
gulp.task(
|
||||
taskName,
|
||||
gulp.series("clean-translations", function() {
|
||||
return gulp
|
||||
.src("src/translations/en.json")
|
||||
.pipe(
|
||||
transform(function(data, file) {
|
||||
return lokalise_transform(data, data);
|
||||
})
|
||||
)
|
||||
.pipe(rename("translationMaster.json"))
|
||||
.pipe(gulp.dest(workDir));
|
||||
})
|
||||
);
|
||||
tasks.push(taskName);
|
||||
|
||||
taskName = "build-merged-translations";
|
||||
gulp.task(
|
||||
taskName,
|
||||
gulp.series("build-master-translation", function() {
|
||||
return gulp
|
||||
.src([inDir + "/*.json", workDir + "/test.json"], { allowEmpty: true })
|
||||
.pipe(
|
||||
foreach(function(stream, file) {
|
||||
// For each language generate a merged json file. It begins with the master
|
||||
// translation as a failsafe for untranslated strings, and merges all parent
|
||||
// tags into one file for each specific subtag
|
||||
//
|
||||
// TODO: This is a naive interpretation of BCP47 that should be improved.
|
||||
// Will be OK for now as long as we don't have anything more complicated
|
||||
// than a base translation + region.
|
||||
const tr = path.basename(file.history[0], ".json");
|
||||
const subtags = tr.split("-");
|
||||
const src = [workDir + "/translationMaster.json"];
|
||||
for (let i = 1; i <= subtags.length; i++) {
|
||||
const lang = subtags.slice(0, i).join("-");
|
||||
if (lang === "test") {
|
||||
src.push(workDir + "/test.json");
|
||||
} else {
|
||||
src.push(inDir + "/" + lang + ".json");
|
||||
}
|
||||
}
|
||||
return gulp
|
||||
.src(src, { allowEmpty: true })
|
||||
.pipe(transform((data) => emptyFilter(data)))
|
||||
.pipe(
|
||||
merge({
|
||||
fileName: tr + ".json",
|
||||
})
|
||||
)
|
||||
.pipe(gulp.dest(fullDir));
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
tasks.push(taskName);
|
||||
|
||||
const splitTasks = [];
|
||||
TRANSLATION_FRAGMENTS.forEach((fragment) => {
|
||||
taskName = "build-translation-fragment-" + fragment;
|
||||
gulp.task(
|
||||
taskName,
|
||||
gulp.series("build-merged-translations", function() {
|
||||
// Return only the translations for this fragment.
|
||||
return gulp
|
||||
.src(fullDir + "/*.json")
|
||||
.pipe(
|
||||
transform((data) => ({
|
||||
ui: {
|
||||
panel: {
|
||||
[fragment]: data.ui.panel[fragment],
|
||||
},
|
||||
},
|
||||
}))
|
||||
)
|
||||
.pipe(gulp.dest(workDir + "/" + fragment));
|
||||
})
|
||||
);
|
||||
tasks.push(taskName);
|
||||
splitTasks.push(taskName);
|
||||
});
|
||||
|
||||
taskName = "build-translation-core";
|
||||
gulp.task(
|
||||
taskName,
|
||||
gulp.series("build-merged-translations", function() {
|
||||
// Remove the fragment translations from the core translation.
|
||||
return gulp
|
||||
.src(fullDir + "/*.json")
|
||||
.pipe(
|
||||
transform((data) => {
|
||||
TRANSLATION_FRAGMENTS.forEach((fragment) => {
|
||||
delete data.ui.panel[fragment];
|
||||
});
|
||||
return data;
|
||||
})
|
||||
)
|
||||
.pipe(gulp.dest(coreDir));
|
||||
})
|
||||
);
|
||||
tasks.push(taskName);
|
||||
splitTasks.push(taskName);
|
||||
|
||||
taskName = "build-flattened-translations";
|
||||
gulp.task(
|
||||
taskName,
|
||||
gulp.series(...splitTasks, function() {
|
||||
// Flatten the split versions of our translations, and move them into outDir
|
||||
return gulp
|
||||
.src(
|
||||
TRANSLATION_FRAGMENTS.map(
|
||||
(fragment) => workDir + "/" + fragment + "/*.json"
|
||||
).concat(coreDir + "/*.json"),
|
||||
{ base: workDir }
|
||||
)
|
||||
.pipe(
|
||||
transform(function(data) {
|
||||
// Polymer.AppLocalizeBehavior requires flattened json
|
||||
return flatten(data);
|
||||
})
|
||||
)
|
||||
.pipe(minify())
|
||||
.pipe(hashFilename())
|
||||
.pipe(
|
||||
rename((filePath) => {
|
||||
if (filePath.dirname === "core") {
|
||||
filePath.dirname = "";
|
||||
}
|
||||
})
|
||||
)
|
||||
.pipe(gulp.dest(outDir));
|
||||
})
|
||||
);
|
||||
tasks.push(taskName);
|
||||
|
||||
taskName = "build-translation-fingerprints";
|
||||
gulp.task(
|
||||
taskName,
|
||||
gulp.series("build-flattened-translations", function() {
|
||||
return gulp
|
||||
.src(outDir + "/**/*.json")
|
||||
.pipe(
|
||||
rename({
|
||||
extname: "",
|
||||
})
|
||||
)
|
||||
.pipe(
|
||||
hash({
|
||||
algorithm: "md5",
|
||||
hashLength: 32,
|
||||
template: "<%= name %>.json",
|
||||
})
|
||||
)
|
||||
.pipe(hash.manifest("translationFingerprints.json"))
|
||||
.pipe(
|
||||
transform(function(data) {
|
||||
// After generating fingerprints of our translation files, consolidate
|
||||
// all translation fragment fingerprints under the translation name key
|
||||
const newData = {};
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
const [path, _md5] = key.rsplit("-", 1);
|
||||
// let translation = key;
|
||||
let translation = path;
|
||||
const parts = translation.split("/");
|
||||
if (parts.length === 2) {
|
||||
translation = parts[1];
|
||||
}
|
||||
if (!(translation in newData)) {
|
||||
newData[translation] = {
|
||||
fingerprints: {},
|
||||
};
|
||||
}
|
||||
newData[translation].fingerprints[path] = value;
|
||||
});
|
||||
return newData;
|
||||
})
|
||||
)
|
||||
.pipe(gulp.dest(workDir));
|
||||
})
|
||||
);
|
||||
tasks.push(taskName);
|
||||
|
||||
taskName = "build-translations";
|
||||
gulp.task(
|
||||
taskName,
|
||||
gulp.series("build-translation-fingerprints", function() {
|
||||
return gulp
|
||||
.src(
|
||||
[
|
||||
"src/translations/translationMetadata.json",
|
||||
workDir + "/testMetadata.json",
|
||||
workDir + "/translationFingerprints.json",
|
||||
],
|
||||
{ allowEmpty: true }
|
||||
)
|
||||
.pipe(merge({}))
|
||||
.pipe(
|
||||
transform(function(data) {
|
||||
const newData = {};
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
// Filter out translations without native name.
|
||||
if (data[key].nativeName) {
|
||||
newData[key] = data[key];
|
||||
} else {
|
||||
console.warn(
|
||||
`Skipping language ${key}. Native name was not translated.`
|
||||
);
|
||||
}
|
||||
if (data[key]) newData[key] = value;
|
||||
});
|
||||
return newData;
|
||||
})
|
||||
)
|
||||
.pipe(
|
||||
transform((data) => ({
|
||||
fragments: TRANSLATION_FRAGMENTS,
|
||||
translations: data,
|
||||
}))
|
||||
)
|
||||
.pipe(rename("translationMetadata.json"))
|
||||
.pipe(gulp.dest(workDir));
|
||||
})
|
||||
);
|
||||
tasks.push(taskName);
|
||||
|
||||
module.exports = tasks;
|
116
build-scripts/gulp/webpack.js
Normal file
@@ -0,0 +1,116 @@
|
||||
// Tasks to run webpack.
|
||||
const gulp = require("gulp");
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const WebpackDevServer = require("webpack-dev-server");
|
||||
const log = require("fancy-log");
|
||||
const paths = require("../paths");
|
||||
const { createAppConfig, createDemoConfig } = require("../webpack");
|
||||
|
||||
const handler = (done) => (err, stats) => {
|
||||
if (err) {
|
||||
console.log(err.stack || err);
|
||||
if (err.details) {
|
||||
console.log(err.details);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
log(`Build done @ ${new Date().toLocaleTimeString()}`);
|
||||
|
||||
if (stats.hasErrors() || stats.hasWarnings()) {
|
||||
console.log(stats.toString("minimal"));
|
||||
}
|
||||
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
gulp.task("webpack-watch-app", () => {
|
||||
const compiler = webpack([
|
||||
createAppConfig({
|
||||
isProdBuild: false,
|
||||
latestBuild: true,
|
||||
isStatsBuild: false,
|
||||
}),
|
||||
createAppConfig({
|
||||
isProdBuild: false,
|
||||
latestBuild: false,
|
||||
isStatsBuild: false,
|
||||
}),
|
||||
]);
|
||||
compiler.watch({}, handler());
|
||||
// we are not calling done, so this command will run forever
|
||||
});
|
||||
|
||||
gulp.task(
|
||||
"webpack-prod-app",
|
||||
() =>
|
||||
new Promise((resolve) =>
|
||||
webpack(
|
||||
[
|
||||
createAppConfig({
|
||||
isProdBuild: true,
|
||||
latestBuild: true,
|
||||
isStatsBuild: false,
|
||||
}),
|
||||
createAppConfig({
|
||||
isProdBuild: true,
|
||||
latestBuild: false,
|
||||
isStatsBuild: false,
|
||||
}),
|
||||
],
|
||||
handler(resolve)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
gulp.task("webpack-dev-server-demo", () => {
|
||||
const compiler = webpack([
|
||||
createDemoConfig({
|
||||
isProdBuild: false,
|
||||
latestBuild: false,
|
||||
isStatsBuild: false,
|
||||
}),
|
||||
createDemoConfig({
|
||||
isProdBuild: false,
|
||||
latestBuild: true,
|
||||
isStatsBuild: false,
|
||||
}),
|
||||
]);
|
||||
|
||||
new WebpackDevServer(compiler, {
|
||||
open: true,
|
||||
watchContentBase: true,
|
||||
contentBase: path.resolve(paths.demo_dir, "dist"),
|
||||
}).listen(8090, "localhost", function(err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
// Server listening
|
||||
log("[webpack-dev-server]", "http://localhost:8090");
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task(
|
||||
"webpack-prod-demo",
|
||||
() =>
|
||||
new Promise((resolve) =>
|
||||
webpack(
|
||||
[
|
||||
createDemoConfig({
|
||||
isProdBuild: true,
|
||||
latestBuild: false,
|
||||
isStatsBuild: false,
|
||||
}),
|
||||
createDemoConfig({
|
||||
isProdBuild: true,
|
||||
latestBuild: true,
|
||||
isStatsBuild: false,
|
||||
}),
|
||||
],
|
||||
handler(resolve)
|
||||
)
|
||||
)
|
||||
);
|
17
build-scripts/paths.js
Normal file
@@ -0,0 +1,17 @@
|
||||
var path = require("path");
|
||||
|
||||
module.exports = {
|
||||
polymer_dir: path.resolve(__dirname, ".."),
|
||||
|
||||
build_dir: path.resolve(__dirname, "../build"),
|
||||
root: path.resolve(__dirname, "../hass_frontend"),
|
||||
static: path.resolve(__dirname, "../hass_frontend/static"),
|
||||
output: path.resolve(__dirname, "../hass_frontend/frontend_latest"),
|
||||
output_es5: path.resolve(__dirname, "../hass_frontend/frontend_es5"),
|
||||
|
||||
demo_dir: path.resolve(__dirname, "../demo"),
|
||||
demo_root: path.resolve(__dirname, "../demo/dist"),
|
||||
demo_static: path.resolve(__dirname, "../demo/dist/static"),
|
||||
demo_output: path.resolve(__dirname, "../demo/dist/frontend_latest"),
|
||||
demo_output_es5: path.resolve(__dirname, "../demo/dist/frontend_es5"),
|
||||
};
|
223
build-scripts/webpack.js
Normal file
@@ -0,0 +1,223 @@
|
||||
const webpack = require("webpack");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
const WorkboxPlugin = require("workbox-webpack-plugin");
|
||||
const CompressionPlugin = require("compression-webpack-plugin");
|
||||
const zopfli = require("@gfx/zopfli");
|
||||
const ManifestPlugin = require("webpack-manifest-plugin");
|
||||
const paths = require("./paths.js");
|
||||
const { babelLoaderConfig } = require("./babel.js");
|
||||
|
||||
let version = fs
|
||||
.readFileSync(path.resolve(paths.polymer_dir, "setup.py"), "utf8")
|
||||
.match(/\d{8}\.\d+/);
|
||||
if (!version) {
|
||||
throw Error("Version not found");
|
||||
}
|
||||
version = version[0];
|
||||
|
||||
const genMode = (isProdBuild) => (isProdBuild ? "production" : "development");
|
||||
const genDevTool = (isProdBuild) =>
|
||||
isProdBuild ? "source-map" : "inline-cheap-module-source-map";
|
||||
const genFilename = (isProdBuild, dontHash = new Set()) => ({ chunk }) => {
|
||||
if (!isProdBuild || dontHash.has(chunk.name)) {
|
||||
return `${chunk.name}.js`;
|
||||
}
|
||||
return `${chunk.name}.${chunk.hash.substr(0, 8)}.js`;
|
||||
};
|
||||
const genChunkFilename = (isProdBuild, isStatsBuild) =>
|
||||
isProdBuild && !isStatsBuild ? "chunk.[chunkhash].js" : "[name].chunk.js";
|
||||
|
||||
const resolve = {
|
||||
extensions: [".ts", ".js", ".json", ".tsx"],
|
||||
alias: {
|
||||
react: "preact-compat",
|
||||
"react-dom": "preact-compat",
|
||||
// Not necessary unless you consume a module using `createClass`
|
||||
"create-react-class": "preact-compat/lib/create-react-class",
|
||||
// Not necessary unless you consume a module requiring `react-dom-factories`
|
||||
"react-dom-factories": "preact-compat/lib/react-dom-factories",
|
||||
},
|
||||
};
|
||||
|
||||
const cssLoader = {
|
||||
test: /\.css$/,
|
||||
use: "raw-loader",
|
||||
};
|
||||
const htmlLoader = {
|
||||
test: /\.(html)$/,
|
||||
use: {
|
||||
loader: "html-loader",
|
||||
options: {
|
||||
exportAsEs6Default: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const plugins = [
|
||||
// Ignore moment.js locales
|
||||
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
||||
// Color.js is bloated, it contains all color definitions for all material color sets.
|
||||
new webpack.NormalModuleReplacementPlugin(
|
||||
/@polymer\/paper-styles\/color\.js$/,
|
||||
path.resolve(paths.polymer_dir, "src/util/empty.js")
|
||||
),
|
||||
// Ignore roboto pointing at CDN. We use local font-roboto-local.
|
||||
new webpack.NormalModuleReplacementPlugin(
|
||||
/@polymer\/font-roboto\/roboto\.js$/,
|
||||
path.resolve(paths.polymer_dir, "src/util/empty.js")
|
||||
),
|
||||
// Ignore mwc icons pointing at CDN.
|
||||
new webpack.NormalModuleReplacementPlugin(
|
||||
/@material\/mwc-icon\/mwc-icon-font\.js$/,
|
||||
path.resolve(paths.polymer_dir, "src/util/empty.js")
|
||||
),
|
||||
];
|
||||
|
||||
const optimization = (latestBuild) => ({
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
cache: true,
|
||||
parallel: true,
|
||||
extractComments: true,
|
||||
sourceMap: true,
|
||||
terserOptions: {
|
||||
safari10: true,
|
||||
ecma: latestBuild ? undefined : 5,
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
|
||||
const isCI = process.env.CI === "true";
|
||||
|
||||
// Create an object mapping browser urls to their paths during build
|
||||
const translationMetadata = require("../build-translations/translationMetadata.json");
|
||||
const workBoxTranslationsTemplatedURLs = {};
|
||||
const englishFP = translationMetadata.translations.en.fingerprints;
|
||||
Object.keys(englishFP).forEach((key) => {
|
||||
workBoxTranslationsTemplatedURLs[
|
||||
`/static/translations/${englishFP[key]}`
|
||||
] = `build-translations/output/${key}.json`;
|
||||
});
|
||||
|
||||
const entry = {
|
||||
app: "./src/entrypoints/app.ts",
|
||||
authorize: "./src/entrypoints/authorize.ts",
|
||||
onboarding: "./src/entrypoints/onboarding.ts",
|
||||
core: "./src/entrypoints/core.ts",
|
||||
compatibility: "./src/entrypoints/compatibility.ts",
|
||||
"custom-panel": "./src/entrypoints/custom-panel.ts",
|
||||
"hass-icons": "./src/entrypoints/hass-icons.ts",
|
||||
};
|
||||
|
||||
return {
|
||||
mode: genMode(isProdBuild),
|
||||
devtool: genDevTool(isProdBuild),
|
||||
entry,
|
||||
module: {
|
||||
rules: [babelLoaderConfig({ latestBuild }), cssLoader, htmlLoader],
|
||||
},
|
||||
optimization: optimization(latestBuild),
|
||||
plugins: [
|
||||
new ManifestPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
__DEV__: JSON.stringify(!isProdBuild),
|
||||
__DEMO__: false,
|
||||
__BUILD__: JSON.stringify(latestBuild ? "latest" : "es5"),
|
||||
__VERSION__: JSON.stringify(version),
|
||||
__STATIC_PATH__: "/static/",
|
||||
"process.env.NODE_ENV": JSON.stringify(
|
||||
isProdBuild ? "production" : "development"
|
||||
),
|
||||
}),
|
||||
...plugins,
|
||||
isProdBuild &&
|
||||
!isCI &&
|
||||
!isStatsBuild &&
|
||||
new CompressionPlugin({
|
||||
cache: true,
|
||||
exclude: [/\.js\.map$/, /\.LICENSE$/, /\.py$/, /\.txt$/],
|
||||
algorithm(input, compressionOptions, callback) {
|
||||
return zopfli.gzip(input, compressionOptions, callback);
|
||||
},
|
||||
}),
|
||||
latestBuild &&
|
||||
new WorkboxPlugin.InjectManifest({
|
||||
swSrc: "./src/entrypoints/service-worker-hass.js",
|
||||
swDest: "service_worker.js",
|
||||
importWorkboxFrom: "local",
|
||||
include: [/\.js$/],
|
||||
templatedURLs: {
|
||||
...workBoxTranslationsTemplatedURLs,
|
||||
"/static/icons/favicon-192x192.png":
|
||||
"public/icons/favicon-192x192.png",
|
||||
"/static/fonts/roboto/Roboto-Light.woff2":
|
||||
"node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff2",
|
||||
"/static/fonts/roboto/Roboto-Medium.woff2":
|
||||
"node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff2",
|
||||
"/static/fonts/roboto/Roboto-Regular.woff2":
|
||||
"node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff2",
|
||||
"/static/fonts/roboto/Roboto-Bold.woff2":
|
||||
"node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff2",
|
||||
},
|
||||
}),
|
||||
].filter(Boolean),
|
||||
output: {
|
||||
filename: genFilename(isProdBuild),
|
||||
chunkFilename: genChunkFilename(isProdBuild, isStatsBuild),
|
||||
path: latestBuild ? paths.output : paths.output_es5,
|
||||
publicPath: latestBuild ? "/frontend_latest/" : "/frontend_es5/",
|
||||
},
|
||||
resolve,
|
||||
};
|
||||
};
|
||||
|
||||
const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
|
||||
return {
|
||||
mode: genMode(isProdBuild),
|
||||
devtool: genDevTool(isProdBuild),
|
||||
entry: {
|
||||
main: "./demo/src/entrypoint.ts",
|
||||
compatibility: "./src/entrypoints/compatibility.ts",
|
||||
},
|
||||
module: {
|
||||
rules: [babelLoaderConfig({ latestBuild }), cssLoader, htmlLoader],
|
||||
},
|
||||
optimization: optimization(latestBuild),
|
||||
plugins: [
|
||||
new ManifestPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
__DEV__: !isProdBuild,
|
||||
__BUILD__: JSON.stringify(latestBuild ? "latest" : "es5"),
|
||||
__VERSION__: JSON.stringify(`DEMO-${version}`),
|
||||
__DEMO__: true,
|
||||
__STATIC_PATH__: "/static/",
|
||||
"process.env.NODE_ENV": JSON.stringify(
|
||||
isProdBuild ? "production" : "development"
|
||||
),
|
||||
}),
|
||||
...plugins,
|
||||
].filter(Boolean),
|
||||
resolve,
|
||||
output: {
|
||||
filename: genFilename(isProdBuild),
|
||||
chunkFilename: genChunkFilename(isProdBuild, isStatsBuild),
|
||||
path: path.resolve(
|
||||
paths.demo_root,
|
||||
latestBuild ? "frontend_latest" : "frontend_es5"
|
||||
),
|
||||
publicPath: latestBuild ? "/frontend_latest/" : "/frontend_es5/",
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
resolve,
|
||||
plugins,
|
||||
optimization,
|
||||
createAppConfig,
|
||||
createDemoConfig,
|
||||
};
|
BIN
demo/public/api/camera_proxy_stream/camera.backyard
Normal file
After Width: | Height: | Size: 81 KiB |
BIN
demo/public/api/camera_proxy_stream/camera.driveway
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
demo/public/api/camera_proxy_stream/camera.patio
Normal file
After Width: | Height: | Size: 63 KiB |
BIN
demo/public/api/camera_proxy_stream/camera.porch
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
demo/public/assets/arsaboo/floorplans/ecobee_blank.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
demo/public/assets/arsaboo/floorplans/main.png
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
demo/public/assets/arsaboo/floorplans/second.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
demo/public/assets/arsaboo/icons/Harmony.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
demo/public/assets/arsaboo/icons/abode_disabled.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
demo/public/assets/arsaboo/icons/abode_enabled.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
demo/public/assets/arsaboo/icons/automation_disabled.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
demo/public/assets/arsaboo/icons/automation_enabled.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
demo/public/assets/arsaboo/icons/camera_backyard_recording.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
BIN
demo/public/assets/arsaboo/icons/camera_backyard_streaming.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
demo/public/assets/arsaboo/icons/camera_driveway_recording.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
demo/public/assets/arsaboo/icons/camera_driveway_streaming.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
demo/public/assets/arsaboo/icons/camera_patio_recording.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
demo/public/assets/arsaboo/icons/camera_patio_streaming.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
demo/public/assets/arsaboo/icons/camera_porch_recording.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
demo/public/assets/arsaboo/icons/camera_porch_streaming.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
demo/public/assets/arsaboo/icons/ecobee_blank.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
demo/public/assets/arsaboo/icons/garage_door_closed.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
demo/public/assets/arsaboo/icons/garage_door_open.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
demo/public/assets/arsaboo/icons/light_bulb_off.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
demo/public/assets/arsaboo/icons/light_bulb_on.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
demo/public/assets/arsaboo/icons/light_off.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
demo/public/assets/arsaboo/icons/light_on.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
demo/public/assets/arsaboo/icons/security_armed_red.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
demo/public/assets/arsaboo/icons/security_disarmed.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
demo/public/assets/arsaboo/icons/tv_disabled.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
demo/public/assets/arsaboo/icons/tv_enabled.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
demo/public/assets/arsaboo/icons/tv_off2.png
Normal file
After Width: | Height: | Size: 767 B |
BIN
demo/public/assets/arsaboo/icons/tv_on2.png
Normal file
After Width: | Height: | Size: 805 B |
BIN
demo/public/assets/arsaboo/images/arsaboo.jpg
Normal file
After Width: | Height: | Size: 59 KiB |
BIN
demo/public/assets/arsaboo/images/melody.jpg
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
demo/public/assets/jimpower/background-15.jpg
Normal file
After Width: | Height: | Size: 232 KiB |
BIN
demo/public/assets/jimpower/cardbackK.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
demo/public/assets/jimpower/home/bus_10.jpg
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
demo/public/assets/jimpower/home/git.png
Normal file
After Width: | Height: | Size: 106 KiB |
BIN
demo/public/assets/jimpower/home/house_4.png
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
demo/public/assets/jimpower/home/james_10.jpg
Normal file
After Width: | Height: | Size: 73 KiB |
BIN
demo/public/assets/jimpower/home/tina_4.jpg
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
demo/public/assets/jimpower/security/air_8.jpg
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
demo/public/assets/jimpower/security/alarm_3.jpg
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
demo/public/assets/jimpower/security/door_3.png
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
demo/public/assets/jimpower/security/leak_2.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
demo/public/assets/jimpower/security/motion_3.jpg
Normal file
After Width: | Height: | Size: 87 KiB |
BIN
demo/public/assets/jimpower/security/smoke_4.jpg
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
demo/public/assets/jimpower/security/window_2.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
demo/public/assets/kernehed/bella.jpg
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
demo/public/assets/kernehed/camera.entre.jpg
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
demo/public/assets/kernehed/oscar.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
demo/public/assets/teachingbirds/House_square.jpg
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
demo/public/assets/teachingbirds/Stefan_square.jpg
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
demo/public/assets/teachingbirds/background_square.png
Normal file
After Width: | Height: | Size: 781 B |
BIN
demo/public/assets/teachingbirds/cleaning_square.jpg
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
demo/public/assets/teachingbirds/clothes_drying_square.jpg
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
demo/public/assets/teachingbirds/dryer_square.jpg
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
demo/public/assets/teachingbirds/folded_clothes_square.jpg
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
demo/public/assets/teachingbirds/guests_square.jpg
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
demo/public/assets/teachingbirds/isa_square.jpg
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
demo/public/assets/teachingbirds/laundry_clean_2_square.jpg
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
demo/public/assets/teachingbirds/laundry_running_square.jpg
Normal file
After Width: | Height: | Size: 59 KiB |
BIN
demo/public/assets/teachingbirds/mailbox_bw_square.jpg
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
demo/public/assets/teachingbirds/mailbox_square.jpg
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
demo/public/assets/teachingbirds/meteogram.png
Normal file
After Width: | Height: | Size: 67 KiB |
BIN
demo/public/assets/teachingbirds/plants.png
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
demo/public/assets/teachingbirds/radiator_off.jpg
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
demo/public/assets/teachingbirds/radiator_on.jpg
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
demo/public/assets/teachingbirds/roomba_bw_square.jpg
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
demo/public/assets/teachingbirds/roomba_square.jpg
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
demo/public/assets/teachingbirds/trash_bear_bw_square.jpg
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
demo/public/assets/teachingbirds/trash_square.jpg
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
demo/public/assets/teachingbirds/washer_square.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
33
demo/public/manifest.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"background_color": "#FFFFFF",
|
||||
"description": "Open-source home automation platform running on Python 3.",
|
||||
"dir": "ltr",
|
||||
"display": "standalone",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/static/icons/favicon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/icons/favicon-384x384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/icons/favicon-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/icons/favicon-1024x1024.png",
|
||||
"sizes": "1024x1024",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"lang": "en-US",
|
||||
"name": "Home Assistant Demo",
|
||||
"short_name": "Demo",
|
||||
"start_url": "/?homescreen=1",
|
||||
"theme_color": "#03A9F4"
|
||||
}
|
3
demo/public/service_worker.js
Normal file
@@ -0,0 +1,3 @@
|
||||
self.addEventListener("fetch", function(event) {
|
||||
event.respondWith(fetch(event.request));
|
||||
});
|
9
demo/script/build_demo
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
# Build the demo
|
||||
|
||||
# Stop on errors
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
./node_modules/.bin/gulp build-demo
|
9
demo/script/develop_demo
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
# Develop the demo
|
||||
|
||||
# Stop on errors
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
./node_modules/.bin/gulp develop-demo
|
11
demo/script/size_stats
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
# Analyze stats
|
||||
|
||||
# Stop on errors
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
STATS=1 NODE_ENV=production ../node_modules/.bin/webpack --profile --json > compilation-stats.json
|
||||
npx webpack-bundle-analyzer compilation-stats.json dist
|
||||
rm compilation-stats.json
|