From f8f02391b9480364acc96fdd9c6afd465cfd6bca Mon Sep 17 00:00:00 2001 From: hrbrmstr Date: Mon, 1 Mar 2021 05:38:40 -0500 Subject: [PATCH] zq command line utility function --- DESCRIPTION | 5 ++-- NAMESPACE | 2 ++ R/brimr-package.R | 1 + R/utils.R | 49 +++++++++++++++++++++++++++++++++++++++ R/zq-cmd.R | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.Rmd | 11 +++++++++ README.md | 34 +++++++++++++++++++++++---- inst/logs/conn.log.gz | Bin 0 -> 29250 bytes man/zq_cmd.Rd | 44 +++++++++++++++++++++++++++++++++++ 9 files changed, 202 insertions(+), 7 deletions(-) create mode 100644 R/zq-cmd.R create mode 100644 inst/logs/conn.log.gz create mode 100644 man/zq_cmd.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 49dfcaa..724eeaf 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -16,7 +16,7 @@ BugReports: https://git.rud.is/hrbrmstr/brimr/issues Encoding: UTF-8 License: MIT + file LICENSE Suggests: - covr, tinytest + covr, tinytest, data.tab.e Depends: R (>= 3.6.0) Imports: @@ -24,6 +24,7 @@ Imports: jsonlite, scales, ipaddress, - stringi + stringi, + ndjson Roxygen: list(markdown = TRUE) RoxygenNote: 7.1.1 diff --git a/NAMESPACE b/NAMESPACE index abbe9a5..957d9c9 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -7,8 +7,10 @@ export(brim_search) export(brim_search_raw) export(brim_spaces) export(tidy_brim) +export(zq_cmd) import(httr) import(ipaddress) importFrom(jsonlite,fromJSON) +importFrom(ndjson,stream_in) importFrom(scales,comma) importFrom(stringi,stri_split_lines) diff --git a/R/brimr-package.R b/R/brimr-package.R index 7d701a8..e85fe3d 100644 --- a/R/brimr-package.R +++ b/R/brimr-package.R @@ -9,6 +9,7 @@ #' @keywords internal #' @author Bob Rudis (bob@@rud.is) #' @import httr ipaddress +#' @importFrom ndjson stream_in #' @importFrom scales comma #' @importFrom stringi stri_split_lines #' @importFrom jsonlite fromJSON diff --git a/R/utils.R b/R/utils.R index a44baf6..69d540b 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1,4 +1,53 @@ +is_windows <- function() .Platform$OS.type == "windows" +is_mac <- function() Sys.info()[["sysname"]] == "Darwin" +is_linux <- function() Sys.info()[["sysname"]] == "Linux" + +platform <- function() { + if (is_windows()) return("win") + if (is_mac()) return("mac") + if (is_linux()) return("linux") + stop("unknown platform") +} + set_names <- function (object = nm, nm) { names(object) <- nm object +} + +version_test <- function(zq_path) { + + try( + system2( + command = zq_path, + args = "-version", + stdout = TRUE, + stderr = TRUE + ) , + silent = TRUE + ) -> res + + ((is.null(attributes(res))) && any(grepl("Version", res))) + +} + +find_zq <- function() { + + try_env <- Sys.getenv("ZQ_PATH", unset = NA) + + if (is.na(try_env)) { + if (is_mac()) { + try_env <- "/Applications/Brim.app/Contents/Resources/app/zdeps/zq" + } else if (is_linux()) { + try_env <- "/usr/lib/brim/resources/app/zdeps/zq" + } + } # TODO Windows + + if (!file.exists(try_env)) try_env <- Sys.which("zq") + + if (file.exists(try_env)) { + if (version_test(try_env)) return(try_env) + } + + NA + } \ No newline at end of file diff --git a/R/zq-cmd.R b/R/zq-cmd.R new file mode 100644 index 0000000..f0d94a4 --- /dev/null +++ b/R/zq-cmd.R @@ -0,0 +1,63 @@ +#' Execute a zq command line +#' +#' zq is a command-line tool for processing logs. It applies boolean logic to +#' filter each log value, optionally computes analytics and transformations, +#' and returns results that can be consumed programmatically.\cr +#' \cr +#' This function takes command line arguments to be used with `zq` ( +#' in the form [system2()] uses) and reads the results into a +#' data frame (it is actually a `data.table`).\cr +#' \cr +#' If the environment variable `ZQ_PATH` is not set or invalid, this function +#' will attempt to guess the `zq` binary path.\cr +#' \cr +#' Do not specify an output format as `-f ndjson` is added by default. +#' +#' @param args see [system2()] +#' @param parse if `TRUE` (the default) the output of the command line call +#' will be parsed using [ndjson::stream_in()]. There are some combinations +#' of `zq` flags that will never return ndjson output. There are heuristics +#' in place to detect this, but you can deliberately force the function +#' to return raw command line output by setting this to `FALSE`. +#' @return `data.table` (if output is parseable); character vector (if output is +#' either not parseable or `parse` equals `FALSE`); or `NULL` in the +#' event an error occurred when processing the `zq` command line. +#' @export +#' @examples +#' zq_cmd( +#' c( +#' '"* | cut ts,id.orig_h,id.orig_p"', # note the quotes +#' system.file("logs", "conn.log.gz", package = "brimr") +#' ) +#' ) +zq_cmd <- function(args, parse = TRUE) { + + zq_path <- find_zq() + + if (is.na(zq_path)) { + stop( + "Cannot locate 'zq'. Please set the ZQ_PATH to the full path to the ", + "executable or install Brim Desktop and/or zq.", call. = FALSE + ) + } + + tf <- tempfile(fileext = ".json") + on.exit(unlink(tf)) + + system2( + command = zq_path, + args = c("-f ", "ndjson", args), + stdout = tf + ) -> res + + if (!is.null(res)) { + + one <- readLines(tf, 1) + + if ((parse) && grepl("\\{", one)) return(ndjson::stream_in(tf)) + + readLines(tf) + + } + +} diff --git a/README.Rmd b/README.Rmd index 5b38540..ca35308 100644 --- a/README.Rmd +++ b/README.Rmd @@ -114,6 +114,17 @@ ggraph(g, layout = "linear") + ) ``` +### Use `zq` directly + +```{r zq_cmdline, cache=TRUE} +zq_cmd( + c( + '"* | cut ts,id.orig_h,id.orig_p"', # note the quotes + system.file("logs", "conn.log.gz", package = "brimr") + ) + ) +``` + ## brimr Metrics ```{r cloc, echo=FALSE} diff --git a/README.md b/README.md index dece55a..255de51 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ The following functions are implemented: - `brim_spaces`: Retrieve active Brim spaces from the specified Brim instance - `tidy_brim`: Turn Brim/zqd search results into a data frame +- `zq_cmd`: Execute a zq command line ## Installation @@ -180,13 +181,36 @@ ggraph(g, layout = "linear") + +### Use `zq` directly + +``` r +zq_cmd( + c( + '"* | cut ts,id.orig_h,id.orig_p"', # note the quotes + system.file("logs", "conn.log.gz", package = "brimr") + ) + ) +## id.orig_h id.orig_p ts +## 1: 10.164.94.120 39681 2018-03-24T17:15:21.255387Z +## 2: 10.47.25.80 50817 2018-03-24T17:15:21.411148Z +## 3: 10.47.25.80 50817 2018-03-24T17:15:21.926018Z +## 4: 10.47.25.80 50813 2018-03-24T17:15:22.690601Z +## 5: 10.47.25.80 50813 2018-03-24T17:15:23.205187Z +## --- +## 988: 10.174.251.215 33003 2018-03-24T17:15:21.429238Z +## 989: 10.174.251.215 33003 2018-03-24T17:15:21.429315Z +## 990: 10.174.251.215 33003 2018-03-24T17:15:21.429479Z +## 991: 10.164.94.120 38265 2018-03-24T17:15:21.427375Z +## 992: 10.174.251.215 33003 2018-03-24T17:15:21.433306Z +``` + ## brimr Metrics -| Lang | \# Files | (%) | LoC | (%) | Blank lines | (%) | \# Lines | (%) | -|:-----|---------:|----:|----:|-----:|------------:|-----:|---------:|-----:| -| R | 4 | 0.4 | 123 | 0.36 | 48 | 0.29 | 53 | 0.27 | -| Rmd | 1 | 0.1 | 47 | 0.14 | 35 | 0.21 | 44 | 0.23 | -| SUM | 5 | 0.5 | 170 | 0.50 | 83 | 0.50 | 97 | 0.50 | +| Lang | \# Files | (%) | LoC | (%) | Blank lines | (%) | \# Lines | (%) | +|:-----|---------:|-----:|----:|-----:|------------:|-----:|---------:|-----:| +| R | 5 | 0.42 | 180 | 0.39 | 71 | 0.33 | 86 | 0.32 | +| Rmd | 1 | 0.08 | 53 | 0.11 | 37 | 0.17 | 47 | 0.18 | +| SUM | 6 | 0.50 | 233 | 0.50 | 108 | 0.50 | 133 | 0.50 | clock Package Metrics for brimr diff --git a/inst/logs/conn.log.gz b/inst/logs/conn.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..ad0904f94ab83062db5ee773647e332be73cd8e9 GIT binary patch literal 29250 zcmV(xK;HE()PMea zm>mE2^Ru`A=Rg0Qtar!T|4!Y>YW(*9@&C{N{h$AyHt=)rAO6pO{<|9-=WnC!X7iu_ zZg-Q-8#a*oAB6tLknok#|3Ume|Mh?R@OC`Bo!s%8JN~ov+}Z!mKfl|-ci!Z%d;iS; zZuhqHw#V(;Vd9((7`!n>YVAhPUJ7@aF&E`?s)!|2-TB$I07jI~uJ17k=#H zTllfJwR<>B#veaDcMp1xxA(ubTk3`R-?_W*f7t)r|L*hi<7u;*to~P@(PVQx{O7;N z+YUZ;*ORxy(Q`Mmx50Sqz3sN%@!NNk&1wDjpSzo*-q2vB7kt_rKfZqav*C8TdjIm{ z zZ-N+a{EbkoIpNz1C_;$JH?!NBwu+?G7`vzXH9aiz4{DhGk;WS{Boh9bu>52E!AQPg zf_|*Pppt8n##pEP)_tQ=WTkeyVL9D)H{^l2sKJ@~Sc=q(l@H8?kiwbMD(ng<;smIoKe%0(*1^!5vV5L4K7dC+IH>$+Y$6)AZ&3w8a zRR7QTI88O)G*fF%p#IecFI97PiJ;DkcIw+qs+GO7et@mCSd3yTgBnV|1}y*bRsL%M znzKAjn{o>4zyY>m3f@+Y&WZzin^iaSO=-LskAv4N|DHP451szvqB+uk%iI*#^D}Ks zZ>c_+wnuUpcuEMf=Lh~tFzz)oeMWC)XW-%k*^p!ZycJ7YTKH52Y)NY|1p3H8e;*M4 z!^p!vks(N!eO}-8`;)QszewDB)daPOR0h89sdZTmMzhnX*LI^Q zf>L2xV;Dvg#G{uX5K(VLpAptP7+A(}`mqe|F9QY6Uke7!WW!2on?l=C!N_1tWsihi z0Qq|X2&6WZN`*=77daK4>MG!?{MD??LBq}H{I}as_^tG6?V%0qDv*jtR%=f9oAX-pi<5#zd zKo^3brX%$L(bKNR|p3=`T>mP!fLu zc21PmrDm;X_p0P><>g@8ZdD2_VAx4YK9_(3`)0>E=!M{{#-TRYrZ4{o`}YEf#6 zNNMbA;Nyq8+i z`G!V_Vg>PuM;V2Kk4gUq(H2|Sds0g3ljSGRM!2$QZ1!?H?e-rTnF#qp-72^_qWK9^ z7V)06w1oHc=q_MI_1`y_+k3B$kED3l_jb9RW)WgUgo%;ZwhmQ#x#lLFn^mx+rCD=1 z9y+~8D+At%`0;)}eX_qB*GfWfnsCj!M21O{_l;w2fJv+5xDUsg63>M9X{E+rU>z*3|<#ZoXOn|PPbV&ZDgcv$@Cj$Nl#l-WZDx|`x_fa?UMP@IUq6qfuz!}w=|^-i&~Y%uIA+OomRA5r2bX@f}$4xxB8eB z($!s^lxCT^8EF>t55FY2FGM8R;_9BR*U)A&P3NypD;s#ML~-=f+x#mY4u_ThR57>& zLjM;DLZ1jJKa>ER`9|TI9(K7gsb=h>Y~t#nAF2oU(pN^BXMt*5-`2ZUfVocG%dDf-nLoBUcK~<0`Dlk z5|R``R?A-BsiS*;v0Hbh*7+y`CcBW)mJU-2P8$MOJj&AX0}D8?b4KAEd8(Nm`r7I&3$+ zf`LnRF>Cggx>HH3B~OlWp>pwu3J%_9?8l=Yy0&dvS8H`8PB$exczN$fUgx_GP9Bb= z5^0TTnpc-BaM$Y{-TA(;M(4St}2nA}}*3oSf zy*g**QpK*Hqh%rZTZt)BAt2g0wTzWPJG?$BWw%GW{}?7BLeUp&tRHmpAemNl`fr-{ zp?cw{x4qJw+4L^+#{{Gn+%j?*U=e8(OK%_Jkc`6TGAO(zAp(}G!MVQi-llNmbiNag zX!3?Rc#K$4_7yUG=Iaw=@Ha|Cw69Om6JMWc7eyb)g|0=Wmu=_HNAuX44Wpm6*24-V z6=;kaKyg@d&qZQPRf$fy_8~%j(w~7d91xF>pqZZMQe8}kP2`?x#&o3~`5mhlsVnKna@4~92OQ8`pOUgg%pSA ztR^XEU6sOS#=VZkrok?ux{7`y8De!&5uYZ+&GwgzQADJW8gGilOr;f?c>Wp23OHtQ zPZmgOVL52k8)>5MRr4-3a)^24Wxo5|go)%dwQ-5nu%5>mLfg1fQ}fZwpi&6W#!VwJ z<-^R%mCHoojI}_Ubgy!522g$SE0OX)HG=PW z|H9A%n%b=1ZF<++dUd>;J7?XfM@E0&t!jdj=^#TeNJ=7fFOAT^S#AtT_V>A#Oza0y>LF8$OF zel&Vu8TzT!8x5_J%9(Yq=rr?lXB;p_4e|n4qV(|-te+ZtYJt;W0t3oW-Z!H) zDQ=C^_PS|uI{;bIMr*V&O5q_SHb(U-v{pBfv>l0Rc+P5tLa&kwN%DPnq#war+O!UY zkF}6_W8pChO%%fwlqOlc->)l^(VQ<^Q8ZDICY3Vq;*}qD4+C5XZFuT^-lx6s?I_oU z=ApW-TwXhN$<0np5uC}>^tA738sv5ta8;;O|GAjrzbr!~tDO0ytZ<)ETr5 zl**k-2j3cOb;DScEz+^_6$_2GgV0_6h*tk1sVNW> z+VqpPLbik4;XdDObS3TvQQ<~7Sol*P=^Fxl#I@NI6{DdLqY(ixtrU{M1-t8|L31;= z-WueI+j(IQ;;;x@TytOQRcMJ->DG&DG`jB!_48qP@4g5$$}n79?EBR=lHTR=(n@(! zD?#^m-AwJru&x#{Bm%B%{39?M5~g~er;0Id@bV#dPMPz1F#;Kff_dF(|GnEkaCh3J&S+GsgvOG8WZ{#iet@Jt-33pb3Z#_c zLv>E?)7i*)-Ukx;Q6LNTm0J6}Ux4~U1lcG5Kw9_!+5u|0DOxFaH~BN?C*wtafcbwZ zk?zq1!AT&8?s|&u zO$MXFao?=+%@VU%le00Io|pVoJQwVB07eQ4n&{|mf-9xbN3q3mJQef>R znYAPOVb|So} zAfl!(Hil9{tkFEBSfzsMg^abRNG?(VumSz5t$X7BaHgO(5+eRaD4s+!uf8Vf=h%ED z`RIyZK(ZbNgUxa)u1iGhu9FW|kSg{P$O@%+M7&6DfyWZ+hbiLAG1~9mE_6cMMVW4{ zHasX)USQJ+0Yf2)As`H{G`pI6NA)&%W8SU7xty>LpG8q+{15gXqW##adUFON}!GU=nlS*Ww}1rn!F^eG>Aub;S<)LC3d zWpv&+xxv`oC=#kFe*l?6{Iu9|MS%lmnmM&lWSQ;KzAT^AA{smezG2YfihIe(@B_C~ ziD($PulJKX3RaW4Y_W?*I84 zvKB;NvsO3(IWj(GT7#)C(xfjZ{f|n_NHn=y;0?`ao1Tq3b_C36OHJ1 zqj;>3M%svi@{XtF(ImV)TAQm(Y7KVYT=zXv$X;YRwQ5g#0jEhY`ps`cfdcJ+^qK^c zey4@)+AFV-Rj^jOOnpXouW`h|qmF&O(g*d<`hyO~!;$p|lB;-ZR)x~rSay%_7Hky00$suV!3-pBWL#yvd+lS-F{@W^CidU^?M$PlyYY#^6 zg6nBfA`U@<#=dVqeqwg+C3UCNBiWR3Z!H&5EiBNl2%>k4&GyLKg6tNh^s#n?JIqr=3$(#WzeK?DqPW! z4+{Z)r&_Q_IJMYl~>qj6eX zX2*;bnvD42H9yEyhziDhW0V4nvYs!j3EC|N?QX7{-E;$WFxoX?uUVceed$SAUfZ$2 z^7Z_pX`n;%e4IL_QM&~Lj+DMien||a8^9e=PS?9d9CW$_!BlCFXMM%{JN8hurw;ei zVHD!=d@J8iUN@=fDFc$M?R~RC26T7FH_@-IV&KaX!-IU9dXK|u<37gBEz);02J>?`xPXm@Z|O?T(FN*K9<`JpJ;8#6}8W2er;hpS;eUwmQ>JW6x_@ z71FNe8!#ZCLMWAibivcE2-EY0Qae)nCB9epfx|6V-BabIHwZk{VZ6w{9i7okW5Nd3eoY zd@&&m=$KPcyXh5KW0RI;1vk<3wL|p_nhHUx8i_@klJp^0TAxmpPBaIF7YqIaMG(IG zPWn*AllpF0Y1Jxx5}G^x=~yJL{SlZ`tgIYSQAT5Kp){Y*5BOoqvrkG&IC{> zLfVGhQRttQ!>Z8Hkn~BQk)4+su6jOe2jy`pzjlDnm{YRn&!obo$o|6@V=^<-WQjcvU@*SY>n=bVI^W-{T-SxqCn*IILzaHR!fb>NsKB z%dFI|yy(prUYhz3G$CB9oZF_0+K0@(pgfVkL|by<1-S90uK|FQEZWl^gG_hra=F&QBwaX-#+S(YuD=##(%=g-C?MCIZGCW~ z?U6g~_V%4|UOx9ZLu-K{ssBLmX)Un87=ylB-<|4`&NB7Wri%OdAc&mEhk(yxfD;=3 zya~99=oTP8fGMN}h|up8x=&{4xJvL6nd^4?hV#|X`1MaaGY~hA3BvSA0>mm;lOEyo zL$2q8+&MU zFK*{cBkdJKji_&>iZV>w$MubXraoC}6nF*qhSz3$T@=$=oPI8e{V_%*KP$q>#vp^>Ml%!cN?aIjh9v>Z_656Ls7*Gmn$W7T!?FYqT zs@uPHA`@y)YCz*UMv$4*6wl6`?FjEOp4m#=^#V|QVTf0;3<5S8WyXtG1_=kG3#JV_ zEvvdT#iobiuJ7?qZ@7)d1mMSNi+|WTIkC@22uQBT#0Ieq{1O5SY;0 zD4EHscLRlrD@cV<+2(UBkM7r zRl3F&QJN<7E7SBQ;bgj)~Rx(QuyHtM2tKK!bx!aQ()wu5(Na}aJF3sn>b}dXA zXp+tsB8B#c&6Bt|6lemPJKtJ%70GahiwEbL8%HWc{^V7~)fJriKA>2%hBa&#dg|!h z*RvP#eP8hhZP?gn%Y0Y2oXK1fE!PZ3RdR*$B+S@A-!taH%-u)l-?*7OCZUn0DQ3AH z=gs0aO|CUs4z`Gw(U4ce?>dyUyS0FC^;4eh)HRK1>sBfpm!<7GkUnOLM#m8;MaesJ z2oA|(eHiC@)x@Q$G))tw7w8d1NhtZ=h4Z(yYnrUoOEHc9j$P;bp5jys^!$tdNq%%I zki&}2_4s`bE!3Em9G<%PrA6)XAb-$<)lMN5YzuMAwKCzvomU^Gr(}z{Ofl zw!NnLRHf$H#agBJ!eb8<0E=MvE`9U_5NIKHt|grobXS`-im2da3#+NQEJidl4y!q4 zC`j^Y^^^WnelO$A(Ym{crQO=eS*-5cKCncn@lD=-~Lj}ysg%S(byfeE@_lx-;vPKlYn<)vq3+j6|pc1%| zn)OX`u~xTJ9`CN#Krqb5JHBwdIMi`yQSqXcG7dKj1%P$+ODm01UEHN-_fS6%&?}OXVzbl-+si+ON+d<5bV8h2zRxp$w=pxjDz?49z^x#+990s0BPxZhRBE zArFv2goFjms?nC-*aoHbeYB^Uw zRww(qbx7^HXS=bFECPIYLxXVTxW}wXg8O4xYx6=54R^aaQrS9227Uh)Whad1Xum-7 zqB&2cwqw*Wt|F(7*`X1{8w&NZ+#l?QUm%_&gPca$Zj5ut+*MpPRMR01bTu*5_lEV_ z6yOZZrXSS^inI4lu8=Hy(aBXj_N*6DVo>bnl;v%_yQiJjCf69;L%HptBXZKvJCM|G z`rO|2W^{VZ9Vr>7o#9LO>=%}+M1E5vp_M<_Kpcy8_ezY;AB|*s14}60f0fzizYQ>|L_k(bg-EDlr$C+5R z2Kmf-6A1J&`l3g-_9_z%EEI|m!2L9@6=IPlJ&cBGcBnm3q_&JxoI6*?Ij&%z24Zt`-Y33oA99x3=9?6<8u>U|1UIF zaa*`yJ1yZ2RnD8#1Ev#UJn~^tfJY}WAS8!(-L=Q-Jj$SpLvZ^ly)XkNMzj@tpv1yX zt1sv)O)E4zK$A)3(5bQOJr|tINyVq!4e#soPri&22wcTQ%ed9iHC3Hd=hy9d{UUJ_ zthkSBJ}KeXof+*y=S))jvC25><$y#3ir;7JC01#gCKxk=`&72JqHteVik)>iGy?Ka zMVM4?L()&5DitI*!d*jD%P3zVrC_~+@z9FxF&aUDrhqmUkhC z+m}09_v|na|68v&78rS_Q0QdvP)Q=S2!H~&w0k`@$QiGji&eq8U4kQzUNz11CssoC zBqEZ7_+3LnlyiC4>=)u0~X1^@~6j0;q&py5*fV78%vI zN~V3=2RwfI<@Pj1oa5u{InQ{gXveLktg@bZ=q5sL^?RdK9aG z?tD6+Pilt=YR&T3{A`48IkC(mxm%8+Utf6tfwYkvVrmD}dp?;j$;DiT?z>mkN16oDYs=I%DvrE0iIWt!9ex)7XGj^dzalop7|)rb;)zXh#67qnoi!+cZg z=4OG8K|Z)P!caj_RFlY1!4#OvEP9tg1~<|bJUXmaQyCC8TAwb}HEB zv4Z!ew9f8brDP;}<)ansj))&cd3d^S{jo{OOj%KiOR)*b)bFg*D+b7?Ma-R zt&xC1ZpCdTb3k5uYt?$K?k+bE7;2P61G5praAum@1hg9uwG#X^ISifBcgI9vE&7Nt z%rc*hTZ&#vY-aN|&vYV3sXi$bj>~R9Qg7cqHE5OOE2_3?U&Q?!-K{3PP&hWj5g%Hc zDwC#zQj=r8dakr?gO?tBm_HqxCWWA_S?rR<(96yTwWVbkg9u2gwtL9qqhd11;LvW7 zN@|2LxfDL?y|3oid5UhFino&GfG_R0lZmo`8ASM#BBdnM9q3gwyZ6I^l2NHUMCFB7 z3v@NZhKja!z4g|Zc#~|cVOW{;A~>%YfBHk=+Jos=oJe~Rh9QL2 zshMO+mS@2;c5l@$#Hd|PT#N@a;qaH^Q){!#)jKVFWM%g+<`%vW)J=we)D-=4npUwh zCQjzMv#iR!W4x~W|IHqKw0LFZwQ8$&DKdY-!|yWgHmP2s-ewQA zk5jt3ua;FKKfhL9&A$3gCoxTv0Ao7C~siY;8uv zGi@20QTotKWn>_@>{EDc9|) zJ->E2l?ARXh)ij7emyTYaRsUVMgRR+(;6M3H6$Pp^+K`#0`ozB#a9&S;>=8`VD7L- z^8vewOK+T?vefF>mH$K85iiMGpoyL?!6g&8?b`~7VuotdWJCWV$9i`&6F zuqJGC0a)=K#>8`lK<57&t}zlNNy}Ej6GwgV~$qYeSlG z8^=wqARCk zuPbPhDdg4}H#KcX*U*MaPZ2kw2_*HMvwWjquSWOH=1w3Ck_%bfg!JUQtoQ4wajvQ z9Q1dYK@5GAyedR8<)7=o<}Ld$J6{i(`m~mg9&#OCryBc7!mtI%-$<+0srN^-)?Q`Y z$R1IC_AuZN$oPBod;NFo%2<+n&+e4=^5WfN%=}Gkgmc4hG(x<}x_hj(4B2$VC>=5# z{#!~qtmHZN7PTF#xwX=2$lc_m@xW2(-fKv4@MX zES>ZlB5ieZv*M+43bk8*RwMu70dc=f$(*O|Vuf2RuRGm0JFXR)!TQ;fDY5j`Bmu7F z+Us2fPpDjX^L1P{B6|cqt4WRfYJsMJVS@XmO-7w*vx1M-a2z?3_I;?_qpciUPGBGL zU^gch6K~DIzR~B!RB%eF55$kMP$3PGJQABEr?fF`^i*XSMbU`18)*355N4emQPy(x^Q^VXgO3SITWBJqDjOK9~fO9BoNSskB+-#8>eNXUEfYb-R6px{=TD{HqYliSX{ zmPvM2sC@y_fVsruLrdH@PiheX1ww;6D_XQTx(?2EJ~b=72%?~{0->0FDu5(};Z~{K zd5cn)#l$;|$xP4d=_MC_$ytqzIn^xNT8dgLpI!x~EVD1j zWw_YHIHA}S3c%pzIDfcT?y_VrRQ9q@MQ=Q`lYsiC9^g`c0fjL+kERDay{*aKJE%=P zuye_Hq?>C9c%O+AWKdfJX}YRetl>t77sX_TCZhmko+%^R+tz>Q7v8pB7$EnB>81;$ zzHfHtqvpsPga8f17x$5n2~csh2BY_cykex^11CyAOXNQa z>)-eTLv(%+WDH!wfZ6wM^}$gDWeKDLwJg~!cBoixt}EBcay9NompFzO_{O!r^j2ZG z#C30(RkCTV_o=gaW5!SErCv%e8drM3q(}&yv{rY5ujfT)=nXP07TKF4)D#i?-(Hlq z<)M@_m20Oty6%eRa=BR?x39zcL328;U7$&7p<|v?rM@a#)6Kcs9WpDjH}iYGF<{xo zRe)L)qztGSG)H#M&5n*2^HSZf_#zU2^1JFxpCUxqvpHGA z!%o&!1BRSo3=1l8P+uScgZ*rrE?@8}Gn+MYHDuocL4Ayj$j%x_5zK$nSwkxLPHVsg zO5gGF=9Cv|)>r!%%`Z_%mB&9ExHg`l0vE5ZDe4utktzu>ECk)OAA|qG%Cf#jp~gtW zDdHCytQ!@#PR8AVH1|zZI7WA!3@`tSy;Dun&>A(Rz@_acvtQj5={24}iU@gec z{*xH?3q#H8a@0;wyTe&M@5~yj$HCZ?(P&4QBCVnlS#%1fp=k$kewj=uOV{f4q1(&E z8Tl4?$8pVPB{+;i%~f*E47FA*q-eKVr2z*~ep7iO+WU^hRtm~6P4nt>EOd6d%x^op z=P&f+r}l{r&{WtD`g%)uamTYmFHJoq-9Z2qNudv3n3Q;^BSnd4)o2AlAU;_wIjT*j z2OAx2b9q}vni%AFa6zA@wo%KA&Y?>V{b5c`^CyvcIaK}^C4b7mK342dI-jOwo3qW# z%q?YtC6)~H@54VifBW4)J7rM6=r4P(%`l$Nmu|J>_6I5&U;n$RJEe~Wnp?>o-Cj{= zFK#%$*a<7(bQv_df1CFGC^X}MOsj}+y1)?qbZj0YQ=X$9vOv4!0_lVFkLW<|$Djcltu-sE}x8tt_G zt~yH7^otDo3qHtTwMbbW?@V@`*VwPbSr=t!BUkH(BWPaWHY=py-zj=ClZgTl-nuNh-hUJf^>GTqPXFMH1ZqCQPQeHV-X>2JF= za%@ay?A(mX8!zfG5f7fHql0*yF934zrjYDLU-)9w4ai1C1 zDo7uBVLl)1XlK)^H|{BU$p-w%Z=FFSEJYYdm3a4HL+Q)k*nzVBHJ3GPOtAG0D$gG?EUj7mH7mAc&~mJkJ~B^<`Ht zWJfvby?}+03Qm|%GNcX?O;)O zF(Wd}$BR#qQQ(|uxl}yyovO9doqiU-R*#7XVd~dnK#lb2G^&u=S^f@ajEso1r-G#0xUGX|0tAOT4L`XAR`8c{8Z+*5uj zXPcM7isbNjs0q`XtaV1~5~+>$X*9fd`evYOs-Z}9TYrQZj9Z5ELUeltFc(7FE9k%P ztKUrDniq(bDq8mGvfPee%()3Y?zq~QLJvOePL;j-k+Fka|xznCX6NKE&llrs7PA=XPJfdVW&~q$pJ|=Cpa@ zb4gcD*FH_hYxN=*8(Iex`&>B%j8^A~P#1H{JI1_27%-<_hJ00zlbQk0UoX$7Sbs=h2M{{sR6IHapZbHT%4o1IHO4jA|A0 za2s01?%(N_?=Vg#p|79NN21=+2c`t=GyIV|XEG z+_EC;C_dtJkHRuOMF0Vtq`p7eIJF)w`L0+U)}sAM95x&6&eXAvaL2rM9FdsB6?<0Zr{`G+_^jOn8d#L3m$Xyk#X>&Eo$QPl; zC#5*CH>)JDZML@~3}1Klz$<%bT6)oCEUYpn{+%i)!!S1ou_4W6(JD_@c<984q9-;= znevs+K{?`X9H#wn=2za02u0OqTAYT)bP>hUtR9lj>_( zoY+|Aej9v~c{O?^DPz;{O4PZPqU%QRuO=P&H1&<|M&<2+X7lo3q_(x)?u7#Qow=-K zBgBdqx71;Q3uwc0m|B(y6S=jT3GZ4v~$bKTO7ig(8Y` zzhRp8*Ea@PS$nc%O=9II&%I{E_1DK#9}CXOLJ$Ihk(nVxr7w$zmwb=mp4A#|GsnJp ziH>CAU(9M%`i(<%0_x1RRg^n6hqV%Is23BB!>cgjo~+=|#m+qMywr%~E904}(J@cI zko}Dgj9?{Xb9f z_B7IueFRg#|2u|gpb8*mrJm#|;uzI+y)TZLAU8n@ILf8crw%;^0H05vm2-WLppiJR zWtcst%?m;58N6SehGi{Oa^shXK6vWM6T$MB2Oywea}C|k@I#OM`f*8t9lVis*k3C4|I8B&}` zn31r~j_X%COVfst?R1>k<4P!JC@M>;*NKv~4pmYK$gbT=+tw5rsAZ~s?piN~1}%P6 z{U*fZY3-l`wye!rXr`jt@jnAQt)I>bu&QATaMM-_7U zfhi*pn0oKWAZvEEiHaco&vaQ1JTH3yboee93@hiLm+lkFi8W=eXc5diFFbTy4D&Rw3Hcz>L}$O0t?0-*Qa4O%$%kKN3faAeP>JagFnZ;2mr#$l-g4+3vXGs4A{}9Ih zP>{!XhUO!t|9&`8@Vn_Ud*MWM)^yz7o-a8TK~x2aQb7X=7?{z^RVYo#AhgUj)7B1M zye1zmiuRaC#{GT;V|}LyEgij1r`bi-k&DvoSU>b)bzOR>GK#GPwAg~l4vX<(h`N*U zpnh%Ca6ZuJPD&A(IVL#KBt-NcB-WQ}w(2?TPEVuq)Y)Z4WK53y_OW8EHTC809K)%i z4exF$JLh`L2b`fV>4f$}{pgmyD|@KkTAhX&)H`eS%qymAD0xlrg=@8?P+$`_1Y!DxSNgR7CB{ z6R>k^4rUPjG*J!}h6H)!(61~uPBt=ZL&CTCFC?L)HJ7bdaekSaq>o-ZcZ)3EeRp$y zvq^oA1J0)tG;Wjqpq>m_&lPipHM+e%&g4Q!zfmZ% zM)rkz@KLwe+Y%l$C+h;Zh?8oMVw@_m|6 zm}VC4MxI~ry_#jKZkI>;kxy`;aW5Ar`n5NA)I>(rUEsAlI-nQBYhY-4q9EG`Ma{v} z+qSqR!@=Fi6ldwi>UA0~Xfe>ZQjZeoY-FBF?M*G;s_q(tHsR~nh^vIL;}42Zt|(_& zPI|pLpY>*LW&L8#moJ181|jtGgBWp_3RhC5U5crz9P2WT5bfaz-`E5NFtNGLvqGAf zg?Ud5S!FSgk$MOoYal=RoF)u_H=FxY9$nW?eLu5v9tu?_Kf=%nv8b9PLom3=l$omL z(|(U;HVax2F+j!1(0U;5w7IS+-cz0I0cXX^sgvu`90Z0tF&W*e+>eSR61dRrSPNWH znhtw}n0K>$qV2N#I(Zko*|^@5CJBwJC$s%&HOL$fo@+Q>C9*quIG`-{y)pstE;X1> z3P*FDDRxTJ%iy)nP6~MXAgS$yCa+ZHIPFyqbTu7SCoz&JN#7`h7_?BZ^PBb^)i$@; z`j|Dw=4+U3Lio|UQ7fRkdX zu)b`kk=trc9}O2x7yXPLG8ww}n0_MHZUoHvQ-@v}*|kBBE=xwr_%4VEc_RwT&o-*) z4*-xE7wBq2ItmN%*V4tJd4&|&@VB>Qq+XL3J+``{H5uWgh< z*Y4~#c8sGljRsadfjRvPO&AI6R9XwvZr8f~oD$yr#Tepng%ejSaW23LJgoN8#xip) zohzrsejEvnc>+3${bq$feD!)sTSZhU_wr|T%`7Q;uE;|{N8rpp2I-#k7XYHlFDtQE z_H~!7F~(Bm^@c@S$FB&55XZM z>}v$*llo1pMdGhIrwIj8x{}@+Wn>nc^Q*O|6%wesChTi~fXRJNz$9^ zqQG!;?)4dfC9WjVM4`dgXv1U&n>j1JX=a!E*~{^HNm2U1;RNsiCgr_KmNbfk&b@QI zH5QXccEbuqhKD(#3Daka2tZ`5nZ4eVNvhUc?@Oiq`pW?;GStmU_aWp0#xEg4{|Kb{ z9X*ONZT0(|@%4Xxw8r<@90Hm6qgm<$ZDv3g%`LR+7h)ZG;XL2hW^QD6{NLpC5o|_6 z1>&)>EX?NhhB;oi>CDIYn`cup`D1j=kC?@l+&~jFRBv|A+)yT+vPQ!KTa-d({Crk+ zYNAO;FMJTxuLqyp3Z|>WtZCJz{GuXepzGfXBN(eG3=l+qV=rfB^E&d9H@`Eke)69@?< zzSq|TVu|{}00*xN`4d8y-C;0j)hCB)07)o_icaXmwB_IULO*4jx|J%3}=- zyi4nc%}8_aa)ZpL=Vk9#}*#gU=UguGHuCLr@OKtW-8}KI4L1W0s^fr9;4$_8zd|w zsSgwZay{~lo!8nPugywvkv`2MNQU4DI2aQF@B)8hPY#wSh#apE!|9kz4#aHi^Q{&R zTI}5T*^5^Gi2exxJJL5JAg#QQxjq!k*~k6ro74NP?~m?r>A3ydbi9;SAPnf2i+u8u z@vCl@Kov{y>>K;R=}xn_wP-3eEM5YbD}>ND{f@()&c8G`Rz$*|HMzp);q+Ltm%H+0 zc?&clp;-NNNCHhrBnL$b6|s>`NT3OAun7rhMF~~?X5OfD)2N#>#^uVkMy|m!aZDrI z4|9o<<-3q}m;Cm_&0e#BM8_Vcj4nTumvfy$Q5A7TCKmo&6t0f*GTx+*^t|p~Z|MN& zO#eLkCc4mXMHfLnDs@n6-`kT+zG1B`L!G1Z{7+yNakomaKkv16w~A|Y=0?q)j!jvS z5t1YXSHYlYBOpn_r`ZEh&LP>)YnHOn30>@3^GtCnR7C#>{w9rZ14U>omv0#Bby^Ou z`*fz;T13Wlp5==Fg(P$-pZ3mFT9{=URi}K3^l_hL`~QU^^uOPk^OH8(OZ!!xPAvs{VZ;#`OL}oA@j#)TFCXsmL(6|%^2B#|dIv!Td`Jp_zU9A8z z2SQ9=QVGew;C!G8xG89ftL+Vj_)p3plu`{Xj$qV>UIh9%Yz|Z*g31E(Fg-XWBF42$ zs#x8sOF%AS#G`{(Ffs2}MlAL1bMr7>?+W%|UlFrbFFlEvY8#rFhpvl{w#U=nV?uIh zfV->@8jJ1hQm{t%tF;IK?Svwa+UbXG;sgfr!i$y$3M=>Wx2_3e|9|y1A8&zT3AG}V zahGlJB~|aNQ#)#mB6Y))^m)8lr0+ESl+LB4KirjSrOk~Po&AeUZx~1*K1Bt`Ev)O@ z!5Nc_a=+BHJKu3i+TNv7+tJ^1DCk=b<+&U|I7~ik2M?-WQs>ith05c?a?zVQjXVBH zk}%2XcaroQN#f%ng8^X`yDtZdiYWaWm+{_}9e`@TFk|2AGc)PM z@PK;OxMifgS$-d|+tp{~K)5++U;)F3DCA!vd)lG!o^}FB1_6iMWkhQ!RW_8{7&M)L z6)zb7R#f(APE&wDu{R~ctjWQLIVrS125qJvMFwI1sm*BIsA=5oN>?5VVz*tKpUG_UcH>`&5i6$%kGzriHD zYBzu1SOquNT+v~9k!1XH3(Io)vr%9hNJ*(;Xa5mw5H$h!i^*c?;lef*gqG5(H8g0 zuz@-gJ})&Eyjz|AP!AxRKWvki149D`Aj6KGV+2;7Gza96nK=DJb+Vd`1AYy`FJjbG zuj5w|n`wsAZ0_6+_=uH**ZX?6e8>j6)%iJ^$eYmqjy@NEVs5nVrs1I=Dg6!ro%N_P zBbk(zr$^bYq+iSM_SPkANWX6LGUKb z4#oO;0WzAiyI!ss;ZTL;Eh&`6KSCkE#0oRFHBA@?YPQ8qtx)e=-L{&U z(s~{Oul}^~f0efM3F_ya&DzSWoYu}Fzx1*=qG9!utYvJwm;1PernMie@G)JYqBQA^ zWMDcgAtb`^GxTfHVmXoFhYfDPLt18M#^gYD(z;e}c`=A!CHhA^ohbHt%UYs=;My?H zJ>c&6RGY8bx0@Z%6-?1+5kd^jtcho|z|M(3;rn8ohI6ad9NTSkHE1t_8v3)0DeUZF zwzW)n_81e$1l7bYuZWo`9@I{?H?@###kX;^A}|d(K7V6@!5AWAw}DZr(wN)rdB3?2 zq8+~mw?0dG{fkk85tV>+Z_?S$#Kxd^Ol44^Ndvt}{GNmnXN{R=iiBq^{E~vq_Ealx zGZRtc^Fby5=wiYgNYKx;)y`bg3EBd4R_aL$Rn`Q>`qLp1Z_=qsq8P`-sW{m-j2DGqi(IG5qNO zgg-NX&Omso?$}BLP3mYo( z8W8-EgxA2ZU&?qx)p-*++r@HV%}+P`(Pkr3`w3rb2peDdFHSb5%6Cpk-p*ID-TvAg zs!sOs2ymlVvB)$(B{X4h1#`on+u0vzTlrEuox0n0${vSA7mUaiKz1nU3jCpJW?I=~ zhUcf+s(EU`{~$?{PM zE?W~706f5ostQHH+n1C8`q`gCidtT7KJ87&QF}j4xXx^e6##S=#qwg(w_81tfi5QArfF#cj{nY|EfyPkB+H!m+%fqZZOO3ZF5+cq? z!Ho(b_MM@LCn zffL>eWMsglXk6}-9CD38YdTd%vm6or3kwZ!FgXKKFT5Kq5TzI-Kq|jzmI-(A3$&ok z-F_J%0gOK~>EM_Tf?5J-lhP{?MhCs3%Cp;mKPN~+2y#w>AZi3zP#jJa#yOa5a^n+k zgF4&xK69x=IBQ7#k&hW=%2BWu1VipGl%zk-!}QMGwIsbUKapX_=j!!xbf7WIu)p} z+K$ckW;;7Z_mO&!=O*?0p?fn7e~|XlCa#EFF8UmA-@PDiNb=D22Am? zen}%*-QFF0h&QcfXpP)gtvd>~6_J0B`nzy$K<8T5jj42hz&bn)dbqE0CrGi$dXWcR6vVu-*>W<6AW zws@)gjpI&Tyb3Fb{)d`pVBuG~@YBPEbpg{w z%j}}f&T1~Ki9DTGiDM}z7%}D1Iz$HZ@krL^9c_h?Xl}R1T~sxNBS$I}6!U11N15R{LZAR!nG4$s}o zRohb%YSU3ED>2lZU{Ze#p8FV+v67GG@ssQuw*Hd*M-7$E1yW!eP!^Q)O4%pqt>J91 zlB?FxPPcfqj0#%|f8(PZ`~F)?`Y|ZGQen3@bmR@5@!3F)Mx#mq=Rp;oE2U7Hs>{jv z*+=ehCUlLczElhRIOTuhwxP z``bgdHASzX)jZw(fpjWmqF=^YVIJlKG8v)>O-ahdB)C)Shzn}HY83;t-p23ukm*3S zP3v_xEMxHSJO13N*t{dsJmAN6iULI{`XzBE9_~lDKeSEFqNS5f-{xm^G47uL2^gN? z){)Tt(2fGyqC!})dMy=t-;)UAC~EV`eokcd?lk9P#b1;nk|Gj0E)h~T+I2bZlBF_j zc~%!ciWgvJHK+LHi)4`OMNT{IXhxc|6MDr|iCUi+xZmF+M01fcJ1gjP2xRBhH0Oh= zMaKm+av(z0#lYTeEG!=yxb1G6>!kE?{2Sf)2`Lvg`2JDsFj=f$$)2q6lXP@?Z`_Sh z)l9nrvBPnf(0w_c?G}g*+xu5L(xlOXGEm7KWE_8G8zRfWAAf6cHcAX3x9{Nm4x0KjX3d#6>(>TA@%+(OdS~Pc&Mpp?)=^ z_*@z%``2UniAp(-n339+T7f`Lw|zyo}LKn!DlP zAX!d1EGdTNQ`a!fbl%6kK3evaQ9HKlBeT@FB?Vjz1H8B{76Q!8{rOHB1LG0Bx{ntv zk7|&Di>KN)jFv}IE_`u;PLsGyO?I!$9&(<7q+!S0tT)eRe{e6q z*I)6-AE@$gwX`2TS!iwPB#TxLGq0ud9O>S?`-$6lP(sZ_)L@>+giDx9|pLzRvD#e52n=U6k8xx6TK zeo28=Rk)%WRE4Q_!|kHu;HhX|bbF^gd$~RqqLSZ4e^Fjk{Ibv?WoCB0yVh!q2(GP@ ziFWJ2M8yifG%GI9zr(pWm>GI6-P=a7@oZ~o%wc-%pP%@{zaKdIuMf_l_ZTkKJMqF? z84em=q^M%aGRouPf9I=yii@!d^bXba(xqZe)9TmN-rkowsBfP}RWtU?hXoxeBzs1i zr1dzE`{U@G1u;sja%~GL{%;V|-3bG93TPmk-pO@v*sWS;L-UBaB9cEN!e*igRUQG3 zu%nJ!iuY`k$|rE6vViDQBN4y%!kWGPiV~wy+l>dSc~mZhQ+w_ELuH6eO0*Y-E0cPE z+C2y~d92ExXsT~=ke?HY(mtzBecL7G{gsS|f%teesB{55{;n*tuQ3H6rN_DQ57_c?XEb$KWy^@jiEOyL^+_40Pbm$^D>zZ~l{ zDUH^@ozuU9WY^d~s=F&CLvMMQUJq`)e0z#ibgUeRP(XXxVe?3Bp}oIaUDr}7q@4J7 zG=iJxodx@VX0hY?o6#exbQ1r9abN|CK3T?15ru8VINwF{G%Vjm4Tvzt;w$%?AwrtJ z8y>G~v{F0AMQ3WrO`L^(M7{qgJCNB(Pi z=^UPmx>7<<42^>t{*D9KJqiE_SV`=Wk-Pq;kDGdmcTpG@ta#>CVDR9G)ns6L!Lj zU`?JRn!EA&ZXX8ga#ITz=o8H2CjlyZsN=mLFFd(3yckD)Q7a7{y=~bXD2LO+K%vHJ z7tP7jcG~lS^O$Xws@RZC z1Y%!R?4IV5)hb7o3l5kF97#J6zl_%X!at4he6k9<&6#kxSEcoVg)`ESS4gCRNXM1; zG@|EK*n8>r`6Ey8C$SP=MGP<$({Dm=*N?EK`+n_$W|vn*KpQ-x47uzFxX6Y5H>!7^ zy7%Dg}~4!hD!6UO-{+nD?Q9By<#gJ% zx1K4KEGCE<{mtiAEoJAo%lN%n%pjTl>`pO2CV4$P!X6H`!DD5u?B%n{FogM!_)E5tR9M1bjJ9V3E!(OQ zciShqTrQA;TO?d^S59kM7qxl!(&{>|dTctkO+~#LDTpIB32 zeyEo|Nm6jITp2_xQ{bS19*avXp1UfE57I#?SKT0ZvMl@gBY`Fm{Wz^X>$uzZ`=P!X zgo}zYOOzL`Fv0P2GTB3clw~yDV>}ofdzUAD47%kZxzth2nhHF5cR*#1qBW{93AERT z?WsMwU1+&fPd&vfDo>>_aIXYiN3FX;_Vdwk->&PmpfooBcG|M2#e?DhgbMW+dedIX zS2{Z_ooDS5)z$J7P7V7E`%*4aLbS+pY zPcl-50%@&RlVz!}S8~#Us(eXGCX|?Ute@|C-K3`6elYJ?XwND#?qGoZ#Kl~8y$qf6 zdL%ic0GY0MO$6zDN-CocIl)9#t^+2}a5U^$t0z6|PV%vJBFA!}{}xP{BUZRT+5cdg zrnwsJX|L6Jw3q8Ao>rL+IaX4*0$7Yv=t+@Or%sV}3kKx5j^hu)W?5$9do&Q#8Ptr; zz1!(GsK4FMj#W;7PCBSEkKZK2970`w&g*?5iDF%8CG>FlAbjbWjU@dJ}E2vdA_R33k;iDbU~qq2_v%~I_uub(yD4zvYVR~g|Ed4KuG^cYF?6)VBZ6GrKaqJtn5R1h&KO4IS?1Nm zSV$JV(Z&+X^WjQP`XegvRpa3I?qSOn^%Jf6dw(*sk)KrMi)jW{miS)~3^`Sv&kkBo zTY>j<9`?N=`In;>R;O?>6hx64yI|jXj%wD}SS)H@sccM@K<11kUeq*B7}n`yVm&uMSHeQYq*cPyz4GmBZgv&~6HtrK=0H_Qf7+4T&Q*|470o*^G+F&} z_hbsm-W4$y@dP(Fc7HgqtlF#8On-BD9`n=i0rRts`E;tBcS6hFvA7uk!;txYGVK+>hha-XE3My-J15^Eo7e zoMSjy&S%8erAIF@h;giLM95~bc|1x+Cv-;%W3pH9-mzBGO<=W)rwjj30C_q;teN*Pin zgMMGR<13QRw?i;=jB-mj^*DY4=I00fnRj4rgdY1&yC>j|P3vA;D9@;-F}!RDMB#{6 zGSLHXq!(TfYtlouN(@m5D#|_H4qcXeC{I9w@hl{*FQRsDkn^yUV6(Xkn-w+85M|23 zVxB&2IAdnCocp975$v=Z@n#pryQ&V2z7L`w!dAoDD zQ|2ilVz6+^V_TcA&<$U^QGZ_V&Z<*XSyT~m$s-D7hMRiFuF38!@9ntkpj#P_^t5l5G8 zqg1_t!}tsA$vdF9HLs4 zgOQ7fbA~~{$zZ4l&-bKpEK`uZD z++D;lp3gQT+|j~j)U1kCpSpK9dlHs&MmhAL3`tcrCXBzuzbo@NbhWXKf1{SytH8 z${ywOE=9eKc2HL*Z>aSv>a%igDn&fYt>nF9o2 z00S4E_pyAx?2ofUWAgMq=r_Tc!E`(xl%#@xoFF|^$k;pHhl2(_Cl$fB#E=}nu~NqsYys@#{{9WzgY^VKqo zOux!ojog;=P-@?u=DNa16f^P(<`!~bs!-3Rk6-iUirSR6NPRqhmFt;zf&RDgbQLyV z=)N|8i5BYAdxvDG%|7Tp&H^f*1A_C=Ydn$xs&7Kf^uj7ep z;PL6+=$#FjbSi7tzqYJZ1>CZ})R?|V`#RI+YiqYURk-*d2GMtyNI{S={n8wf8x7Tg zrkt&4d@Q}iU)~D(&X}h{+ADK?K2~S48q6KJDfLbjLN{le5T1@ySV{#QLEG?{kYmks z{7uwty~?wr?@;GYdx2-n7KOyZKl=XZ>>6|_dcGK;S(KPcrY4FyV>a+!B~ zkM4FTT^G~3rU#$I&3}SQJRK##v`n;*-3vCNF`CGt+P*Ey3kh+aX(b+e0r-}2(WN<> z*NL$8B;wu4Yfx^=ll;9wfE{1kQ)(R#7?i{sOu|`46%Y;wG9s`8AGSeOt zc0{&D7+ZR6KduhEeHl<-cpzqLaw3XoYhPB%VJS|})h-#5{{j*Otv#4bH)t<=LLxK` zsnq6rhvk2U6DWr;V36SLI*03Xh~0Qdhvckijf%=Sl#}g*XEG-Pg?d+4wLO_y?P+^x zs<(JmwW&eL=Jlz-BMk_Ke4%!lD?T#qR{gNJ*+zMv!!L*Mr!?ScnSmQ+(m<8RxAudC z=3#QUIm;?xkiAibr^$iJusKLighl;O8Kks<^FKAZ9tj{oq~8Jx8@A(VEuj*tnHP!cjIb zgs6!5OcB_6S*tHE0oklys@WY+J^I0X`QOhK2?|dcibyaRdUh{Z#_0B(4Z4fV^|Goc zzJu1`ECX?cZDkdvo%Gh)TtIa)zlN4B)$7?!;#4SK@X35>>B|jIA|r@BSVIs!6Rk9a z>9HAJ`_<{lEZq`M6^!_fHy+0AUJnOIyfTe+;MaGEesYqr-!&Bsbnxn zoB#z!#VTj#cPnTHR^}O{BeKJ1VnV#Wq|lua`Dt#H)&4Dn|FmaM{eE9KEMbR^tK}s= zF+F+{Pc&X!I=!mAYyNOQS2WD*gAA6jy^h-0ICeXm^T;&A>~2lQwdE_yDYQ_1HylG$ z({<6S2foN;HCr_t+?uKT@=0Is-q#G-B99LPGb)+j*m%LchQne1(R~~n{y6)DiNt>L zhbx>fc}GxV3ay?MCGW+1EFr@N4NA}6a56{ri)>J{_3(s>8SW%!o$`27l7OIuA{r;H znK24P1$ArK++~RuB}&S!UBtq-*Di??ylFq4B`bodmmHt3`mKCv+uQeGe3TIzYMI)Pks#_gS#R`;ux|P+`1!yE$xQ+S^Y$Xwp4gx7ii(M1|=G zr9p4!2* zuCcn{5|%4ok^QOSR>X9a%sPB{Z8Q?xGMHS1ZTq!COJTM9C&)-2|=T`U~s07i6VEwFj+<{?@Z`M|Rx3T>) z_1PJyNPK@O_RPh1b!ob)rQqOmbFLJj;P6!n6?M9NQ*Di!4z~PzyGP@kEl!Y7`uL~} zuF6-GLu?X?1LZA}d~BiZWVY=lmtO@dzl(LLauv1k^>?7K+)X$A+3h#;uo4NsjIkHT|n z@9KLsE?FN}w3S;F{~m)$tLoI?RqwBE&q&JxRqNZIg3q6C-4=# zZ@5V)fvs(q=NE~_wzm?tF6owc1<=AE5l>$YMF@;dJ)&xF-S7E+?W8A@eYx|OTX*}h z4xzB^nf#;o4w!E6Mp?GAh zqp%B?{=u*-FhjfyGc_9(Nx^ppyg_d+Wz9% zEANg_ih@?mis3_L7k#=2C`OL*XwNzq*{$-g3ocsa$ciwEE^<0$1yX@$k_H92hIcD=DWMDogYsy9jJWQfWqLm0UrE#1|K90lifRVGU< zOvAIbLnrHVqj@vYo97dNy6W%c}6xA1jf7V{6uzJHJQ|Uf%nPM`Rs!w zh=Y^iv=KXPyE`$Fsy~mL#a(Wn%F~;uD8@`VmXHEhflc?6=5>uu`xD7<7tf0MtH08l zKW~|*8!#o7@$$WC3|7Q*FLB>7#e@Dq_ijF*{&^-Yg$0FoPVfYuFTO2Zl5WkdE(*%h z%41P5P_QW4VrwqrzLQLZ&PzB=szh;t{3jgm2=0}!Q`0e3gUpWR+G^a4J}s}KqeZs5 zpdzkCa49rYw;scmfo_M+z-m8gb-7&Qy-WDePh7r+HHD_4y1Vx57FWyX%pO#ZF^?2e1st)5 zBC=2EX{hz;tPydlTOe~*Igg`@MUu8wB(pQ~M=lfUx0}ZGT46JSrAjgbn>kD<_MtG| zMfInh7fE`Jmoj{fHoI!`IA<^NZEyr&*vjHRd;Jj(4C5B>UprMOFOi~!LYX6lozlxx zfw;a;aP8pPk##x;>#DwRC0}VL5x!FfYf9|QL!F8>^qB4hY*&5e5eqFMT_~gbL!Mi?dkADw^boOp@5|Xu1Sw6Fw9Y2 z%nx?U_nQ4$eCxi-2ORw3sGq_@%gJIEtSk2mp)5-&BG>#w zpcnl3&D`5{*YjXW!rLt=pP7+9pxhyI>>*>I6jEso?W7Nw->2If_c?ur<<#N=V@l*0 zN&;sLfs)tG7zvo#qx*GH@7Cq&9-&-#hGUH}phDKjTXg*$dX1;%e!1K@v|J$LA{$O2 zTpO|BYQYDa&*hVZT^b)3R=YK+SaA8~sh{sw;!^TrnyHfllk|u#Z>5HBKN7Q|(uNuZK3OK8Aywto1MF%C#B&;yFV zW1Ta>$Y_-x69>_*pdb46*(6Y_*HvXnaq4}@`+Qp)KM zh-r)_V#ev{K7P4ja=%}ka{2UYKok>%--cA-9=a5da}@?el`4v7ls{%Te~VuflwGETLj-$sWZyxm4USW< z)%2<*WH!7CVaw0yR?{+RV*AJ?6E{IiL7D{R)x2*5J>!e;#5e(zQ5x*l^A}cko&798 zmM@lq{_?sqZUM)T0EQ~S(2$00Xah8EY@4lvL)YzcetuhyS-*?xfCcDoRITlPN2aTB z(_E^;zF#FC^Qb&K695%rj>-~SD{9n(eQPBLlg$U+`qMrcf(E zi5mTma~wHFd8mXI$wtZ*ep3lB)8uZOkNW)Hz~^~#D}SuN-VObWV1=6QFo;H{r7m2y z``-O=oxRF?kl#ZQvj@x*@nfvS?8SPkcW@-})t$F=dmEHbX?gp!8A>_kaHY4(oUQGs z*)d5paH88TzQwao#!nyt|6I|d@NpCLJa$Imri&IWBWX?7_&O@LWl({!$g}t(WhR(} z6H0pptKMw-x{+yb^pS6wp_XvD0xAV2-l(f*(!C|C*zqRMa>MN%{mOu1E~`Q%&{Ywr zi@ibWm!@_)j>nN**`ADYu$&SRf$3&WPE7;Z*DX1kEp5K7isk|zX97b1_8@&~yQ%4> z^!;L_9_VTNnh3a2Uxgn`p3DLZyudKoR-araa!8ubmO8DN?SzV~3a+S-ieZ6(I6KHq zq!`}K-wzMwuBv(|uYhE(ppcrjNuJgNWYX!>z~f85KiE{ao@Sjcj{SxVRD=z2+oQa- z(S6hvo{Q&oIV}%>k)p>#F`saRewCBamK1W^UFdDsjJiR&lzQtu<>$0bzOjs{?Z%`O zerXfBln literal 0 HcmV?d00001 diff --git a/man/zq_cmd.Rd b/man/zq_cmd.Rd new file mode 100644 index 0000000..c733cde --- /dev/null +++ b/man/zq_cmd.Rd @@ -0,0 +1,44 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/zq-cmd.R +\name{zq_cmd} +\alias{zq_cmd} +\title{Execute a zq command line} +\usage{ +zq_cmd(args, parse = TRUE) +} +\arguments{ +\item{args}{see \code{\link[=system2]{system2()}}} + +\item{parse}{if \code{TRUE} (the default) the output of the command line call +will be parsed using \code{\link[ndjson:stream_in]{ndjson::stream_in()}}. There are some combinations +of \code{zq} flags that will never return ndjson output. There are heuristics +in place to detect this, but you can deliberately force the function +to return raw command line output by setting this to \code{FALSE}.} +} +\value{ +\code{data.table} (if output is parseable); character vector (if output is +either not parseable or \code{parse} equals \code{FALSE}); or \code{NULL} in the +event an error occurred when processing the \code{zq} command line. +} +\description{ +zq is a command-line tool for processing logs. It applies boolean logic to +filter each log value, optionally computes analytics and transformations, +and returns results that can be consumed programmatically.\cr +\cr +This function takes command line arguments to be used with \code{zq} ( +in the form \code{\link[=system2]{system2()}} uses) and reads the results into a +data frame (it is actually a \code{data.table}).\cr +\cr +If the environment variable \code{ZQ_PATH} is not set or invalid, this function +will attempt to guess the \code{zq} binary path.\cr +\cr +Do not specify an output format as \verb{-f ndjson} is added by default. +} +\examples{ +zq_cmd( + c( + '"* | cut ts,id.orig_h,id.orig_p"', # note the quotes + system.file("logs", "conn.log.gz", package = "brimr") + ) + ) +}