From 2f3eeebe728d7a00495bdbb16793bb1bb61731e7 Mon Sep 17 00:00:00 2001 From: Radek Davidek Date: Sat, 1 Nov 2025 13:37:05 +0100 Subject: [PATCH] added icon --- .../java/cz/kamma/tvcom/HttpServerApp.java | 422 ++++++++++-------- src/main/resources/icon.png | Bin 0 -> 17421 bytes src/main/resources/index.html | 26 +- 3 files changed, 243 insertions(+), 205 deletions(-) create mode 100644 src/main/resources/icon.png diff --git a/src/main/java/cz/kamma/tvcom/HttpServerApp.java b/src/main/java/cz/kamma/tvcom/HttpServerApp.java index be40765..b11d845 100644 --- a/src/main/java/cz/kamma/tvcom/HttpServerApp.java +++ b/src/main/java/cz/kamma/tvcom/HttpServerApp.java @@ -13,219 +13,257 @@ import java.util.List; public class HttpServerApp { - // ✅ Statický API klíč - private static final String API_KEY = "6666-1234"; + // ✅ Statický API klíč + private static final String API_KEY = "6666-1234"; - public static void main(String[] args) throws Exception { - TransmissionService service = new TransmissionService(); + public static void main(String[] args) throws Exception { + TransmissionService service = new TransmissionService(); - HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); - ObjectMapper mapper = new ObjectMapper(); + HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); + ObjectMapper mapper = new ObjectMapper(); - // /transmissions -> all data nebo jen pro konkrétní datum - server.createContext("/transmissions", exchange -> { - try { - setCors(exchange); - if (!checkApiKey(exchange)) return; + // /transmissions -> all data nebo jen pro konkrétní datum + server.createContext("/transmissions", exchange -> { + try { + setCors(exchange); + if (!checkApiKey(exchange)) + return; - URI uri = exchange.getRequestURI(); - String query = uri.getQuery(); - String date = null; + URI uri = exchange.getRequestURI(); + String query = uri.getQuery(); + String date = null; - if (query != null) { - for (String part : query.split("&")) { - if (part.startsWith("date=")) { - date = java.net.URLDecoder.decode(part.substring(5), StandardCharsets.UTF_8); - } - } - } + if (query != null) { + for (String part : query.split("&")) { + if (part.startsWith("date=")) { + date = java.net.URLDecoder.decode(part.substring(5), StandardCharsets.UTF_8); + } + } + } - List result; - if (date != null && !date.isBlank()) { - result = service.getByDateLazy(date); - } else { - result = service.getAll(); - } + List result; + if (date != null && !date.isBlank()) { + result = service.getByDateLazy(date); + } else { + result = service.getAll(); + } - respondJson(exchange, mapper.writeValueAsString(result)); - } catch (Exception e) { - e.printStackTrace(); - sendError(exchange, 500, e.getMessage()); - } - }); + respondJson(exchange, mapper.writeValueAsString(result)); + } catch (Exception e) { + e.printStackTrace(); + sendError(exchange, 500, e.getMessage()); + } + }); - // /search?q=... - server.createContext("/search", exchange -> { - try { - setCors(exchange); - if (!checkApiKey(exchange)) return; + // /search?q=... + server.createContext("/search", exchange -> { + try { + setCors(exchange); + if (!checkApiKey(exchange)) + return; - URI uri = exchange.getRequestURI(); - String query = null; - if (uri.getQuery() != null) { - String fullq = uri.getQuery(); - for (String part : fullq.split("&")) { - if (part.startsWith("q=")) { - query = java.net.URLDecoder.decode(part.substring(2), StandardCharsets.UTF_8.name()); - } - } - } - List results = service.search(query); - respondJson(exchange, mapper.writeValueAsString(results)); - } catch (Exception e) { - e.printStackTrace(); - sendError(exchange, 500, e.getMessage()); - } - }); + URI uri = exchange.getRequestURI(); + String query = null; + if (uri.getQuery() != null) { + String fullq = uri.getQuery(); + for (String part : fullq.split("&")) { + if (part.startsWith("q=")) { + query = java.net.URLDecoder.decode(part.substring(2), StandardCharsets.UTF_8.name()); + } + } + } + List results = service.search(query); + respondJson(exchange, mapper.writeValueAsString(results)); + } catch (Exception e) { + e.printStackTrace(); + sendError(exchange, 500, e.getMessage()); + } + }); - // /refresh endpoint - server.createContext("/refresh", exchange -> { - try { - setCors(exchange); - if (!checkApiKey(exchange)) return; + // /refresh endpoint + server.createContext("/refresh", exchange -> { + try { + setCors(exchange); + if (!checkApiKey(exchange)) + return; - if ("GET".equalsIgnoreCase(exchange.getRequestMethod())) { - // přečti volitelné datum z query stringu - String dateParam = null; - String query = exchange.getRequestURI().getQuery(); - if (query != null) { - for (String part : query.split("&")) { - if (part.startsWith("date=")) { - dateParam = java.net.URLDecoder.decode(part.substring(5), StandardCharsets.UTF_8); - break; - } - } - } + if ("GET".equalsIgnoreCase(exchange.getRequestMethod())) { + // přečti volitelné datum z query stringu + String dateParam = null; + String query = exchange.getRequestURI().getQuery(); + if (query != null) { + for (String part : query.split("&")) { + if (part.startsWith("date=")) { + dateParam = java.net.URLDecoder.decode(part.substring(5), StandardCharsets.UTF_8); + break; + } + } + } - // pokud není zadané, použij dnešní den - String dateStr = (dateParam != null && !dateParam.isBlank()) - ? dateParam - : java.time.LocalDate.now().toString(); + // pokud není zadané, použij dnešní den + String dateStr = (dateParam != null && !dateParam.isBlank()) ? dateParam + : java.time.LocalDate.now().toString(); - // načti data pro konkrétní den - System.out.println("🔄 Obnovuji data pro den: " + dateStr); - service.reloadDayAsync(dateStr); + // načti data pro konkrétní den + System.out.println("🔄 Obnovuji data pro den: " + dateStr); + service.reloadDayAsync(dateStr); - respondJson(exchange, "{\"status\":\"ok\",\"message\":\"Data pro den " + dateStr + " se obnovují.\"}"); - } else { - exchange.sendResponseHeaders(405, -1); - } - } catch (Exception e) { - sendError(exchange, 500, e.getMessage()); - } - }); + respondJson(exchange, + "{\"status\":\"ok\",\"message\":\"Data pro den " + dateStr + " se obnovují.\"}"); + } else { + exchange.sendResponseHeaders(405, -1); + } + } catch (Exception e) { + sendError(exchange, 500, e.getMessage()); + } + }); - // serve /index.html - server.createContext("/", exchange -> { - try { - setCors(exchange); - if (!checkApiKey(exchange)) return; - String path = exchange.getRequestURI().getPath(); - if ("/".equals(path) || path.isEmpty() || path.equals("/index.html")) { - String html = readResource("/index.html"); - if (html == null) { - sendError(exchange, 404, "index.html not found in resources"); - return; - } - exchange.getResponseHeaders().set("Content-Type", "text/html; charset=utf-8"); - byte[] bytes = html.getBytes(StandardCharsets.UTF_8); - exchange.sendResponseHeaders(200, bytes.length); - try (OutputStream os = exchange.getResponseBody()) { - os.write(bytes); - } - } else { - sendError(exchange, 404, "Not found"); - } - } catch (Exception e) { - e.printStackTrace(); - sendError(exchange, 500, e.getMessage()); - } - }); + // serve /index.html + server.createContext("/", exchange -> { + try { + setCors(exchange); + String path = exchange.getRequestURI().getPath(); + if (path.equals("/icon.png")) { + byte[] data = readResourceAsBytes("/icon.png"); + if (data == null) { + sendError(exchange, 404, "index.html not found in resources"); + return; + } + exchange.getResponseHeaders().set("Content-Type", "image/png"); + exchange.sendResponseHeaders(200, data.length); + try (OutputStream os = exchange.getResponseBody()) { + os.write(data); + os.flush(); + } + return; + } - server.start(); - System.out.println("🚀 HTTP server běží na http://localhost:8080"); - System.out.println(" ➜ /transmissions (všechny přenosy JSON, vyžaduje X-API-KEY)"); - System.out.println(" ➜ /search?q=Brno (vyhledávání JSON, vyžaduje X-API-KEY)"); - System.out.println(" ➜ /refresh (spustí opětovné načtení dat, vyžaduje X-API-KEY)"); - System.out.println(" ➜ / (web UI)"); - } + if (!checkApiKey(exchange)) + return; + if ("/".equals(path) || path.isEmpty() || path.equals("/index.html")) { + String html = readResource("/index.html"); + if (html == null) { + sendError(exchange, 404, "index.html not found in resources"); + return; + } + exchange.getResponseHeaders().set("Content-Type", "text/html; charset=utf-8"); + byte[] bytes = html.getBytes(StandardCharsets.UTF_8); + exchange.sendResponseHeaders(200, bytes.length); + try (OutputStream os = exchange.getResponseBody()) { + os.write(bytes); + os.flush(); + } + } else { + sendError(exchange, 404, "Not found"); + } + } catch (Exception e) { + e.printStackTrace(); + sendError(exchange, 500, e.getMessage()); + } + }); - // ======= API Key ochrana ======= - private static boolean checkApiKey(HttpExchange exchange) throws IOException { - String query = exchange.getRequestURI().getQuery(); // např. apiKey=xxxx - String key = null; + server.start(); + System.out.println("🚀 HTTP server běží na http://localhost:8080"); + System.out.println(" ➜ /transmissions (všechny přenosy JSON, vyžaduje X-API-KEY)"); + System.out.println(" ➜ /search?q=Brno (vyhledávání JSON, vyžaduje X-API-KEY)"); + System.out.println(" ➜ /refresh (spustí opětovné načtení dat, vyžaduje X-API-KEY)"); + System.out.println(" ➜ / (web UI)"); + } - if (query != null) { - for (String part : query.split("&")) { - if (part.startsWith("apiKey=")) { - key = java.net.URLDecoder.decode(part.substring(7), StandardCharsets.UTF_8); - break; - } - } - } + private static byte[] readResourceAsBytes(String string) { + try (InputStream is = HttpServerApp.class.getResourceAsStream(string)) { + if (is == null) + return null; + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + byte[] data = new byte[16384]; + int nRead; + while ((nRead = is.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, nRead); + } + return buffer.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } - if (!API_KEY.equals(key)) { - exchange.getResponseHeaders().set("Content-Type", "application/json; charset=utf-8"); - byte[] bytes = "{\"error\":\"Unauthorized\"}".getBytes(StandardCharsets.UTF_8); - exchange.sendResponseHeaders(401, bytes.length); - try (OutputStream os = exchange.getResponseBody()) { - os.write(bytes); - } - return false; - } - return true; - } + // ======= API Key ochrana ======= + private static boolean checkApiKey(HttpExchange exchange) throws IOException { + String query = exchange.getRequestURI().getQuery(); // např. apiKey=xxxx + String key = null; - // ======= CORS ======= - private static void setCors(HttpExchange exchange) { - Headers h = exchange.getResponseHeaders(); - h.set("Access-Control-Allow-Origin", "*"); - h.set("Access-Control-Allow-Methods", "GET, OPTIONS"); - h.set("Access-Control-Allow-Headers", "Content-Type, X-API-KEY"); - if ("OPTIONS".equalsIgnoreCase(exchange.getRequestMethod())) { - try { - exchange.sendResponseHeaders(204, -1); - } catch (IOException e) { - e.printStackTrace(); - } - } - } + if (query != null) { + for (String part : query.split("&")) { + if (part.startsWith("apiKey=")) { + key = java.net.URLDecoder.decode(part.substring(7), StandardCharsets.UTF_8); + break; + } + } + } - // ======= JSON odpověď ======= - private static void respondJson(HttpExchange exchange, String json) throws IOException { - exchange.getResponseHeaders().set("Content-Type", "application/json; charset=utf-8"); - byte[] bytes = json.getBytes(StandardCharsets.UTF_8); - exchange.sendResponseHeaders(200, bytes.length); - try (OutputStream os = exchange.getResponseBody()) { - os.write(bytes); - } - } + if (!API_KEY.equals(key)) { + exchange.getResponseHeaders().set("Content-Type", "application/json; charset=utf-8"); + byte[] bytes = "{\"error\":\"Unauthorized\"}".getBytes(StandardCharsets.UTF_8); + exchange.sendResponseHeaders(401, bytes.length); + try (OutputStream os = exchange.getResponseBody()) { + os.write(bytes); + } + return false; + } + return true; + } - // ======= Chyba ======= - private static void sendError(HttpExchange exchange, int code, String message) throws IOException { - exchange.getResponseHeaders().set("Content-Type", "text/plain; charset=utf-8"); - byte[] bytes = message.getBytes(StandardCharsets.UTF_8); - exchange.sendResponseHeaders(code, bytes.length); - try (OutputStream os = exchange.getResponseBody()) { - os.write(bytes); - } - } + // ======= CORS ======= + private static void setCors(HttpExchange exchange) { + Headers h = exchange.getResponseHeaders(); + h.set("Access-Control-Allow-Origin", "*"); + h.set("Access-Control-Allow-Methods", "GET, OPTIONS"); + h.set("Access-Control-Allow-Headers", "Content-Type, X-API-KEY"); + if ("OPTIONS".equalsIgnoreCase(exchange.getRequestMethod())) { + try { + exchange.sendResponseHeaders(204, -1); + } catch (IOException e) { + e.printStackTrace(); + } + } + } - // ======= Načtení resource ======= - private static String readResource(String resourcePath) { - try (InputStream is = HttpServerApp.class.getResourceAsStream(resourcePath)) { - if (is == null) return null; - try (BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { - StringBuilder sb = new StringBuilder(); - String line; - while ((line = br.readLine()) != null) { - sb.append(line).append("\n"); - } - return sb.toString(); - } - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } + // ======= JSON odpověď ======= + private static void respondJson(HttpExchange exchange, String json) throws IOException { + exchange.getResponseHeaders().set("Content-Type", "application/json; charset=utf-8"); + byte[] bytes = json.getBytes(StandardCharsets.UTF_8); + exchange.sendResponseHeaders(200, bytes.length); + try (OutputStream os = exchange.getResponseBody()) { + os.write(bytes); + } + } + + // ======= Chyba ======= + private static void sendError(HttpExchange exchange, int code, String message) throws IOException { + exchange.getResponseHeaders().set("Content-Type", "text/plain; charset=utf-8"); + byte[] bytes = message.getBytes(StandardCharsets.UTF_8); + exchange.sendResponseHeaders(code, bytes.length); + try (OutputStream os = exchange.getResponseBody()) { + os.write(bytes); + } + } + + // ======= Načtení resource ======= + private static String readResource(String resourcePath) { + try (InputStream is = HttpServerApp.class.getResourceAsStream(resourcePath)) { + if (is == null) + return null; + try (BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + sb.append(line).append("\n"); + } + return sb.toString(); + } + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } } diff --git a/src/main/resources/icon.png b/src/main/resources/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..554c8026a92621a1adab4d6e1f6d3a130e4dc023 GIT binary patch literal 17421 zcmbqa^IIj}*R2VYZR2L$IJr;mX4_4+t()D{WZRl-d$MiYu6MqF!~4V8``JJ4=bU|> zb=F!ZLQ!548G!%+0s;aVBqgT&FDL(7o^Y`L;u_|1} zfl%B5zJX8!ya6BJ|9AYxv%OJk5A4J+U41%v))VsA;Qp`D7edIopO)^qShq#yGF&A$b=$*}pRDG5dwmc>1W3AKYxkhNJC!r|19Y=X|Hw64pkL7_N0$Yqz zW^FbjE)O~VoDmQ?>=~awsAKTRsPA+Wf;Rz5v`JRaKqel|(_D;`zwH)!q+5*PppD** zmXwoVGb&pkrXkkbA-4BNjKX0`cSWxHh;T;H*<$oq0OZ$r2<-}9QFc(GNiD&}q?MV0|M zxTiXkKR9SkG$`bAONmrc|4^NkCt67~u29pR_2hS4v#g1#jK`m@di>-YU8OyaEA+|5 z?7LH6s$QWIy3vPQXl!^vP4dzIH8|kfTt7eq2yw&iu8@}wrntZnclfu{X10MP8IX_dP=BFVf*^$?=8!rgxdiQU1To3y9)Rklj z&xvdn4KoP;ajDMM^1aYsF!PC5+u&DCvt(kW2q;jDb7o4ur!)A>h;w*!43kurET80( zl@%sSmc(O0GWcA4dU+S}4O8ceR_paLrI;#{8hRhNR><+ADamxenrwX>5D)aK5cjW# zXSh6y#qEqKaF&@s1i80AS#5uaR9bQsGe@vtcg8;1RdBW4Rvc7CC@Vow@^6}JJ-*76 zeN42c%3@>ZDe%5p$7#b|BMd={YYl)2I-nlF8p55q<)v|;eup2F`*I z2h>q7Ph1?R6PCnl&`Xpe6d<##&C+t#D`_cLVY2XiuB9e!iz&luLzuB&%y-pG<$JRN zb`RCwf`}P{J~D9N3M28Nr4UH~kZ-Y)LB!Zf5UR+!a$EvXck zEZ2Gv>s|T-tAql-jiPD++AzCcgNWerX0f17qTZTY^vti zF3h-qf|MN?HmXyNI;cxo;~AWM5{{D1^q)4y-}&5ZOowBcqR*HAF2_zp+iv|`ZkpJy zqK1I&l^Rh5AwU#NrxKM2@<^LFMc2*PUU0CsCEd)}M#tF=A0UhM@ApbZ>|^uOFrqwq}qMx(CJ=80h-5S1j808P$3WaCba-R1kR`Q%nlIiFuVdek-JR7|&u{ZXphu zWy@ZtpQP3AJOA^(G-^fZ6fsr#9LC^d@CT8c-DNY#nd8u`S7*Wboe(6LwW)x%=f8CJNe zuz(lsrTV*yX^J7+lb6*0h)`=?2(9RnW8-IE-HXC!=IT9X?-rcaIi`JPCc91bv*jz@x)4FYie^ zZBFAxfqa1S6O~;B9ehbEA`rwR>aa|+Df#ih(wB|^8>eUpTARvF(u@St$EeE_i>iax zGA}0+l^lAi&JgrJ(tjwAzXBz$zscun?aSJ&j~xlV8|gpp&aF|*ilM+6s?v$kLJtig zeC|``9IonIp^7T}{uWWj%Ei@pm*Yy3<9U^lx@8_z^utVOUJ_La^B0uHmJ6T#*S2}8 z0}d;E(|Glqh1_j~kS|}2$6?yN3@iaaFgn<1Wim6|CB6>hFL$Tes-CJ-uyEu4Sq8Apo zNdGNm^GNiG(Ov_Nt?rGlN0XZ0Z`WAw0Mg*Z-$XM51BS)TSMTP^?Xv(xcY$jE1)c#_WtDWh~ z_8#eU`YU|LeHm^V_*a_DCi6GerZ7X;o4PXpGk5auK88gCCj|ND#BrVj9fR%tE8mF3 zt{Zov&wTUQS)#aYu@R=@K1h_0Z9bkmZ-ec7|1WR(_oePVki8%N1c0L{PI-b}Gh`s_ z=URe=8Agvq3-e^7yEOeVl5M;6hG_lp9EPNfGxcEI`QTJ=h-e{!_8M8LrD}STCi$LO zC>Go*SQuT5*n8d;n&b&FLD50b&K;{5GqW(aXc6mlGOE|)25^%qUWfMO z)psS2BtLd%Ui|oB>|{)P7~he~HOeGn#t5n!Yco!us_}roU#g{cQH1I(URi*x$E*-t zraM;WCjU+c_TW^6+o#nZlSV*ISjO!Cf%{MiL{tLnQ7-=pp2v&j-A7~QKeCBbM}&#& zGqD+wEvm`MF>uGsXo^WJ2Jt1@q8l9km?Y{9%{$*2UUHrqTL=d!UI}Bz6(s-|vo-ea z6XgwSwR@ZAH;y%@z52? zs)1ct^zfR9YEWtMGj7@*mF>N}6BHM`)=P~8Caf?Aw4co1FrfReMm4g3 z2)On}QB)g>5fb@q(m7nSN%j5Zk@``*|0@f_I^~)SW#D@{9JdleM9g~Q7_gC+q?cR| zngNKV1S1wAeizF9@VrNROI!!TmwlJlECA$kN=fIrh{I zz=D(RH0*mm_e~uXCrnNSW+-Bs;bIK7N?{-s<1vb0u$#;ZLLcl#O&+CEq7;mrsnXMx z8x?CA;w>RGuREf~c-8O8?CV*;Av0-Rf|Lg6)Db5IFT~1| z0E?EX6Q=qg)oG5vDr9xvm+yb?`b!n+FfJ^(#fXRAxPx&3-xjqx>PuD@7M^L$K z;!tjHmjxi5k4VCqQCv}lqw*?E*|-UWH-fJNz1O<{&Ev_F=}NE4q7n=jFM8HQgk-3HK12$~`;7zCDo`Q%)C< zh&FY?oD03;F}{I%(=#?Kbp!AaL)rvz_#|pG9kk*K#6-eUBw=gO*X|-{zR(7pH7AzA zkm`zs+i~_%kS0JcMQw|K;bVx$vm1!wHa!TtKc5&{FCr^i&b|v7&xytb+}JcDH!b{r zfZ`#1Lu`8T)Rq{HQ69iizGCl(S73hBYpa zx$&^gd}xGieb(GMh_?uADEW!h9hS%23_K+2r^$hkB*kDxWFnNmoX(Bu1T3mr)GEq) zj&V>-;Un;WY2hY>Q%>pJWallZ*Z)>K<8qi98+LHK211*9@$x$yjWyb=w`E1r0Z;q( zH8FH|dET#0GacrC73#BQw=Ck`)ksI~UbW|}j^KeZZK1RBE6!w3#0Q3=^yGqWZQj^o zx$ih8{U$27_e@iq#wzrOb}>`tZe!0!iiqyhqj-*!ri@M)a)#ei1X6C05TG`L+4%PG zYH0hX_;N&9yy?a_?w2(F)>nXIIh?1X*qgKLONiu0AO$ z7e|a(*8~_wBeNSIW2Q4DeQUk{=J91Z@_iHe>n?8D@6rju1Yf5GZ}Zjc@7pKz=ee)L ziZySBf>=i&(waw2bAae_U(<7 z{`M`%D-XW+9i8plX4b13p}tv#FMR7s-h_uF92k*ba0T-P7xnej^t1Tl%Gk4vrawQ? zGF`b67Qqr4(q~$={^6YBl;@vxIf%G)YLJ6Z0H*}{zIc4gS1gkrD)SE8w`sM1G z3;uHv^7C1sw`)I9w<(es7q(+l4W7p>#Kh#k>MQxR4D7s_xz#)6+BTXnYub8(VB?8Z z5-(1v%Br~CQBnt)C*)G}URBh92}$~h8_-Y)iZ%JA?1F7kYeE}!j7EK2R=#l`qQ!dk z!bE3$b0lHyQ%~EU*U&{8KitDb5n&2pBJ_N|8P;^!nd3gF_ZR&dXBJK&5zAJmO+cvT z`mcUg(%KMCuO&QCL$@!&{{xrNZ-Gj76}_@7aZ);Vx;2vp&sFXZqI{5e|30&YcYEI_ zxqADqH)r2E8Le-G!%pi_d@z(SU$~Xb;?fk0-79CslC4 z)B%uu;GvhB5;Mb)fs=zhp1{YLybrEL612^{pfuk|s+;pKz!V$ z=w=rTvDI482|bT;Ml0ZK>x8p7P?s2GV9gqzJ!aJK^&DhrX<*eR5T=gItX&qjxk4wZDn+pCz}pF&`f?zAhu5ONRi?joR7N**j4Xq* zVE;?un;K)O4=l`%abHIu{6WDKH-|LI6EucDtegsRS~BcSGw-h}QG7NOF3>s(^#4K+ z1K_KwT>GY0N+?&c`Yo`uydnD!gvxC7jD0;yaJ}c$n5+Zj(|e$ig@orc5fY&(PZ>8U zP$UZy*c|$txZlz6O3AwLZEhSFg))wpQ3vQrmE0CqNIDtdk}8MtVX(7r?&~dW2q~3B zcl2ug%9JlEZZ1f5M;CwH7}_N{=mzxlHZE<6m|FO0THW@3M!REGk0z@zcz&FH>P$n+ zY5s~xLB^rmtIQ7}lA>SpuggX3djBBU_v0dATe1kE%TIEwOT10#^b<4gh zi_yuf)tgp1*Rf=ILpsVSrcLXf9W|+*LU*(9N?gA!-en(fnalAW5256DdxZdRsL3Fw zjw*n>su{1_6UJr(J^IoYzu!D-=y?~01Bd13vE|Xs@l;<|SPb9t^+yhSu9og?_>dWV z+wQwb+`qBzOmO~sCeHl&>I@Q{6ku7!2$E9*5cusSO#H)1W`Z6zdS=J-O+ zTP?2#1x2PjerqOAHeF?$LTo{r-HQ!Ykq_X2G2tV&#QoQBdMsPLGo|{EK5XIH_qg$` zv8D+^aEWjx3RL_;%h!&Y&59sS7+X-k)7u9_>s#P=bi~&G(4!TmoihE_>oVKk9gvuU z^Ea@`JP=i*dnn`PbRC7X&`)P%YTttfCfPbeOH!O^4q}AxVa|fwMf|J(8Z=^G>cNNf z!!WRZObO(C%CLZoMDNwC3Xz8&b?i#m*d+3~s((rm&FL=FD0-yY^y~vToGq|`C%<5U zvjJYhYVDcb4ehWZtsS&{Y^IwL<3=|W2!wnx!_DR;&rE36Q|OUs>s*t(CwQ@5v%Of% zTxL8;k}XGpVXa4jlKDHc+tEAaIbYz$r$6$C2N-T4M4^Hc@?TQzWuJT-Ss3&-R)1c z_PIA4t#@NW@b%(6d|Nkz*s(wE_1wz-ph&vSO$*6q#aSlXeK$ zpn#xKqRBvrQG*`Hdoo5+nUI|O#-%hy*kmceH?PnWjc40=lAxIF=!4X|Z21e&u*wtc zX`;ip-u#tUd?hbxzP0kSq%(iyzM;KNuLu3$^TAb$z6F{v$qHG zvo5TtGu;<0=l|5ge-ojpDoob?g7~_?fG0e?y;HZw(Llq9(#TMOefksQoa7m?!JyXS&{wLXrh%I}_~L`|$AT z`_ru{_+YrQgN!(r>1w%6dNn&(xuNK1OvdP|h8L$h9AV~l!a=N1{a9M}fA5nczFN{@ zm}D-06U9-cGVgjITm9-!sXI=H!uQ!2PkS2DV84o~`FR{uW4L){(3`K(9sP+om8XyV z8v!=Ch50n-?mu!M`Ir%|0i4WHP(;+KvUH1{2`PqkTR`TgC3S^+jG_{(D1BdjwjW7M z9h0rGa4q2qz{p{fzw51&0WTw<`)ktQuBnm8q6 z6kv~A2JcU0?+VZ-0uB$D@90QmMVa{AuHM%c6OO=y3KKie<6$EZ_kK=|qaxbbTLNnh z;4pzqWA`u_o#ai!6nrmXe3_?7{fdaIzs4jrxuN+?2oii$!g(M3u65n?gEgJ=Mp^8r z*YLHr+=GDwQ}oMd9FO}$6YnyLlbCOjh|rM~v*M?}0}V>qJO40|obWx0Onbsc6{KqFw^!Wu&x*~;-4yTp-+uBaQx@AAN6Dfo`Is|}zlY>?9C$?$uX!NC=2 zR8qVFW6Q`Pd+pg?SF9P?1h-j|B}J>RDs(o*cW}un5f7OoUXOm0Its+qo`^UOv-%J0 zpPAdM(qwfabSB1q;}8jWUJE&dW8Y~tBt>Ibt}HD)7G%zRdUX=?L6r} zAv9I$i0%+=4ttmHLPu%~8N4nwmmx6?6aa<{eQW9DV`Far;C81{^>ea8%3>5>3X=q) z`l<4_1-dqG3su6GpZK~55?$dM|UxW$DeIRa;wHm>k3=!8_GT5w+ zI24F8;r}c(GW3R0w=Mi*$yd46*E4jXO5}k-ggu~9b_gFuApLQgv6I)Rx@2F{6$WGo%bIkp0=i)w#IdW zMpw2~BWj}R>g+g0wBVm)|M%x%j}saB=%|*ggN!WU@ok205(t@nCOR}84{Jgrt1*=L%bc*8iS?vU)(I)o)br{Z#?~=4B%1 zi{SO?t1kf_#$L&!K!X;bEe6vRT`!&)gUu0RYU2=KE6GU4w@cQ*BASjo%ct?jV!@3+ zba&ol+3#K%p<@12F1_0`I)uSpkq(0h6d$8KElqTWQua&0ljj9&G>?m9TS@6IByam> zMjv8aR|;C)#7b0OVg32*AS|BL4M>l3CcwllPmWVVSLS>V&!JJ1_toUBb!xq>l4%*T zs61Xsu$biy81_5$by%g_PeQUzBnuo9To7Q*hVcef*8ZOE6Ep5)#;9mh2wy<{$2tOc zw%Na4O$2XNYJeOaSbNSLkV{pDL*iT8t9DAn+tcEGG=leGnZEBcfP-XuOrKL>v@2G3 zp^=T6j%Z5K3H%Y0&%y@Gqywf31`^Ec(;JLJZFcyzWz{}1ZMxr)h(|xF@+^Z^`b!gd zOR>nevf4v^W69-12Ns~E1b&7jltw-BLV{MAXN?|_TH*EU$sFftpTKU5%vBmzA^lB* zO0fw0L%ZKYSKi<2dCu)O!d`*n3}YeM^g+adHb)mZc$Z&F7o0>beq!YfsP z(xq2?O{S$NbM_-ET%E z&W(z&8QCw$!w&s3TTX?Wk~(@X_lCQQ@Jof0D&qp8a>I)ChNUNXcC>eA*)I<*4tP%t|g3{?d=(61(o$&(Ja+$1L8eysMGsSl1d_Uf&OT znADe>fbt4PPx#x*uBR|XsD8%mewqSboM)r9&I{72vW4^wLZYkNx*H3W$!eqDqFjE~ zk$<&-=haMBiCvbx0=dx}UT7cQQ0VJ+spuNwg17dcPHJ^Rs*3zt1motjtNS~5sDoNM z3>+X1>d#ES-8#S`^k^YLXc^v)JU}zNo?{T3DbyPND9e$4ft$lUeQ2Bf@9Lth(Rp@Q z*?f>?9*tLHPUy~3xS@=D+6GAPETTPQ6+czto$hGD>8t50E|^@cPSzuyJvJmUC9wqG z3dx92vIcxb^zS@o2{|Mmt}wu5BkDtk2WB6u?du^nd_;G8dema?GPSZI={wLfX5$`0dk1z>sHcX9 z8N-}l{g80G=s~6(eC!G^){W{%)$dc857@T9T7;pYL1gn5YY>oqV|Wk?NY!u9 zD^j+J!W%IATSLYF)TgrCae{u@l`9{Te`(2yNF538(;ON;I;uE(T!>Rj z8Y;ZSXgDEp`T7}`nxjC`mIX$48XCbbFw6wQBT%<1XNeFBB+kKZK1uPeP|9t)@_%0N zUY$kwKGnQQ^Vs!~p@fZxh!0Km|HYwUFJ;PFBPbp2cqa`yI z)rOj#Y|afn$(x)Lc$?cPqEa*f`CF=cb+&Fu60DF5$Rz?Wi>!#Mm{On-;;i8vqLLcOVD_(jd;EcPVH3H_zNcCf!7Jv^ph<( z5u=^?9UdBO-tTdFmKlb;E2(dI0!P?q1XR)x+lmH=6sy$--mLj}ol<>6V{sIyDmmSN z5BL~-{!71rVX)j5qq}4thwEgW1f02wcvU}^d3lG#>cy2j$~U1AeKdW0 zc}-6`$Z?pDDdl(}<;T87g{c<|J|{EHFIMHH2X7N)UC#?QO$=Pdmk-#XA*QvNR`095 zrRhywQlDep4o%IG;+v1#xsG)uU97zIN1Or_O@MqUvBR;nf5_RsH2N{ChN$39JNY1^Mrrp<1~ddsn8p zzcho|`@=p$^r!4K4Cs*ej!pm>j<$5R?SfGO$bq+jP`2wCP6^|TN33IkzQI!n8_^OU5}1fZ;|J9 zyei?+ga}Dc?QznQ{;*r<2}~OCw|eGP_Xh(qq@XN5cOgob;{-evblj)4g#!nSd}$g% z7g?70;ER@>$jy~BY;O=Fu2)Ow-;j&dgEdkt%oI}IeTJ-^L+MHq*0~dxmTQ$<)oGUg zUruQS{4C^nitRPuXcY%S^tG1NhGc z1wZUmuGU8tGBgjKj>VMxP)IqsdGmMD1jRnmq$|s6I@1sz6Ew-`rOm_P#b+)xi}>&- z-4N7d-#)o2S6r8tU4B9&{i9l0Rq=#Nt)@5BN!*JJrO zJ7u#ZkjST{8-5J9{oo}jKqeam!Nl-ch(+jF7H?%`4})i#E8oi0uuZ@NdYc2UOxHhc z=M;auh;(!b^y_0(WQNI$UvK|fKKoWzY+hFtcL@!Kia{pPS5x`~V(JZGa7a(H<%*a7b?}Pf%IpIB9SbiN- zc&H2|oPxpOG&WI6SW%RNgCopZ&0QNI+bd|i)4$<28Ch^MK$T=a`nwBVHbhse(5vAH zem?8NO3!Fcx?zLx6`J@c?~l)Zz-TbbF{B7dn-6Cz)Bok3o99vRK63D@WLxP!RW zU`}Qsb_tT5QLY4{aHjSeN{IS)zBA=h!$;r(>cTmV{0-jz$dk*IB&(Ac8y>*$e?G%r zwtOf_NKiY9&-j&Oe`AK1nDr=0X!Ur&GXYf=(eiJ4zrJB+JI=rpHQJD;p}w$0&-Trj zCpO{!_kD->Ke_MSTCI^u);~<%LTPKmoiE-AO@e4_X7;y3)Fyc!pxNfAs*YD!D2p)} z6d5EvEGE=1{e1*r=wKCg1s2W8Vat>dG$hxdhl%~rhKb$a$~bpmP;LZ?Uw`AL5#~vs z!_+lg93RzU^*n-xDXqD#lk9y`&iq{2&z5Zaq>31_%}ScgD3e(X{ODrYCwXHvI<{9j zw)+sdJ#NsbRXVuY`ef}8@;SR<8u%+$funJLKAb}BhhBakXYJ;x%vg$RdP;c@V0?;H zn#x8acx6aB?kg~+XK%=n^XOd8q>&8lG)M4orB&wQ6WNlKz>$if$yd<=HAJqVA&OTFd-ywEI~F1)rb?gIe^0D~p0t+NEA$*SueI{4OQu1Hs_!QjMcy z&_ehWF?!0um@azTH!)&HPWSVB%>m2Soun#8ubU_PU%+DJ`DH{WS@QRE4`n9|5`DhD zq<_wyDgTqR=TizGd}$PBU+JowfaO>`^^FjEWu3=S-4GkAI*s)r&si{~$MD+LNJI&d zc##=?Pty}r^7V{jyWJaf^Tr1-=OxVEX^YYtRQ{0)=s<5=unKipL%UV24ijEdWj|Ns z8Zt~o+gQQt|7r3qQJD2l5TXK4h>+KuHTS{%0n%bFLD)v__aPtg?>&z8FKa9x>^ZNe z%_lkza0w4azBB3%_&kRE>_-2NMiwV zm*1dk#}SLrRF41Ycxv8Ye32$1=$rVi11K<^h!usEgq0)%ZU_v>Gw~vPoH@|!0MQ1V zb_o6jd#=APTWvmX3LO;~JpZ`#v*3dv2l~4^!F9h+&M{vQxy8rrM5F+&R7Q;s)g{ z%NQX{>36p+E%@SYu)XMgX)+@m7M!A#R@>T(iBz1AGlNC-{PEjgRBZY>ZJ9j=wp$(> z*-XJ&>g^5m3j2K6?HkA7|9)5ItI_W=4VCk{oAUA*_Z1}?%l(bYLoIZJLj^N+df8aS zL>wulO;xH zL+7*pQv|iVEb^@g@}ko%jJM!Vd&+b7dMfOQK%ahfJZeNQ=y;Ikw?natxwmlrO@~5n zPq8ucoF_4gi-5`9oU!1bRZNhEp$vuYmAUSAGX|+jWs$qWFX}`$;~7YtbM7oSPAWQP zM~;IUu`d{uSYu)oW0wmG3RLdU62CXaMl0c$<|&gY5718Lg~|Acs_pv1h41ty#HkII z+n3yK@Pdb}!nF{G6wU1FxJvt(W4f^ zFmRYc7BU{J@$2dQVbCk^KX&z(LzbZ0Rl*d5`J2bcdq*6#BluI217r*=1)LCbMGY29@^PRsG`uglSd zhSQSV*XYKNk7(=aXOyFCABu^a8;k98q$LP#48zr*V%`n%4)!Nz2KeR-18-v(xs$02&2V<^Bae7SWVhok`gL91jRMpdy z1G*peHQum4-!JUXS?eGG^xLg1bg(G{?e-ct9wi z&V!{Ce(~(~{W1m;!J{fTB7i$yeLfK&c6-MYf#tzUOJ{+j=V>_HJ1_md-fs_wM7J|L6hnVwEtZ74aWfis z8c6}0%5-n}eiJd>Se;Yl_*)K~J@I|&3*%84sA zjL-~^47&q)yMktJ(1(U4@K&0VhDK;-$M#Hkm)y!L80F~{g5r`P$T^xsyfL=g!RG3| z@f?E8yx;Yx+F*sR?NZ&8(%6|u^~cKfKupLiGeqgl;a@GM1dDd-1Rq!Cq8}Cuk37SBkZ09?pM~Pz}F$(?Ml_?sNVJICRX|&s3<9SWL0VT`8q4+r^k=GRcYg^3JU^g1?wIU% zo&7)U1fRN^uUnrChPFPZe%!U98cdc5zHfQ%Rpek-#4cB|oBkCPZchx8K=m&Yun46c zzvy+Qw=do(Csf{K%Xc6z&3Gco-%4e0iYy#r`KN5iT_kf8--&rxCY3nA=xSK{_21ov}Y?!RM@{N~U8wP_a&MG-3{u#lQoR^0m{$QTt8oM%fIEzcV zq~z6C!BUz#*t_-O>uPJhW+$xh46(3 zk5y?gYKJEF;%zj)YXBi$$U%1N)g%w z*3I?1U24(tTzx~R@C(>YZ*%~7V-*su&ZPEBk5nsDl0^bpdN}y1QSe@@_DJttxoU>A z$nvDw0JQs`R5wzB3-b+2D}nPFTlbKSE3~-?GPH-1w0`a9DqLPGyQ{4y=nV{p+sbyK zbF7{Dl_X|J3$B*?7u>zm9V*2@7w{`sx-l;2W7lhlkU3Q;eeid*N65t}ZRuL08wF3U&li zz`HR+5j1RN^jJUTm_bp_N-wb>9)KK@?}u9T>xqAz)kf2H_WDIO3^!=G!zAtV=7&a-}b`|CMeLum&IJb~|Th(v4ohv2(n>WRe3!<5!lbj_8dY z>#d0Xt=r{Yf@|v*JKcs6K{cr&vm;9Cfoo0T3Fj(Ze<14P6&N@e)p~k*hHoE8y>lRC z>dS>){q;bMRmgD*OOH~M4JfO%o%8zKo!S~UMDX}=fX!s2F6FI`Cqm-F6?_i%ckc6} zT>K(DuHG~xPPaPVP=V%)E)8IrCd&4jJW;Kpl41W-Nx*oSkHoAwkka)k*Ay!sZ;dX6 zO)4-m)_SP%L%9?tqGoZf7I=xCeG`qiH-{ABLKwp5Kdv0yO>BHY)GoN^9bp10%n(X}I66ek=MSN?bz*hB5=afy&yrjX-IagMqFls8 zo-0(JioBB0+A$S%qtw;W_dRF*?)*AR6aT}BAKy^XQHp8rS0kZTb8Fxn5!R{e^NQ<_ zcw{8Q%0aK*Hni`Jsdxvw=KRPrMADrIWYubJNS&QW5$vo>f81(u2TpGwiX;y{z5=w) zt-Rw}8Ze;>F670hLgnEorobVb$)vt`X^kF#wiT#(w8vXMKEJn|eTJ3&B%gm-WZLsN zG3XNh>NC>zj1mhOKrGX!w0D|3QJ}^YrNAHtlr+m+<<;VTK)KaadJ9)#Y@nWD)Vx6u zo1D+9hC-a&KR{Rqp|CyeK1uLBDa9bLucM@atrl)_!e$@H3k5v8AbgX8qjEeUC%iO$ znDa^f=J*gyS`R}B%L*FMs#|xw3cE!_5eMMZd$jvsW6nH}4*dT!_-3h#fN)jqW?Pdu zi7Bc-j_>nkKZSEne@0Y`8qTTlx2i2FA8zzwHOPhQZxaU4+{JZrGfB3=`r*}d$_QOv z;Dy@?TXOt|k_j4!6@WBFdYJL`C?`R{Q{dT)`+35^$ZtWns4dIrTpe3H)%v`GJ8KTl zE>F5Q-8@0Fv7GgOHQD+WqFE30K1`Qa2#2%6=m20DuZ=d&W&dnllg1Z3??{)P4JPI% z7H=k08E0>voj`$P4BZK&XX(B-raq(exT;Gq${Y+g%2zr%J+nKgL)Ou1^kn~l3Ib4z z@3#LLrWtB|-Zgi+-Zk>s6uG-@Ga?_N&k8;1-#$;hi?BThG02G?ZwgBd;DZ6=_;YC- zF7V(ox@cm8BcBKLpo;3Qz?%0rmgn8(nuDmV7naXYK8>5FuUpK|PaO@1!G)zTTT|!Y z$lVyksP-8+?ji|uGmA({!*Ku>bp-i0z+sC`VOg+>+ZLJb0JC>G!!$T&` zBgg8V^4)od=^dKux;Xzd|F_9Ty!K!U8v5s*q+VXGJ_eSy_!lTTkgBsGlm-(fx ziIVO|`}Yft?g{hmPd&lUkQ(QQ33pdp#T-JgyI7hrDzgAR1$x_@YA}-#7cOmI{(cWk2`nA!iK>P|5O8V?Kgucp9r|G&X-cm4p4qG0boQ{cz z%Bi0fQm8)mV$5}WQ;J!BJ+qkc!=D68PZjtqz>TzW8`qPUrcGY!57nBCfJPCjkfMM3 z?&aK+x$#dvFuZ)gjLo!=f4Hj-*G?t0LO9;c6mF;}igw?OB(voe*(sSkx0&y4*RUOC z1y)|so779|TGG(Y=%`Y~{$?Ka!0{87$1VP7yh+C}x6}f;XJRCLPQP~@(Q0MlPN}Jp zLEcR6xtn7y4VDN|1VD6_zE^HK*Z5jHH(db~3#OKq8Rw_*u&32Fz0Of~5*IaJ-_ZS3 z9?DK<5`vsnBHT@rpt5Oomp0q}eW0)#PlZ?qf;BS5paiR9+=^XC^y)-a{aogNe&If< zOe_Tm*F^qP^lR81w+%m5n-Mv5x|1dzYu^EagR*qMLF)fBL1D$I~ zD1vLwqZB@J3R_tye6DE_vx+R27l#6FNbwg3B3ADT{T@@Q1-x8HsED3XLNNTSC7sbX zqXdW8L<9gQ(aF6|^FzVyn(iG3w%#K=a>4?HdA1AVFtIP7)%h3M&SOXfC|8Rcp@y3Y z=$3Fd#g{0peX_z#ZY{9Pw!yC~Xc0Fy+e;#uq12P7>pGX!aYpGs{!^fL^&dv+N>JGc zXZ&s59u0Gt27A^)J$PkF9e0{KpgzQAT=}FCjR)1-B;hir7({vdGX-sd*QZveOZLuGcri1S^2N~D6&9<7Y5oI|qt_We#_ zx8L81N0OO9q+pndR$h7Y!#rmv@~aIh%Y0N$L>SCMlvuFVdd|tRLuv2N2~~#Hx8_!O zylKc10VC9LqrUkuGX*@MSLGmg&d&5&_O77wtcQW4C!h49i@oD#l>2X5N7}@kY8+?@ z!wH+xRI4wQRb;FpG1PqfM<#o;Wb4k1jj32FI$1N@bLDG)XMs>^FrW~Nnzp%&9iZe% zN=zK}f~$*R9$~6B^#1!s9Hvy2%|=-mFp%ct$YQ$t`*7K9^FCe1^NX}Avo|v4^P)(c z56^)nJ$uUUMaSoyPy^`SE41#AJuI7H(U`lM!k2zoqtSc^NBT~ z5>`34L6I^Sepf|V4y3%?a4Fn%pXYv?a3u6S5l@Uiw6Dm(M7fQV9_fjMz6?~$6Hf~u{!|>A{;6krap)ypWp{!4@yN_#iTc*#?-_q=V&vQkG z;z@y3uw66%0fOgosGuokY6aB|PY5$fvpIocRa|2Jwj>{op7U0B$5%O${$FT~pGL2* zVWp3#fmPd(C9(Vx#pwSH&ZQF3JY@eI``rme=-NB$L|TZx&(*QtlSHW5zRLJp>SSCQ zMaTu7hSVRB_}~>iod}*12^Pa3g29X-=06D!;@)X78JPtfQcZf$neU5{)+?4s^ha^W zz(UC$m8s0l>ppy%a@|+|YVG6XdEE|bJx{7JcACREEil=+Kurfzmr67KMBm(9@%ySp zrDmqwsfnTMqL@l0lf+0doG0UMvezGfDajm}ljljx4M`e`gn)YgWMDo>HI-Rzaukrz z)8u0qTS{@c;N^m~Mk<3won)h;07%qQi#68|<<9t0$x1Vp8qzM;`3f9md1ByZdRo=S z%B^8vZ`>y+Y2Mlc<}n4B)}tZGyNl+eX<`KoXZqq_gJ}e^0b8;F?5YEOe^bx z?y|jb!blvsDdL-Nm+xWe`g8aGLx@htJCPLO{^r9Mpa)7>DZ5((Bv&~Mkjr>Zt?7@u zci)00c`xAz3JRY8Sxh5`(o+Em<#6QGdnlPFbS$S>)q&W9Tu635!Ng~zI|`rAPtW(m zn-enG{&svLAuhkDgkL&kSazLB{ZUg49+e|+c#C1W7W&#Jaa`%3sv>q9d#nXHU%u5; zXN{#6?dHu&IbtF^VESxd*zeAfdgA^gY`Dv{XjDDSn`|IterewVq|gCk@;KO)i1sAT z#?vj>1{}c!YX3Gfl&zm`9MxoW){~n_Y8I&u-*|SKr(rvOP&CtVw(eeyJyRqZfLDj7 zEXEccU={evTMpL11k=!frG+mu454e7J7)YyjpAGx``kvCJ8;5kz2*Q*>n?l-ACIUn z6a8_&)L*X&QpAlRPbkE`6SvD)_~cn|Xd2RYT=OU#xYqcQD`<25?eqL7bd;-#p?gB7 z&NP4fIk|yab(FF7fm+>pgF{Ua3m9DmAWgu@_c^(>{9zZM-)g1Ah{ZPJFcQAz{@#X1tniJc&{LQc7;~%)3idC$1CLm?U?TuX% zaF2@T=~;$x&FpmaNeSrxaQVu+e$*b%W$V|@tWs3eSLi_ z8Xn?R&wVCmopcO+NkNuCnpP;hQZaT`k?hrwI~ezl9eK`mx31vFKe>_3o41pu@fBbM z<+`BbYTWI=Zc4{Dg;p~sNfL%@eZ1|ZmvH*YM^mkVNtB8j5|iwt6+9C;Tyy>H+sO6gLS8&hWkC7(BLB|4+0_R6K;)wZN z^z<|7?;nU^%Yz;l^iyc&@XMR;=f)Vv54eq)1$qeKG=QhO-G~A#M(~yYkE%ZXY)o-h6ehgu2R~>0Xk9#I?^Tl z68fr6v!suXHQMKNqt{cJmLF9mje+HcYH3$_Ls>+L&gQ+~Q4CI@(I}-mq*=M$-ILfL zbOpsqc;$(g5FsZVHMDZq*~HQHs4Q}c;fOC{acQ-Whh5g$?)=P+SmimvMieA=IM-|3=huczRTpQJD4-}h zerjntb2Wfz#L}2onU>Gl^Sp1c&xo}@Fl*ML5pv3*p3U$?!qf?h633@m8@W@W-oMWc zv(@3=+;cA2^*HrJ!~U(0-x?&0iT}@(XF8tH5^FZhmfMNy%PFm)V}R zH}{+iekX}_08f1U?hSG6#5#cef&;`lfc=64#5#cef&;`lfc=64#5#cef&;`l ofc=64#5#cef&;`lfc=913ktQJl_gb7MF0Q*07*qoM6N<$f{p~x@Bjb+ literal 0 HcmV?d00001 diff --git a/src/main/resources/index.html b/src/main/resources/index.html index 4961220..0c33753 100644 --- a/src/main/resources/index.html +++ b/src/main/resources/index.html @@ -2,6 +2,7 @@ + TVCOM Přenosy -

📺 TVCOM Přenosy

+

📺 TVCOM Přenosy

-
- - - - -
+
+ + +
-
Načítám data...
- +
Načítám data...
+ -