diff --git a/auto/gui.files.go b/auto/gui.files.go index 45b31b46d..fee775805 100644 --- a/auto/gui.files.go +++ b/auto/gui.files.go @@ -18,7 +18,7 @@ func init() { bs, _ = ioutil.ReadAll(gr) Assets["angular.min.js"] = bs - bs, _ = hex.DecodeString("1f8b080000096e8800ffd43b5b6fdb38d6eff9159c7cfd20b9716477b0582c92a68b994c6690ed154d3b2f811f688bb6d9c89497a4931881fffb1e52944c8a942c27edb463a08d4d1e9e1b0fcf4dd4e0f917915126d198e77782f01324f98af4d1246792b215297f2fb39550ff8adfe8f9e060f07c96e5639ca16727688a33014098cd5619e6e6b7023a8856f045484e27323a3d38b8c51c89359bc83965337456ae481679baca481c5573511f5d8f7ab0a21a49144b3ccf32c2e3e8aa1c3d973c03d8e90a7ed39ca1f89998e44be0e5d95cca650f3d1c20f828b24b4e6e7fc39200d5615f8fce887cff1a7e2a8980921a2a562b528c688402e61f36a7b5c9299df9e38bf5e56f301a45ce28cb53a2905c8f02482e9912a462c19a279ce73cb04e10c22ed49c4f097448329f2d4e967989488f0f06e80a3684cd041a9369ce091ae779265096e737302225e12e45293530a0d0e30f343d41d11b2a24618008b40f124e60d7f5aea00f3c97f924cf5001817e49534e84200200e57a09161549722fe1170c4bcc6561529bbe85fc2dbebf222c7d3d5e0a0bfdfb959ce5ca6e3eaa6d7c431754a2f8f5af4bd1dba266abc598f056e41f011d66970ce4bcc5d99545a09841e5148af7c66c0c278cdc4c3e1eff07cc31d87ff691fc770540b66e406308f4032b59aa55b405e98e1f909ccfe148929ae215f2df694650315be8bfb3e62d027f688ff10b63170c8f33925a348a290473399c65b2c5ab8cb395eb37f9a401a79e790cca2b35fe6be1116dfb56c3683b6ea333eb47ae2399ade855f8fc9863616be0f3e553cecc67975785ed97959c13f0e313ac7de36787eb9d083f6021ee729eb623b5a00ce2e5762484bcd450e5b2c10d5fad2613425292c6a5c7561f3a45f14fda49dba35abb71f47f8c48a072a39d61d453de0f677134a729897aa70eb4ebe7cbd1cd41f1bfc7ccef184cdde7643f461ec6787293f27c090a011d80ba401d37643dce314f4d80dc34f0a9277731aae2ca79be58624e62dc47e33abb387907102a229d9dd911aa2e012772c5193a7e512758221aef87a8114fc5d04b54a2dc8b173359a17955a139b5155445bd2918df5c69b34a0d6c723a3d4840e3713450563a106b38790bd83fa16c518878bb2ec512d759758dd6ddc732706a8cc0815a6f49d42b827b1c66cc202f8dd05eb7fd6e87f60442f8059ecc2d7c6adcb3d4bac03a5d1844e80829f00476a3a3e816031ac7b5593ff244adb3ed8850e7c7cab93aef82caeb587e0784556607b9d65ddceb3b103285c958c11c5719600f0dd08be170e842d2d438a6f263258cb03eb8c59441a054096570365fc96ada99871d43314d1165a849c1daf7a9c9648ec5fb3b0659d59270b98665bd10bcfa9439fba937bbf146245f37605144af693aaa847b8be53c59e0fb78d847ff42cf8b9dd01097ecd7b524e2532e21cc1e0792670f4aa95ea63d9f438772a5b866d290eb74a1ed803512df20086693398a49936a3da50cbb8a1000f477c331a7a3b31a391f836b60f68262a8760443c6e996387517d5724e8bcaa4f311add733614a1b376d5245df07c2279067e019719c78ddb7a983a2128f7cea3ba5918e59d18aa5644a19a4864d316b386c8a5a3ecea4287bb55969fcc36e58abafba188532e04c4180510748505d1716240621008b87d37a84d487664268160395b07e55f200c9ac5c0947b73aa798ce6c7914b3ca54d059e8889905260e8f4e1dd529c0ba6acaf144a52e19d164950e4113a1a367248a2e19520a896a768d886a33342f536b543114ab2857277b84a2ffefd53186f6abc4f61b154676b0a446b55e4e94487f07a5e637fbead32455fb286d010149346beb3c8362e1efa12ee3eef6d5d992d305e6eb7d7446d9346f5699aa0dff628d19c6b4d24c69da92a147ff6ed96f4be5df4d849a1388da646916e54fb2731b14332ea71d8b2803714bb800dc21febea57a320a71f7cf66da1df6f91d5e90bdb403f00d3cd9202ddcb8224372321692abbcf19fe11048522aadd64c439508e57dd9ffec5adaeb56472f54930a7c4b76930cf6876b2d01072879bfd4bb9e14cd2373401dc3f0a1ae244fc432a390d6f595647869e571f7c050a9d7fb448207834234901542f569976f400534f19fabf7ef12a11bcc74ba8e1d267a7df430273805db3a410fd139142c606ac79f207f8b409b78091c157da5c11791b368e3d00c6dc6a16af81c86b7d8749f76f4006c21cc8ac82fb51bfbf501b35226b8cbf84bb42bce410366c5b384dc8342d2f861d32f0dda674591001d5cdcc346164f51dcc6968f3aa9fa89b0edba9c2dce4a359c7cc929034b40514ddfa5388f327e5733384d3dc5ecd4c883cd39904cd70c2f80e6a68356ea67e6eb8a03b93891a45da21045af43a92bfdb010618f182c2a6a4f9bec9fc9946692d8fda626f7cfca28f5d3364ad96664b7db34fda673a221eb7c584d10dd0051218cea0a19febc747b5a196133398789a3a3868252c35dd3519d943bde41f627c85fd781bf1f3bdcf85fec45eb5536c4a356032eda6bda57f4519a33d247f4745f193b1d02430585d4ee416dfd56c8973d32b25544949cbe1845cbceb3d6e280b558abd543d0b0a5659a54d0cd5a5a3aade5e2adc47e57c870ee4683f233e604df7428428ac623606a387785c4cb9598c77e846a704889c8b98cad27168ff51bdff9c0e4724e78c962f8c8b8097ca3ffedec7e5591b0b35d26e754ec3cc814528aba0b7e8441b3daee804d9e7a16cf3a963b96f0d76cd46c9d0199754351e5b21db7a26840fa7bd1547690e413851ae69577f162e76e4c3282f945d9ef6c4d76ecdb1c0e9fd72ed7c57ea063f462a4d90ad29d72a8dbd26ced1b281c0b9b784bf4ddb9fdbaeeb41d75d80884ce33e17f158f333c21f1a4f272fd7aa1a8e67abd96da0ef03426db1f21deef976c9b15db645b402aa79a7a5a71e020366dd9b785a44c31bce76f5e8e1158eb10bd2e0fccc87f4cfd8802c0845c45e7eb24ee9e92776a37a0d4c7a7ec5f491095efb44aa28c5be58f5f23df7178f6f21d43c5cb77d42a0faa8a8ad7237fceb523cbd7faa6549d7b563867cac25842394c981c2b8df6aca015f6ef961045e2f05018fb8961a47e0fa2eef9d5a728b7c2fc3e3679db596a58c95b555698a05632d29ab4958b5005ff9d92b64252ad7bc34887aa2551c628a8cc21aed40bac1f27272b0ca3dd41753a925fb50e2f2f5dba1735eab9076fc83d7812ac413f16f72cdcd8f0b4bdfba1abd4fa9367d30eeff4e8d9eda03bcf9d2bad3de50e50fb1d1fcb0d9b392b916fa66ff4ba07fdea2e72907e53e777476fd894d24e53d0eb09f80d66e38b4bc0ae955f89ccabf582272960dea135fa3965797b6a97c207eabac1fe5aafce8bde5f7bac465690ea4270ec72d8d7f7908600a8812bc22999d0059c4288d619e4a2ab857d913da5332a85ba9439296557be4b5d28f6ae23188732741e471408caeb35d32ccf79acbf66f9acf882c79a744fdd98a9665e0ccb245d51aeddce011ea13c29301b2843bb607363dfe4378e30621820b07b7fbfe4deacde4e50b65cc93e6820a36940443d9dc8fc777a4fd2b852a0b36aeb6036eeab05254363cad4b3daeefcd49f67e941bd0dd5a593061f1f0d51f0c1e316cb2b308e9fff819edb7fbc0c45430ece02a0a721aaed5afa1936fc0845e80fba0f6b5d787a02336fbb31d3cac513c8bf0e93b7efdaf01c36bbb407b526da65670ba2de88f981ec4c5f44b2feb468b30efa143bdb87b32e2c3dc5cc3af1d2cac413a8df7c0323137388bd8fb43187f9e0b3f406a238bbc36bf1ae7c17e4dbdb77f0e69ecd7e13c729e5eabac42d89a35ca73f17a94a28da98b6f553bcd30689ec79d4b78b72d5ec322fcd55c392632626d92af5667436705293cc3ce406dc67e6ab456263a1250b2027d53b172f0b85a98b906787eacd8e43c466c7fac6e0d9a19be45d1b9c094d4787af5e0ef4ca57868251d3ff000000ffff010000fffff7fa6c8316380000") + bs, _ = hex.DecodeString("1f8b080000096e8800ffd41b6b6fdb38f27b7e05d7db85e4c691ddc5e17048ea1eda345de4fa44d3ee97c01f648bb6d9c8948fa2931859fff71b3e24932225cb49baed19686393c37971382f51fda7dff294508ec62cbbc9313b469cad700f4d32ca095de1e2f7325de5e29ffa8d9ef60ffa4f6769368e53f4e4184de33407a098ce5669ccf46f017410ace04bce1999f0e0e4e0e03a66285fd3099f133a43c36245b4c892558ac3a09c0b7ae872d48515e548245862599a62160617c5e8296729c04e57f09b6414854ff249b6045e9ecc395f76d1dd01828f20bb64f8fa75cc31501df4e4e80cf38f6fe1a79008288921b55a90a25822cc61fe6e7352999c92993bbe589fbf86d120b04669966081e472e441724e8520250bc63c662c639e7539c6f44cccb99440873875d96278991588e478bf8f2e6043e82c47633ccd1846e32c4b739466d9158c708e994d9173090c28e4f81d498e51f08ee41c534004da070927b0eb7257d02796f16c92a54841a09749c2709ee31c00f97a091615707ccbe1170cf3987165529b9e81fc7d7c7b8169f276bccc0df41f577c9609bbf92cb6f11d59108ec2b7af9679778b9aae1663cc1a917f0674313da720e7759c5e1804d40c2aa650b837666d387ee47af2fef83fc52c06fb4f3fe3ffae00c8d40d680c817e60254da48ab620edf10392d3391c495c51bc40fe86a418a959a5ffd69a3708fc213dc64b4acf683c4e7162d0505308e63238cb788b57186723d7efb2490d4e39731f941762fc95f288a67d8b61b41d37d1e9f523db91cc56e4c27f7ef4b13035f0f5fc2167e6abcdabc0f672c5e718fcf82496bef1abc5f54e849fe23cbfc958d28cd480d28897db111ff24243a5cb06377cb19a4c304e7012161e5b7cc81485bf48276d8e4aed86c1af1473a072259d61d015de2f4ec3604e121c744f2c68dbcf17a39b03f5bfc3cc9b184cdde5643f46eec6f1e42a61d91214023a0075813aaef07a9cc52cd1017253c3a79cdcc5a8882ba7d96219331cc63d34aeb21b471f004244a4e1d08c50550918e62b46d1d1b32ac102d1783f44b5784a869ea302e55ebce8c912cd8b12cd89a9a032ea4dc1f8e6429b656a609293e941041a0f83beb0d27ebe8693b780fdcb852de679b85d97c43caeb26a1badbd8f45e094188103b1de90a8ab827be8674c232f8cd05cb7fd6e86f60842f8593c991bf8c4b863a9558165bad00fd02112e011ec464bd10d06248e4bbd7ee4885a65db12a1ca8f9173b5de0591d7d1ec06088bcc0e72ad9bb0dbb320780293a180392a33c02eeaa36783c1c0862489764cc5c7481861bd778b09854029124aef6cb6e2e5b4350f3b8642922042519d82a5ef1393d13cce3fde50c8aa9698f1352cebfae0c5a7c8d94f9cd98d33c2d9ba068b207a49925129dcfb98cfa3457c1b0e7ae85fe8a9da0909714e5fad39cebf641cc2ec91277976a084ea79d27539b428978aab270db94e1bda16582df10d82603699a310d7a9d651caa0ad081e4077372c733a1c56c8b9186c033317a8a1ca11f419a75de2545d54c339559549eb235aad67fc94362707d59a05922dbeca2d075ef56be29088a4239bba0e6924e355b0a2099e120a69614db009bed22b38de3430634ef955d6ab5c398140f84a974e24e7b7ab0b70f9f772308a78f6750967f734ce3178fa433501da1b43591c3eeb1abe41c8a3970f51475453903876d05f7fa1ede87992e24e5516350d76d0416167cba5a89d3f613681742d9e61adbe43d4f9addbf14aab556208540daacbec3485f4eefbef8ac84e8f089d668fb62f967203026a6c26aecd3ba8cb67b6b872b551cde8968c2c62b6f6a2ab13dad6bebd9bdf7d0b2042d689ee51b6ea05495f2bf10fda61b5367409b5f1504080a7f79020b259a248f47d00060f2755ddca4832c1240d818adfe9888cdae37464a23d9d99f2086685ff44435fdcd10b74723ab22d50005655538c47229f4fb1242b74089af0c5a3c25ace29120a092ace1e61d17bab5fa6dd0a0ac5b1a9923d44c16fdd2ac6065711bc26b9961d2ca956ade71321d2ff8352b3ab7df5a92b8d7d94b6802c2dafd796eb627f5a75b94eb295ce5c67b85367a65b7455261a267fb3c634635269ba5fd3e4dbffddb0df86ca7f98081527d018a7ea45f913efdc06c18ccd69cbce8286b8c62c07dc3efebea77a520271f7cf7ada2df6f943bcc07b6907e06b7832411ab8b1452e724e28a6fee90f813821dce857d6b44ec2e0d7e2a140db7e97ecff75bd594d7c8d7793f43e34a9f4c92ca0e8e352ee7aa43aaafa805a86e1425d7016e5cb9440add31392c54ba3b8b905860abdde461c3c58d83df1944acb2c377b1a400534f19f8b8f1fa25c3e7521d3756831d1eda1bb398e13b0ad6374179c42150fa676f405f2b700b4192f8123d56ced7fcb331a6c2c9abecde8882e68a7aeb4922dd91d8d315308bd2270fb4fb50fb13c66254c7097f11768578c8106f48a271164c59826e1dda65718b4cb8a20013a38bb858d548f16ed6eaf8b3a2a9becb0edb2c7a3ce4a391c7dcb08054b404145df8538f7327e5b337192388ad9a9913b93732099ac69bc009a9b165aa99e99c715077271cc71b3443e8a4edb5eb6bffc42f83da2b7a8a83c82357f465392726c3661ebdc3f2da2d42fdb28659a91d98396f4ebce8984acf26154ffb22b284218916d23f8f3dc6ef4a698cef81c260e0f6bba2c12ee928caaa4ecf116b23f40feaa0edcfdd8e1c6ff662f5a3161118f1a0d58f59ca5afe8a124a3b887c8c9be32b63a049a0af2a9dd81dafa2d9f2fbb67642b8908395d31541fdbb15675c01aacd5e82148d8c232752a68672d0d8f1f8ac55b89dd56a9e6dc8e06c567cc707cd5a20851dd78c05473ee94c4cb553e0fdd0855e390a23c633c341ee3ddd76ffce00393f13966058bfe236327f0b5feb7b5fb1545c2ce1e329f937ce741269052545df03d0c9a5676076cf2c4b178dab2dc3184bfa4a37aebf4c82cbbec22976db915aa2befee455dd981a32f046a9817ce6da49dbb314971ccce8a87008dc98e79c5c9e2f3d2e65aed073a42cf46922d2fdd2983ba2d49d7ae81c2b130893744df9ddb2feb4ed351fb8d20977926fc2fe2711a4f703829bd5caf5a288ab96eb7a1b6033cb5c9f66788f7fb25db7ac536d9ce2195134d3da93870109ba6ecdb4052a418ce436927c7f0acb5885e160766e4deddb84701a043aea0f33889bba3e49ddaf528f5fe29fb230922f29d46498471cb073f8f90ef583c3bf98ea6e2e43b6295035546c5cb913b67db91e16b5d532acf3d55ce99503f165f0ee327470ba31d2a5a7eff6e08a112873b65ecc79a91eae5a0aae7171f556ef9f9bd6ff2b6b3d43092b7b2acd041ad60a431692b16a112fe07256d4a52a97bcd488baa2512c698139e415ca916583f4f4ea60ca3d941b53a928f5a87173791eddb4bd5dc83d5e41e2cf2d6a09fd5e5233b363c6cef7eea2ab57a1d43b7c35bddc7b03be8d6658c526b0fb918d77cf1cd70c37ace48e4ebe96bbdee41bfbca0efa55fd7f9ddd11bd6a5b4d514747a026e8359fbe202b06de55720736a3def49f298b76f8d7c4e595c29dca5f0beb86eb0bfd6cbf322f7d71cab90cd71794b3eb439ecc9cb79030094c025e1044fc8024e2144eb1472d1d5c27cbb232133c27371537952c82e7c97b865ef5c47d00e65603d8e50088a3b67d334cb5828bfa6d94c7d89c79274575c232b679e0d8a245d50ae5c59031ea13c51983594a6add8dc98afb7684718d0182062fba596827bbd7a3b41e872c57ba08194241e11e574c4b337e4162761a9406bd5d6c16cecf76d0a86c6848a67b5edf9a93ecf9283721bca4b2775576506a8f6be8dc2f2028ce3f77fa0a7e61f27439190fda107f4c447b5594bbf77c59da900fd41f661ad0d4f0f60e67d3b661ab97800f9b77ef2e65d1b96c16617f620d604bbec6c81c56b623f919dc98b48c69f066d56411f6267fb70d686a58798592b5e1a997800f5abef6064f91c62ef3d6dcc62defb2cbd86689cdec4ebfc43f182d4f7b76fefcd3d93fd3a8e13c2c475896b1c06994c7fce12915034316dea47bde80989ec69d0338b72d1ecd26f9296c39cc5349fa4abc49991d9c071f58aab7ac80db887faab416263a0c50b20c7c58b48cf95c2c445c86147dcadec203a3b923706871d3bc9bbd43823928c3a2f9ef7e5ca179a8256d3ff000000ffff010000ffff264335362b3b0000") gr, _ = gzip.NewReader(bytes.NewBuffer(bs)) bs, _ = ioutil.ReadAll(gr) Assets["app.js"] = bs @@ -63,7 +63,7 @@ func init() { bs, _ = ioutil.ReadAll(gr) Assets["favicon.png"] = bs - bs, _ = hex.DecodeString("1f8b080000096e8800ffec5c5f73db36127fcfa74038d3369e3325db497a1d47d64c62a757cfb549264eaf77d3e90344ae44d420c102a06d9dabfbecb70b90142951b6e43fa993f6c11649000b60f787dd1fc095068f8fde1e7ef8cfbbd72cb1a91c3e1ad007933c9b1c0490052c9b843ccf0f0233cd229b886c12501de0f1f0116383142c6751c2b5017b1014761c7e13cc0b126bf3107e2bc4d941f0eff0c797e1a14a736ec54842c0229559c8b0d5f1eb038827d06897f1140e823301e7b9d2b651f55cc4363988e14c4410ba9b6d2632610597a189b88483dddece92a0184ca4456e85ca1ab296aaf1c2264a2fd590223b651a24aa008b6d54582622929468181f04637e46b7bddc69861a5861250c6b7d0dfafe412dcbb71b29658dd53cef47c6f4ebbb5e2ab21e3e09ca2eed54824900ac1f8cbb67769ae3782d5c586aec4a181ba978ca2edd2563398f63ec3b1c296b55bacffebe935fbc28cbc638bf70cc5321a7fb2cf80ee419581171f6060a08b659fd609bbdd4a8d86d66786642035a8cbd88d923f791ec6eb3640fff9ee2df33fc7b8e7f5fd743b87537a588731093c4eeb3a73b3badee796f64b3ba3752461843a434273befb34c65d0aa5fc8bf25cfebfa29d713918556e5fb6cb7f71cd256dd9e1397aa4c999c47d03da7ba78a1294778870889183203f1d0bac562f590c0ba5c4a665b5d3a465cac2ead25c7574aee2cad25c7f5ec464ac7a0bd4e96d4e73a6356e3455be95c8a09ea3bc22503baad0aa9266a41e3fb6ce7451ba38d27aee7f0f91caab932c29b1357031af66c41d7b956130dc6d49d242558f676e7424a53574b41640962ccae10545f8523ae6bb1b86e21ec92ed0061c47f0151b4573dae84464a4a9ea3b6c33361c8e9d5f2626172c9a76d35b7dbacd55c6434b205a50b63c34c85a3424ab08d29e063e73e42721fbeeb8586880f59a4d9aa7ec29154d169ad56d4a973c1e85daae5532b5b7b55edce0b463c3a9d68556431f5a2349a74327ab2f7f4eb6db6f76c87feed6ebd680351f3581406577e03101566d006ecd9a28dd136f8b861878579e16acd7a31478fbfe006248c71b43b733fd09adeeecefc7113f26e922faed7158d63d077bac7d8d9f7c1f3d1c0396cf4d1146f34da1af4417052458d43ab65194f1e8721fba07246800c43ff2ce3672c92dc9883002fa9c47fd0e2ad2e6318f34262f844e1e0ea8989738e65c018c4a2164263e0386c5d9651a84165b5fb08479a6771301c88745295d0120f98d111c5aa90eec2ddbd6f5c34643e5a074ff782725dbaeb213b998746eaa4ee7154e00acdcae8e66f82aa1ff2f5f8574dca5d9b94e508720fb66ad658e0484b2445748a142616f604acc5decc932d1c7b735a1339cd138adeacbe426b601c2f07c6aa9683be1f4ea9b83e6ace85e33e76ea0db24297be3e59f05ba18d45539c6f3395c9294332719e3131661944e86eb89ebe60efc158ae2d3be73ac36e2b6b97e271520289c363943f1693e38cd458eb0705cf4dd71a8c0cd3186d5297b6cb719a2099fb1f96dd366a76d40d09beaed62079da2e713c271856b3780310438c787f3aac35b65a2cad8656cf58291f7e4880f9f9163eb0b3841b3602c0c5cccfd04ba25dd09359c6238c0edc42dc9bc38ba505a9bc1c8e5575250a66a8f7f3b6e8dea09fb7c678fda0298836d6cc063846ec36e13cc77113bce5d0d7c2ad1a8fe7b8ad4da0cedbd0ed9a4a2481ebb1b8083accd47ed0ba6ddc94974b60874921d135213617a0dc026d258f1abe0717f2959eba80c59e903f23efbc3597d009f0afd7c077e5106f8def728c02cc6dd05dc8da89526c2e3217216207000d39704b08c8154614469f664180db4f2c3e5a70dc6d1e1b0c2f2f4952ef48688848cbb359db07af1e5ecd289646b172248baaa80371a78815632f704db32ec05b3e77d4eb88a3b85f2be0f868f5cc5dcb45937e8c19252a858da7e4198929228a220e3b1459fc7efd1d68a2e57c024fca596fb18303e433b8473ece9ca3bc516fb916489ca6aeb744c4707d6fd41579e42797972baace665f6cddc822837e37f6fe00484ea41a6d6e410265aa62903f97baf8a54782b8fc56e0de9ffdceb83ce753f3a64847a0673336a6c7db6c45a35753eb1a8d44c6697dbffa3c60dea12424d81bebc8b5b91b153d20dc455215711823a1948ac777a1db0cb9db86aaa5260f1f7c4d7abfbe7e06bc3cb55bdc5a1017702e6c1d8a96033a41396769af51c0a0cfaf1cce86f01bf40bb9c412966a2ed6ba17a6dbd89a7593dea62e715bef54b9961a6561e64a7c19c70dd678df6cb7c955df20fe1b2cd54df501d1541adea6fcb4adb5e4f9f01d806695a4e73720b019b63d1c4f88c32adc7569278bcc7c07549664bfe1293c293bd9fa84d92cbd19b891e3a6b9e31ad06b28c1c9f8239c6ecc4d32525c6f1e9a3cdff4b33ca4c78d6956b33fb1dc16e6b6f3ffbcc2398ac970872754667e2e15d3a3a547815a64a39c82740a568b6836c3bb078718af8222bf1705a8c2de8d061e10666eba1b26ddfc0b1eb4f7b863ca4628a8a7fbe9b1b6a510fd2111c685e8db47688ba29c7aee3b3e7f09a9c95f7c7a51da26375a64666a2ca43dfc68ee8dd8fb973f3cb8c566b93935b799649417e5e9cec2d6116f330cd49acbfdddd9ec0b76f8eec74fdde9de41a0fe5304e3cf31e0fe1595ba6b3d88b3842a88dde02cc147d28f708ae0affd5142bffd8a8c1ebdd65a69d3fd0a18a8ec7b8c904fb67a12b2894dd890ed3cc477c16f941511dcea1d7093abe0c489a734e64f364eb994e865f069ef834801fd0c2e36d80f92643f4df78de9196382d96c1fcdecaab2cbcbb11690c572ea8f23a8a5d3b76328f7ff127823383ba87934d074dffef3e3bed16dc1b44e6da81351e8f12b9759b55e7e4af5c2bbbcc541425ca666b144c43164e185592f41255fc84e21874dd1e60cb4c17d5fcb940d6649432b5b342efdbbf78662d0cfa1b36ef7e00e694a074eb9adfb7d548e8954a10df4ea84cf5e06b61f0c4f8a9cb257599f7dab74917ae7dcf49e2bbba81461d26667067b9b089b14a35ea4d27ec4659af4eb4efb1ad0e8065077df23f88d65effd830dfadda0b773712a82e1918a8a94dee3d13efbbe27288c29687aaf0acac7b9d7bed07868d308d8a10b06edbee601af2b0fc81d0c833d57fad4bb2996aa98cb7a6110a4458c23f475dcbaaefd82af3ae63174ac005718c6824b35e974efbe4299bdbcc2c5fb3ae4b6710d7309884ff73f8c793659706283e459bb59e9d3db6ee7ba080b1758983a8484464cb26ed274581fd7f8c0d7f258c9b3150eab6b6e4b316490b7bb9aa70719c06d28e5058d801189df668ad25b4103c32d3567b9562309293b47a0b02922821d538e2b9a8ecd8f977a2de1ef91e04e51f6970948295a5bdc5660b9c6efb61c70fdae8178e24a4055247273307981a1bc1b54b5757f5514c46d85c1e11231c6919854d4a202c6b5e0a15fb9c8c4758173f8d2626c372fbaa21f21b54e7c784c9a4013bcbe4082408bb913c473aad744d782a8b52411f3ee107503a08e954ecb644dba5c5c690d09541c52366dde7150c347c8e2b0863fda393ef2af82d8f1117a312a5b6a21b29cb2e82664054a138f3b66ee7c9617d71a4499bc1a34be93e0c88b7b398c362eb446dcd000cae3575affaec3a561d4f11cd74eeef36703970098f9e1b3083d0d2ed5312511fbe32a60885f43cbb6bc0d2abb22ae3cb8952f702f9f9ca4c534bfce7dd14d94cd29ad81cebbaed6732e7904899231e5fb7ea790af9e8046ce52ea98a4dc58c3dc67566ca0df139f869a194be9fd6acc4aac540a8d7083843e8f19f792e5be74875b36cab9a7f0feb2badc408bf114d526a2a08de165ec513a523a250893aae79dde54dff5584facde50efaf2992601849538e7128e79a7257af3e5015f93e11ca6ab35a0f9fe07f65c3523d55430c783968e76c7881bc1b6373c41c8f45144e090364f852fc1a161ff449d6d21e69b5436ecbfb29818cf9b47e8cb994954bab749b9d02e484c254e06ab709b76c00e9908ea85d85411fef7c86efc88d16d5d75aeb462090ad523d463ea482b59b5d2902a3fcfec2665303e5c24c7d7a20ddadb975ea72f01dfbc2b552839bd975e51e90729dab338d13bcee0c821ba4cf7747dde12145e4ab6457e70f8bd1e1ea3e1db5f429ce94cadb9c182e29b0f5d48edcddf20036654b940f723d5ba25a7fb1a5b5d95233c9e64e38d32a810f8139514a177195463efa75fca91d91ca9db109d6e0556567378842ef7df2dde6315fdb6d5664e2b7029d20a2c68ab1c0253af6fb1f9f6dee66dd633f941e969e1be417e464b994353120477a6fbc8006f28ed35bb78621e8c106a6f85fff686e8c4add4ee84d155e67cf6fa877ea94a26f5bc555d472a9a9c408501ee81efb49a09651f19106c70dc498e1a2891518f785172008dda9de9ba76d0944a72375d1f1a664d0a9f886f2bdfe6a092b74f81edddfdb4ca20a195d32baee7803d16de58e39de0d85272cd79973dd7d776969f175fab5d96e77a6468311334274b88e5ca24b95e512d03177eb0dfcd66c760b0daf74266e04fe1b55340802b849b806cfb31a38a763943f824ece87d0452a69e02d2f4f673f057d019756aa68ac54e1263701c72e4760cfe95b68defd11c59c329a74c40dfa49c8e87bcb67c84bb11bc751916547092e5a1e5939ad5b9323f5121e0ecfacf2703f439e594dedae7866f5f5d01524d394c57f5692d9c5fc1a5fa9fd689caff93eb4abbc2337bbab5a2388341d7e6965f22ab5c13bfd7ae3056e59b14746a04389af886e7cc57eff9d2d95642e79e6ab15390bcde87579593516b1cf8eadeedd0fa0d08e7665d0a9c30ee17641d05534695e95eea972234eb92fd7f6dee63e0b732ef39795bca9030a2b4cd68c8b9d1a1d2925afd65a7719634b7abb4a375784e99b4d7f654cbe4237dde1baf3e17dc07e528893fb437e67598e433b573afe84d7c53f7e3cfeb3ae894da67e9febe15aeef9b1b957f3972a3e3eff5a9bfed0a5ff492dffcb1f48bce88bfeeeb7ab7ef5f954ae74b858f1d7df0ad0d370afb7d37b7a7dedf94f64fdbaf80b5957b6e379be5001e74a3f86443fbee27ee4ecff000000ffff010000ffffd2f2ca86f54c0000") + bs, _ = hex.DecodeString("1f8b080000096e8800ffec5c6f73db36d27f9f4f8170e66993794cc976925ec7913593d8e935736d9289d3ebdd74fa022257226a906001d08ecef57df6db05488aa42859f29fd469fbc21649000bec0f8bdd1fc095460f8fdf1e7df8f7bb572cb1a91c3f18d107933c9b1d0690052c9b853ccf0f0333cf229b886c16501de0f1f80163a3142c6751c2b5017b1814761a7e1d2c0a126bf3107e2dc4d961f0aff08717e1914a736ec54442c0229559c8b0d5eb578710cfa0d12ee3291c066702ce73a56da3eab9886d7218c399882074373b4c64c20a2e43137109877b83dd25413198488bdc0a9535642d55e3854d945eaa214576ca344884008b6d54582622929468981e06537e46b783dc21430dacb012c6355ea3a17f50cbf2ed264a596335cf879131c3fa6e908a6c804f82b24b3b97601200eb07e3ee999de7385e0b1f2d3576258c4d543c6717ee92b19cc731f61d4e94b52a3d607fdbcd3f3e2fcba6a85f38e5a990f303167c0bf20cac88387b0305043bac7eb0c35e68047687199e99d08016532fe2f281fb48f67658b28f7f4ff0ef29fe3dc3bfafea21dcb89b52c4398859620fd893dddd56f77c30b159dd1b8111c61029cd699e0f58a63268d52fe4ff27cfeafa29d733918556e5076c6ff00cd256dd811397aa4c999c47d0af535ddc69cad1bc433489183203f1d8bac562f5988c75b994a66d75e914ed6275692d395e2bb9b7b4961cd7da4d948e417b4c96e0739d31abf1a20d3a9762867847b86440b7a1906aa63a881fb0dde76d1b6d3c713d87cf16a69a2b23fc74e26ac0893deb609d6b35d3604cdd49521acbfede424839d5d55210598236665708aaafc209d7b5585cb710f6c9760661c47f00ad68bf7a5c098d94943c47b4c33361c8e9d5f2626172c9e76d98db6d366a2e321a590774616c98a970524809b6a1023e76ee2324f7e1bbee3444fb90459aadea279c48159dd6b022a6ce05a377a9964f0db6f650ed2d0a263c3a9d69556431f5a2344ee96cf268ffc9573b6cffe92efddb7bfcbc6d889ac7a230b8f21b0651d90cce017bda9d639c1b7cdc98878e5eb85ab341ccd1e377dc8084298e7677e1075aeaeded2e1e374dde29f9fc6aac681ca3a1c31e63e7d007cf0723e7b0d14753bcd138d7a00f83932a6a1c592dcb78f2300cd907953332c830f4cf327ec622c98d390cf0924afc072ddeea3286292f24864f140eae9e9839e758068c512c6a2134068ec3d66519851a04abdd4738d13c8b83f148a4b3aa849678c08c8e2856857417eeed7feda221f3d13a78b21f94ebd25d8fd9c922345227758f930257685646377f1354fd90afc7bf4a29776d5296a3917b63abb4c602475a2229a253a430b1b027602df6661e3dc6b137d59ac9799e50f466f515ce06c6f17260ac6a391afae194c00d1139178e87d8a99f901558fafa3483df086d2c4ec5f90e53999c332413e7191353964184ee86ebf973f61e8ce5dab273ae33ecb69aed523c2a2590383c44f953317b9d118c353e28783175adc1c8308d714eead27639aa0992b9ff61d96da3664fdd90ccd7d51a254fda258ee704e34a8b370031c468ef4fc63562abc5d26a68f58c95f2f1870498d7b7f0819d25dcb009002e667e865e12e7053d99653cc2e8c02dc4838579b1b420c8cbe1585557a26086b89fb7450f46c3bc35c6ab074d41b4b166b6b063b4dda6392fecb869bce5d037b25b359d2eecb69e0275de36dd3e5522095c4fc5c7a0679ada0f5ab78d9bf272c9d8615648744d689b1d536e196d258f1abe0717f2959ebb80c51e913f23effc7821a1d7c0bfdac0be2b877863fb2ec728c0dcc4ba0b593b518acd45e62244ec0c40430edc9205e40a230aa34fd311e0f613dd471dc7dde6b1c1f8e282240d8e85868850bebc6cfbe0d5c3ab19c5d228568ea40b451d887b45ac187b816b9af519bce50b47bd89388afb3500af8f576bee5a76a7f4536814a9344516bdbd56de65f82585da1dd1e5a352cfc795ce2796db62f1f89afa8f86fd33fd3b18c04caa095ccb04521583fca944e2e70109e2f21b813b6df61be3f29ccfcd9b229d80bebc64537abcc356347a39b7aed144649c56d3cb7b6754894a6f0524a4b35b63e4dadc0e44f7c8ee22a98a388c91be49c5e3dbc03643a6b425b4d4e4fe1b5f934c6f8ecf889767645d224f91d739b04d08510e5924e48213bd4201a3215f3b9c2dcd6f342ce4524c5eaad9ad7527bcb2b111eaa7984d2c7113eda0dc0846599805882fe2b8c1d1ee9a5b3699e11bb4ff062774aade235248c3db960db6514b9e8ddf016856497a760dba9861dba3e98c18a3c23d8e76b2689a6f813892ec373c854765276b18c4bde78e740e7f2dc74dbae31ad01b80e0647c4e34d29f6d791d3d855c2859e95e92c81b6affc70ae62826c3dd945099f9a90466400b8fc2b4c8263985e814ac16d1e525dedd3f7b711014f99d00a00a7b3b08dc239bb9eece93b0f927dc73df71ab848daca056f7f3e36c4b01fa43228c0bd0378fcf16453978ee3a3a7f01a9c99f7f7e31da26d75a64666e2ca403fc68ee8cd8fb17dfdfbbc566b93935375132ca8b77a0e9cd6b67e388b719066acde5c1dee5e5ffb1a3773f7cee4ef71602f59f2218ff1103ee5f51a9bfd6bd3849a882d8354e127c24fd046708feda1f240cdbafa3e8d12bad9536fdaf5b81cabec308f9e8f1404236b3091bb3ddfbf8def58db222821bbd6f6d7215549c784a437f9ae3944b895e069f0e3e8814d0cfe062838320490ed2f4c098813126b8bc3cc0697655d9c5c5540bc86239f78711d4d2e1ed18caddbf70ddca9c9da9796b2075dffee3d3be3d6d99699d4650277dd0e3972e8b69b35c90eae572798b8384b84c8362898863c8c28f66b36490bc9309420e9ba2cd196883fbbed6543698250dad6cd1b8f4efb91bc0a09f4367ddeec11dd1940e9cf2480f86088e8954a10d0ceae4ca410676188c4f8a9c3245d9907da374917ae7dcf49e2bbba8803069b33383bdcd844d8ac92052e930e2324d8675a7430d38e90610bbefd0f88d65effd832dfadda2b773712a82f1b18a0a3ad671a90a77ada030a620f55e1694fb72a77de1e4e19c46c08e5c3068f7b508787d3937ee5818ecb9d2a7de4db154c55cd60b834c5ac438425fc7adebda2ff8aa531e43cf0a7085612cb854b35ef7ee2b9499c22b5cbcaf436e1bd7309780f6e9fe8731cf661d27364a9eb69b953ebded76ae8ab0f0110b536721a111b3ac9f341dd5c7353ef0b53c56f27485c3ead36d29868cf276578b541c03b80da51c9c093022f13b4c512a296860b8a5e62cd76a222165e768286c8e16c15e533e294e1d5b1c2f0d5ac2df23c19da3ec2f129052b4b6b8adc07285df6d39e0fa4d03f1c495065591c8ed8dc90b0ce5ed58551bfb755110b71506874bc418476252518b0a18d782877ee52213d705eaf085c5d86e9ef7453fb2540c9894be76183c2424700a5e7d4482408bb9d7881754af695d1d511b4922e6dd23ea1a863a553a2d1323e9b2bbd21a12a838a4ccd5bce7a0864f90c5610d7fb4f3fad8bf0862af8fd18b51d9520b91e594b136a359a094ecb84773e7b3bcb8d620ca44d1a091ffefc88b7b358c735c688d764303288f5f69fdbb0e978651c7735c3bb9cf550d5cb25de687cf22f434b854a794b0eb8fab80a1fd1a5ab6e56d50cd2bda95376ee50bdcab2727a99b52d7bb2fba0ed89c921ae8bc6b3dceb9e411244ac6945bfbad42be7a021a394b893149b936c2dce7556c81ef894ff9cc8ca5547a3565a5ad548046b841429fc78c7bc97257d8e1968df2db29bcbfa82eb740319e236c220ada36bc6c7becf090a5733261827ad1e975f1aec77a62f596b8bfa248c2e8b518c73894734d79a2eb0f54457e4084b2daacd6c327f35fdbb084a76a88012f07ed9c0d2f9077636c8e98e3b1688573b2019af852fc06333e1a92aca53dd26a87dc96f7630219f329f4187329039656e90e3b05c8c90a5381abdd26dcb211a4633aa276154643bcf3d9b413375a84afb5d68d4043b64a0d18f990caac9d76a5088cf2079dcda606ca8499fb543cbadb70ebd4e7e07bf6851ba5e1e65aa45ccf9b7b40ca2baece344ef0ba37086e91aade1f75c7471491d7c9aece1fbad1617d9f8e5afa74624a9b6d2a864b0a6caddab1bb5b1ec0b66c89b241ae664b54eb2fb6b4315b6aa6d8dc0a675a25f03e30274ae822aed2c8fdbe8a3fb52352b93336c106bcaaecec1a51e8bd4fbddb3ee66bbbc38a4cfc5aa01344abb1622a70894efdfec767763bad07ecfbd2c3d27383fc829c2c97b22606e448ef8c17d040de717aebd698087ab0c554fc7778bc988c0a6e27f4ba80d799ea5be24e9d52f46d435c452d97984a8c00e5811eb01f05a28cc0471a1c371053868b265660dc974b804ce856716f9eb625109d4ed4c79e3725a35ee01be07bfc6a092b307c8feeef6d26114246978cae7bde40f4cf728f8eb743e1c996ebbcb9febefb50eabe4ebf32d7edd66034183123b40ed7914b74a9b25c023ae66ebd817f7c79790384573a133702ffed251a0419b849b806cfb31a764ec728bf079d5c0ca18f54d2c05b5e9ece7e0afab22bad54d158a9c2293703c72e2760cfe91b5fdefd11c59c33523ae206fd2464f41de133e4a5d88de3a8c8b2a304172d8fac9cd7adc9917a09f787675659b87f409e59a9765b3cb3fa2ae60a9269cae23f2bc9ec637e8dafaf7e32ced77c1fda57de9399dd57ad11449a0ebf9c65f22af584f7faf5c60bdcb2e28026810e25be24baf125fbed37b65492b9e4992f57e42c34a3d7c545d558c43e3bb6ba773f36423bda9541a70e3b64b71d41eb68d2a22add53e5469c725f641dbccd7d16e642e6cf2b79538f29ac98b2665cec4574a2945c8f5a7f19634bb8adc3664d98be9efa2b63f21a6cfac375efc3bb30fb59214eeecef27bcb721cdab9d2f167bc2efefec3eb3feb9ad846f5bb5c0f5772cf4fcdbd9abf0af1e9f9d7c6f4872efdcf57f95fd940e2455faa77bf13f58bcfa772a5e36ec55f7e2d40cfc3fdc1eee0c9d5b5173f47f54bf7d7a8d6b6e379dea980bad20f0fd10f9db81f14fb1f000000ffff010000ffff7b34af28614c0000") gr, _ = gzip.NewReader(bytes.NewBuffer(bs)) bs, _ = ioutil.ReadAll(gr) Assets["index.html"] = bs diff --git a/cmd/syncthing/gui.go b/cmd/syncthing/gui.go index cb5ec9f22..603a633dd 100644 --- a/cmd/syncthing/gui.go +++ b/cmd/syncthing/gui.go @@ -88,6 +88,8 @@ func restGetModel(m *Model, w http.ResponseWriter, params martini.Params) { res["inSyncFiles"], res["inSyncBytes"] = globalFiles-needFiles, globalBytes-needBytes + res["state"] = m.State(repo) + w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(res) } diff --git a/cmd/syncthing/model.go b/cmd/syncthing/model.go index 8a896021e..4d39066cd 100644 --- a/cmd/syncthing/model.go +++ b/cmd/syncthing/model.go @@ -20,11 +20,21 @@ import ( "github.com/calmh/syncthing/scanner" ) +type repoState int + +const ( + RepoIdle repoState = iota + RepoScanning + RepoSyncing + RepoCleaning +) + type Model struct { repoDirs map[string]string // repo -> dir repoFiles map[string]*files.Set // repo -> files repoNodes map[string][]string // repo -> nodeIDs nodeRepos map[string][]string // nodeID -> repos + repoState map[string]repoState // repo -> state rmut sync.RWMutex // protects the above cm *cid.Map @@ -54,6 +64,7 @@ func NewModel(maxChangeBw int) *Model { repoFiles: make(map[string]*files.Set), repoNodes: make(map[string][]string), nodeRepos: make(map[string][]string), + repoState: make(map[string]repoState), cm: cid.NewMap(), protoConn: make(map[string]protocol.Connection), rawConn: make(map[string]io.Closer), @@ -536,14 +547,20 @@ func (m *Model) AddRepo(id, dir string, nodes []NodeConfiguration) { func (m *Model) ScanRepos() { m.rmut.RLock() + var repos = make([]string, 0, len(m.repoDirs)) for repo := range m.repoDirs { - m.ScanRepo(repo) + repos = append(repos, repo) } m.rmut.RUnlock() + + for _, repo := range repos { + m.ScanRepo(repo) + } } func (m *Model) ScanRepo(repo string) { sup := &suppressor{threshold: int64(cfg.Options.MaxChangeKbps)} + m.rmut.Lock() w := &scanner.Walker{ Dir: m.repoDirs[repo], IgnoreFile: ".stignore", @@ -552,8 +569,11 @@ func (m *Model) ScanRepo(repo string) { Suppressor: sup, CurrentFiler: cFiler{m, repo}, } + m.rmut.Unlock() + m.setState(repo, RepoScanning) fs, _ := w.Walk() m.ReplaceLocal(repo, fs) + m.setState(repo, RepoIdle) } func (m *Model) SaveIndexes(dir string) { @@ -647,3 +667,27 @@ func (m *Model) clusterConfig(node string) protocol.ClusterConfigMessage { return cm } + +func (m *Model) setState(repo string, state repoState) { + m.rmut.Lock() + m.repoState[repo] = state + m.rmut.Unlock() +} + +func (m *Model) State(repo string) string { + m.rmut.Lock() + state := m.repoState[repo] + m.rmut.Unlock() + switch state { + case RepoIdle: + return "idle" + case RepoScanning: + return "scanning" + case RepoCleaning: + return "cleaning" + case RepoSyncing: + return "syncing" + default: + return "unknown" + } +} diff --git a/cmd/syncthing/puller.go b/cmd/syncthing/puller.go index d0e968492..45e030675 100644 --- a/cmd/syncthing/puller.go +++ b/cmd/syncthing/puller.go @@ -127,11 +127,13 @@ func (p *puller) run() { for { select { case res := <-p.requestResults: + p.model.setState(p.repo, RepoSyncing) changed = true p.requestSlots <- true p.handleRequestResult(res) case b := <-p.blocks: + p.model.setState(p.repo, RepoSyncing) changed = true p.handleBlock(b) @@ -155,10 +157,13 @@ func (p *puller) run() { } if changed { + p.model.setState(p.repo, RepoCleaning) p.fixupDirectories() changed = false } + p.model.setState(p.repo, RepoIdle) + // Do a rescan if it's time for it select { case <-walkTicker: diff --git a/gui/app.js b/gui/app.js index ffe98dd08..98dfbd578 100644 --- a/gui/app.js +++ b/gui/app.js @@ -108,6 +108,36 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) { }); }; + $scope.repoStatus = function (repo) { + if (typeof $scope.model[repo] === 'undefined') { + return 'Unknown'; + } + + var state = '' + $scope.model[repo].state; + state = state[0].toUpperCase() + state.substr(1); + + if (state == "Syncing" || state == "Idle") { + state += " (" + $scope.syncPercentage(repo) + "%)"; + } + + return state; + } + + $scope.repoClass = function (repo) { + if (typeof $scope.model[repo] === 'undefined') { + return 'text-info'; + } + + var state = '' + $scope.model[repo].state; + if (state == 'idle') { + return 'text-success'; + } + if (state == 'syncing') { + return 'text-primary'; + } + return 'text-info'; + } + $scope.syncPercentage = function (repo) { if (typeof $scope.model[repo] === 'undefined') { return 100; diff --git a/gui/index.html b/gui/index.html index cce0ecdf3..14ddc50cb 100644 --- a/gui/index.html +++ b/gui/index.html @@ -137,9 +137,8 @@ {{repo.ID}}