From 3df2c4f9662c737a32bae92c3fe81b5f0c1600c8 Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Tue, 19 Dec 2023 20:31:11 -0800 Subject: [PATCH 001/116] [DOCS] Automate Tines connector screenshots (#166313) --- .../connectors/action-types/tines.asciidoc | 14 +---- .../connectors/images/tines-alerting.png | Bin 78054 -> 0 bytes .../connectors/images/tines-connector.png | Bin 61197 -> 158992 bytes .../connectors/images/tines-params-test.png | Bin 46631 -> 128864 bytes .../stack_connectors/index.ts | 1 + .../stack_connectors/tines_connector.ts | 52 ++++++++++++++++++ 6 files changed, 56 insertions(+), 11 deletions(-) delete mode 100644 docs/management/connectors/images/tines-alerting.png create mode 100644 x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/tines_connector.ts diff --git a/docs/management/connectors/action-types/tines.asciidoc b/docs/management/connectors/action-types/tines.asciidoc index cdaf56912d0f0c..c9888ab7b9087e 100644 --- a/docs/management/connectors/action-types/tines.asciidoc +++ b/docs/management/connectors/action-types/tines.asciidoc @@ -19,6 +19,7 @@ or as needed when you're creating a rule. For example: [role="screenshot"] image::management/connectors/images/tines-connector.png[Tines connector] +// NOTE: This is an autogenerated screenshot. Do not edit it directly. [float] [[tines-connector-configuration]] @@ -34,23 +35,14 @@ API Token:: A Tines API token created by the user. For more information, refer [[tines-action-parameters]] === Test connectors -Tines actions have the following parameters. - -Story:: The Story to send the events to. -Webhook:: The Webhook action from the previous story that will receive the events, it is the data entry point. - You can test connectors with the <> or as you're creating or editing the connector in {kib}. For example: [role="screenshot"] image::management/connectors/images/tines-params-test.png[Tines params test] +// NOTE: This is an autogenerated screenshot. Do not edit it directly. -Once the Tines connector has been configured in an alerting rule: - -[role="screenshot"] -image::management/connectors/images/tines-alerting.png[Tines rule alert] - -It will send a POST request to the Tines webhook action on every action that runs with at least one result. +If you create a rule action that uses the Tines connector, you can likewise configure the POST request that is sent to the Tines webhook action when the rule conditions are met. [float] [[webhookUrlFallback-tines-configuration]] diff --git a/docs/management/connectors/images/tines-alerting.png b/docs/management/connectors/images/tines-alerting.png deleted file mode 100644 index 765cd95abb10341d8a49c728348123f9f6f3a7ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78054 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 EA7{Qmpa1{> diff --git a/docs/management/connectors/images/tines-connector.png b/docs/management/connectors/images/tines-connector.png index b4a1b12a83f0c400969c7674841fb29060a87264..b63b1b33041ccda2949c8bb43fd2683fb2da1dbf 100644 GIT binary patch literal 158992 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
jlxHC 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 F{C{;ll?MO- literal 61197 zcmeFZXH-+|vo}l=L5e5}(ovd7Q>t_j=}l022?(J#X`vTU5KusR?}+r?NdOV)y?2lj zAcTNGLJN80ea`vc=vmKN@0a(>yB^j`ve{Rknd{m!^PAb>FEkX%ZqVMq!NDO@R(h_D zgM;6JgM-&jM2NjpW8rcO2M5>GR!;7PvYZ_A3s+|=TL&Nx&cn}+F;%M1wC?DqEUKI6PB4%1W#go#IqC-Bk^Fp*ADe7W}2&(d-Db}Xtlggxm2 zlgg0bshVqbZ-T<0ir{m|eH5L6qIC#gj^BYIh2ev8=rIv!i{%yU8m{ateHTRr#HO%-qnzibzMOOXnF1iplutEw{K zTq;X#IN2Hv%WT}c*Jx+EHh-ak)2K$YI1!lcF_GRy);71k#6RL@IqzH&WRLfCc^>II zTMsLgLE-z_XR+v5oP9mpbjK207pSjnrLK<8~=Z<@!GLvII=J0l$Ei+FD+bwKqogFXZJ%nc5iG~Q?{@4-SySg z#4Ma0dCe`IUjuo)99@1l!IAJ1!(KW9-OZW3937n8#JnUQ{8K{=d;R-1-vj1dD7co9Q5D3Hz65w@q zwdQ*wDk{qNn4gcIp9fom$IaWx-Q0`E$&KZ|I{BY|o&()1Ty0(4ZJnK%fA?$t+S$Wh z^1*}O1O4akzvc<_vi)}?C%6Az7IuMrzf1U@@IL1IPv6+462I??y|DEHIv6~+b;Obf zJBF0VV?l|3>i@5je@DF1QvctUqQXzEw!BjEcS{{NpsSp-BX&r4sed{1-;J*p{&zzO zzTYdqLW%z(^FMd7be6gy!S^4YN!_57>hQwBk-<@ZF8j(0cX#nxvW`4m`vGWMK^wO~ zF5Zd2R+(7&^p%WEB~A#rmiDy*Bi3u%drq>p+vK-iG@qw|rrer9vm`AJl`fb=$rjXt z+h)4Jq4vGDK=br}@LxG9u=cemvCP zVw{pz?(+j6{#n#trE++mFD@?pzP7mE#U-GS!THZud(yQBDL?zsg^0h0W0fJ;mAjc% z{@{;UKzQ3-YycQ)8O*IKz2M+7-TshYVxe`l>)(UyU&DQC2Jq@Ty7iwC{~5de#$)=_ zK%&3LWRYQ?v1SxvkpFjrzpu)U;xz_H(L-j-Z+F#NWq)GIcV}^rKAmjNT zq{(E&MTxejUPIRFPput&U_N;>@$~wioMKkPc5TK$1(y;ujDBBBK@j#T=I~G66Fie= zHpAI978Jxce`}_gp!p|9f;k@ThxH!$7!mXnzpK+wQi=CP?Y&?3`6HEI-KH|} zP>a>5zSL7OO&AWG*m@HC^v#2meHdS?sN3fG-Pvbq0Yn(^YtdK8$*aQgF2s2&bT8+SEz&)%aj#n ziFYRlYpP4F-V%0mIsH2akDj6J#Vj(u)X~9F_x{rWQf!6 zFL{1fgCpxg(N03e%`EUm^Wdwf>%=|V`FgPZa%D~k8?Z0Qcsb*fIB2gY6YR_8kviep zNg9TRRZzx0karzL8`V3x6)W$&;$*{~BCf|fI;Uuq^!krabnG@mtVIKtVF`!O;eIAM z5#=MBQC8om-P?Rl3t>7*FAFt#J3_(+ptj+ZB2oEDnFC84+W9LtZ#;eT^PR&|>twBX zPV287uIN_OVhaek3_(|04>S4>lhTZ-nxP~EF8D+}&T8Rd$o|vLj$r)j!0sr9*q>e0 z8wmq^ssqVSB+r`dr+J%v;LVFk56$tEGsNmlK03@J;Zu_S&9&@YSz1TYluHp(N#IRy zxCqK;_M}h%N-(8>I;;a=MXd%}pd9z(vWg|uw!wF{#=2s64m|IlRHu~uIEPg^{pm=c zI5nSX{HM)XyWR}(r0&YO+&};mA%FEFnz2VNH^PPTZ1lkx<;~@L}itA zE-92JogE19KIpnLWQ%+`Kl9^4%VIQ_jq$kdlLrjK;b_?4$9xYt#RoR4vvcl6Eqj0@ z8!+IP-FaxkLe(Uvv-?cKPOJd`$ss2gpT7e7{3hwqY{1!exAwu{jq+w(41)(^N&bsw z7N=OWN#y0c?ZOtmp1<&wN5{TL@Jb=Z&xHHq8RqbV)=h$TpOR6FAALc%ArgCHftPrv z`+1s7M6tE8gk1?GuNqQhpsa(hgzb^?*|?QcqF(#it%pt~vz4nL=$(ozlNQe;CN&EB z$2e1z^~ubT2|A$UoCkbP$h%_boFCXH7`>tmvv(;zhfS678S+)SZVng}y+om}<0+X~ zmO6n68RfUMM) ze5?xFy0n|L54YM0d3iJ|>~v8Tmg5GIGLrlv2LmTyw@NdfnX|`C^uGs35FZHzfnrQy zMMp~F#pz+V71LsWH2AEi%&1|vTpF{mTBTh#g0omS~E2NXdv&@ksPvtvHEes9`ZS>?&O;k%2M!$-<MDrJeWA_8>Xa<3UCOZK<}Nd_HP5KZ5Ua z$X!NwGw8J6->^e>Gtrq8UURTmeO93yMh=(Q42ChW1ki{qtZQr&6GmWzn1w1x9T0oRr(Tn98orDi+cB`t0{q(PEKWhVjXo6j)} z1iIAuu%pSZ{~araJ^g&vKFpDZZ2^*;M~1RSnqk*q>8~?X z(+37_2I#-R6Du5QZK~P5c!@4g8T*{4FfZq}Ip7BLTnq!)zYzXGuq?*WAd5y7_t`Hn}!KIO}H{@{0B@;mn*+^PGu)Pk6S zG@(>O4vWUwBO!Fn?`if-YxOzPOs3;DQ>A4lO7s+WQtnUEdf7jQ$L|Og_tF)phymDE zYS7*%FF1`GVE7LC39i zfJ{*=n*&bi;OMn1K`*zPZ->)GEkevVEJ}|BDaFNOL?J$E{ZnN|juh$QASVn123>Cc zcKF8KKIKclQ&#&a?y+K^TR5#yv0_FLz-bWzzoCDeY~}8O%U&pGk1Vnb*Z@LHdY`3T z`+|hK`A>gx-RNtiDj1W|7s%e5oyf3yQfMsd=98WWxYRp$)RRFeY-wtJr~7Vn%t70 zczSpHl4`Jz@`(Vltz|{`C%imWuYXi$$)0XxW=x&!RgAl4otJiBo^%GT2RXG+`)BHu zEMux!^`9(bM(~YvNzQH=X z$@tyb>bd*e7NWqg1_GTMFy^mU`Ipnr?$5Hp~6DPn9ZboQB z6ts7Z<|DK>t{dF!FmJb%N2f$_(Z`iyax6HX%C2rVoj%)QB?N8nE3vAxL)}e%>0c!RNA!qX4fgN>?#7hTSO8+iSr+{WVQxD-1PBvIY^3m#u75Xcm1!$Qjul< zh@#@4Dv=J89vjW)GX-;AJn+~FqVGAuIP zM{IW<+<3ig@4V9$J714Wm-U_{OiiQr;S|2XVToS(yT)+bEO-K!9#i9Hf$HU~Gc+iZ zvhpOQROH&#xwVpbVFJ&WhF5ziZ;xab#u(K08ZhXGL3oofD_qfd_L+p=#Fljek4!qm zJ$GXZ`V+%_H(%;0?k#~!x?vIN_5~UleJnTtEB-MaL%(hMdJ>_gn=DRC7l+rWs>gDM zhm0*HpRCwTVC9b2Z=>1ko|Dbg6xba;Hfu4;i?SF(7N};zjj>8w>!pu5v~mkpqFcHT z_`t0&aPPNTIQ_(#?#$tscId*QZcO_2Q^d0=M^w(feB=_~OpW{E%b2SM zBRber?!@tCw0$-dvTrOeq+6;^6`P*)e_Au7w^Tce$!HY=oXjI2Ne68jmD0^NuVPu1 zS>p`i`@w1%VkSq6&4x!W+gg%HY4{rh$&wsRo(_PwZj3bRC%$wCI(dwPB&SQJ+X=tm zo(uJJ?;Hol&j<-4txFn1-J<5xnzQ;K^kM3>PGgj`uHm#tBct+UVs+$rXX;IvLs`m< z!>n6ccEj6?<7wh(J=JYLBMt%B5+8%9=~ox6Ui0d{lIhZ88>?AkRYaCt#?Pq&t)?X_iua&|y#N`EgBz-R*T69ObdCqE@+=H3R<3kyj z17TY7AyOPR|Ydgz?&tOXx!qO=lc0XibL3KBLi}ab>%H_8?Q^&x@~*xHLpNyb`vD{3 zI(cs!3v}+PIklpS7ciJA)H2-yat7=i3QX&nY^msxPoa=MBB>EM=yAP+bWyh{-lzmt z<=4?c$2lB?uKQ8mlB27gio24>hO(Su%gC)!i&*{*)!QrzAG6bM?|C>SgRU`2UnbF< z(RU`ZlZ`!gECg_Bvx>NtTU;+1^ojmDnyaEM5IAS_xa6?4j#V>LLTNhx_SNm>McoKO zWS$5)&K;R%N%^-<|0KFv{96=OMgT%a_ODL-tDp3h>zF|SO$MMJ)SqT_glxV8T} zEQ&skgql}5%AtZl;ya3hNFv;t=Iy5IqpKsli*2X8@z&#{ny@lD3)d6TM)+-L-^RM! z#b)@Xl-Jf*cQho+80@M3y6dB@G>c*sYgyaH^Xk^vUa)9RGuZu<_S6l^NJ#)9orHx> zb$uB$WIkBy`g~iSL~@Ev#9`rqI0zo+gP8IvJ!FFBXG`>RjFxwAlR&SYE;9QB-_UoJ zGYwWoj3%3&&z?`a>ZX!2c6Hj{q!ZQ1m5*k}_XQ=ahWPYU;x4P^z9Y759~r$VeLy4K zyc#`NZI8O_-YX!?hY36Q>|#gx{(l}tl5&^SXo|a%%KAN2?!02w!O0~RaT&onc(D^5 zM@&BC@m3o(b3myLQ6pB~H}*4<)Y#P*CTaCW;5PZ9%AZH9V^HsA4-1mCUlLjxkwZ~}PW>c}WU05-hJ}nsp7pi4(Ew*Nm|%3PF__n1xcSk9oNQ; zfSBlv6{rJYe8$ydRylydbS)}w)BB^j@(E*Xk&V?5fXAsUIg==_T@45$dz#yOJ@(N? zB>Tf9jx~$Uqk5q00h+#RP?f#&ld%ViVa!hO&$-G_7 zCU1Sm!TU&RHpMBuPe!83$?ceBwRYG-qxZ`%L&+TWf#-7NreI#%@%(rcY$AT0PlBnk z7=8KGTGZ+1$8NhMAL%T?DtaNtdC+bmk|(Y2LcSj?72>p98=L$@e^g>5?7PO5ee_L< z*;t@MqaAi6U-PY5Ch^k7WtX5*7Cqs1ROmP^w|SV}XdQyT)ZYYM3!v&r>n9N8vRph< zcZCiy_|jxh8@DRS>fuN@{d7MCeiQ6X=LFy3jMo%)TH<98LkS)u=FT`Y(JUc>v=(oB zZP;V{1_`|BfH9|gcgTJclF_jc-~OId?R+P0IbfN)Uk|-WPkwZ0j#4|-zTta0Su$-5 z9Wtp@d)*xY#9t|!2ld_b4^wfETP-)ky9gXkPe5k)^lS$X&75H_d=&zg8+E=6n?8Jh zWBqgEo1Z_W4L zYBO?+13Cx-Vln+3!gMGu;wI`jviu zCzf|Sq9H_*5(P1N3GQBTbu$lK`zAzLI%`_^l*Sy|5l_ z=X5s8dpD5`M>SitG;UO>q^|s&NFQ9^i)hJ9xjfi(8Bn0V%are- zQ3Ik9U2}IKV4I1gKD88ni&8=iYM-?^0C+Sf(YciEgm=f+u++vX9 zpv-B0R!C#dlUjxl@ya)D^-})X6={!Z!uU+okSe$Q{2tD;?CHc35DZbdrRO}{ z4mNSPVvz>P%#ggZr`YA$pCom1!8Z$2z&9r=$8V{B$ss6}70INTnrc?%`AOy1eCS|q zXQEJKF>VDR6^ZIPBnI9`UL;% z%R-ybS0RH~<4C+kLW;>llWastA5j0gjO?vm#d#;;{x$V|pK~OGFM#28S*KUVZBA{= znzLiTkltwa5OI(Pv_ECcn;xWd;mqPYHINH;TFgniGmtcIWqr8bXNS60N;d;4)T~HT zYknEauFP8W68z8?#Xu@ZG-ZJ$X*JDyn;MlDLJFgHT+pwFNA{NKm^b7dmoyW}Qd#m&3PmXQlwMOb-tm>!>O>M=-z) zsKD7%wTqGyuy(UQOGjB<9Mdy-jH{@1zN%RG57 z26Ww;u`1K+e9F-mGSuS1*L=IK;dZ=l;v=mY!mZT1CiSjmy~frJomtMQ-nE8UJZXNX zw#n?$I93vdo_-=9?%D=6Tm}!GNt%t~cquLKX*WHiq2spSyr|J#_99!y&qN$?DjaPw zh8?xI4Xg#7j)9>#r;ur8QJ4J>DRF7fBdB@qRjOn!gC+ahABm#^EL$!p+ZmG{>iqPG zwvL(pNHKDM>krj}C=hp;h=UY?kh){&Oler5=$cBu@8217 z@T@IWic0+B{cAal9-81#Q`InMn6ZwDLqE+XJ(sSUZ`=3q+cRqQQQCZdg?Ma`3pw&9SZ=@>)5p(0;TF;;!Uj#`bV{Oq7om?pmIcb^6OoD&)+=u8GNt z?y7P8O^bPfzvGM%Q25Rh#}Ct-*;yCI#b!HKGx^~*hftmhk;tG7fk^9Zl{wl47@j%p zfSo6*8`3#&V*!+(ozg~Mxy5u-uxGh;LsRt4uXuD`a3-vbV8dXi>AqvqIXW-Zp_!a) z+PY-8orbW&<7jcbQxUymn(^m8kqdU|Cuq5;t`R3?l}xIm%aH-_b6H+a9H6<4Zan4@ zo}yeT(vcrZnM}YQwl;e4Q#eM{Sz@k7jW9-B5k^nVLZ{xJ?|11pe_F}gp-zia%O=es zsX`f2_Q4qqC9`ukfT~XmrGC{IZv3)h+m!ND`jw^|q4wI2shO{ho4?sv)Zh$)Jijmp;_aXgeqpuR$H?~BQLCt`(*a8!)cXXtH# zRlzRz&DsMkl26wh1eUL&p3IhbtG5ZRJLFnfcUE6a32P#S94@qLBTS1Ah_w+Aw zZ#YJ#@mdG&pnFc~21ri`C)+lS=-mW(cLMCuiS5HQP z>ypraO-Hjrrjf8ijPGPc3X_oLVb1OE|2d9K_Zdf!KfMOWmPdKVi>+?0b^1Rhw=zpb zG|fCCISwnOD64qvx=F}17bvMe*Sw!Vxw})B0o#&aK-?{j)TX(5EK zzdyBVk_pXdi1_7E-KU{@lHzaYPWo5nDuQqR9yTaFHe2DRwGqBlPix=qjM&jl%l>I6 zf4GOY%1B_pIZabsnqr1pIew#jL~9w$q!)eor{%hQiwMQ6Z@XC2LE9S2O5u4k=y=XD z_p(bf=nff z(ob*j%u&;X4cxNei(n9*G-O3yk-@oVMD>39v z(6;pMDg^ag&M022gcEjXSR{ADl=lBP8?a@Gc$${xrIouB(+YnQMW#Is>njqWL0(nf zu-!?xVIhU#1(pK2zvN(v;KBEFGv`khZO%97(dX&uU>Etl1u!%XNAv6SXO>gtZzol3 zz-j``uh$l+{$*5fB{eeG!T>k3BkmZw_wP*1xnwBl>mkOH$#|r}yA>5W;*NZicDhkxvX*7N5bb_&n9}UbGVLh|6LPq*6%falMX&5p;BGC z=*sW7p4As5+nKKc{-F)lH4$|`QKA?MaMg)olD==!d>q52SKdr}0Q+9V4_bP5?hl)i zE|`Uu8F%B&yHvDU&fYlPJ721w+gtPn4$J^HD%vz=5W$OFm9Y0n2-e6{nY_`pJ~P_M zm{g9|r7?I63hjnu2Q>L?R6ER9YdKw_!lJUmj^ci?{py`8$q{+wJCnUszc}ZKwmsbF zuJ%m8FmW(W4k4OrlQI|E0$vG4U1hlpGnQV#*^P)Zi#03T*)uM0EYb+vsBWtE>!nYT z1{Jfa?WeacuUL$7n?L7)4rRoJ$9?HlkL&X6JK}8XxhdH!24FhfE(_QeQR(?X#>MKk zsfMHtUW9$7zG?n`yznyd)a^_EXyOu;m-h2Zn$+*>}!vgT4ZFlLka3T=OgAMTj z_^KrAIIC6!v#{!x&d7qlv%oUMeRX*Otq;lQL=p@!C0v+GH^bBbeLZ34h5a74y1h0` zx{sygqpO~l_7J>Ma&&fhccyGenCfWm`;Go#=>(9ahTpt;vzm*;VH!?-=8B1;LuuvM zr=P)J$VVBa17f+2YhMke1@U1$G-K;=3ctfQ3|gE*j<#mIr_T4|hS>rk62H2vvwEVz z*Lxy2z2FTc^A>0JorpBcElrm7v4Vc>tvbA40gE73r-i3TFSFz0pm9h?h)-|5qc~%u zUV%veEE2Rgp)r=P0j$8n^^&$@rSI=>YAf042C7o=8Soygb;q@OyUwn4pzCZd9en%J z5=#09Y$*!@*4TeSp{RBs7JlJ!v(l(anesZwqAbf2YQac$f4ui#G*2-J8%NR$k!;D| zPI3gkXv;*>roJiDg_(pqWS&=d9c~=wvcZLPD~#FSN8U*?80Sz2+pICa5{l>0I>nQTA`$DclU#{PLkp+t zX`TR;lp6^J?e>?Ldcvbi4ec))Tz5+*yjH~M0*qKxsfL~mBXaNXT!zMT0%oU1r2{U+ ztQsAJ4B&V8z6fGWx%#;bs-<0|#IGFk`)s)U9XGw_Kzj>SZf5<7yxTW|GIp>CMx0|B z;(9w4jlqwbJUooFto~8AzTW%tS3qa9Jap9VcdW}`AFqDxcfz0~UX#y1n1tex4C1Oo zyR)nS$if(Wp2_ks(Xsw=gGQ^wk_SN_>5t1cckT`?~PR+lM} z-GRLa#D$XW%(d5Ij{$hqM3HIijSba#c!RxeoHkqJtRtBzM%dAfZ&1palM~>hwZsij zuo}$dD4TP?18+%e-+=`b`hyS)3GI6c?COt1FQ)<3W~;Z$ocf~}T6USpO#RtvY|PH& z59`ZUCp9uw{DzW$m5@E)((^UC6bpFe>9BlzYdb{!#eANTqH+d1c(4(IX?yewT0dA{ zPVRdNf$6cI7(b!`1ju9UE4FO`h(k0uT{Mza`By8wwC8gwzGMs3HuC!$mI6>TZ|uW2 z+BD*J$?oT0$|OC}XF{h(At1GONu9AT!w>O&0{QUI{rFlyXxnJ%-DzxW#Pcxo?hiEM zy5l(KGoL%lUrv=7n7=*BC`Sy1lIL7D1_uT)@R|DAPUnU@W-(5;pK=Jqiz}A5x=vZv zNtXiVFRC_}ps%E^=ym(b|1fnoEc)bnC5=FSpb`&84t(SKTiYVT%C23JlfE_U6EiXytO{DLweXb7IOlHQ0L+YWWcN!OIBJ&#&3z zGTKR(k-DjYqZ5R)KE^fGbLH^By?FZB8Xxg4i?#+|og(87s~^%1ua>8#gP!UX$JZm8 zEq1reZ;N|!N84XJjwA<3d6{MPF4V{Ein^+PdlwE|ZB2<~oA(z7Cl0~T-Zp{TQ#Ebz zyn4N+my5I;jxS&n>SuoZG*6sTd)v=3(0zpz5p`iut&K|txAzSJ>67T|sgpI!nz8&k zv~;_k=goD4-*z6`IgaziL6yG@RP?oYNXLw^x4_EMB~BZT&{ZwQO@7LWJgLqlVAI<8 zhMnL&CV|&q2Xz}xi_;_-#Xad$gl$_VE&!5rt%Yg{a~Emes!K)VBlSF&Zp3(Ca`CI& zx%&@y#@?)*+$5eVg?2^^kxY>~(ZoIRj3Bq=b%Z!CdPV3NGqix=Dz!A`FIP60<_*~y_<#( z0s0m*K+qS5%0R>t`cnMaz7ghOHi;E{p>EzPzce)J@JWwl(6G|%Ywz`poeg0Bmu2`1UxeP; zRhVcP5)`-tn?*n^jvr$K+}JylWstkG9HMTPzALm`1N)X_&xP08@FvG|4bK8=ll({iXSKf_=wl5Sis&=h)7xB$fo6LXlfGgo z7o_A+AtCxK&n>aS6l{eDcGE6b+vm>+UPP7C6iapzwAzjXV*)kK+nSX^v`m=o(Q`W5 zjW)#7w&8;@KpsbN&!h)dkkXgA3ZHfyLgxwvu!h4W*i)&loW0DkPcQpLHfjVJc)rFg zPTK5n;O8j>`&rO8*Gy}ZB^`*l`Jhnq3?;Dg-aXSrSfK569243h-dz_ss}}0F`Aw+W zzFT7# zi?S6+H5xn*S&ST_^kkab4dDJdPbadN1ud=+8!NT@qDBL^k3P~-Tx@oa&s+xGVsK4o z>*oqKMGl!@PQk&9g5rx<1X1F3Xs|emkGFXD{ACcT*sv~FE$c})A?&?rKi^r{`2u=%bm_c|L??ySBEsaW?CZ)=^xI5L5mrPx&bC0UwrI^Ye_06T(&mV4Mo^{(9 z@%rq$8F3*<2g+C9R;Ac9;H&PmwNz5Xz!Kr85mSjX#6v^tg} zF{`;HGO*YBEQ--Jk;`c( zGx_D*Gi!Zq7m@bc(k@@m%b6Yd(nb1*aEB5&vPvL?{&yeg)KsXAng7_^xGoSVVpXa? zwz60(j5D=5>^!*-Q0oI{)?`RouyfkIePNRLl>E85gwIi0nrRxr4h*J`7!xW-7_f#>th zG{Gd1K8Wp(P@VsmWyN)2}(OT@2Vn&RzCVS)ObbVQe#V zBCpk5n>RO07al#2+C2q@gY2eb#Exm_X~hCPM}kbt^;rGq;dHi(^?3%Pvw>O#hC(HM z@4{bp4PR)gR#Rst`D}V9N+Wmp`V-6IwO9z}(R*#~=8sI|4XHcFauH|-hrL@Ip8HGT zFt}+rC0jM&*&|Mq?0(K>v7@MrmW^M);h;&;%SufXf<6PHKCmfEO>F(8&8bDV)-*N< zH!JBr3wyFoT}6rxghjR1X4JUbozba1m&DR`#ScEGW2DzMU1~C|JFaPM1X}MiYWJwX zMxXT;#c|}z6(ZyTShJ~dXq3k||9QKSQe^$I*Y3FRph@#m9U?)mrgw|DW_Q69g|xed z5>^bq-L+KV*zM%nSxQ@O04&`423RZPiHW4I}$2wEL@pp!$20wR8Q+>2EDdWI13;P(5uil!>js=On6TFf{@#%Ev`@_ z&AXSFF*$B`0&K3UGzB^$Ob6`JPivOB{SHFi6GfCLwM?Vx8D_vcDc4fRz9{nm>YO*; zq}H269$o?$mm0@?e;7t9uDf;-9FZ-TSY=|oIrSUAIxIDIKw@pzPiQS7LkWK+NPTQ&(g>#nrJA|>KB&;k?`ES} zQg;UiVv~_QL9%O%^52^t(UU4O1nUYr&OHKv8ZoI43n9MyuwCC&X^XVU?_p7ytT5e* z$6Qi~7z}v2op)@5JNZ};^{M`fMYvyz&9G1$;h+?)h984R%9qo3wH|EqHDEf4>XYG(-E+BDV#yuh?b#r8oZRvBb^I zS{)<>SrR++51Tgr zdS(4COCewo#~x=_BBZeDX6+RpQm`U11%b56hqYDSY}tFk`i(Via{qBJ;1c*fYd`dt zkQxPw{pBZFDZyI7khAq|kw2U;Ds|6jLXVQ(uk zN&J6Pn|W+oAjz*5=KcrPL?P2YP4IwC{m%6CnOfi##r!uuj?IQx9g#X)+5R&uXC?CY zb~u^X7Wh-{^L}rK|6BXYQ=NI`|45V1ye3Vnk?1eOSF2+~y`&yeaC#2dNX$TPO>@rJAgh`;!=vE?Q=MPa8o zZpCQE$QXE@)?edwP!lyUdrj?%Y9r90xmnjpsN%5?&R)>+alEFKE$xMFSSJlOb1Ej{ zZb{FFTY2ABofhz}_&Tv$f?0y#0kl5}1N*hn|9%_nl;Ysr8w+IBNS~>;+i)#1LP-_@ z+A=RLyA=#-ZK__C8Oq;gRbqw?XC>WYQS4vokhAQL%J`kprHl>mAEXkoJxehL`{+!S z8gOAFK@;q!%axmJZQ1N5zW%bPkg9f{b!~D&9&a7w(MxzKX%{N%Cz2UA;D+_+?Nk>38lx8|IR$I~vW_ z6><0OAh~9$;Ovx1oon6mh&u*j$>%mH0@j&>4ls`vk8@pZR!!dC!Dy;MPw7&$p*6gD z+45xn)~~~1mW`2BmM@9a-pR0onbfo)9!N3pSNMdp0_XIC}FcqiEX_m@53)oQ3Gir(cqy<^G+Z( z+J#*y%4rzuzKnSOiE7dbw6madHY15K1!|{t8jKM(uMQP)_^J;^Xdh#Ndm5i zQ#`&=m(AGa%FVZV_fr*_f)geA{LkDm*IKSy%3vVnkZmS{*J;_hA@C}TZsmo>H|x8z zHNrKS?CP|=i999ldkgBJQ;Nqm(Y0-xc2Lzup2*n7#vQo=>ki-Z0T-El`Eh7(iKXsC8y}_dd4w
e9e@l&3}viIldFT)Nz;inVK-U}zhNHG%X0U?^r;N0oyAcLCLAxWb;J12yQM<1*A z+9z#cm%X_SI$yYmN1;NT7P?|yq9GD=ZU><8|>0cP^gm8_rQ7ivT!g}?59}k$=+hi zZEQ|qT+^aCh`J|hI>65JWlfe*gM&x0DmIT}fMQ+gHkU4UZ@OsBh41D^Sn`y5$}hHa zNyVsLPp<=Pz&>!k9`3np|30F5XXgiY7V9%rYo36dY15i4F*Towo>fnyn$kVsa3&a8 zVii~SJeqN_-a40tv8=N;Lwmh#Z3u+YbcXAN&v6%E=5dgis@!_b*H2ok0TFW2jI`QvaL~*8u%S zY%F&Qri#TXvyv(UBtA}%Cx#F<^TuX!!pqw*Qrlwg*sw6VQah_D9mX*QXE@@tGa4J$ z7>#I4P^X(#y}URzP9oV+7|U07oD@TV?azz+u_r{zAn)~K+KE5oZ8JT7bHzSp2I6nD zJywurIsDm3@P)V;RfS=tSr6xB#IUI*%~`xGREwtusF~w00Q-~D zyC$>Ue!hES#kL`iH2KzS=MK~5kqFgPjPPq~!seVJy&h`i zomC(mK+Qml<jJmu3gRR;FCx}KZJ&mupyNj8(r1;Q z$;?Vpx~eAFLFMT~oXGJ!XD7vl5a-1yNIurp3puHN@937oUr^uyqjIvY{8P(6sSjE% z%o1*zu3#*45dEKb0c1gcYM86%Mn3KOMA>ams6(9-K_^l^y%s$$1$JunI>3`OiSByh zI40V?Cl5fl&zBzUO064&xhsah*8LBMsGw-Okzu1f_z_VlKw~P2$6&`uD_dR zBWW1-HR>m za4j^>i43Lq7mCYFdX4C9Cqa6xMIf<^ru^a9;)}{OhPcX=o3ycsI4|F7 zqW&SW{_C%2->sMJnyiNLJ+}oEUWHSNH$RWC^n52r+`xQt_Q}ZgV2tcQfFY8SBh(w^ zWO+c6B^8R#(r_hw^Y@yGqS__n?tp=@d3qI#@i6NOrPjt#Hie_F9ZlaYCdrbR^#$5# zaTFt|Jr_I8N@YN@G1DI^l9%B%L92Zc5NHN5 zKlL)5_)8qTBCukW^)pOy{7+4k;4KFhfS2I2`>Pv?F0A-y9(3ky|Hb(Z$`7|&cUJYz zQOhEIi@qpUEXWzWbo6~WuzyMNoXx0Sj}5E;1Wz5*AI{amssqr7CGvg}J_$a)wsfr@ z7%{BIsLWlULWMFEDZRPS>ix3bdHH@=G=0L+_IO`^3ct$H)@bKh{om|hzxKd^;=+H} z)OCNwJVny2npG9~4gUn6kUZh^kh-@W7p$I5-^zUQ?LEm@-8rhVIVqUs#6Pix}m^C^!uRDZ4ATvpkcC^CjeZ_%}( z>t*XPO>$B;Cjrl$AHlCaH-fE=nZFTsM4b;9xD~v~I~&qF_r~Tb)8Y8;lK!9`JmNKc z-0z{V*ZRJ|U_83Or|wa?fAbUDpZeHW2OQ2&n*y+k{cHRc(50U0P8&cm)0Y==fkr9Y zPOs9PW*-#tI}Ztl-)8$JE!AJ=jKMX)I^tzrywGc_Qdjw~qQm@5Q7bhgLjssejJF*3 zRV%Mq?1?>6BCQFGO*>iyVdKqDPvVC2?I!!QzqoVifpa}K z2^$hHUsv2R2eIhprFmlakzT?@$#uPleX>~hvmRh@S8UneVryhod;R#?FM}FQR&7>H z(R}JH#MmiUk$zEVsVP_^;;!#vW_1TCLzbj(Irb$0imn?2_jQ(wSyKioZF#Pf)5i~) zv|)3V{T{CU(2U3W?UcJj`seFQ5P4Dak;#DZ!r@pTmu_!3B?qf>=7Mmxdd!L_w6d|` zzR6terkA8LHsR~zJy8XAja2qR&8$S9V>(qV4BMDFTDvU(JdK$Ag=oX5bl{zC1lHL% zhSpgJb~qr5i;r z5%|A@?**L}WSo+b{wHq)L_vEO_=98i=&Cn0@w_HucX7lMVmVaV=>h@p8$lweK1?aF zlN6cLjJZ0s7+*tL;j>p!$)ev4c>ztYp?3nun_3utnlJ~NZjaV9I9k7mvd_@U3#JNyTP17pNxXZ_azHX9Zp+_*rRyG8aVE zUD9Nhd>iUpV^4v;L&Gczs!8R`sy|4#3tS6CfL(n$zp#k-bEv(&)_JD%(dV^pOf2Cs zOld4X93BvG|KH4K?A85SA8w0id^fS=#2ymD*%K?{2I)H@HQ5PPce!**nWf2?Hg3J*Fx-pFdpk$PtJwp&J?Ysu9MO} z0`^1hFS|Qf4;R@~k0YirFBGC_pr3J_k7WJ5$M4xT`JF~=`B@CQhPzb@${=TFOxJ z6Y%a*jiO58L#yFw`-HG0!HlISJYnHF|lSb{M#0QRS08}Y89tOn=hdbwH{1SLIve=q{}csB)Wv>~@c z3ClHlGbKxCmcS#YcG6&mTFkkCP-2ME#vguq$6XP^BFr~LYU?CbjWKQ6>% z-D|CTtvSXVbIhTl4#x?RTo3ym2Uldu5R3&(w`uOd*;%WMnkc?j zEtXJLi)5+BM#wtYyxtWj)@0U9d@2Ox6D_}!c5h_21mRYH$@mgvoK-yYgqf^ax&78> z1$?C^`C^_Wacu1EoMoG<>dFqk#8cFCn>4k&%^;F8%%fJTl&=bWz|I+e__q8I3cPMIx)7#C3|e z7e%df&a}pttp~Y}Bdsh!?c9989hGts>rRW;rnq~0AdY=c+k|mITBSRUR+!B;@0%C* zCuL*WJxZDJ%~cba>dWt3oSp{n?X-W5F%OrQJvg(!Bg_4z3V(#v*{?6h)E89m=HPZ0}XF3zZZThJ23#$60 zlChZqv;i}a>+ZGovGDiuH=WOMr__Nbjd7+=bL1~!r~P{(CB%wEa_PaXnfkj2pC`pS zL=wg9k?wMC^9ARKwl7NT`tFuY7`Qo>ceu%hG-ij#N(tHhcjy}md#~8kC#)^%5<*tzhs5$Apq^8>)%)V#y zWO!w#9|P=Sv06X=CHEhkU59~7(oT`w#=K+b^N#4+Vsv~7zPp8T!^dbsHATSw@|fSJ z??A4!o2c+v^wVA;G|)F3WFjH=8&|TxpkO;BQ%eG`$Z6)0yjoe%SvYX*C*)F(=BkJnKWPAfv&_T{X(_t_x0`24D^lY+>1viE{lE)Sj=BE$V* zJpux#Xo3;X)SRC{a^Bw+Fey@zJy_Dh@_B@~u(|&wY5NzAuQ-|5LIFkTDr~$y3SfYa zSR&Y(n|>)jbmV^0DJk~c%oH?L0S0s=4ZS&YrQZ>mwFo}7b!(9}->zp#!Gn2}6*?)#N z*jZ2R3Gx^Khn-~RvupoaXs!o*sQk&%wX|=;86~QWYTO!W--k1ZBs~zbb*yu~f@ftT z{boB7#+^9XK;JD{|1WsRe8T>Jeh4T6D5bysMKR7sBfWWs4}jenoQu{RRk5C~o}B5i zZ-1adMvq^-`jqu#KGWnXRS?7V(U7O;#K4DlUcFs4e}iOZHG%j0Y8_k7>*4h=@2DFs z)tsNUQ`84%AMw%w{(LmSHyP+<3poZQ*!a-Lmha7@Lm6*CZb4UY}_8^~?lQSq+4bBu6! zaFK&5{E>QS*g4T?t5Xs2nmWu?g>wLE8shhfKAa*nu=8O4|aj>FP8Q^rk|q$ zy|>sCmmPeBZvpsP<6H4E5VJ>Fb<}!I#@~NU8!f>X8~8Nv!Nl!n(>6oJz7fC^>H%-1WjwN6SvqS z=h6blbrNWfti_~0Jyp5N>XM|ZF`4sliEXAqX*t*PsRx*1jr0hMft&$#`10BepTk36 zKrCNCF8gk+l){qb0)rJt9)?}9B&11u_pU@R-+0GwaL4qJuYYO6H?NT(bYubRi@DEB z2JY{fCh$Q8+le~mCjL?zl@H!N6NU|2B=5ks?~*4N=}AWV!1gMY1|uF z&jCo-YT!-sNDaQPSY+98T|=e5Y{G)?&=Cw=0rCCWT1wShtd`sAa&2h9Jlub^aZ$`p zI}zeuRU&%dFM>^qI}m>78Y{#PR{Z7p)b}Vi?h~Hx#t}|+WWA-h@-10LL6c}8+I*Xq zmX`ko#w_NOx3N58>O)xJGc0q6V>Iz<*mv7rwC_2wKHFhfbWnc?zYA-ObF*ZGZY^W; zyh7$uV-8Knph%-QX>S*)j-s?fXFJ0FRyCWj<(jr6?3`#Wi-e<*?_OEUq}_-QY0z-@ zpAc*uw-HP zoOZa#xcGvSBox#T@wR-Y%EnLdM|l#6UT;7!FlnDJBy|EXi~V1ROx(az>a0j zSgplLCjrtfT`ZeSK*31T4)*u12yBt7B~31EtV`&~8^Td@>YL@A5~A}jKqPr@Xv}5m zW@`?KA<8^awc^`ta6W{?aD@r*cr(LwC5otH66L$m{rQH97^MESOy&53YJ?hmHek@i zx;Zkq$l{M5w%fi#+J0dmH$uh)BuFK_o<`)S6JOJ@UjxZhiMwl#(8!_UCQqvsJT2Cr zTQ%j`$mUO$%#BMsdHVE2)z*kHS~cQ?Pi_&vX_=m^&0u{hZqJ2og;5|$2&9Q(tK7$9 zpupnK>c!Yd+0*^2l72R6fYE8(vL3DYv-YQny%lTfS&*RBL?6f+Wpv;VAzYDj3_HgH z8Qfu>M@UQz70*?j{FhX0xcE zhk28xK*8Evtt1(h*ycdN0(->B&#H+%@-b$y-0D|s*6kk~tjr{w#;>Cod6sg<3e5by zWo~^1$MLpy$wi3X_aqGBJN<#u>G~#%sEb-5$b>nH zG`=EO{C@Rro+Z?OAgQZa>j+8jw5UTz7jpSAh7ckVt)}~0V zC%r6xr%Vf(*lQc7um^DCJjBd*n)7)jK>q49JzN+2$j! z$+e^ft`wkVd%ThC0UOzHKA*Psxq+v}kD{;MZX?Lq=*{Nsmtdvppx8zh* z(wXhoZ1JjJ(=UXg`KMvxy}v*6;!MsyOzJ(aDJbLm`j=ENCbz%dF8CFnrBr&yh#wymKZF zlvA~Pc%jCtE2vXSZJweUcDv2wTB6bwEx&g)a)}PJgQ|90Gu?7bk@K(XmHu;OV;EE5 zt9uESPWc7cmGXG6U5=dk@vfz4rfoT8(s2wjQdQ|nM2Y9?4+>lI4NA5{+-ksO>+!iT zK7V-dM44@$I*c^A2kxvqeW2h>tG)i?9kJ`Zhny+&kFHk7o}J-l#98Kl?0Gb5DtvXy zj>J~M&Y&PwrC{rp!n?{5N%c36GUV#PgS)8J9bbiK1MX&0nYC zQfAfQ5TE|vN2A5_sV4(elf}_kz%j4ZApC!H0Z&_Y;0Pl=KU(Sf1;6D!i+-iU=`J=u zSZMBxj-bWMc&^lNf%36#ZX1rAV6S@b!p}Vc=&dnd&mW0tECpo4Wq`l&D(%NUT;Pj8 zxleYNm{*omO5+HM7YgzwR;xdrwq?B0w=Q>3Q>pUtPD^Jl=GTl`4?zOQmwPe!M|Vo) zK*<}Ll<(w1StmSJ9{&;0t)nhz`|Oj^`3BmJ$f%*q^y z$dpU{?i@`_@|_DOO5x`^{a0K&T~l3ayWl1Vl5>&~#mwbeCa6-iM((5Ba4<(C&s}E@ zw-oU`UovZqpbl+wmykV|N7|Y3H=Gg^QRZ%s8>C7P`WxBnSInL zzOTt^T15YLGNm{lnUSkN79tNhMHSRX{qP8SY1R(zMxPG1v?ISGdE{gScxV42RY!uv z>$=V#-p7E``DSghtozoyayO45iB$xs(3LBdWIXy=@>yV@|NZCxzn>Y32j~6v_q=yz z5@=k+Wo5N)AK!HKKLpONM6A%T%W86~?vMV?W?RB2oVj$1V|fLwZW7>KP*PV8Z*pO( zbZz|k;W{<7W{!4tSf04CdnV=;k5*Pox5PxW2IoXH4kd)kDQ|#%$W%$}UHch{ogSLo zZ6!(gI4A+3{IPa2a#A{El{r zR^C2j8~#l`P!t{x1l%O=YDN8bW}q%RGdmWOK>=IE`-3I6#d&&#_mJpWJ4v_s$Qm)f z7bOloMgayj4?LEKZwMqwB=~GDevH0;SO?uDmv;RuBZ))unQJqvYVsrCTMQe|)xu^f{x?KL`gDD;>Fi7*SN4B9uoK8fTNvUETg7y*5u@i zFLKK+aTqd~?J|9e!nlIkqEJ&mePDfc!yc0tr<*_A3aTihjar)DP+_fURPNuq=de0b z)geh$ ze!c!Z-P;`E0tnKELWh#maTI!4qI5$Ku(CN9%8QyHe$f-Cu}n7 zC#fZf7DcHfZ6pd54~5;rY2!|>;JN7KNO}Nnad@xIs%rWZR_Iz8phnkTo?$2>U}ihv zh7ZH8-cV@2g;a~c_#}^x52oI17?oJc@SbQd-GMAhyJ8%qAXhJ35Nw?A=_@ghKgT92 zzc`T3$9&~rYXskEw$}STbf#@cWEx}PBPBOrmhte zvvIbE*nc|8u$`Aa8IVXza=HUd1}y0KbQTSW0jrbOhDx5tjO}mqDSZ*TDIgJ?nZ+hk zHF9Aj88=}S`YT?*;8CT^Ov*F133mlMRxylr-u8e}>(X%PNB~B@+WFT#4^RQhvLw0; zY;KiRR7zN7R@OI)l}=8GSa(${WQ1(yC+M37OOH0F33`V`%z6Qc(8(5$V)Hx4jlu=^F{j^zh` zQM1Rm;quFyqkqVK{InG)+&GFL{;G)J@?0@m177MQe(G}9zcnt~xTH#ZTa3PDAG~g0 z{Zaq9WLl-CWT~k6PktsbyReOwf%^s@eLo`9RE-8CTW+fn;RLS4RJlt$MuS#<)>+S^$z9D;TrAo!(qWZb8^R!^mraXGpbJ z`8Dv{ZE+KjMHa&wLJt_Ls!;c>7oM7oM~i407CgN>^aqC$-v3QKPWyc3rc)?iql0#i zc2Bqk4&7Ykg#|wPD#?(c>oiW)&Kc!j_21;0HxVsnat780pr+M1yUXPh7E6QAkqLsL z50AFX2+`;G^f2W9{r$HsW99I(8JsCTX(&O>&3SY6!7(2?hcsFBkBV$BTXIpgTqKiu zC&sp372~KX^VeIQzmT4+3ML0_l+`D671q7772D6!lgy!~ z`X4z%h6Q_idU!5-(m81HW^fj_wAnt%M{Q&QdNPY}-f&!tB^sJ>w-zBU=PfCFj7auk z+_v5?BoxISQ?|)-JO<({>xDMO-$&pS8AUIr{P`3%f!1RULo93oBhBx>VG%lJ!?AZn$AKi-QsqO_+h;aL0&V>Vo3#Bq0Jl06^3zwnxi>@1c7b$R5tA)Rx zUu0ks98!Iue*C{WlCfU;5Jn|}vXL~iItS7*oQ<_?7q;5Giq(QKW~L`6C-2^o=>@R;MP{tDzRtiHPb?Jo*OAFKkhc%7F#)ZQJ5 zayTNHK>8!`bEo97JteFF(j{7hk~~L;BX0$&{;Xd?=8mP4nlA+h(S$Gx?rH!loHU+W zwvr2=P9%fa7{SG}Xq)C63>)!m&Ka;D^~|gyk-o7{*9V7|wIk@|V!S6h)l2tn{Y zavbI@kYhg0XGy1hmks>|!LMac&MW8UIsbEk#kBvr|pwHEbMu|){h0S5w(0l{Q!-u-Tv&t^(C%$9uy*UG<2d@HYHxYeu)~XX2 zO#a9X(^|i^@4wMAvp(*cGJ2uy0)}O8nL9qp>RWYgt86XHaj=K81U5Y1Rg7s6LJQu$ zeVcJwQc9CAy#ZNYKlswYe{gOZ8Z?_@oc2Av@Bv$rJgrSs(y7feU1%`e2GvJPikM!Qt=pv`O_254=5^T#V zrgK~^uCf`rR)iIqSt-qKo}|U<)W9|CJ|mKi{chewE|P95HZ{w5rqx(zQR{1WTvofR z{zhYj%W^69(R-<6<)I==Blm;ab-JF!6F~6=41(5`lXV3^{{;i&-X>0>S&x1d$h8_V zLtnf_04$8xUeR7c8sgpij+nd)K9X<_@Qk;UkEUlw{BgP=8 z`G|SkBX`Wv9eOq!O5lzlmIP5UGM|&3@cg9x&s}?fw`S0UCIC|v2Y+wArtF1m8j%0U zMG5k#%dLmt#>YIzN%Fg!fg0g#GK;)*Kz}L4?3GC^2#@tkQ#i!0I9U4F`fd2zvfzYq^W_#bIs>#%zV!AJp||1T zWx?|+#=aRHV}zj-ow`Y_5&e6kBg@)_!z!m_0dq&1H%jA~WghFvD2zoT!}^i>jr+mZ z)Ked;{4=84njkcHHEGKC%?qv;Elv_=E68jZ5#8-}n&`P(&-$kolBM!B!Ws>k;K~8t z{TNgIYwOUa`s7w5&LD*L(4N`DgC|oP_sJiq?kXmlH_;>Pa=Y5B49dni^BMpe+vlcB z^zGPWvsU#{_rf~LSQ58bUDQV~(S0fnSbW^L2x?)nA+)!)k^CatWkK*J#8-$|XCzmK zLxw@3mpE<{kcJ?(_S=dqv%^Z3cUf819!{~Rl*q!W_hn;w-9PYXb%m9wM@kuv!VYfr z7yW>H?C#_4kE^&WPS>$03Ge)c(u2|tcSMB=I(d4?I<s?vrdiw3VcSTyZMD%JH%|o#| zy8&g*Jevz+u{TraVWHnZz&6~qdtdPjuIj^g?_t79wRz?O>xY>I*@%(fqVivLf2Z|K z>f~Yu>jOHMvc*4P?m@19B{X>8eCl8cGTn_4ae?eoj!RO2Wypk4qdj%W^;NM6Xth_h zf8OCt3|Kor9{jVzU`5Ny`n0Iu^c9g1&jjgxJt0HIzO3@c=-m&N!yEeCkt-Hi@TMDy zK5Q2+K3jPk&VXizBCaE*t@$1|M%*?ZkM>J2p5@I>Ut^Jgxv0LxoLK(;HgM$t69Te; zgL2XRUrh!CzYKiUAeUm!3(gq#%w342E;DauC)@CX>vXqonQl+qVEZGS`8ZK7$0#m?9g>tJy|A(P`Myb6@uiLZxrgNv z5`i!D?Q4HCShV&paKGskaH0i0!p_@Z^4?1CPm6GG?+u!?zp`v zbdf)EKuPfmTziZ{HOXy5mHY!`Ii@__@X+?cZh-f32lIf6e9V;%yZU^gn{c^6li6h3 zPI96gekppI*qJKBhYK9yfJ;rx@zOIfU314_%F<)1w8%BlLYu#-V~i~Kh5G`5SF82&3xL^{MY{ zowMF&Rw6uqo-0o$!aGV}tj4vuI#R^br{DpGbpgge*-<;)8Rx|+N7@kCS??PA(v%U~ zt7+AYds}=V1>zR}jkUv|B?Qkn9OYmg=rfK>#J^PQ!@5;cBgJm*1Dv?*sfEZ&yPaO$ zs2KKKC!4ctWS=&mZOj=>5*!^v#*EsYv>?d>)q>InG5&wP+CUg=4B9cFv@oEFMad5a z3Y-J=%?11`H8jXN#;BpO8M!w0=Tr7P8?DyJ|1B5_R=Gqq&v8dsxL1Mx;u_xC(Y|0| z^dOf3a`03RSP8=n3XiTw7p>MV5C!0Y0m{pErtUydJoeVU5P!Bp8TQds8`xf1k z(3zhsP6dQ}ICMV{g{YgfZ|aBgt6t+i@9GpW{yw*%B+GYX4EC_hseGi9uIaW+fKOhT z99ju68{l}k)m=#lA35Ht#r`7m$-RRsC9dE4cK0FQi*{Jy7w!s&^S8U2`XE!!^36-MBx zr@E^j`k_s*x?k{~g{RNtw5{i%1sLaXs8kXV0q~G-RB|d=yF3u z2yVVmO>4s1@j~~h9~+qyp_e_!I6`7*et##>|lk{1S{PVJLcb5Mq}nE~*%TqS5AX24a^}0!~^!g^gcWHKj|j})q_((<0#{fLH(~bf2J}u8&wiK)Kj-? z&*!|i^B40>&Bvn&a&D(geDcEC7E7?fp{9ko!Z`oZs#{UWT3pzZ>a<4x>Sr(4wg%^R zX$uH9Q26+0qo)EY6cO!}4{2j8Sa}k(< zjZTcP{T5UyTy?)8*%TCjSXAn}8$gvYKRR}$`y{*>4t9!>MR{lMEGUmu6~w8H?OTm| zdc-};H$vdJ12cNeBeqI{>sGLn;sTZ>f;10K*KOyJ#uqAgH`yH&libgsxsCsM+=b6* zYxnQ0ir!YA^>tl+GR1%5rjP(0qGMVYQS~TAZ32tOk1a!nf0S%&E4&Ygo)y5y;~Dp# z*44>{swY$O$aBFQnjsH+~u&Q3GUbrNKu!_|RJ*BFXs}1x^rUhgl z)U1~$@RBSA;cV-v9oP#G<|L6-yeP__)}1M(@A($c*{toq-BU6+pSKWfQw6VP@Dc6m zEfjm(FX{N#L{SPSxp8^7f0bB%hppl*=7!fwPnRYvwf;!G{G{k*I~{8#i{uoI$jlDI z!uW5E>gwo9#*IWoTEU2M`GP5Lv(?=-bqjGoa-Oo{G%7K5ulf)lIV!H z#mKMZo1sQ}w)(?~65bJV7{iTJCu5jVOhEbgZLPWY419KqFD3ShG=NR*XMOR39Q}?_ zYm*;>mj`Bo)p}=w!_{MnO7jI*?WN-#;u3dBm6Cz{T z={r?-lEO8s%bP|B57*&%i|Q>nj8rxMaX(>XPs1B2>+G1MXDl71t5lSnSfhJ{kbhm zt#opL>y+kB#R%`t|h+Xs~ljU)|E-9%_{Glo?G40 zXS4ve3zqgyO$aelR4y_MK8i_vw!-f=(~k(G>e-hfXh;$J){*{wz8*3IpXUbTs^&}F z39g7yHh(wm)(J@%3iEs4H!iizPT#4HWg$P}ui99~y82YKVrDnPTlIrK3Ql6wIJI-rsq@$Jl|YL6VM;Wzh5YFlo-Jt6`etRscPU~o zG1XvVqb3#U*}AMml1jL+yt!2!HNLOK_SfwlcD{KHctpRrD(Ui(Asn@;%dffv5z{eU zX#oT9E4x6YOBNszvf27?-yDvDQ-Zr3dhB!=LPt7a9ny^Y9_}`RtpCYs{0CjN0A$H( zs4FwaXsV(-z;?x>-9(S(s^mG)fYw@INIy<}#xtw}&3KoY@;}nEA6^`#!h(Vnfn1z) zL3~%53Nx;t@TzTS+m%hK^%#>zMsZle+kD%tp2LMK$WvplmPF&Z>p2N zyau;s?$toV!I5yYvtJHv@9lWA(_yGm9sk@vn@iNZs>~n>4-D)%KQ5`jI9&RB_ z)K<3!owie`{=MShCn}EM_IK3x*Js2o*m857oK%sYi~TG3<_MAxqO#CcnNRyOd*W^u z(~*AydU*jL-X6uKjsJBDgQdTF1N>S$A-VG?r}P!+iyg&vU4w7?U%Ys+ z*GI3aO*Q3?z8xlqPi}8pt14pV#9#O1VbFh}?sUU%xl|4~#Iq1( zd%$2rpGnfC1UFb|+EwgcyNRK~%9=VXjqbdbDNj9UPZZg@RPC`GJ<|ql4ofTsmP7PR zE(YrUdt23b3*y#tk=sJiImy#;he!0k-{uDH!>3rA?ux!5WK?mhWv;|;u*AC<@YLo~ zYsv9zO!~8c4cZ#@+27vwGIY<@%(U2A60-P3m{1D8TFB%AQTO*Fl|rZc)PJ@$j*GP)iNi@VogD22Y=PPRx((u78nz9XPc2o7I*--`*3D1<0_LnP@VdZ*yTTUD zEG|IkQn|ldYwO@#aE9u5P}IDh#tV-#>>#@^OOxOwR|_U{JsAlLQu{OX9C4Gpc_fnSao3{ zjA>)0blNTH`m_! z3=5qMu)*H+9iP>`6_~!XyDm}L5H<}_A|Jh-uGs835g?%O?owH`b%)Bi+SjzKR^%h` z0?BP#u;l3xZ_}Z@LrD^l+I!>_;0a?`lYrenzS)7UGDPpiejr8HR7hN(QGr(G8;Um?U8-%OEbKxwPtxFzT%Mp+~gGz1LU7Ng)BpKiE?71|EI|8wPXLI#vZ5GA*pox%49V^iRrm_C) zA4CG4o@QKBHCdLku?9G}33`t9JV2tim~Hn6qPP!MyhT|*9$zGHJY+2uN+^?fzN;Bj zZv}Q{`2!m?HO&$m4coD*I8t7EgRLsiiWDi}FxlpcpM>i6ToQ=`4kBmvKJi2X@392GR!if#a z3KCApWzdB^v7Q)2N)fT9eZKM}}Vs65m}R(sR`7 zBb}z?Irz?k#CYrfM> zY==GS7>7tf?-*J~BGza9`G8Yj>3cu1iu^(&jeA9eCR}}k3?(o9NF@{zq&HKnYL`-dL#3Tuf)mDT2H?z zH$nlS+Tgn1AB8D&*$0*zNNrH80gdCo;VBApTpt516`wQ&^eg0uR_xj1O$bYu%JHy? z&RMkC3XS7XQK_gs=3c5-QAEw|;`z59R7cp!-FVB#ak&dy+#O5b47Nf?A^_(zA`DqG zD%8};)>!ApUe|{#8Uhz>Lj&R+=gIfIH466S>GTqPy-iyL?k&YMb)#Gl(I~5iTaFT5a-DtZHe^K2-)5?$|z=s#WIm8 zCObBo3?=*xj6$a9LQWftghOn1_jg5(A$Uu`9dA`fC;t1dYaQ9rwMUWddFfd+EaH)L zO|_m4>;7;>-j^?L-00=Objc9HK#O3-uh2ZbsA&fuBMn!fKhsKS!!Jujx3MlhoeO=k z2_PBx&-;*pvIx!I8qab6u2>;{$UP)asqCvg8OsrG?1iQBS2PT0x#3EspFucxaYIAl=zRsU_lTrXPiFIEML}DA~PdG00QcHP3+^m?WPN@km+4|G{`Ti{3 z>B565xt6Xr>m#wly!X8-j{e?8Q$}LqQx6C>3@zr)&dY@s6|}1JT^T= zC5MQ%)=%^=g#E9_k~u`QJzw~bghxU0@xbA!vo|5)=TRs{m7xe`O~&B3#OJ>!|6j}S zf1Uh#1$qk5V!#BH_=To?i0JBNd~tkcx7F%}?yklQ7-m}KS25Or8rC>786eF2++Q~% zzO&Kywg^NyzDS^bOE%lox^Qg0FpN|LMaIKy66pS(;4qO>U{4Da!Ck|exVlI0{+(?7SJWQ_x(IS?1MN-`Kq_;iKogzt_`!o0D#=?f z{f)s*KU8X;0FVUq-NzGz-WqR9AUhN$wh7J5x!X^Je(8r|-L382O{aLE)Qw@{<}d*s zidXM=bz?LTovNBZ+lZAMJT7~yzp&aS)6m&+DA>-{C=SP!`t6*#`B?OX$v=UqHN?&< z)t~`Im9Xoqn>Wys9^#gwR*FU-(GcFtm$2+iD7IMrM5c*yG#;uu2-*WeTBOha_8lBI z$m+r=${mJ`R_unp4a6Tx*@tTjjU=m$Kgp9319aYA+(JM3%(v`oWR$`xW&(r}y>koJ zF%-4dovDSE+ea@bKz`Vr{On72^|655{dHv%_qhHXoxV*#5JIaK({7u`hcSyiTyel? zUlvFair835ME>SEX7PJ|^yIHf*B{%e@(8&IR;f<++FT^>HJx1D=l)w|pWoZq_WA~R z?(OD=9e9P5-)}y46v@}$n8Yr0uh){)HfAzBmRCGZHGDQ}aa5KUe_eGmj7{?TW9q9i zKK&F8g%_E3)$5ZpA@b(O&apkgNTBEnV5RQ-$_C2pMACDfJqS+Y zP!fy$!I9wxb6i}-aYj#d!4qO`b~R^Lc)g8~1HGtkQd|%_HoEi96!-4m2Z&DPOZvAP z+}xVq8uvsV;($k?+o-;z3%^=Pdf`wy*EctDuI~%7_+y8D16SnJpAWi{8hT<7?eYts zV-7hxi}&wVC4)^vp0bk3dPu8%x!!oA`t9oR`?NveQ|Ond3udzn0yo>k%sw!=TMS}3 zzXdQkVR*VBOOH=n9W{0FIeJHWT?D-1TP7g&&z7fLS@%Al^7LoLCfnpkn}jK7NX&A}j}wJ?kXs!ZKL=z6m&P@yD#lu*DfJVq@MhIL3m)ju_zk*7oy5a^^vOg2j0G z`pnDPu19We;t@^7$AzP=r%sAfjf2B5?EfH+6U?`?67|6330XG&RMp)7>C(H`DK(vB zk1X2(NHqau7NZ=EA#K|ca&hLM3u3OWK!(fA8DW=xskJsCmW)o-(oEP$HCGp?xiJT- zN*;RIL@tmEf6$pGB?O9G)Q3wPc`jVIAa2@)AX|-5m%g5_YMj)WCMWdy^JmS%XWk>V zY-qL^!Zf8Nge3&rEP4;U6=JU=xPdMuKc5zNc&OPdDm}Ha^sJU&Ir1uZl-(lqO z-qdjkM9_NFX%P;kgiAxFEy1CuGYtlKzs%Jx6+MP+?QXJIELHp|@*kn)fv))2_S7WC z@@Tb6ZiEmP`m9^`@Qf{{fh0?mLOGJ~xHCo4LDCcJFjS|Rv&lGRklk%POQLM?XRT63rbq(+NN(Zhy>r6ui;QJ8_YQ`ygU@NuiygJze%Xr`VT2SO9&?QUC@Vny}LQP3{ zr)Ida*-Q`WcG6UW#*`D}4 zyK8+;s03E~jiP$kiI72dfV=-{h@;3Au@x;eky+%kX<#S_fecfYS9>lOE(1?ul#JW2 zFYGfrwdAUDZOTMn{N+u*{g=Vf;FdY9`egLD;7k%h`8zdw3wkhlo+Wv#Ohd7)+Rb+m zlZo_CUE$M0bj0q?LgwdpK9)};Tyv_K$x$9TXw7wc1nzg5GSCV18leQ|fb6pFT`e=b zAsc!n@fX$p6rgjdVqEbD)>Y3^NYS zb`5u_CW%Ie!>d{pf6GP9rQtwlya?+we`VfSp_>4N+9+ObOY-$(_s@9Uf&JvTf?c29 z?_{-z(+^ubO`q49C^JA2wc`-*`5ttb!$48&uvp4@_YwXz?4QBq1`{ib%1Rm^_cI%Z z5+NQ2DirSbIynSfj- z(m+4yv)~s>=9(OJ50UH1(r{USgAKOXadcH1dU<$wsg?WF!C+V|J23R$*tccXPm}(` z$)oY5q66ErJI?(ThDClb(%|S(2>p#9N;|F(7#w*03bT=@D6O4mCj%k5aJwZg8T=OOTQWy@ zvR$hbK7d02U!};Lc%nvmMp?7WfyuCBlmn>TLDeXh8jl#B+?48z(LYyh|V zwQC1PKSiu|i@4#uD;o+EPEMmwcy(?$t-FbOY_;=fmXE6n2R7VW0P^W`|D5%;?R`pk zZyVErZX>)`)4^mnvr2i!r7K1Z`4ND)F~6nnR^bYk7#uTaYq&v2ds8i?|GIc(`NU9@ z)RDJ;@@#O>Rcg#BgvZkMfFPF+LQQ~0rL?j-G_g~vQ7u`(@gXC2A8#$9P*v1s@v;(C zT9dfD=M)|Oz^*>)teNpX;ZX*tqf=#k4{@3P3LnoUv(gZ`;R~t_mffsqRySlV1ab*= zcEdYFwaUIx*SxcuB&#y(&h2)wDaqYsf>B5HV$MYm;@oE4V2>{8lly|`vzrV3bKvr{ zCVyi6na4le*-nXE1 zyTm2*_bR=3!HR)zVOMZpbRZCXDpLHcqpgA6%5OCK56r_bbcQ|9fL|;J8l#Cd@x4oQ ze^=sT?5nC|nEH1QGvFpCcWR&M-o~6hI>jC+&U-PEHDOf4c zfX1+N*tLNEBn5m5b+(sFeLmqDJuF;%r+Ip@{DPUm_)Q6;xieXe{CZqf9C6_lwS@84 z$XR2%ENvXRBD7u7-Hdm+$*@tedd)rk-VVz$Rf*tYrdGOG!Tx+YwNk6sZg4!=i69}DqJ+{ZjWkMkNVjwh11LG92uMqJ zNQ%JF-6B%bFhdXBFx1eo|6KQT-?wnBckQq5Ui;zG%sPiNkK;U#{2f|mTo&?~5>4h4 zg@^anhe75oY`ESe3B)-`RrNZJ21mXXm$U6{2k~detX0TypgaOu)ev-Vq0?A>3~H(| zdGYR-&6t(@z58y``tGZa{27H_(MlSirc~Lq!U73CRIO%7Mx~JFb^qE05oSk(p`Pw{ zucl?2bbdFvxs^N?vh47#fvgvme2K62dmcJ1yuHJ$htF8izOuqOxzL&5R&e+v{4pxW z16EXavKz`XZJ2AkZtSt2?TAOt_A8pyj099FnwG#)5Ui-DRh;gT)xSDq&uu_nm&NLl z90C1Qz}irxMzS|J5}pF!f}JlWET1HeL=%#%*G@6bWZ$lN?}em}TZlDUijd?}(?Sl6 z3@_)kFDz>K^QyVH!yoFVd>61iL$5n2PpwmJKN#E(`&D_?I#t&Jl#TuIh0!!!~*5o z57l5Vb4|XEssz~kE-*jdap3!qu3y1!D%1IChrA;)yLDZHUd9pRyU4G2#@!wYy%ckQ;k zitUl4;B#h|_!Usk0P!Zze)e0WQPAo$t-9H z4!R##wzDkY6rFNIjl=wpUONLgb_2t(`M%NJ=dk);4B2z%~#;@Q{qg z>`VNOC?ot&Xl{7LKqlhD86a(vN+XPpl>a302dikY({mud@l#UsVb)_@A8)hvthG+gGpGAiQz(W-_Hw zzdybBnCO8bW^JDm9-(7&I%X%`*u2|UNQ)vQzB$)>#5__5)X}QO;p^T=3VabjBftHD z&Eh%+lD9V)Fui!J%WnQ}_y7Od93VQR+T%1#rA%G#@#(Cj^j|>8so9}*YGe5%2Dv*O z09RMFn2Ma}+j17-$4KLMR#1m(GhYSKkHxG(fEW%bAU8vm`3=qWi=?@Y99V!wnvrV++4|XOL8R8~Dy7l$q)D0N&zp?*kzA#2|eF$TMGDjKk;- zT9l>Y=B@(_us`maCO_lDJ_8^aHrk7pdSg7#?~Q||ge?b6Rsk4~tH7IMAY!7IQhFMX zT!<-L=-`vU-tRpCj75Kc@7n-acKNifV}`^a7BD4@#3BH2kwR;rB#=`REJ-CrTA>-^ z#)arju&sli45+5`jM-BShk*)JPKtnD8+i((g8;P;WC4gus*4S+n#1V_ z>=ymOm7~@68 z2_3pI-Jr8oo9`FR3`rrPR~Ze1t$izmXcx~w>Y7xSSt{K#{c)+OsD3tlw&rJIlDmhu z1{OxBT$;HaBnUa|uPD17P90_&wccZQ-Ob%y++f|P@ozkiUFV&00gynn8r}Wec@G5h zG)q1*>DLcW>j>D4lCqoqrb`e41#KX_L>kYX8rQ3740>Ye(-ccj8!t{sHOQ_P zVE~|qS@E}uXnK#{#R`suZSn)6j6UJBnh^@sI|JX<@~abP(ewF;YaR3J7TQP%b9w8q zUB>$Jx)TA-+7gkOk&z{{*u{Qa*0;FO8Re9g>fD=LJ_l;mhK1qe0_jWqsTb zAf|)5)&dS>!gj7Gw=R~tAM0)!Uk_vwp;*U0T1=gJ%t4s@n#XGRW#HTHSY{i$dbXjL@eG_yc>(dSkw5I9f#)H`a`3p5T11+iwOKHAc(M=KoFTCbB30m z8$4jfKKCbA_b7N$Ly1Nwl-cE0NM(Q$-nYR zWLd}cYULf5Uw62PP(I#1@slCUR;WjehH6KVr3N`U)u!=m%C_u zn6O);z)4I{%P>nFI58dHkV{)AznJE{Ih}X-+13Vl4Z2N$a$pVswlt2yD)Z&`?29XV z5|G$FakqW#0r;5T`GOMRStW9?HMPETG`velKyYP+2mB7<4s$;Pal#H`k%i#t-3C;T zj;EE!P;b`1zOy!8U#M<5+HFCC4QahQZ-Gc5t!Lw^30`HaLPGjv8`C;~S=Jn{Dce)f z^*H-B^n3l{WsP;!hm}$B2V?>!;jXoP^Mj@09Ppj#T@nDqV&8K?TH|fy=Q!SNcIyW>A)|qC(wdvQqVPYvq9=8&)~ARPrb!;f=y`@sRvk~M?yIQSzMVcgs99Dl`J+cPK)4`18Il>H zgQ#DGtS42S4WBHnH`0pE-}#feuGYqY>EtCB2@y$tr~!x+8H0Jo5Dhg&VO0FjU%zUF zAl*%cErlw8;Xy|TNV8uEY=_i^jo^Zh`5NjBTNpRkOl9ICD?!>cuY@Yj`umk0bI!PG zP)ue?zsP%=_i^0?eB2gv7mWDlx<2i1jByx^78?m|ZuIH}PJ_bSs>kNlS8&ZdN z9obm*ni-D26~C{qatC|t{p)yD*OLw?EB^KUubpc;TLNvdIZ~PagSc%Pmk3Euj|z_Q zs#Ni*MKP<%RfLyS#q{o!WVoQ(0<-Y(@a%#ka7dQpWv2j{T~YJDX=Xfp_+Q`a2q*qz zCA%GL7cywQ%c*SN4R!_iK3(!7s?i{2DLEDZa8j_Om$=TSw|pob0hz%^n{2JVM}z&2 z*O>U0Psk%fz7GsZN@=JkVe5J8MEG@2s z!Fh{FTmdeX)1j{0MKI9|ya9xuPoK~u@E>~IaNGganWdY5h0r+dJMR8nog(CKo5cT1 zdJr!al~{(nq(Um+{CcC3@Sn5^1d}`>{_~XqUeG-bQH5kG`~%e8Y|m?3LXnR}^(zR= zt39j{)No~#xVSP(LW{xL za(4l+MLFBDfNi1U5i#W~&9%U$R=GJWlaQ>&Txbd3;lN9h$db8YOfv&LMfXH4{~5+D?M|0o$U1C$u~|3dd7E)-n98kl7($-eL`+eWr6 z>8V!a@5;mwxGqLaKNN?cVWP`ZR(^GCGaDw_0&FU7YYc{@yT<|QM>eJ%|heX#t&pn0S9}{w2O5RT?Rj_4FGO%r6 zXukOv|wLrl2pVq_T^cXH3i%owodY9Y>dYAYiXZk zUrr5Qdg`lE1Q0cF)|o^rOXwDrm#4A+O-IsqBQF?vE%kFetT=XQAzRb9(1^e(!po8j zA0RK|)O1B7=|YWSa<##f?3AMf!qs$-k&HAVEM+{L-> z9V$zlr^=A#rD)q5J6N%$QuRpyBDs1W+&7(>yI5w*4{CUVewcJn_9-FV^1!%)<4l)c z?Pz9{SY_nw>&p2lWA0lqr)NUchhbXp_6$HCzU5GDUgM$SFFc{Z8ioqffe(}P-pQK3&73rF7U&Cl~Tz)kV=X-hC zIsSd*aw9*D@QmLa5(Tam^tA1kacwSWcII0#hC=y>Ymo%Enk z6dHD@4AvLh-7>gfFqa8tjp9`9bfoI~*0s!!0u&qH81hYfy(| z@s5s25lV4MyRK=U{6nJ@A49R5(jC_^^jM!{v!Y|#=5u$~cl}#=4JZ7&t?zldi=7rX zg@e*~GAH?DHkjLh_#^Vm{rrL{*HN7T?@r{%j8$MLcAO85i||7d@C30Ji|C1>9=OV5 zM>6X7%2{$no$0~2UV{DF+rHIqWQeCZ>eS^|$WoNbqfy6|XvaZk+EuUa{U%HF=CBSw zWM}B$t_RLAq7?@ccMK`+I8mHNP@F%(M?EfRnR>6~$x~~?~=tMsc=M$E$sOESxZ%iGCb{yP-$avQ>a-Nk-AkrWYjO}&CM$?A z{M1nRGHR1QVEdPR8u>khN-xL^+tD#bg#*t$2f3E8dEt5ZC}M{@8rk=!_!51#W*In+>Nn@ z$qd@6eq-CG#tnjkUIG?6I!8S+r|rS2px=^vHWzcml@sdE(1JS{{IkLKs)jq`8kzehcZ1k2e(c>|d09ea2Rtzq#&VXu2j> zD*Rc%B)e}UK=1e`hEw~>W6C~B*QV^FUOBmsf(x#1-JWoN0|TYjhdtL)adxM_EOfsQ z(K$Z@CS?;{*M6`%NHa`av3^<~N*~_tdj5sfgIn4-XYcz9)@uI7xzS&(8l;LWi(hoM ze8IhySknRf(^(Z&xwfz(ozsep?zncBuLW^lWC;n|5g6UThA@NRaVX%wsJ&{nbVu zI{Q6UH2GusTb0ZMzfZox8`iM5lGBS7Pu&AkJSUPCp=AcldXJfGXb~s1mU?*$$gRri zLj!}CJs%k!(6cnvfK_-&ggHkq(7D~B3a29r@FF50|t*fj$ZjV z4@p>S+`+Bn%olvO@x*$TQK;I}W8B?9a*AD3ec_SQ)DXEA-X$cLY;)6z+>YVdnAjvu z-H#L^zif;GvDie_sgy&8H1yTg$)xJKx$JO-N`tyxrU*2Tvv5=9Teld|q{T$v_E%(X zvh^J*k!yB29M+v89^9$46Qvd=D%y2k+MF*8WfU!2_9BcjsPGOOE2c znCXR`v>J!J+wnB13tdIE@F@&`+WXT2x=xEx$N)}{vN;{{w-se|deXw<#EgX=aX;Bl zdzojI7v7!3GSZDv=^I#_cdIuI)8_U5-aC1r42eBWr|CI4)^@MRM%1krnMf*@tp$#U zc8UA`4k9?sFmO#$63)hIE_cd%xr^fBBR`cZOh69jBs8pUUT`AsAX3UGh7mT7G|bZ- zFAT^l{otY_ZvtVLR+j;Eb5393Z1NP1JmyBUDHM%1V3X?R`Oa8s(Umi$$e9i3{1r3ip}f*)~^NI%5{Xq6=K~xcD3>q{ZLPJ<;4w>A5+;6T;@& zDYaW+ox)1hvzEzOIUp8J6UmuZj3j2g+gGn!fL(}T<&|g>(}Ly$ud$_;CoESF}geGbyVoCky4UYU}Ns7hvzSMgP?6AUZG|T*<&&Nhr5Q=i*1%hKb8fmN@YzfRmLu+&F2*ztYgGB~o_Qr4+k`}XXkDYT!Pig6@H(o_J~BnCciMjup|$c=5kblPv?yY{2FThgzz zzoP2tIBhvDeL^CBM1Vh&No3k)wY{dqSJ5N^ahMu*p_kvMBEEt^Us-{vu0AD2qzX`g zEUw~#rogbRam@m@Dr}_bS)DQOd3g~|51fVTm6}D`ar|LI;&7C>TN9%JHtMzd;ooc; zf8g#Bzxy?iT;A$i$oSEMlnU7^^WwbA)Z;}0@Ooc>wB$%zc_W?wSLsN}zA-_UjE-6s zYO{qgU*BxGAYU3nqSynll#KReL9K9q8aU~cZ}KQ)WhDxu6viOD*0h-YVn79NQ5L9R zsp--~YjA2ao+D7J>&n#B?DefLqD_%71fz~enPt6VD^D&J2ULZv(MMWgz&vm?p5_A* zR18<_VwzIA)FlMHWcElbAOfRC)|}Pgtag6#9$;?id~hvo;j<+MfLH1Dr2}0_l`FI4 z2;-aVvXvz6xdvD~H<%|FF&H6P+@#a6yWE&&Y(F`sbCak)nxOnjei4UwUjo6d=SFq! znm0nbVNkAzaj|A7@hAM9`AgggelaqGC*V#}B@j1he%G+C>{QC-XKaZ6Pxl?%+n6F0 z1mDzT?Bw2_#m?m`D5p3(e!gc|S}QS-z9XSgKYUx#xdl&1&m!@53=?BnuR=UZt%jgL zYu!S6b&THF@{6O?b8!tBRGjIf4Ex46r5BCA_)qB)jbQgn8#AShVl6~6IXe?6?rLUe zS#+LJcX!7aW{cjD33NIdX?=sotwlDt`!Htayb{5ikMPl3?yPCYNAC=}sp*Ek9 zOZfpHmVsMZ>U~)juPNyrykae0GDWC~&+&Z%EvrA&nxs}y&u466;HO7D`PSi(r&mrL z+*METgZ!dIvPdqapURKs$(+AhRD-9CNkhnU__lk-?SO)l@4+hArpGWr2H+G*}8&4fz}rAKr;V-50@#e&s*L+`VDR9a3K3MYpbxxW(q3Zi@Ef&g_t z_-f0L*1)3=@&0Q_X-8)_P^Dd8vFazn}JoO)M?q zo_HE73n%$}WdT)$Ba2-fiiC^NFc#x#OOKrB+);xo*)~~ra87L^Ityh~^Fzb!`Cd;w zxthVlAytb>ZI*{)42mirO?x8u*OFJuni$FkX@??U!ujDNS;*k6kBs4gkD*zzlu_Tj z;90o>d~YQ)-xZnS5cA9eGNp+d!(JV`tAcfvy`^M`!FfXT49VH648EgyNZ!xoP+d3b zk+FM2gNINErqpmORifsgm?jG~ukKsFaQDR+b=vtON(t7Ydnm=-r7srlneq&oEA?~1 zK(@d{U&G~>7SSLt9${MLS3jxI?o3U{K4*>K-6?$OP_bUl8PI(8CaT%KGpe3!7xY>) zp-~fTB|>rQHfGjCfL4piF8m5mBV4tWr5O+w;S8|dvzQUd=T+v?A3|YB2^0smMP?4F zwN|w-A&`I^dk5)`DBb9i=km|Bc1AE{7I(;V%D7|xY#M50d_Yk?ktg-FBiH@VJU zVtB7mf7}m7aV43i-G>;I4tJ)OOO=hdweEm$FHB0@Yix=m8GpOza`Z`St=KLQgu-9s zGxJv*lv;wAb#KQ2_@R2f1ZP<~m{6Cw^KFAi5Us5;X=LccC$6Tk-Zo>ckeQufZG>76 znEhqp#Bi-KZvElL)ByamGnN-^(ExJ6ZEV51e(tASGSxsu$r*}2sa^=APsf--dbYd_ zs})nv50cqll(Zp-MmTC<2Qs9R7MjNjEtE12fj@l(tX6qb_kI2P?GViS%Q!!7wfVIgV73CkL$c6V(HyB}u z*0J~bn4ER;MFl6szV1LPa>|p=xHI{^5KAPm;50Ib&~4Um?u7vvVVv5U`QLJk&f66g zPRgw1p83Z67H^yf)V(Oyi>cW2d%5Fd8#`*GTe%#o#52e=uyt>fEHf6pUN;Gm=q}xV zQm4C^y+=H6t$mQJSL@zGLlj*uP76d-i3H2CaP;8dg`@l&wt|68=wt8pRCsrO6L41?Du`!BW zx%cq3=VN2TUpK^L$CGp04H@bM-7%)eBG`%JkI_}n{weKw+%*5gxiY-B(N-b$9lfB+ zOq4bJ!})<}>@%(MdAZ_fO06a?>96&T$VW$v*8j0JJjT;^?@DX39rdNi!Wcdm`ix%;MHZ9z)@DS#~XP^g? z+N6S~zckRFNB1e9vge?$N&D_8^D5%ol(flWRE%bna;bwg2;wO9)ZKdTJDtPhkmt_r zowhZDZf>BT*;thvlY;8gceHcKcs|R<%GUEBoVDwQck!eh_Y*qHv)k&Z*p&L>E?jKI zzow)jl&0+4Ie#L{FSJN+eFt?D^Vw3lEayMIt7-HNnpfoYgZ9p%0_)Gh$!Lk95j2QpPe zVuB&%5<5pz+*JS`itJ85U;Kok-hArYgb(f3c>AFlCU-ri^xC+NV6F0zvEeJ`6N2s(zp}cC26f$5vCYaJh|u)IB7jELB5liDwOc` zh>MTVjk9X%Zk1g9HIJrFN8;cpV}Nhu_FQ}?H+OG;mq1S zE$xNaf{ITAZOrB(ca!_?y?;_~)yhn75^zctq>Fl6xjfA=aDiyl@k5z=d6+oZosugp zy~|BERr|6i$}fX=+>O)1b&|Jta6gJk4fJN5LWVS0@O?|F(Thy9QWeiYr{@}wkx#+9 zuxyXAW_^;MEfY%4p(Ba%h2}yI%RN7!jin}PaRf}Vrn($?dIcjw!z`H=htp*q^3_h3 zm*fV78+`Wh^{Q?aI}u{GP1=Loc!)Czq+M8${rwjc0Hw;UTVt&t_HB zrq>z-f92Jy-GUanA6VRHpKhVM=gES6@p+mfOG))IGk@fVmYRqMd1+8@s)%sX!41{0 z{mihyJEEV+(B1IYZ+``yR{H*FU3%U93w~#_o}BBnk{$A7d{R+?&E>`)ySc+cob zvlI-wipk)~TT7)EI0sE06qMb@Dkf9ahjG5{hSLIcgl;1W0qUV1N^oI1CAYu2g7Olq z1xHQkhwtnw+G2H5yTw~&hA()5G-IPH1``Elo1zwVEj*)Usga8J3J-g`HV^MtC0k1x z*F?!OsQZ{`@)g}q5Np3&CFSg_xO{>zl<_r^_ow@90~j_|M|6qBqX;7d+Rb4?@ceh+ zbOGx(tny0VY^_qVb@S9J-4NfLJk-Z5naA~V@wBanzIWsYa3}4BCYV^BS0I~pVz`Nt z;+Zn7mh-cosjCqAbK9sUMUgg+mlSkq8=T=5E*Wxmyq#L_XlhSVw|tF89yZjjYNZW# z(FX>_!&q=Otr?cY?c3|k^EoVcewDYsoI?;dshMeavuMmEr6y^6^69wEb*_EpH>e$q zx6JcS#nV2_Z&avDCSSv@r}BsV3U~8|3(BKV35hNPVk_VSWJBz3B5OEX(T+~4g0^S+ zRD1=CaE&hYuY?fc>9{im{oMJxRTE+qrHx%L#3Cp6(*M4Jht+LS@&u@ZTk;vww_%J! zRK#Py>X*NRXLCx!bvKLO#dkum3!`?(LN$IgVhd?yd1_)8$FirKM(NKIq`<4iSZ2qw zFA=u)`>Av$HDCG@?h#+Ys=A)bRC2aM1_ul5Yz4j=tY~CoS{t{6)jh49lPllXIMzPT zf4wFurz00|5sQ&n|I`Fa@=9u?!Wt$8N?5E}1J&PL3&y?rPTa(^TcZh>{4{Jo6X2dK zvgnOD-_hWE*CbjN5Il*Ur?L1p&caD8NY25-T&)$Rkg2j1wf-i`2qq>JIosX!O@kja zvmTE9uqMzdRBcyOdq>ERwmWt=2H@1J$v5-0gEsKt;lE#NzVhxev+aBp@^a;{=wu7F zP7(vQK56ObV6(|;+Fyk&Qi7~!3)*Ea&@agE<&=e5;n+r$_NH|bMHmt6diFdpm%{O+ zUs`JPLw~75!6Pm1i_E`d%*7Ab1aRFKMZbVsP7M zCcHmL(t1HKe$1znYL$VTldTx#268`E`3i9+QbAaKf2PiKC-kAVE2K~DaM7~Ai}?KY zo;usv>k9>INroZ6#;B(0*AeoiB{KOKop!^qS#=tfeX{;7U`!FibNrQYZb*~Tv%CnX zvUSYNS_g%Z$SpK{Z@^-tREK4;I?%CG)|z!#(Y{d~yR5va@G8$2Xu9Q-_*`j7#*X+I zg*C&(CmcXsz51tSJRk1^=`UxiGeUID!k^G+!>>BBy6v+elv_bzM0NXL9pCb)Rh+4v zcPcndpbGfcQ2CgKSWvY#(RWvL@$U&-eN3mpN=JuN>HWAeKmXb0qb+`mx>}tWBk=0M zzt)mSJZWM@!@_89VtwYMX0=18e%GhOYF{TFw5; zU;k*4Mx$%tl8!5;{B!WDDXTve`9Cg(v!JutcvNqKJ52ca=8|q>7Vw~HeuR^{J-^xH z^Nvsii-p^M?(g0I&w_x1KuO%9c4_!Z`|jra=(vH!z9Xa+y4j!!2A1@{gZxQlz(Lb- z`}nto*=+?aaw9Ii%GUUG^fo#ISy_GDJS(-%@4*`F3D;LH;Q_ir=XXeVR+%7>0W_Tw zw~-SmH2Wor{%U=X^`Y;f&!%hgQ{bTdryBNu{YhgLNg@N$GmH7^W98YwpghJVK#otB z#)|11G?i@?6F*#HE|fl>xh9P<{8?bG^O%fiHKU$+B;&9N-3l?%9>dv5uL7Xkcmg-$}sh> z>%p@FJtzaPCo^SnVi9F-lw&>mKmMo;=fkRc$-C%hbs}-L=jj_VRU1;T{=>6JUkT`f z2+rR4$u|Cjlbo(NNpDfq>KcPz@z}kqYk@-d<3AW>{OVe8iowYH$F=a}>RRx%!+P@P zCjNavkpP@Bu11#i&uifea4q2eptkt;s{cKYZ+hrYV9*7k)Wie>cUy9I_V(C9O-miy zdix`TrsVH!BrWwU-e?OP*#g^dEyTkOCdF z=-gV%cGYYcKFURj=cw@tMccu#jX9j(+^gjW_7@+o-KAE{J}7fOJxQwh9C=*q?JuCJ zvWLsbV8Hp=A2tdq4s|-%&yChoO^`lgIVZH|@7YwUK*VS@~!6|V3YXL37j1DpaBw!eH)I1q&>%cWH)b~fuN z$JMEF5_ff;u$~ZdLgZ&|23GwVYYQMZ)#JDMi^a>U*QRd&>*c8E9gMMybBxgpaAOHX zuf$`s6|cav!L8D|XgcTU$#9>LdGT%?vcPmGr_%oP;9#r0>~*|Da4*gKrM@!6q$`Bi z@iJaxqi|Jqv(#8|o3m0n^ssPsXk#l*at!$AGEkjUg%SULnO^0ZDQo>+rQY63E9GxS z2_X}_1|b+!;3CUr;Ju9=rd&!yjddEO*~EU=*~Lz(87^r&vsUD>P8x@KlHf(i*hEwh zWANCP@9ziG2%9m7vfzt%l^}2#VYu%5a|Do40}acZxg)3hh=5&9ZvI69VNDtRZ4T1kA5G?FSKv<2lC}0<6Aml!rq3H zmQyEK)1{@u!`Qjg7)FNWsS7X!vLrW=p}M@y+{V_$0cBd(Et0Pt4FWe+>>;arY&}n; z*QZO2F;7ou$;yP!5uaU-4;#JeJq%9WThLBNgu#_K$i^3RITN7D<3s3>k6CEa=!2=+ zfcHt@>WIzZOmp7YN5}%!reamwdO&z+bs8NINVk`u9S5B6 z3qPI7Ttjz5?SHg3J7~@{%WO|%cFtC3Hz^*wXk~8_zWlNAQ8=-I^OsG4kQqq3F6L|q;*A-jx(U>vd~{t-*2pbTtB986;!outw>U%O}s zva@R%_Pv@hht+EB*)biLSQiz(;rr#e{}r`9-O9qh^(k3>{s1VLPXFexq;4`}0s%)) zW80vm{8sKl+vmiX*_|g$W_G$iMM-zw*C5FDld+w{)nm^2}%$@3g!hx~0KQtcD| zozP;kW24GEVd_KD7`2A!k97pxrs=C0|6$+RRCChcPJnqqgI+zE=V=OKhh##-Via@0 zQ^U%`EwiX;R1<=Yv^sNaeV*e`Izqp?L$5#&OQ@N6ZAkI=Q-q`U7p430UA;;LcbC>@FHy8B_Nk>!Vo4 za;8E8t)M3DQr?1x4=@PGIi?1gRtHMnf8MK&y6g^XThrJTKSI|iR&1QD#aDDV-;t@AeLf;PGmX)6aj5ScC^TWS-J4LH z#HB|V01h!@J=Hes#EnaIT(ejz+ATemFbiu_tPyH@$v3ZFXbjm%d^OY>V<{cp({r(2 zz0Fa;pUT&YkgT^{0t;OeX@Gl$?`?TCJWDRW zoK`s5#3t=h`Z`tM38$!f*4BVOX77*eJQC6gE+ZHSJHO>OVrc*G}0DH&s&C9Gr%=_D1^(r5W8ar)*kP3~n_qGVm)t3%g z?)I zjAgWG-36qL8;52d>`5&#em_Y5Bl!KTW8Ou>z4zehQGmzcR28;p7UE=e*L0PH*hL&E zUwdTR6}p+-iA>b@-LC~pP!ISkOK$M-(s_^5S?!-9$2xd^`O6m_IQuz&WQ-W+a`k4c ziR|4RpLmw3kJ*H(&5{^zfQxtK=?Ct^_E#^ye}!+z*PRfpR7<8%vgZ}zwF zRil09`l+b!7qZACk=Q9OmiXAG#JIq(4n)gbQ7bP~vK6rl73f$ifO9PdR|PCfuZNj7 z#AfRhz2o~3r?;6!3BiclblS3Iv_|cv>Tf!E>`uRVBhXn6T}Or{RnMvWI_wZRQ$u?) zo+Vdp%m)7uehJy^2|*LMT>rh*f9YXm=DZBm`z@4gbx;ncuMq&x6(M)stlSD=jlx|E z3QZ(ToDc+p@_g_7cO|2$Etm9j)048A1UOZwgSa*nPW#j{2e;I!=FBJj8G%GL`|a`K^)C z1sOILvBm=pwpHzh(mecu^^`|-6~&HwOV)a+toqr@-QqZ)J6_C@(?+_=v8Voq*cya) zN2t%WtMZ}grT(f&X#+_ehEkWnrb9TbBezA-SO_v#d)=oZN8=H~@nMbndW97AzURzH z>jRy*WCy%IryHaoa`M(_TzeoYmh7vOYb+O6+E2&EV`!%{v^2hUQvs zgZk3v%iS7;pz=?{Pj7?lvM+10)Vg&6G)ER3J1qKUKhvQ6Kd&Ao2xj!gR(}NsCH+6t z0u@R?EnuJ)=ex$LS2{))peN^te7W^!PglBr`diF&^f(#m2!(4x!j-jv9nd5gUQpe- z*+54O7z?shRI&)K$+Q3qe3t|Cl`c%IKg9okeU$MNQI4K*%YN6;&w-2Dt z5m8rr%+q8`2fWo`>)P7x)uYtQ0F*ldX5Pp@l)L6D<<9v7b@eOQOk}G$|6?$r<3hs?j+voBt?M9T3xQnI|Ek^v9f7$NXyfRz*4~R~diQbc*p&r!XFcD? zeRVqC$FupFTeh(&j$_ldrq(HY)R2m0LC92iI~IrY(F{uWFEPCTiXFwh=s`K??L;y) z43!^==a=dZ2){V^eN;Q`4kWs!a=pbO>UmcC_I8Br&9nQ)575E7f>tEq%@!$ubdu3N z5B<5Qzi%~XfI#3WrBt*xTfV%$Ma_E`KldNBwuKL9y8Ncn3O9+3!VgeEu_+Y(bBO=5 zHj$|-x^?b~Ouk{r@D{-ah>%Dm`M)IcuUYuiz5z&WE1LS%KX`x$piX*k-v1K7|IETM z02q9VUe@7H^T6K|pa=Fu^_KlVbm_GRz~Hs2u?yEo<7xsbz@FsZn&bSFK{}-o7;5MkU`UG^29T5% z=^=)Y8R_TZ|NGw`h38%C`SPxHe}KgT=Gyx@_qoqFj$`le=jw_#N$!zcx^(HLvXZ>k zrAx%nOP7cmuU!Rx1L0NCzjTSf-uCI!=gLo?GCg;3vbJ@wx^#&n4jR`6dZJ0uDWgJ> zB&T^tE@a@B`C`nGf>3@kh1^RbDj~`2mvIyG`&_{yg(p!R$=8e?+@3HoB1y~TH6r>r z(pUF{8yV)>zwC#d^C!axO_$L;`-r;yE#9i&uBMH*{p9%WGycmr?&cT|p*o%jG)9zS z4_sShUTE(*t4!Cqj(Rqjyw4Vm?qJ8NkDpAQTI^Z7T7m7rgM&AR2#xg~dpXcVRJ>JG zrBP`pczoL3A0e1+;pFf@~!r9yxRMOY9hT_Rt9>;cRGj-lr zTdxUYTX+$7?ZuH6H49<9sc)|QwVsr)e>9&|hZ)>u<*_mS#hV-*AZcTq^~hQ1@h6H3 z$tHuxi|$XKsLffX-W4Bec506NWDK$HXw}~^2P1TIQ+^PYr|Jcev*;-BQ5*P6EwMztH zwwJB|KM??5_kgcUmk4tR|K~Tv(45Qv^D|N7*&j^^qrER(lD(uXFQ?;4us-eKOQCSu zzRe#yAfc@EL|Ilv_DcRcjvT_lMAIueIut|%aukymP8{#v5eDbJ%lXZvCL6(VEkcWu zpqSvU(i8Uk*B9ztk2V|78>W2Stm~}VUZ$NJeZ75stv2(F{dj9OjfmtoZ!QsDV+uU) z+rq=39}Po0U&${o{@5nh;uDf*(_rAYQc2la;nc{Ah+{vv8DCVi;%2t?{pO%1r;|7a zn8B6XvX{>Lwnalg*{&O8LOGxt1g89{`)Q&!K8X-nQsMQXIDIr$Gy1$4oz1tE=clBF z=;MY`)f1PDD@0fSk&Yh$KA+G#EKJ8GaOeEdWtj@E{jgaN)h#tQRyX8@I|x~fiRHjC z1vZUKrL`{$9Q81RA{W`k;MvdK)S5wT_a~P>U7E^L7NSsDJc?gBA)Xavkc+(n<$ZL+ zjqp4poK3R&X*)-y59@w}q_Fur2vtSeM|)UcxxoFRbb6<&_zPa+5&`Pk*Ke801R65j z#ANiz1F`1H>govIP7_W^RW|>V@I)@%K>EInbLp!>*i>Eowk zo3Ug5?V=YMfhjO>@5(idk(27mos0h0@?&5c>`>?Q{+Ye5e@`~kV}zFO=%kL^Me!R$ z|>vo;35|AowD$GkkEH)?DobRO?fEi?PQw55!<;qW`GmrkUt1|$8wYNuN_sUXa)NsrRS=AV+M<)) zjrT7!NQ$gC;Pe{6qUqi?APRB%9SIIbj_)B}GhVa-yYvW_1IrMS_el0MWHg)rNlAK1?RDykZovw1Ubx#Oa(5hy!BDC#)3TzmNJCgbgQ zQBg?&_)YS15Sre(_6O9+d3S(f$ho zw=O0y1N#M^W{PzVlAO4KN{lq?OWM40a%7+GF!4LRiHn8{?g!$vov2j~Ef;Qj_5By? zT^br&1K)lr4-op^9b~oFE_IjS)2yMzaSdsj-8eVw=r{kK3pcmrlXko{#_s;gDefC8 zT86(%rirg-1fC`3H{<(2*pZJ1x<;L#qDvCKu)U7#9iBk$X?O*E?dlbJ;R$JDKk$|+ zlJMA+G^}xNnL7>+4mJr!l2Y@Dl)?q5`Ap=WkLiRFUf>Xe>_4^TrnSE-S9@-9iaGN< z^3y0DY4ujH#7Bb=8jU3TFzpy7PTh_|2AS#pj3nv|aY~DcqwRV28>qf)8GfIWX?p{z zdv|#jdy)isn8^vu$bW+Ib$9aG{%&Xk<93_ev?c^N_S^1DhfjtIM)|L#i~li|RY~3< z4+y{yIVQwwEx4If(}}qm@`0NlbVjrFWX10^N91%CS1MA=SE3 z3?c6M#hBdl?L9SA_&o*ZgQuZ41{b|tT(*C)YLsXa6J%2Z7TLeQK=Ai`-Q^zCJnrA= zHuF$nQqW`dvpvDIq>)q8?;D9!5Ky5+4%{)lO_sqH8eqHnL#ln0w2l!Q19~|$&RoJB z6fw~|Aq>}7irECiTwp4Q7;)1UmsA}RGUDqOh010Y^ZisLF|HG25-C!q2l5c&y)SG} z-Tgan*2P{^>`p3&u}EeOZ#SLSW4WF%%3imoRa>SURhrd_I#+K#=i!#J7neJ?qa-=Z zS~DW|J%^*#3GvVVYU=;|fvJnhx7FhL1jk5F!judc$t6>9Jy(mf5`e&9V&M1EY zj5FE($Y~XVco$M|>2Q3hN0yYWwXD{ot09x_z~o#z?fUhfrDv8|i>7c>b3xZe<2vd^ zg;Qlk7NbdUbH zdQ79gexkx_q$Jz&G~hH`K+6^T5C52Vn@VO_`x(m7%M zN0qjyDGZb{I1^rd_ujqS7IL+G{}$uvXnptQwe9Wg>Vv|%YNuI$O>DV$48KW(xlh0b zR!^|3Vx&YD>ZM*2iM8pCZ)kX&@@o(V0##&5v1nvT=FY&yT$j6@CVa|fVtn^^#yftF zoVGal6oUEKE}!G*&0J^BK{C@}hNP;!c?-?2&7L_xh)fZ@u{GOjPw`5lv)2-QhLp=3pgyIWwxi2$C-_-w;9>RHujplgU;EQ*$prUV%Sx;jmmCnwy=c25v z3RI_+It6xY>Gelh2Z+#RGMQmxQ{Oo;PTi8k7mb<)Bu~^&9YZ&y!|E1plHJ)7*PDxyU6W+7o{apz}K z{U|tzFZ|L<<+5pF0B*gCTC7#S?4;XS^4GD4ykSXuPN6c9Q(KmRu1=+9YC)2?2Zrfs z7LDcMrzb|xOqA~Ate=c_>;96lvVHTgL}{{W0H)Y~5F6h4b#`{Pk#o{nuXT;9s7!VE za4|fbWCrd5e|mU0SbMsIs<5mOS$bBiuK)WkmS_nH#j=K6y%n2cc5l;UVS79DW}8y~jGtu5=?-^Acg#fTEI*r? zlHlvIdpe)iPA*^dp=hY}kZoDR>~62b?a0PB;vDK{X=wO`(~ny4GO_!+)ID#uErx_? zMSj+fWYPf?Q% zM-H=RdmH&1)r`(>!gH2?+Jq{bn+JA|{ZaW=RP<_fhaBPJy+bE-wr$q;GzBDr7d*kxyIXUQ0g^l_-S!gSs^J!#Un_LV^+9O@=} zuD*R%b9}QT?(I39hau0;@z5;8sq1-5Bc&6rHYYOiho_Wj^?aOUQVcwEy0upELo@@r zYDHElaCwUO&Vw+O`GRlIdMO`qLv;oA)g9jr%gtt@Rg#s7Y;60d5C(pbLt6)C*6upS zChTVaYuT~=eTL1UF+@y}Yu52&Ha0eG0Y-ST)(PBHv zJ>tLFji;W_YALB$RkM(xXU9khg6w1_dat-`Z20H$ik0ISML>2=7K<5iHm@DE(Iy)( zw4R>ed<|FeafBfGKph@*{7Uwix2P@rcfs!?S(X-vHsfD69l;ez>Pm;_`n+N589KLd zw;-YA`tek^9ls-Lg(v?A8p@wzK|C%HR4+Gw}IFXPTZ?&}VA112dzMX1(&@(%ohLEh8UW zVIk{Yn^4_hhTf2?WWqeIeWiEq+_$Uv@jxNsu}u>le#jaQ_cM=*-`N}0`rP9bgott0 z%NMli>j@+Xk+Pde@Bjht=Z8@Kd!@_0BnZuF=*P{?Wi7#3$-M;6NgdG>lC zPJVKwSk@)Mrcn^iqdttrWPPeQ1k(S#L>Jyu zHQ#9!g;1?Y8~>1G`=jRR!uZGjACB9djK(nS6o$}x?Vw^v0OWhpVs}E&>JKBJ7B`92 zHw(}n)59bz;ip*pZ_;uJ+YQH3K){ZaCi(Asr1%~GjY!Jh7?=**^k{R-l#(MR0tyIUcHl`s4nOVN6|*r5*^ks%1&TD{}6oy@Rb zfRt59QHwu%@C(^qGLX15BdGbU;km)9HOsvTW2OP9txWxz*VI75Vp!dcEmvMF@tuYh z5=&Yg(iWRE#zUH|`_g!^%@Ut~$M<)r#S$~DIPT(>n#xssXB0+g_V5CxlVkOA#|K)K z<^<`pU&GCM7Agup;B>u;rNV|tBGQGQV@Hu%6*Fa82!~iIAsJ@kx*YfYoyFdggqU-- zt0_gLCE%@1bbh}kw7R@@!-X77Orq&jw|-feIjPk7t-p$-`auqKGn#$bO%J|B*o)S^ z5+HTs10#DOF}jtQq!hE;hkF3Z0c)ko2_LYQ!7)DU+NewAt)10wYMd;f+nX9yX?nef z5q9L>!;C+b{%5=V&ptTd*tot`pLFY)5=w95#^tvqpJq@0Jf$86SDMF79;%-FaPFK1DAfJ=PwS8Bg0!QvZlc z#h9O-92dJtN`RYRWo;ZgmrvK(+f2^1TZ3pBN3BzV@|uH)WWmG4nslH~giI3NepqQ! zam>-~ALp&1^ID6@^sM>mANA}1@Ce0Pls@Vib+Ynw^3M-itsu|6%Mn|Z4~Mq3`YC9< zdbdp<&&;Vduk~1NPI=)R8+_q`n@3(X3kB(15CRloQI=Z~ z0Ul=YSEDM>*Luy#$Nf`{N}!qPe)8PrF$@}-^sCZ3(J=X9WKq=fv9!$R`==3dcuO-#GcTWTr2mHhL{V4rSf!kwSEYx>{^nsSAJlzw z0y6nUzvYmtc-yFm2!+1$OW;PAZ$f_x7>Z7{HI%;R9<(H8GS-f? z@Up0qZr=0Du*umxIb zzzSoktUPA@EnQDVcVL%bp0!rDPNd8jR#GMtCGDk^Qe``2J>9q)j;Yt&nr>9Du~y5_ zfOZn!qI1hA6gIs~oYtSA7v(mX%qQy2u48JFv3=4KonE+WzPrThSg|tIm}lE)6w!#a zi20BVZ~r|4*H=SnQy0O$Twf{Bo1^<{<_cP;u3S)^z9&i@mjwFdaL;akQGNO{OzC^6 z;obeCMoUAX<%t~>CREstvin4{Yk}UvqQWp$c&J*zwdR4bzZzuxMV&9a$xm%s#Qfvu zT0#ep>5*QD6I`cJS>(h{l6h$V^UBJrW$l!CHnq*y-L8ENyL}yfg?ycb>fX{4Ek<>A ze84K}aG1^P4=+BJlCgXaI!)%#oPyo-2{o!VK!>{D3Y!KlkwCKWm2V6)d9?e6ffK%Hy{KCR>q!HF#D`mfB27%ble@vX z9z{W4mhFt0DoAT7#)&{vhHvP21pO`&3hwBGr0~)%_+ng4NGFvlN zYPbFJo8&DFgN*;@QX1pdrkt`#(z?$ag^zmHJz-FOr({Ki)Kl{ulSUWY8Lr1s`1?kO zp8^Zzz;#ZK&Vw%;n*&)xkP$F%^aG>k_((O59i`k-!#nJ}6Un%eA3dy9xf6)Ocj=^) zWHm=kGi6Y#lV(HHMvaVgpcSNBLZ{=nCO>_;Z@P+#a%2&S%5gL|&(TNzGruJLDXo#c z*mvKhAjr*QqtMZK1C|EnEHj6CAKsy~lI9j}fxyZcX=&HGT$Wc?J;m;!eqHuplat%L z{HMg;wq@S-IO?%XR(?;!xP=DOw#yJCNEPU(l zzl3k}-LFEwg7)0-PZHws(6J*LR*yMhgpOz=zg|LVOiVJsqHaF&}F5~)7Hg9xmX7lt0d0O zQSb`Ids;7Q>Tl>_B>Gfe*eo|O`%1Df+3@(G`8TY9Rj))XYZ#UM~dy$-X=RdX_r3m$mBOY_UlX{ISn z82ws<`N0FaF(fU&$NbM%OtfTE=roV|+47e6wi}FeI-?RbBOCa6+P}sOfDtlnua*Pv ztpHKsJ8nqIMtf_wpSfF^)8)@ks||AAlZi%>ql0}fs&O@S_3z29>WK>rYehH_2)?HS zmQsOlmr%6bh-vh|N*8MvB398l1NdwyA61lJF%uJ0JH&&GUYrNOGK9E>n!i;_ zKFCG>z*q3Dv8|L4uG%TD55mwP8+Nwl9*5tq5-mozr#DG?n|W`0tseeh4z-Az>6I1D zvZGVamga@2Bnd$DHoBW^`rASm>t|<_NGP^u*7ZFIjss4V53#@7gF-@&Yi+I;Y>U3E z=sXW_Hc)IIl$*u~lS%|5(Z)%MLsi{7olCp%xn(73`9z*E^ewH7j^0YUuimTAjy5zT z4qGpuG_dr!7b8Yc;W8;D% zjuR|o_*HwE5kLG{-E?m+h_}MzRZ%(5UU&08DQuR!W1|RJG6m)`E6-^9MW;=L>2O}| z1DpEvku0K`Aof7&-}xO_sJiC6wHra}$2B?t>Qi>VP&M+ps zvDR<3(cV-w`6nU(wq>oSDt!)_W1w^P@)2`H065qje>*@onhwb`&2S_BnVL$M9OU{E z0D<3i8f6(1(?!kV(uYnwyQI&O4PZGDX zY^uQBJoJf>%547!*8Up|9F$xQR}sTJ)7P^DUbq<|mQwemm@`)oHrPl=q`i$F3~J~=8Ed`wPGzL@UR3N0^} zC^spNpB(>+?2-0&!B3-Av(0fCUIIC%368wh=qzs6<-VchVZQsUpyXj`)_l+HUx?jF z+G#es3>_8wW;V4no*3z!N(#R9gZW!~mxJ~lgSY19<`6!f2O36L@Ap*r28dk*ZW91; z6JKP8gx%^c8Ihq$F79QRZc0nmJdX?-r3By_eRNS7m8O#W5mXa*>Z5#y*|UNUyUSpL zGDGXX-f|;EMh0{$G?jKd5fL?G&vpP(7r|;KIGB@WyS(h-x3aT@=B5{)VmH%xL`LDh zIr!8XoxvwM?I!iG_+V?rLZd4vWHZGct;85r?z~x}xt|>XN${>873NaWH!Y0bPzynp z+!rRtPZpc4TJsma8fs$?5LQU$0b6@l+yl~oUvZ&`D;{8iGHd8Mxqci1J-5}b<@tQ` zPlVA&s1$Om_Ms5fkWVEqV;CCQxAc@r-<3Slw{S|#@;Oo1x7%TPWEAZ^UodO=!rF$S13a&47nETV@hQ0$|m*% zhm(!iZ~+y~MNJ5`^ijtUBp1iX`ew3=6N*Z!)mKc+bt%%}#}<5b-4r};Dy|vC;Zf`t z#y5DB)s&xs_`L-KZRaM}p_S|ga$1YV%dJ1zQMTKA1hB8pl)WD=GgdV2lTb+JHRhug zg^09drd{_7qk82EK+x_FZ(>Tk?K&*S9Lc);@O5>tgY60FgS0IF+AdXmfsRyi5PB~3T)d!!z0xM{Nqo8l1;#oYSk)^cE7&1tv- z3Nb;(vYC=5{D4J$(grU9S#_xy|A9%v;p>O2uQr`@vD9D>LRx&%u0lurMqG;)i?K*} zDlRW5*hMM*BiuT*iBuZi7Jjg|R*X6qL$DxBCc}j4b8>w8cybpisqBBanBksb=2)K4 z$h6+q#`hS9;nlz2_C^<121~Jc`O?I+M&jNqpU3Qo&hXCX&G;sm;WT(Ts#jPNcoQ_F_m#xm++^mVeN+3n(pmXImk&Wfga@$1k(olL z<`WsOwGF&#`g4M*+Teyh>a$KQ6lEzf)@|Eqr~I>V;<3ZbPSado@nVdb|Dy00fg07k zZ4y#AM@7p)b@T4#wHlOzjLRP*WAVwM{NykZl~lhmU30G>#8_QZ+t?zvUc`ZCn)LB+ z3(cB?bFJY+D7}5URd374l*=1as#cUpRP%D7aM3wFu_!ZNkkwQ@E=lHVcdpnY1VYC* z57H^H>hLXXWcSsYVjF&Qa&$dIyCO}bWoWhcc&-oJG^PJq+o)}(Y-fGolcSxdX?`;C zCIDE3QcKR@H7B(iL*K6UI*ita7vWrtwLp{s;y4RVt^9ZT49Cevq97*-u0j)omp8L@ zGk%(v>$Y5szzi2dyusEp&^^4Q-NLns)Efc*AErvsD(v_F9>xNlNdCw_ulF?|SpA_! zx_%NcQ9G9rdB~x)%r zJkwg?4`($SVJKf!1B-ja0|~1TUwvaF;JEH|+$Yv$>Q*LrepDM}q zTZoOClH>+q6+6AHeC2rv>KSd4Pg-Ge=85lTn?`pwn9<#%rqx-`BgYSoqa(qkf;Ort zxe8G>yYTG;3|tvuxM2-^uuaO^h`TOm^c&tODt>(gzV{NkQAKoI$sWsq9%@2y>#Z!?Ddmt{huf8_?aGr;x!VI#Bg#cQpr=;hI3kKzI9+p zOBj3PsnAn&ku1JM7sbN#^MH&b@}3rGLw)}MM6=V&l=n+$H}n<_%dBc@#z$Deki%3M zm(VcoiD`?SSE!9N+$y8(baPUOe#BGlcnN-k_{hv_pJ@N(;1x}5O4CA=N6Rz$H$28j z10$if&gn8$RO`{p;O5`Ic5QJZwFD%8CthXS?-ELr59=BUJ90h<2}?;C-2j17Wl!A* zN>Ur`WM-nLFI)bs+|h!0e{=(5K}p!=yefwSXlC<6-w(F0>jA!1;2@98YRV>Csp{po ze4XO>f*1o6ZoIXfuMhKh)dpTD#LjESb9ryQXhY)wUk(uf$d`Ph5iVP46}%(ZaeVa_8r21`}mPV?B8CQIUQ(r^NT zB~V)79$)czagYDp(fA;tH)-+KRnL;NTAN*M z7}5ed8BSvnC4lM7w(^to|Mf;*LBT$oLs>~F_A4s0Nt@kqqoA&BAWgF{ZA9SNtAU{uZ;wyT1YnXqP}%@qQ2+FiF6jNBp6*1 zk12vxK7IO>Rft7i=k^a;Iore8@Lf+%fj#vrcG&>AX?-9)<2{xX?p;58=wsqje{_88 z!1ifEYYua)1qw|#$6uIiuHPO;8_stRT_k*wy+yv&cYqMP@wQX$0tTDlO6ddH=VM&V zax&)({ojXN2IMVQIV{hKX8#3F_3khg*(b&2FrI^t{~HnmgD%N|FH=-sJUIN??cur} zr2(?PV-Wv+NV{xcPB{UI;l+dNo{8J6SXPM7sowuJwmB1ErAu#lE*_kV@Cvj{;O_79 znBjjX`tUYjrNAdt7Y|Me7+#O&`a#e+!1TXw`ww6xVcGkn=X9X|4qh1n7#<#Z<@iDo z;*}eKmG0%lo=0N+JGg-YV0hhU!TuLH=q19dfR%1O@484}@xSi*zwUXFEC2t;J!L{9 zt9jU7@4Mud8nqbVHmCX7HL?b6<}7~lBs;uJc}!#peTLZUO;w_ z4s*;5C0|rYVz&;hN#uF)>ra|&bZW7LMF)@9e3{20U=}`$O4l(*&Fpxw>AN={!019jKExqsrN-^ypwYTy?J!n)y=|j4gX#&+sk*t}YXHokvsl z^W_LnxYxwF>C=r+nsHc7MI}DP%uCI>H>1qwVGX(Pd|jqU4fNM?_PF&%+DOfl6F~Ek zcGXSy)Nc6Q?SOy)+wVsV`?hE!#S{s*SJ=mW8^rYD?jv`8`>o&cTHX+K^HSSvei}i+ znOoyH6uOuKRmxbo!a&=i=`pjt`OvHIkQXVber~pOy8g%aIXFj zv!m&G!A))m8{QQR* z_ghRhsylOL1T017&>{Hi*AC1xJ#^pEZj72%?JG@itFAf{zrqUi^6qYhK!sa9x13G4 zOqb95y!?q3m^CjIi6qIeOl=Pryzas$-3>ct4PZzqM&VX>6!A_Rl$TBLt>p#@*c+47|i3x=Pe{Z>7U=K(*TM5dhQj_%%uuBH($AW^>NQVVWgV38-aj^sVSTa7Rr=3v1*H1rHx)6Lg?AZ}UMeane5{M8loV@pni9aq zeeLg0!v0Pb6mVaEylidR6)UHuN=kziFs@`Px-p4X_`VNY6r8ni+ll=y`^NM2~ZWV0LLjd{xo52dZgJU z7A3Y;Pml+gh51L>c93k>g;}HeXt#Awh}bLUboOjtlO21(X#KJS({Rf`2Kl# zrWMSK0?J~;?Rk}P1f&TN`|0#$h?S+jRhE~BPA>OJ+yiAvdeQAwm^41flfGwRkBZwr zC2j+xhhMf@-68oezFd7dT)`lPR91s{+2^_C&5-7`{?Rg3>JHA8E*?t0TkbXT^nEzV z&w?cXQ+{>-sXMH3RVge>>sHqXaEP)TqL9han{nQAuqo4W+*feZVZMXdZSKyO^Q>Ha zrV-SA{FH>G%JQ$ASBG;l_yTpCrQ%~fkDbu|A?VYuU9_$qYLL-A zV9(86S9^6xA45LE4n*r&rhci@-0~^S?NhShtj~;52eQGzgb*=6C#eOSKo`RsGtQtM zKzP>*EE}hp-~BS9x?!+u-YhBD#$}+p*6bFlh(-dcQM<6Q1OR)~cgwr-<^vL1h}GB1 zU8Rc+>uP;>45Y4$T)TIQ;MX(Fu6mlA%P(%0E71q=@czX%ysM){!Mrl2q)Q^+?v3Tq z-@9|lg%`V*4rqQo+w1zfavEqyBq_VrY!%=m#!c>-pp;NM!Ix;@s6=&|S8?!LJL|&Z z1n*TVVeMM%yhh{Al@i1)dqHEymHixf#cZ8IM?i@pEe!mcH0*|-x=yWA^Ru+84rAqD{uV~>ueDP%TN?JGDgaPemx?}M_1##U`O_DU zeJg6>C{KG`Ss&0MrcVQbzU^d&nmu#&&`>?It#oY($859Mts!zY4br=HOq-Lljwx1? z>MP~Te^(*`B~O- ztPoeDmZ@W2Z&MNGfWjB>xk_gXdbI8q&sDiTuk)@e$;AB zwAS6@5q)rc(y8}lvV=7ytZl0rl#ATM?0Tdc9fb*#FHQs{`IF>kFi~oRiYivrMCz#lcGvQ(@`I!p;p}}^ui*s{aR1I zozGs$8tK7uk{Yw|xHOVvLbJ!uUZGeEr6a zE}fVqwDC`uRv=68wmtv&1aa)KHfoG#E*aPm$-$$isdA7CGL7OBZ$-#64) z*hEHQj(Rq4t`MUl7C``8^b%?O_SNyk&g4}wzk^7e81HhOU-V?H<6@C^zS14rnIp$k zDVr>24fLq);cAKVj&;x3mh-EwDI-c}hStOB^q!bvU1}E4uDlZ2?hi}B(DBN{e7eWJ zqnaM8X6*UiU3DJ4vohHbTPvTBM%Md3Rz0tiHi)=3*~~}W)vAuA;EdIXpxhag_SZsq z%K1RgwYkdjh8iWBP#Y$g`b3FMhsZ+z$I}xq^>XyV<9&)`6kJTPsNUHU+8`DAX{O{-q zxoW$iy`Pn7;gcs(!diJMwzfIEb0%(7f^!@RIP3%jsC(#FQvN3C zQTkFAa?@YG%1^Hw3v&U)q97fe@T3S-oRZw)-Y{e!#}tFf#i7v{w>^w*%6R>qJ0mxp ze6$yPLiY_b4LPTLi;e2&_Kt{10WzYaJ1B&>2FV?|vHTVPc}vcZNsv=aLG+6rRE+B& z*SG4GMp}yul~K1GN-)dXZEpkt~5?ZmvmivW{1sIU-WC%xAWL&rq@re0C9zu zf?|OXVUKqlk}Yl7F`KCFvM4|yFv_pz@EOnaVK=ma#5|DG$JV%}P%K?Q7$0{J^y!M}M zE7N4Z_0vrMZm*%nOlZ~P>d`gOZCpq5Gi76(Z}#w3R$NN!6j#8sv7zav!BExL8jym( zc?EV54;A2tn;TJ%t{*i8#UPktN}0y?5c%xE9qsP6)^)_Scwrk+PzRB(gRoV8i#^gV*X zX7|@=QoLaKQ;X1pBoJzFY%@-{DbMP7w$QRO=&=~I=T8_-jUIh0V!~k>sN@El$tcf# z)6(0oqv9>Ufva=S6Ln5^>SRiHtD7+fMEjwVf?ZqDK$$roKU=$+iIAksP@SGR$QJ!! zy;qQx+GICkm*O6bN``jVJbCtwgmMAUNzj4!fuh}IYv4Z6X>WFEe;W7NrFz^Kb?fMO zPp<024}IzSyISgzLOMScbx(KDV$F$MrxTnXxd8f52T@ zja1t^3~F!xjQnYz`ip4syY(Cm61x4wKR5ZM9%E9UeT`SZI5~5I-e$t(uzt*hNg_O!vOiRFFzl7phb&ulN zJRea-)3953vFMSYG^n`qpe1;wCkbvfiK9n0`xql)hl9+(Z)rUTkx)=dlg#1z>+ttY z2#=yP@Znt7_iAm@0VD`GtOJhdjLPP~jTcYWT9t*71$4urzuz6;OS&PTp7CyQ5z*F` z$(NI!n8<=kE*luxUa*YO4xCIlC{b7U<(KqxhmY8s>dSEB3(;{q*zjGXqiM6Rg1GNi zjgbEfSgp5DnH%jfJQ7^huV*vVYOpHg62fbiB@n2{#kLuoE@>Fj)NeRjVC$(4AUq#Jc~P>jvN zaZH&DDD$dTnH{BA0q>)Y?)YxqI%M%sJPal8_ar!EQ9e=nS~}9vyB|PPnCwIQM2QN@c+3B zfJnTj_m;~qpBK1Ny?(5VF_9+fzCm;K%?h?UuEbd8M=6#w1$izjD`Lh;@2SaI zRrpl;*~a`6pG)O`K=DkGS#QR_$%kuIXaUD4#pMc0kNX?FCY^OR#Fr^d5bxv_%*;lQ zfFLRG6JDl;eC1Cwh$y*YEBNmG+N=JGuXs^9pva{;?0&U6P?c``{5y~N{#511GsaY0 zvF>Q67u%MU)pEG9W7D6?jDv^(ce$DJ~JCp=D z<7X^pSikrouNCRP5SbahJ50R4yPQy74?f)vQzyxQJpGj>C9qPmm;%bSEWt%ojNl+%y6wO`91~}UR-mt-|Qc0 zRR$j&#!Dilo*{zS^aqhQ=wCMXS7IjUqiDN*u&s-T6ovOxNn|pf{gBKvnNgas{R(CQ zonEEy&?R^oA{Ypbf{AMi)(xou%3}n2RHUTdBFvu#k|&O9&iG^cBO5)|nhh}qPl%H4 z7EN;HNcjDr|AqB9cJi~tifh%_*~XMt7_>I@`ZuN)!BR7a2HZ#FiF~34qnQh%s=Lqa ztps>ttKJ!hI;99xCvzEU75MKa`O5f}oWTvh*`yd(_+)sp_*=ZC%#9Q&Yk|7DFHLM( z=(&l0`f)Mgho@PO$P&e8+xyKJZ);hd>>p>s|6!o!S{Qebsry>%+5=!7yTwH`=r7rf zY%&$b5K`;e05b_qpW#-3GZl%Unbp`WlIgM9A5_TAniVS^Z{+$pSqHLNc9^Vc`&1*L zFHo(y2nf^S_jj#n5Qcz+Uts@z|Dyi}jTZY}X&1@<& zE8Q`DES?%dwsY_3=jW3K|NWgVAF`xW4Y`L}^TQ}L#^xdg4#P>7qzB7Oc>bBu;UZo=ZPm%#3Vg6rN5#_$L#`dibaYIn z&z-0IyS)`5n?=Fv1!E-@j?c*80kGfUWXtGe-wD<4In{D^i#9%Du-WcR!h04OQa}9vQ$gCKnqV+Ofr`RQdg3shJGg`^lxB2Y+{@sLl76Tu4l@y!< zqToB)Wy0sh@5t784?bx_^^EWo?PWet_~#P@Q@N4#_>kNExrmI%wEXP-Y)Ux@YRAR) z2f2iuSp}Yu{iUvMURr<$SDT#wRHK@BgGK9i-@Jbu`4EHL^z`% zAxom5mlLK9z-hcu=wd4_69ya+%y-`~w#3f(?R+5vv9gKi=@(jr9bR9-$e)*w&*+Dr z9oHUe<2xE`*1(67I}Jy*)@7Y|9iQKP#?=Fe;i^t*%{v#d6xH%fPRX?@dC7PG0NMfD zF+`N2pWPW0ytpiU#Z783_wG5h_StJ2^0%u_mx>~K=@BRUDXQ5gE$dT_#wX)7oud_j z0#>zFAM61b?hT-cnxr~HC$Ps@9jGdvS6ZEc3>yFq=ekN88z29mySp2>hanq8oJqy|B_S5U4N8aAL2~eD^kJNwPy~vO*#h2u!O~kh( zFTBF#Pbfff&i=#h9ey6|aAw;^oxmJNK6+1vbNBBVQ~Lkq-DRJPrreT@iMnX?*82dr zEZPxn`rz*}q5nKXmXDIDC>=zc)p?#e;y_cDdi; zoKqkF89mSm;FkBIoO4qyBGzL;MAtA&gF(wx7meO73UJE@9gn|*F7UbAU9kVSYWwbw zi$(`zidUe178xt77wo8O3tE8F{XcilKr=o+$1_iA<{9|;R?XD$(Xt4>v#Uc4Kj$fM z&TDQVF9||h)Kx+*dcnXzJYY5N{`lkzwm0Cg6{NtLiF4k($h9sJ&X9N2*kh|Gu)>O< z3ugfQJB4{cxu~%1#Y%&%>i?v@MzyqaGsC~{vK4=3ge%GyUSA68iZqsY>I3Ie;PSAPsl&UvW@dbz*&J3{lk!^{7A?Q7=OxFfH| zTq0;xJn*pxMd_xGFc-zsON5SB?vf{{f+|={g?R69OBA_u)0S3$M+({g50G zLjB(?k2wJlu&MsJg1jJ60$%w65X%WC+`oA3Dg%Kkf%FC;_}_hfUP;pnSShVL_Ppc4 z|C-w1Oo2vpHHh!OPI=BQu?DP!w(L?oZ`}Vl8PAyljW9%(`r@E32w2HlVBum1q&ice z1M|8>v**Y3GhBg{t5=f|gVoPCD`rEkUX(PL@FWWjIh)yveW=6tx4J*(QCCBC@^bmQ zLE1Q_#mZcPqt@59MZDitFV01n843#E`0psPLs^a02N$Jh z1BLeGVC4Mhv!3KkXT5EZhm8N^9d-d9=JW;XkR~HWiKz^^|fCnflJrXWx@IH(OTB=&Q^HN=4VJD3l~N!nl|B>xE~b( zt{N=RqsjI|04!=(zs%`_0LUbpV$3rY;7$fQNl%0L_;{9w51#{4gnZ!cw8jlY=wS6X zDXkJ6&TKzDalkJO`On0ik_QGdVz0MyHm&VOH!b|K6Lq;$lmSlH%_`&X^+4g0GVmxBj^yCZz4X8-O33nT<6V(7Ai6sL_k z`_hk3kIOeGOS86vuF6U8M%GyOC%x!ziT!wT0`Que*?pPfUG^2NFVnxJe++fmS6J@P zPLVp@6xO+R^LjEsPtzpFh0D5Mqmyxd0vyb6^n_!8E8Vt#eY=6uSsJggQA6p-^%nnA zzew@-o-~%6h=+byO;tUPU!NWwzKOI+Yd$D)E2rhyKQ5I5>+`-p0Ipo>svl|{+LK{s z2SC2$B)ES(aQ^7s1b0HBGy&zn#&BcPoWcuA?ye5AG1`BpbcQxQ^L^N}rFVAm+1br1 zFH(C-_3BD&Q@P$1X&#^cXd>II^kV^?vYOwq4Jf6qP*>Onb~{`&*nyVb59KQH@%(0P-)UTL8`PM zEkGbdL_kXD5FikG4G`%iK<4ng|9Rdo1Fl(XX3czfzT6+~V9v>PuCuSb_pj`|vRn^X zeD9vnxx3#B=?~G>^Zejgs0?i4XJ>_UYMdtDs~#LF zGDy08u-1VYGf3KHk9s)XYkg}z`|@Ae`9!jOHznBW{KN0q!_GUsl@2CK39F2%%65w~ z=M6P?s>ZFnXqpRREQhvzS8Xm_3MD=I7!uNsOd~|iRf)$*8B|84)w*MQ{WeyfEv}i1 zCroe5lWv0sVc`6}w69+^Ye@C#*KXdlU`-MBNI%%eQxBI}6sAgfsK0yn?ipsh$dMvt zr42AhG;etS(UL^mUP&0M^=JoN201m-M-_6N{Qv^^R}p0K=LJS6M%#UPh})mvkRQOF zg-gCMbj)`)DZz{+(CqFtE*3csX(K@FQ<`R|@TW@PH|Fv$u9iHvoi5{JACld$(L?ZG zaH)HIXqfZl<2pY$-CYFaJ=ZbZ{Aef9Y(P*^Avb~i+{G95zFq*D)22ll^uBiWYGT;> zP5+YEExdT*^h$TyHU`ap#jPqoMN&Yy}IJfoac$x>? zg?R)4PC1aaC|Dk;Z1-FdgW4aaw#9Pu#XWc(>tfOVXoL%+pd}-IAzZ`wShJoY?id9j zZYS*&g72OY~&eYXB@6jDG z_#59~X&gn|i2*oYi+${776tZ?Mw4-T^VxWy1JWv0(fz|ss8R#m8YeLt|E51xW_^#E zD4)IZ`SYVIjLGVB$d@X=!gk(pvq<82Lg}#QtxX`a7K_`zvt(&J`f|~|Kb(cJ@Z=TZ zmM*lGnIJa--rJ4QFkUK3D>YL{A!`m{^;4x2*y}5BucKw|#!%BqJUBvq!|(X5%~CKp zs_qp%?)acQCRv$nSk;pAvXSzFC|IK2drNM8GSPXxz2DS$X~q4^O}+;Lb$?Swd&+7) z1P3>R#MW0lEPns-m>wW%36APTR%qu%z}3LWnMk>#SGnpco<&JQ7Sa4W9%AHw$2dWQ zyl@EDb^s;T3Y~05d30n_)0XGpQ0x(Eql+|njons^V2)~g4f2+DknvHBWQ{Ws*os;d z_S+fiEa+#W-t?+TFz-n0DNruk$@X(trp%S2-d)}h=pa0KqMZ$5vuKZvG7;F0%~ebB zTwaHXtz1X0Zol^`XMSwv2#qoEoZcUZU~~0k{`4|mj&k?+uFuo68}+eb9+iOS1KSnH zuE_0ad%K2B>OGgPiWB+cFH8b$gy%ew^6gkAFPT-pza!E$tBP7q{)54!Xqk+{ssvfc zcNO`anHrV#%@1na?(>YlkIXjKZq(KjKZ=674CTf11Yf&g&J#T3(C((fFQt4g@OBE9 zxd@olS^Lxz14HTgzX0x1$l^*Aq~)>=Zc5$DwfhZ}9O0c#8Ac$if2F>)8=UkOv}Lga zL&bEzaSN4NT?g#$A@V*!>VX@OZ3uv+ zZ!TJyChn9B7c0Fc-y5~2^v&X`N`YnxkQpOeXqd#6b*InY&~U@wZi$4xD8Q=s`t@s; z_iyR{70oC-n<(P-#jBIZ7It-oqm(lT`t5f_%EpOt^Svqi{U8K>C+$M@=*;VooR=hv z^{&BK8l3|qk3|WAS`MAqIb_&V)C<6$j%rgZAl#^|wk{JvEO%(D@<3$KDv|-=K2O@4 z7qW5p;Su(<#WWipDzZh2zpthBrjZ88e>Wus!iSr1`&AK(uh4)PgU-0?kwhqEH*{e; zmRfL7N?o;wcV4F$+csLWaoyFs&Q&DChXA3yD~Z*XV&3Vw*Grt$o!&~*Y?^J?&7R*t z9(aqnJy@gnL8dOSmu(~h>k~%WbX~N2L}cs$v*tN~=Jq%uW%-?*=f`Ms7V5X8QKFuD znJt0~#ov01iP|QpY4^0eO<{9!{-qO-*4|)wO-isv`j(90hPP~RD7`>?y_s{b!zQDb z*)KYdr+9B~m1Nh*)Vi-CES!%85U}sYJ=~sB6^>ROL-2YWpLja~rB)7^ZBOaiHrhE0 zC_lg@Wn-i+J*(}~7O1Kld;1b#6%Z2X*)kHobJUbz+Pw}|3YwvEKvrlck<-T{ja+Q>BUU9m} zo>gt5Eav=DO%FJUxXrY%QN7H#v@;Q>OB`lVkJ|4cL@Gtk>jw=cm*O3j7Onn_ul2H? zRClw3FHl%$ifaa67iK~7TAcFalXJ6xt?FGz)vzi{A=}OKnGJ$FnMv=n6d)5O zERLp_g_Z6jhaOQkWZZF{WY!XGCAsQ=2$(paM9u)Y0@&$I5MVY?xs0x@qP$ zsax+`9o~K{Y$l^?OnOy?jC?9?NG4 z=hFAb^!2p8F0>f>`$5hX;&9E|-HrKa_`D)U?DDG`oYj5J=^4orPZ92WSK?g~;HdQ; z_BNeLHj8!U3%Nc!bp3or)lTbY?w0A&{23G_F9Ucdf`dqzdrV?>vB1fih_pH5z8^Mj z?=$#w_D|GPw?J{2Yq#enLmWB|G0%6sVbaX&Czxq`h21VflyKQd!S} zs@yG>t0SL7L3}ayAOtE0JOUmRLcQZ@KysE{vTAHmCIZZIUBP!Ibw!Ul6AwW1eBG zwqCif;HIgTmYfy;w)4Hf`@yo(h-7B|1RT-?bLYr!iXz`I58j@{AY}ekcYia!sQGXS zk(J)2A$Mq3p=6}#frZ;!Qs(4=O%x+;O})#&L_|bHH#i~z8+Xix$c=IbfM@~OW%$d< zdQNYVWkTaz7l*#3Ngw>VZjxt(t1;8f3_=8YI=G>6z}{)tgB!s`osNRmYIF-;^}K}2 z`TH?APzmpdBb07kX`wMtuHh1|eR$M2kVO_E^7UEx+4Gy=68B}&HdeI- z?y#VzQ)0mH<8B|f1=4Mu`nX{}A`oN#OBc%2(3xN~Vjy+<_U&jX4+oGqjtBrvQv=41 zA7Ko(x~xkhoF;&S~eI^vaj9LGh)U!S1Apwsoz?@-AJ{9yTkZhkPeCS(i~by zSWfh(uVOo0x_T6|!kIBc3E$lxRgG&Aq7MBJP2_c%oei4tsYP zCas4adNlQUac@z3FJER#Nz?i+#!~W zdPqu(biaZS48GV9g%f*JtdF>0F*)Get_QA9RG(bRx2Ag+&)YLs=rs8xJvp(f%JPXu z`a$Tzt1kE1_1Sj!kZZ;$>z;R5*A?>bgBK*zoDcW6%u_%I^dHL`yiB#uMAlMJ8ukF&ts>(Rk1~7 z`f?sXJ=nYQS<$}BL+)#D*H@zF(1|e43n}u)4E^D4%v{d%4jmaVoX^7>G!JLPKbIN@ zxmF4CIVmTMG#ivJ_W7i{3^QWC1%(u$Jqd`*cKJe>+>~$(d*GKKlYO|ljQeu69j@#- z+zxjqB@EM!iq|@NSjvIrgf{2ZuyZbR1s8}DHibW zR1z+CJBzoQhX#CT;{i7gKWxS-%(zy|HxZ}+UpP^p5958}*kl;ci}muhBOO8DY9eo> z?S@{I=vTw<-P<6e;rHRen7Qo!y~=G;msqumWbLCqyfE&2Z@L*0ZP#E}OE%LH)wlXp zpN)lOWy@2GSrs-v7m%Pj_5R!?uBLA7B3j4CM+bZBT#sPBUMtw;u`0QSjWi~TM&TK0 zR``h#qBr6=({g?Gv3;(>Y#EcbfIP3#I?u_T$q>VB{N%}#>&)*hBe--WoY?*7oPg-N zK9>>%NVM;9VJu1t$AMDS1haP`%~xdG`iYudB#B7i^2*=g;ijV!kM7ehy1U~#ZEtVs z2$IaZ^(m5GeZi|UPD=N^%xs4RTL*^i(SoQDART=pH^R;dy$z*&!EsU>Dex7~mDtB) zsXYxb#f%FYVu`C`hMKwA1HEXopWIN@5avLI*|dhUC|0T32+T zIL44*%GIm7k(O0eWyXyd?4z?_UJ;Q=`Q5EBz$lLAvm|7sqz{mwLRI@~@(;7+rNyJ7 z7VVR+T?`vZzeREWns<6vnpDEX{Vu2+p;GM$KGa7h=@b^r-6;8qJ0^bAkF2g(6z&Ty z-?d4WGc=FhjJc6EYE%XDeKf~`h2i{sV(WHRsj$=OmsQiY3+qPnO7fmsj{TCG8)8-I z2uw_rHqij}9JrUXAX&mbJJZP0G6;?41vuoYCS@znDj$1`Z5(12QJ)bMna`d*O9ai0 zsFnKuS5K)Lhtb^<>-=pFv7IQ^fcoJOVCFt>I?t>70zkvyp~=l04}z|J9+gMxjTt83 zjC%L3PF1iD;}<^5o)_~WeLlz}Hx0gu#(FnOxXyh2`*$Kqrh!qIaAJ5APe0y5?el2g zX~;DaYWiA@Z_1qT75S=BEez<)-xerWYs?s10uVd*q*EQkwzO8hP--5a4=VBP1zjr^ z`vaD0DSs5FWq%}_V2HpgGnZQYzuX=w{)UvTyl=j42opuBk;QHgWE#4$*T3R5zwia=f1GsRjr4&&e>64U3{9I?o4RV5_wwenisL&(=u%zviU0%IU5t%@}+7bAG|I_ zh=_k(NGf%oMq*0*L3Idx@t+io?9(-<|KM@Q>h3pgBM3v|_KK8U%1!=Pntn;^F*6Uz zYt!3sXRMTMGursS*S?)bk&TOL*I;=#8ud{Oder(i4M#4hCIXnFlHG?3y|T z0pv+9S8H015TNj|LBB)O7{DI56$sL6ZMF_p!Z?-K`&?T~WACGGpT| z*U3!IwPtsjo47KQ%5kg%=uV&2!Rp#IN7NxKN^SI)7*#H4uAl|5&?}KNuU+~kCTZ^) zI)}b%2)AP;!V5<$K?!5Gz5X`vvz|qG|5D)a5vfc7_DVRD_@?p};Njf1tI_ObSMJxS zfCbtDU&S56S~iv+08>+JJnp~TLWgtruawPzlh>ems&Nr4BVNmfk;7`wVfU=ZZ=4j$ z$SB@FKCbyMYIjjN;jABzd0QM@3O+YQR-lzrRw4dAdYtq(W@T37)6m>%go_7OOsmq? zLby*@w=;Fltr#zE_thhudh7#vcokzq4=_Y$*o33>JP@hF@_n$awS@5Pq30;F5*46@ ziRO+PV*-$!7pq9ZV{EC1D0zgACdNzBV#n{DS!9i_#P<1nKQ5OTqu##7p%9FAB|4Q~ zrX@R>(8;*DI(!+jFHymJ0_4~ha0KCm>{BI}A%ubAQRt|zYkI)&W;l}O)H|BQ;@+cr&u4NLfk>@AnXg3D_3L#eE>QneFPZB@0KFc%n`*TclBzb000p1%`ti(|=4~ln|<@jp{(JgMi zM9(KC{IwXOK~TF!73?D!B6;#EM?d}PV}4%(wqOQTYqv_+;X3DMJD`0};Ex(o`n;?! zvv+2Ss0jIRgPw_hF^boyddLi3xZw#7H->QL){PRIey7g$NhI6b(f1GVBIo!Bv8)>I z*J&nZ#B;fD_7q|Xd?Xbv^@ARwpCB>_spMg#7QqoK432 zRq$mdZc{(ehEZ{8oZR=o;{bI$bqtgL!xHNTQ7&vt3X)zxv{$1VurJ-*KiGpICR zWEu|w5{S0JV(d&1ZHqT&X}gPnPEq2D*Z$ea6x%`3dfISwS4G8I7}#g(C3gD)%b!HS ztWkectCH~?A4!j^hgTJvzTA8U4F%>WG03U!{sLiW-D)(nh{J1GFnKd0BclRSMa&-S*}c&U2S^CRAE*QfzH!9}Xarc) zZp9ljGD__yRn*po`&8DLmYF+8Zt3J4CH~rf`FL2!0>%T}-L~K2^Ca0r@sjZn4Y>{0 z-<8d|g#EFlt*MR9*LElKn!aX|-{$t-qTn~Fa*L-h$WCjd;h`AsZ|_756uypgR(Kv2klqvtPM_()R4l$9d{(G=N5hE5#C!4 z?zk-k(sIQhVLJJx)IPGxcnM~e2OMKs5>fU0HQ)2AG9Uj0nx47&0Wh2+JCrGH$?MOA z`1OkIZHY&0K7_QZ@T4Nf0L;(t0?*|zKs~hE+Yb+y^!wZ318+H$d1%>Toxt{Z*GG2c z#3b~}3){eq%S*BY-!sh7bg9FIN_&qNWMp*&{I%SZcp;T`Jw|h#M`|Ki5$-RR3jlPK zl)dnvLH1W;qctDh$IR$==e?)ijJwYC#z7O6o(1hkT>Uf81pr1uUcEcf z;#_lx>izotvQa-DZLBPSjvrnugBhY4-~y(!3&{;;;cu3==nmJEU5W@0Uz0JSspr)fkz;2-bO!Y=_kSLT z@B#M1UtKG^uwZDJKS#E{>7OsG>oc@7b`P-Qwt#vJwfk#;y8yDNSaP^$#l{56*4fPQ(yY3$>8cI0 zV@TQ~iYTed8w&Owr)UKF61-k#%=V6L~>Y= zaJ58VIb6GV?xYsxnZP&Ksg^Qe?Ny!M{SdN+`;wB%$Km&& zc9M-jc9Sn(@0;&?-GMjV008<>7$W+^;QrOe2^0cTPlG;vqGISKz1}lxuyai_HqHHH z4_3UCwB3I9xDmxF?3N~g{r>i>KHTk_^gvdvE4XgO5I=Tj+;1aCdS_Yt+O_E2l5dtb zj>>Io+z8vAb)ZMO*(z54G-+a9J-@u>Hb=r42R&rb({RdwaZmezBBRp&x-L8eYU7;S z*z~y#%g^3EJS-#Qe8RaJQCz^$2a2C*DKjsHUN*@iA=9rd%yR)L#X0~+wF_wbMXT?) zy>MDUtQNx>r5$mqHr^?Oq}j1r8B0oK(V?YcqiW9v>|0dCA|v|JT$fl-S2&ZX>R%)K ztUz0tJhw%y3vg6AW$PZbaaZ*t`jgg{efM0iv7qt~TG!QPv-PQ6JTzVS7QuDssYTA) zq@spLBB*A!RijkqM^5tFOeFvw*!uAj{c~X@*ZDTinhxDg{6&*}(OYtirgfe#-3h}S zA%HJ@v%e<43F1Ct+dA-IkJAxX*GzkH{ge7wYT`9|50mX%5W+~Mp*jQTS94R-XLWx= z0EXw*WM9m~)&urQ%#vy9vwQ;7EBC2@L*yz>e9m2x}eS>h221g}`iT z0ZaG|sX9jz*@a7&L`^2=JRYIeYVI{fKI8|++#QVl826R!N|ohc5VnXt*xUHLT_Oj6 z0h>CIZfRx}7Kq_9)cFkHpzBQIjduFlq;XWMh2qI`G(XcPikU@VVhnMsrt1a;KogP0 zW8bOR4(Hd4N9VzVI71a$#m63G!`}*g>q6 zda#uCyHR&c*bBBhj&Omu9*N%n`X2e8H(rQ79-FEW`U6T+Ug9mvuV0X<1Ljt8#|sM$ zj9(HznGN(GdTuMvS6e^@+FflY<~6bXzLn=%0B(zQDd8PU%Nb4A3;(zQEu?(G#iauG z$l!C?4sp!+boG`^%X2c>BTR25POJ?7^T8F(z*m4CHSJroLB-yN#l`!tw2XL7abfH3 zd0I+6Hz6m}hW^)&`bl%=>w_Rf)a32;v6!3Lwl#M7b7lobT!p@*SDZ?0@sxDu)J2!5 z|3P33>=!uxmNr=6m@{o`6hHbR#bKV4V;}jtGp3BfE$ArbUBEwn2?bPM?=Ma3&ea^@ zXcMS|k*0EsdGyhBvG%4*2@pAnGklF4FkGhif_{30#i6Znq-M?Q`-u?pe~9OS&n{-?XTU7J;`G|L zzol#>mpCS{MceR1{t4!5DQ;BSX0_or#`piv zcmDr>5B$$F`k!ZXYV`U4I7a=?{`{Z)`9J&fgiPZ9&bxVqZsC#(lIiKhpC}HY*#sM4 z5JE)-(7n0C!QmLjG|zu>2k5_Yk{9m)X`d2xG93b2>rnz=Vy2l6vwdsRcSS^Av3gac z@RC3uhg$&J{p?25EQhats^}hNF zDAG4-2FW|Pm1E#;0grzC)O_aCx8BmHwVw8}`<`{bo0^igXqEu&)`QqcOz_2jWSYFd z#p5XmN?cdy=(tKygQk=WfoK5x@S00vRT}ho=(f2jEMw6-!+qg$4glob6%*4*_dIx+ z0B;ON@#Sei#qecTUFw>c=OHYoU&#Zw(CVFKm2Xcz0^>1ErbxlR6EQ?EC z+rzsJ1~dz{J=6o2R|sNNeK{&t^?4uV+>~wR0~~&q=xEf2F)yF@XNOf79librAruJ`ajp1;%ReMikf$mwDTn ziR#rK2ms2GuQi56dM~+6VMR4ad!oC3l|xWXnt-WEzDaQbU>&351{rx>sB`Sao9&YG z<(Q*g$P-Bjp=FB#TH}9k5aM0!Tvbasi?&!gp6|?mnVEO} zj}8>%;qc**Jl9eD(LUZWp`fJx;MKc#>yMU{WAF1vMMbS2ToOnE6KRokgEQxEwX$J9{d_CEWb&+LPZU?1sW^woaA8&_!^V6UO~;r6T1q$8;Z z#%wNW>3X!b?jUG_j~8|CWhPlIoY#&mo28<D;BnG9}bn8@wfbHoc8}XQU&4}F1NUDY^oP}Qv|YsZpaKYo)=mp zvOPC7a3_r3xqbU~L}R039iJmgxUG~>wH*{{~S zYX~Z^KS~kgpBM8UKW=tr(T)uPsJ`^Np19%|QwiPV*e?bPKeUv51jbk-{@|4 z5u|uF2s6eDW)zBK^FZWIa#qJElT=XAJ7gg>y#t7r!nK&N2~p8EXf)w8jM@(+Q``Aiuf*@@VbOqhM57 zrECdI5lhUW&wdB!3Ah@A!`+6V(q3PvS%pSldT6w4XAXal@lRgRL+R3Pd*whoprnwj zF@ms_1RQKO)Lmsh$>uuKF3?;+GY?#p$tX z6ao3yV-vXIzdH0YGLQ%NlN{ih#VN9`+Fm^F-%1}nqfL@rv29+yY9=$RXNH)z(=ShM zL8bo8^EvkquZ8?k-aikpWh(+6M%E; z$?m=>nn5#})vYt)2Tj~5bXo36*aOfy!mOoEz?ju{$ijYf*mdqpeMRg8{U?%4+VbPa zYL~CKgQk~(Mq~6<7Ev?mE|DY1|%<&UuZ8 zmszezx{}%jP|*$=zoGR8v|%7GR`dah-v{3wOg z*3S0lYx9>378^=-8vkv%(*obvY(aE7j{BXp*jnn*iEVx!7e9O$T#g9(+HKIc}MM%kJ&j_Y@BBcM#%&4KZ}pdcCv% z5p<`;K^{~EkOV~EX;M}pUQV0Iifm~yq{q}C^X$<>ken`+vZ)fzV<3k$FLKas1W*_W z3VkZU1?Bkxk$0@N_VtD0tA!?xC0Mb*6oPdue$Xw8vKeM*kr&A z4h`@c^E@5uN&Lq{3IH5wXdX$>S5WlkMg9$Uho4pQA@bcTs!$oQvkgjwjKXFj~#V0Ej861Ft6ejH*%|qKee!?g{i(N3r z#YJkk(-SW(O?KXMCFq>1fAurW^RMyS%Q5Z*K0EYJ(@!|7F4d`@s}?Q~%2J>)-!tVg zU+lFg>rD(EHaM%R(Ie_WK%xqZ3^%GIno0+25{{*%;?3Swh*elTz)d(7Mj9o*{;r8L za;@@hvW)<{&Z7ltgpsBZQjgqPDFL>RT zvjf->rwr%z^t|NXLS%sknwwd#qelkb6vfBf(`W-C-wY5PAMR8Vj?;^9M)4%#s=qbe z+Sl8Svw!?aNg)W?q31YHNPv&98Dh3Q!g;A-x+Ss&WcFH*>>UU&m445^Q)Aw$<=Qdm z3?aD=yUZJN>xv!SK=aesxv$oh$8mg@vSj%2gFY=C<&-)H_PryZy<&*`*6Y%sA z#1@O}ru_BO#Ob4SHAoIc7sIApKFg zXzuXhi!|BwBOU=!7Q~M#SKQ@E^*YzF9xRQY-UdyxjKd+dDyAdyd7B>}&nUhD1=YDukq`aQn~ zy2K7nzL)dg-I$yV)L0(0)0)@nq8hS&Q`M{n(`E!Qp}(w*6K?Lg9XxVQSEzaRd1{>) zmVcZZ&cizFX{v4MmI3nOi@sbyq_p$OIkFVDd{84iy9&3LW)Taj?vf$K0&@g4+Y)$~ zO2X5{cZbZIXzMP8Bk+u@a1uH#^b(Y(t& zZ2>9QAE$cFWmn51codY@UQ)E48MMdE3q`MUZqzK7UpFE@1|b1L`dyK`uYm2$CE;S8 z@bwA-rTxhNsIG<*X1Uk=dnT$*P!I#w-roY~=AV|wQKr8*?%egS_dPCQH6Tkh2!++8 za;v)B zcHiO3(n5@@=#Ny*o`A~w=(1E<$O!cvfRWY&9L`5l9`*OQ1)iFo4j?E2W;@~+t}K!V z_H#M;Yz$`N&q&dy^&-s9W48R#BFj%*XLjJg#?2R~B?&sernvG#A#epyC#?d?xY19O zPk%#brp=itjZY@A97B4$_vLe8k(we;*^8-|Wf*w|3Us1KVc?HhSy{(&+V!C-o?m!v%;aq`k;RBTF9`|H$#i>>36{?G5xu%!DL|v9^WV4i81POMzb{Kk zd3p+Uyr!OXfF zmlwKV{RH=%qrj(uYAGG%^s*C*x|B}hB> z{^^tfcQU)Yu>NEo9w8D`lfTG%i|4fG@pX_wgbAbiTR3`6Na@4XQ6z7RdTLyI0)KnY zP~SC{n>Lm!xs}BFmxOyW3P|Twskec`%>oid0S>{`SEGe}6vz=5%6rI9do`%4Yl_H>PoZ%GD=)uv)qZ~2y0WGuHWdI?)f9iz zZ$x$4-ukaN_tzANCM3($e+Nhkz%J0?=l7Z`C;j~YUY7|J5T8ltNB^F2N|gw_egQ9C zZ=Vt}{#Q8u=?^UDQHnF=Kd*k}A@G-ES#wWLcuN0$n*jkNV6PpDPgDQ%>g;cTzdWme z{`l{ZPXe~xzGE}PKd&zT^Y|PIOTKh^bNzU$9Ua@Wj)wu7kkgN*Gl2nsuOZDXQTl&7 zbsf+H=N*c{>i>Ex|L;XQJ_p#pGd;BBKfQE3el2zdfcM{DxDz;g?p}KYUaA13!D64i zvzSg>V0Qb9A9B#xDVSE)&$a1$=JPO_G9QB9=gw69i}Y;*fG>YscXzjWZQ4~rM9d+P zR@u$XauG9MV_vInu(S)PVqA`mSH`puZi{#C-1#N#vDSN2Xf1?$Zu>9|tF&c%6BuW9 z+KBZt=ij0|{5HF_sa zN9y39kZlGkioXu_0UGfZf0-a1fSr%&%z_z?O@(SnQe^1VCuIce5rp>-dU-PR?!i(D z)O@y}(xe0d#$Wb2EcVDIni*$nej_)*=H>*M$?j{pFOS;edNVNIz#vekj(9&nb#?bG zzb-tsL$2=ka-mUDv{J8?!O9Fk3tV3c_?Ag{evv-*9xGC=824c3w7I;jzz+15|MuV^ zxvARjOC6ZWe08Ea%CPi_erw9T$W%$NG9UuJ*XIxAId*XZx<)f;JC|nYkNs5Jk)`(uP~6OG`Y@GafuM zRZH-{1B^r!EWe?9Sgvl1d&OzJI<3I`;yH(2p}Si*J?&Z&4 z+LlKxGU4EYg&>7Dd#J3^YgbvhB+9H3QYFfXqq;_;Uam$!xur75+Y>G4Z*qZ#X3G&-`)m&2NB~l2nL#2e<$8bxb1!dl#pZ0sI+ebIB!6FlFcl808N#3RRGGS zcd02V$BnnkJ`jxas(9Jg$Y$1<(VBif#pvoq;ZmzE+0Vj4JsY#(QAPS$)8UOmy&i=N z^VSwC!NI||cAU{IwpoPzjwKm<^_Ev#JYV5j&3px9bu+cP`q6Y<`!zZ`+atD{#eH4Y z*zGiz;e{-_#cOlU_+dBFXa&->#}&N1FR{0@;wy_iA$-a!U+74cP~4~W?5p#wttCXy zr{kT+NMc1K9Vxd3?D|HmjU}ovxc;{IxY4~FhbVlm(DBn+KC8mhI1mv3x{RrT%Q5Fw z>s0UI8o%Y62WHJ-tSRY|U<1EY5i}BXt1mlv}8lE@CQrJSkS}=pkV$oJhRPOjjajtTFIF1|f5w z^9y~Y`*mMH=!x{7-|HGK660et6r%q z?pR>bx_e+SOvywd3h2llx@0nVg5~u6KRB7@!RI0`k4ADwc{#dXsEM?zpmn815Bwh03$HST$2b!9V zh+I~*$*R;4^{=^hdJbCf;{AOI>o-FW&Jtw>Vsbmaz9vD%4g-lJDgzI07B%t{?y09n z`;{0&;>&NznRmN#pY&vHuTqI$t1DV>jEo8Q?~~y_B<`&3Iu`0kITDi32s=%%CrN-{ zSxF_IRU)nrRewA8#9^U!eok98!#e6o1juouPEAB}w%GcOZr&1~HO1|*P)nK!){Uf= z02q7>Zl6~tW1DLIvwwX3P(wQ$^@jfUr3f3jmarmhWV4171uzA$-f1#3Z2zxzB$=^& z;ZD&!X`3kBlCL1mKRKn6LfR>F>TzK>>b!OQab{AcBMlRu&yI0>s=DVHrGcrDaBI5n zu021qU;FKQA$au>zoxAoj!{+n?=;>h%x|yVuLl)1E^}uT(vS?+A{i>&>f;9jDNV+i z*VB)0uqQwFeElBWdhUnZtjDzezSC&J8aZMlb4}gK+Z*0!D9~oG@Zt?Lry8X16QT6sU+D|8d z=v20Wlr#>2@@~~V>}61?0J6Vp8ikZ(9JX6Pp_ghp$;QsJ)oIvbU^cFl16051tG9)N zc3ZwbW*??-Q=aKa68>yCv}9@-6oL}4C)nNwoD6|B$N(mjtOn3!TB-8*{*itzOpYI{ zSNcNFV@~mawyoE~KSg_fN#q9s^3cS4Yni_j1zU4ZlcPK04ox_)5bL3Ck*q9Kk>Gf` zF_SM0AVS{Ll|9niM?+mX8YOu~xn_gT;lvqGOSO4Hn*1j<|A-o*XHq#oO6@L%vDgPvVZ>w^lA6UW5+5>G0aQDl@cIIaUj4C=(f9ah) z8fSRi?ISrl`$$(@q!yFBUhQ4^r8oPn%!bz(!ak%!tPJi!z=05pRyz}iEJmG`*dD<{ zTk~#%oY$e)4qjb|&XK6!(8DcE(p=)EzKH`xDhMNzo>0b#o}cWURarku>_Tg2WeK+j z?HD6-i6W!>Nd+Nv=xso@WRd^IJUUMpjwvQ#qE?EM;4$S#TppFSmT)ksaX;##pQ7mX zsuz>*Ei?4_{jGsP%rud87i{b=s5hquT|CHUtkk^B4Ux#|6p0JnX*@w=hd*#-e zw?;p2hKS&pmol4FW`^fYqOUfdALb9A_tQYkOobv%qEMvzZO2@ocWf-_UPt%PT`mMd zAq^z1TiH*H)sT#J-;+kufFbo%=UCiN0|PYX_a4$isnwCqo2!=&6V}i5CXUetXcL2fGM z(kCqB4cpUXJ7*a(6Tz;p#LK!jl9QVDjrG=c1~OojXCzJul+oCrFC!XpbShQ_~UgSDoPL z5E{B#jfNuqwf!J6zI_e~MyFKimm^9AlwVL2RY_BQ_tbb48?$fX`D~EsI#2-V8=k2**vSF<_@68z5E{VBpU9CxM;=!+20hJ7)bAYEo(1T z@{P%IsFps>z;}0|esw^WAYfQJ(xU_AJC5V>C|3^=$2;12T|$NNhn2lz--$m;JDvA8 zuMXz(6TqO?;z0<5{PCMR88Fy6ySNm5{|_;*lMF_*asnvdf+-sT&XI6S$>Wh0sHcHK zB%_V_x`Iz#URE>eP;PiyV%X+4SyAu&Ed6YRltY!fm*P(WvcdkX(9mWjzKqAYw;i_y zg}Ftw2awi-nd**P?1Hn$CE_L)IZwqN0@i`OiXL^kiE>Bvzl^|2y`W+jGh zFe*L|GQX@L18eAh!~6V;2|5GJW(b%|GQVyi$*EQ9EIaMfX2Zscx`OkxMm@KS${_Rn zpuW_L*pZ&aBvB5%ahYNysB&W#`60^7A?^qr?42 z&GiF%@78)+(qn_p(@HEA(G>e^ma+mHtoba?6A4(~UHY{1?1E>6``rQ_^(XAkeo0@k*n%tfeh)PP4b8AOM-d)gAkDIyRpHHrAtUtj9TRLNPtEG zKIYgV#J*QerM}MZ6UW{xG?l4uOa#uCx1G~%X;M~oyf16(qYF*SKVcZPXB@p)UI!qW&^n30)c(Q73-BWYOrNmp$v)<-NJ&MsL-i3BzzUrUg)MSKo7C zO{wv|=6UuaS*+yq-5FEA7)}-4N6k51BgvIa9SM}NVDA~qE&L6z z$5y}UsBmzMfS5Zy2Am`My|Bsa;#^#(wg3~z;3QNsu;Om__m^jTva=b zRGgG;Kb0$K*vhAM?YeGE@Iw!*E*MI1b*oLC>%BVGYl~C*f+60>`XUpws&^65`LVf*dJ+ zNmtdm?S07>KC-&&to-f$xekRSA>*_qeUHm5vQvA%&-5SdW0@0U1v>+G@zERvq&nD@%CDFr< zpE0#eY|uG;86?-_Z3$*v*_ao&g_ru^BW)biH(0*1STB=4^Gz#HMBruJ_o&yXvAXm4 zWPe7`vTaZON-pb8H_PjjDwu++-RvuWt_IEQ(VGa8WORe7lhX>Dl5f8xg}d+mc0a2@(~TijvgO71ozuPS6_h>XNE28DXkZB(F)1@z8S{$Q zw7JyLo|oiPS(#*s13X$>MpYt~hhfB;Zf@btfl;cgeZ-UDqvsOWfIu;t3qtFd}j z-Q`=crQf=OL}#l9@#V$%Wte_#kDZv+(H&v!vC*~vgS~f;XZrvDhu={;NO~tJhoqvS zNY2M8mBLU$4x^HoF*$6*Fs1bFM3M8ka%OUvVOTm)ISezyjO4u8R!+lgu2=8R=W~5O z*LC~x{`Y=H^!u{?%q}(dB>Lc&ZoQM>wb5dj8Udq}nlbQW z@#1Sol6`;UoYNxKZgLuuCCPH2Y9iHEWKpc{t~NNueW2IYz-VF>vomN|xq~!QA-UMJ zLVUK&#Qa)V)5nPWJl+V{_59!lUjj&(7>|#eUxV zL`Fk4Ms6;1cPAJj@7XDyY)Q{v`>T8659aXIRu|K29C-Ju={Oxfc-OP*+yDUoy?p1# zZ8Jn~iDO$~Qt1UyvreI1v>szbZ;$KNxwJ_?z1It5Z6DOp<%g#IbF@tDaCmp+& z%c6P z3|i$P8ggqfb4oZ zn=wCKX2mNe%P{#w&|+Xnb<4+??{5%jz++X<*YD*kC$s`l59+k|GyvC|C`}A)4qO2( zvV{zbRQRJy7CXh7=yW=+b6+U|P4LCToq5!1XB6sk3W>}`_QIUSk^cc{c(2uaITdl^mGmH1chlx~ z?c>=8IQFI`DV3PT#V%}SAeliaK5|Uf;DadNHG*X{?NzjgRt-OqV2LM%`Z_^p&grtu zsdl@Wzj%vmC5t3g2|1LVN&s#T-eM97EEqzoX1y4;OeTCPL7nPBPzvoJnlE}6f91P< zHP@imToFd^6ypbY>t{}XxIm=A!lue6b7Qyvbdu(Z$>6_`L@|;q{hGJcfh7I@M$r{` zVNNthdQcnIeJKt#^Qty4&W<34^zFM6MSr_fwK#IEJyzk@vkP=ZV++Rca)ZrDI7+HOjfhr$(;96tDF7CUT^=3!ymD$AidndegQAL~D z`f#81rgQWk%Y#q&c1*PzXL!vy*H9MZH_pEyOHav*oMi(h1RHVEZQoktFK#Mc(3Nt# z8(sQ|GV1lN*e(&<-AybPDRl}-p&>tgZ;VTRbyRu=dINW3gtK@o7{k)%t_E6(xt{dQ z3W@WfS3?rj+&rQvKms)NwExXK79b)un$YgkxQao`y2 zna%3}@J*3LS4;QHcM_8gYm3!c%=iJtlOSB>LBrhVSSej(_?(O*YtEw ztBivM-R+H<*B+hj-k_d#C`{#4R!BoDfh&Y4!Tv3{_&FNn7+(MG) zjv#uqw3T;fVNR*cFd4{dr{<;p`XNesMYc8?BKBFCT}arzv~%eD+flP8_L|W}&rUgD zOG+mw=uTBkRGMq+cv3nns`@*#JETFafvsTnK){qMeZAVEIC)8wycQ9WYA-V!(Q5Zv z;pSb~K-EiJnKK~~Z!SFh5!%)DC?ey08n3l*8GIifs~kTk5VTU@kx|YI47>4Wm|CSB zt%(`rT3qX=jk*3^`~n@BpRPMF0Mq%<1kOS`*e;-{Eb5~wv7w=Mron5DxjiRd#8oc%IztlD!@XSG)^}2$Y2` zYuFWQ!FqR#DOuQ(RbS!ZbS3@jyJ2C9UGKE#^WuZS2$x^7WVqb zX(ybwxsMOqz^aqiiGmFKuJyGF=H3!3PfTQh*Nl%Hy{0XR`xO$(S#4>Bue`Bdo3v|z zjRzKF8xr`AkJfR64(-;v_dE^R7ey^gBaCc5f>O+7esL$tWU<6z52|a@7MfH7vkq_O zd^Hrhxvx_l>72Id^TIJASVbGwQ*Z|}i+*OqgZ@#RlPnm^hej48yjh9QN<26;4odHx zgW*5q;-EhZ>9;5I3o``%XKT`o$s%Hm3Ff;MGjToKJW6}0zVao1bSGhzb<(O|*OpbB7l|Zn@DCW`OdNecbnV zCHuYFyRc>D5Oywp_36xYVmL2I^m_Bob)1~v73K$Kkv2MpF|xlIbB-qn4HzL>cKME_ zYgq4N3DVbdG=G=4N2Ct*h!Ibi{T_K@US&egdp_3TTqY?eRTD7&C8po`wL-1l`c>+H z6DGi9-Q(JSk0`w))%j#lTC1pOBh18>qr2@)CPy^?%imqE(!RX=P*3|-X~KG+|IZQ+ zDIzBS;R4vAXj0&8)1AKcA0ZxJ9s#a^acAH9EJOcU;`njk-Q16xF#MleuJfOX@#bxa zxqHp3>wNw{vTkyA`)Cm4HxQM7ZRZPd z;E}?z%SHe3N*fzMwznv@hio9c|AJrK3){AvF(F*~mJ@J#R770%uB{?JrWUlm`0O^x z9@`%5Xq|FKkuzc5FZU-Sv0`gx8tr+E73S0;$GWwB!e{-0^zXg2*}TQ2S3(Y4;JjJh zI#czrjgGZTuKQ?3dDr4aF3Z41AD&EDf11y4na_@F4gGPeyE1D}@YCFh#BB(R_BS2; z=Kv8=-*fJj!ZfsI^@a;PNd^}9mIx+AJn0+v*9-YAw8Hk#{wkMdDKu$_AD7r%Q>Z==*3afanlEp3h3bb8r892~wVQuFXs4VcRoVrnVN8&3XHH3S+rS&*L>158 zFf%V|57uNB#@RF;9lTmd+6+Mdej&0-x8KVonEOE~uhuRCt!x z7C#r4pv|OjIUD1Zs>&@%34MK2 z&)kHz9);3WA3sq&;xT$lvEw8)GKu)}ul=B{8%_p4x8rTD+>3DDu1iJR1G#zZcwy-D zO?XPdJU}^5Q+qUZ}Z}bL#o0-kqY|wJ=n>MmU|57hDRe&CR+B^5%`=7POAAlzMW7nO3zVP*L z)n1jk)nQ|u@UI`bn;~-d^gmy?_Y`pV*9(R<(i@(v-H_s5j_7jY5e^? z;gCAUl_SySEsLcrV@^FcrDXWs<(Px|CUpo_a{lOpz)>Lo?37q`JtN-~In#OZqL}6VULv5u~@^qgiq(qCa16aJTtj0vBZ9KxdI5%y7TM;^#px4ZxR|_&l()@ z(fM?5eUaMs26&wP>K5HO_E@L*N!n%e0XC~LsDDR4FcGW75uamYO8=caWoR+$ncv#a zCp-xDt3*t!;Br&V>2d~F-+Cu(_JcrE`(9SqM#zFFL$g2Mh+KZSWBe(fMasb2*q1@n zp36{@;1K=2Jl=@{nd`7diIt2Zn;e%+t7R5f!hLW& zQ}VT|x6Um;nJ@t0wn<0mOPLp(l1Kl~T@NPEKY=rR%341b*q-fg&JzwU;%n!mz7dev-XLDWQH_3hn zs2)*^##b3AShx1_T$u+loj!o`zEqsp{`Ssu?|x-3oifZRN7cGABzmymrV+HO{&F?% z0XjEEw1l3ZbS)-nk>wQfXl<^H=)2`ESxF2S+2&Lc(rO=w!L;VJKfX$8!~4>@*`uu8 zw+@52Nfm)fC7KCHC*LIGA+Wc7nNo)3-BL*51THs^T}hu}lvf|)ya1*-UZQEA@>R?= zNQ7&Uu6g+_AWBOmX$hk$mwhas&Chi8`!d3nj^%%OJ-n~=j{Bc-5~mQ}lq$+QkJjc8 zTFv%S5h~k}o3f)rb;9^{d-CU}Yc9%9pL^iE?O4fe`el=4_F88Ls^B9?v8BPd^4t<^GV9&W+~UK7&44DeP>L&q`Ye(v54#vTO#0K40;1D0MwHAckvvdMZ^%o8un7 zb|)mYmr0qd`4;5vg7tAMw9U^8(w6+_v?a?f5F6UyMaDnu2#lHClOA1AAv z^p;Tljp00xrq{zPLP|9V%%GOJXWEiq5Y1-i!f-7@IJa4D0NQtjj^s3;tyiVOYlyHX zAGmE8kmdjR2>l`S83L%)8c@^W2>w=a*;n}Hu*1@uMetomVqU%c7`x5&Boqpr{h-3> z+pQby0g*Tl31$~A??}2In~=7A+4j!2p6Ni#_g8fe^@MZYsLdod9h22L*SN$$181Bl zv@3sPu-`NNPy-q%b{(s++&~0|o_*UYk4c#hmJgc+)qV<+pck5^Su!h}vd=EesS!`1 z7iZe5zFslin##sK>K~V0WHhYMsKcvXo(l(~OzGvrF-d+c;GceMU$me<{}M_gvxo?N zH@}F^8n__+sZp?K=DOt2`e4mWT<#Frvps1Uq!zbd;xOpf&$Wj;jfonQ>3Td*0@mTL z?0!s#d_=0xxk*sN1z@OA99M(=>-?Od)>{<#<5){(=w;25JK+F<=nI%29@D72KRRI*~kY5SvuG?6Pt!&$mSEZ)Bll$A#ZP#qh zrisj`H7vsO%1ajd3E3`DMz}8djNWj~ojt0bO>yHYy?rJQWwjZF2mQ!(wNkqn{+z|#iUn0#UYqQDNpX=dePzsNly5$B+j#s>H$>A z)s!UQy!#P`uK)roX8bB6OT+ITzTS_+9;&hzBCf8WU9+7@*KRPmw1zBqBL8xuHs<7? zMdRbky;_v-40dCDs3CU<#SEB=J@sLMkawEsnNxCoy`;xp)Fx%bQ=Y`hAJnq5>Cu?{ zOw9q&c+F42OTVOi_b=kMBXQP#}c?T;;hLYScYLl6W3KX_PX`+qy*%`r=qoV0IU=Jq()fzm67u4m$RM%=J?>yGI zx%zoB3r=VkkUo+I_#NsAIRlVlB9z*K-C+~;(Lz<1ESg*GH>?nAyinmotA=ETjDTw= zJD6ZCZ^<<_(&=NrXosF%Xb@-bJ8Vd0b9HJU6-!rokgg&}!|%FY2HDI+=lR|szR%XX z@$uP#@cel*l?0%^(Ib)(8r#IGl^Tv?(c)P@ipy#`(bfz4`Ic!%vR1h;nX8!9eriB- zVapayCe)QcMcng>g=dTj+4{3nMLxwEFISXk3_lOaQ+A}n$fzMZPuNc^by`_FzFIMj z^O0Hcd37XG+JYGtdFq)T_HvoTKR`)}w(55jRQbPa9sO&)ixjwaUG%7Hy_5MR* ztF=Vlz_Mxv?d!5QBaHqaS)zlx|V#T2E7c`Ab)h_yFV(jQ>Kv_^7)3#Gq6R}O-YHJ!$@+% zRrNQ_JK=6apO1>70>u z;(EO*if0cM9Ua`vwF%my`Cxu)U1+ZUz5*n_$oI_wTFo~>c{jlbs!SaKb z$gU3;Fk^-1x-sc@t$?)Yu5CdJeF9~`XVck|u1e(QpRK7@%@{!EWOl%8P@}k{ucvfe zRHdsY@}S%DN}~^u`{WI$b@Qb%P<24rVL6~|yX#!{owiIr9cqz-QFQT{o`>7F{|XrQ zm>gJ;{!8^VN%b0eQciY?feeN4SKboUh=Ro=ufB0V_Mnp(mUBrr)qWD|)X;m7k$lB0 z zI3z(&PYK?gZ3%)@hv8H^dQ=HZC)GMB3Hr#{FC)|RAZY&=3?({wsW90d-OL*?m7H(6DW(A@UxtBpY=uY96e#mpY+LLO87zn5>;X&n0u- zi3TAu2AJ}CHJt7ly+?xmrc^>=(j;^7D_bL-2&*uN#XkMSJ((X^vEE?B<5(aX`n>Q} zGM?GX_J(wh5XYMHoWN;Bh9BUpyE@?cyv2DxHWyI>mNSF$D2`IQJ)Bd0xcxF6hZa zJhha}(vzcZ`D_|Hl>~iujqX4yq_259SBE9=cM8l%X?B5_&DlBcL{_jY9rqq@M4>kR zxid;POU3@+j!OtbvJLCH#G*I(+f_NVPQHERMTB2`tTF%F&?Ary1s)TnlATm~2`_y^ zuFGo>1sIl@_jpQAox{OD`Qs)IZ!Q<+OB?v9#i66QUSRk@yZ<>&qyw#&#$ zTPtU$(d3Bq7B^G`F&}V4FSk7NFQv;%*SHf*?6YnLe9C$pj(o$s?Z$VEOWTc{KA>lTc!+A`4rSb@+&lmV&|ZU{sC&0y$Lw7; z2Pi3hQ@Jw;7SjSPbFRxYGxlf74dALNrGh84@38Hepp`FYwPkzV!O5C*K~ISzWFV#d z4vyxwR#VZ$i%!Mo3tVLw@K^s_&vaSxIMYX@nPM#X}tvdMkoeh8QgI5qf(c; z1p#GI7DQn`TQIJAsL{hWI1=0&sZ#vT1%P2V!>a*r{M|}#X<(L#057J_Zc~=ibYZ*Q^%aNamKL68!*sy-kNWAT z0~{}JhH)7ITAD{Hnhw04c!iZg(SB5Es7BQIaC2{1>7zL#xgH{(e?&OEam6tG4Kvh{ z(5VV5>W4U|jub$uhl6N*xc~dfoXIr3DpKp5n68($#_u=N4xK3i-b{f0G3Gi6wtGL6 zO>*J>;Q^n=>RQi_V?(d`dCpCo=U_Fzd||Zsz8$@?52;eXW8PN&1K~mqJ#aHkBt?H0 z^SXx8uZFdd?&t_X5oyMyismXu?X~M*RC|}*938bL9_FU~vJbQkVRYoU6YA_0-AinA zIBO;LT1MZ8%a42}>Qc$@`a#f|ladp-(6_lHWU;bwd%Wp$GR$FOG^^dYd-#Ifq-JrR zT@n^H*#5Y-SelCcvS3Eg>CL-WBSP0d_{(>V`=V`a+<_Bxxsl-(KBN~ezbc6zIvb$w zZ_~Z@^9Fi$mml-NGlrYrJ-^piKbtmH`uX=M&CO;!dC)bodayfks6hhj%wCuf|FbF$ z<}1wGvS{-C92$~Do}*WK#=;XPCo=uusGXCX)bx%6g&aq#Ne`oSvS&83TMBwk#aNd< za1G?IJSr0AEKwqMQcX~Jl{_OO=T2^Qc^A5Zz}C;CM=k=PlQ3A0orH47uK3vzK1JC9p#Ie`=1HJ5c!j6q|+ zr0W*s?8;9lmHq^6#h%j(b}Q|r$S-tG*8HS`ZUcP_&P1Id!Iv0JFBfN6YWvA@yTac;Um;-Ntf|qp{I4Z?Ae#Dn z`cj?rVzp0~W@L_Q!$8HY&)(DC&7(%}`L0dO`<|2BxF)w2R>A8psOHk#faGWAQ!N2eihQmqY9 zz;r>#b^<|uf0jgyoDwH|sdoFDi1HR%T=LP{>0ZaEldL#Y#xxvRd*ErcXKV-i=ccSy zaByyE2>Ifs)m;0en&JN+zpqAgc zqkbiDH=et1?AEzqKmKn&(np(q680IV9Uddi@V0TKK1(4)@Gth`&?s!?1y!rGaV55% zcLDL%xb!r=5|-!7P37deT3>;_Jgq;-DMSimbFeW|Sk9`Y1lyZQ%{R*f#Q^}haxnzX zTwiAxcONMZh@=hGb@y<0H_SGp19)_CPsTpSkIkxbw0?sQFur-f_ZLB_reSWVWo&W_ zamyvBNpEpW&LQil1)Fw+BGZlf+R@#>AcS$!`5wb9pB##{D<-#C!hw9tPlgLgT+=<# zo6KnDVA5~r8z6jCq^%}#wdDbP$WopAQt`FnkTnf_AFroqOkIAJ+5zjEkr$=Xj(go| z`Y=5H*wZckkvyhLW^14C>wB3@Cxa7jid`X-E<_ofuFZrL!Z5&N(B9bcpox8v z$FDsW+>ET=bQYqPI8eeN-|Q4$F7h_eyh9otrAux+;0tn%cn{ACoZq>Zvr}Z89B$ zK3J}h8SNxMj)dfgjAUX$u4HwP_)y7wB-GH8E#%B9qR%&{-0gL{TzqyCh*rjfc}`j= zAc1@PS)s9=ZK+Vt4v4R+W%sm1)ctQ>WQsqp`jkhPALd&Y=2Sd^jUHS9ElkntYJq^C z>K0yZG_=V2I{S^u=^qzhG>>g%R#ZG;!SsMa|npY%I=>f=OI z@M@Sw3vatzlhIE?#PLVrILWwy46I;knQwI@T23K66xB)zK_fXn#ZLkJ#~q<=$Hiky zdiENlQ;ek|>~y6AwIwUUE{Ir?NquQ5a>a6&WeD9^ zTf5nC*kTMM4su`fGF|h!fSKpbtYuK&oi!qZQEF=^W{pZIeJhY2bGl!nj31^-bWugs zh>F}KhaJ{p3yH3vCpub>t*7|9Hv_g9YOQ&nD%PF@!;$No_wUSzX%Z&E@ zY^=O2eDH32Zg+V&Gc3zV*qr+M&5=3DzdD+agSe<6$74@L{=%A5o< z?6U#EccGzit{3(;f^X`cO!$Re5c;r8xESluIjmuHOl+Ov)$zwd9+pWNTP=P(AD_&O zaIR3jfnPku+|s6D`%Y-Z8-CgHjHHi&4=&q&4EmSdRi_BHHQ@tTQ!>o}?9ez4UdkUu zP3ZJoGm|6QwY;LRqZh8LYIby7H*Ex`;mtok8CNuZIyn+kOx?$xT%^X0&jKz}pT$nI z-28*bL(HDcXwe-VN>dN1H+Bx|z0G55(AAE8gOf9YfDyZGMt1GCUnXKkjTc-VJIBxH zX=!qB*J8RT-+@-zHa$QZ1I{z@SuUv=kqrxKohAiZ&%7% z>tUHGh6fD)QFDXun`CPOFp$LP{5GS*Hf>vs1)S>|0){t7HRvRLUwc~coaKhaPDMu` zA%7GEVT;|{b2!_5AW_A^URtX}4alLtWJ3%RUl@#T$o_gSeakjPp!O|M;7M-Z1H5Wa z1-DK4>otJ=T_N0IeW>WCReQ=hLC}ATY``7>-f{V_4JnrXRWDW80n~sG8|QC`EcpBO z|GVb@?&mt@>fbf=|COcxJxA+f8Ge_-|5u0ne?f=*^%W}Id*p@uy;IKBU)CC>Rkm+W z@R%=nc@^tYyDA$UzWX>r2pC+D;Md5v0?;srg+=C*&HyEHePQ_i|F%N^FIf-*ES|7Y zvW5_hicO%wi7IaU{2G5fId5jxs+i=e0F0%rY`I>3D|ayXBVt+K^~%6>yUy^-?GndA zlIDSFt^=I|&M(w|wN;XS)6275GW2odFCWQo8~W7YwoHN@RrJWuU=P;1H$GParyedN z{z^2m0%l>1eLZ#%N3LD=1lpu#`$nz%!M`WLt2HdSz>z9dzN=IjDJc~-!?kC?+zQEo zg$KM(mub~s|1^CR@`(R4O8rddX2M2p#Bn;1jnCyRKdR?t7@)pdj~;vAl0^Oh^bmg& z@Ok50&^~k;z{>t5O|?VfSHh^U%LHl7F?#0#*}E2@Yh^@1qR(Z^`NTD5qD*e+0%NG& zs>G$%ym57yI#f~ZOA984WLziSj6y*qRqWer3({UywbL9(yzZwVM(8HEd{{$aVc}=x z9(o<3xPGn4?BIZ-XQnF9do(veEp_IAnV*13;8q1Phdyk8h0C>#R7Y4$2F6Z7T0VXH zLgWyfy^{}BI+F7OSU86Z^I=;MKR5AtThhIIXY@AB>CaK!EQEma$3AaD?Ob}L$V%>dGgiku^9UzB)i!Q+3g&XlWeevA6`}hKHin0RUUk2b&aR8tzw>{Ie zV9HMS3Vi!#$MY=uK{G)Op@>{G9$SIt!c#o!&IrbnwgBxAzSDz+Z>qd0-SBt{C{4%j zzAwncu_6Tf#zIvO>cg+Vz8^^l7&S)$dcP% z*{;!J;+l0KYp7x7`d3F5-jn2-qVJnp;)=T%hdN4|1O{Vl<el#c=2+9i=(t=iJDVJ zDfJa(&J9zVs>NFFX#@3^AzO{$gRvE1pPxjUhJ)B!=ZyI$a4^a%*M`t1a4w$<`eHnX z^=9_JAxz0jY{s7_H*kBP8s`ZxqyA8^&3t0ZAeXb%$0i?zqJYYN zerT`;@m(?_CiKwcV;RBsk1D|vMAhmvB|d;u3FqNNR^kf<)|*%(1#6>>h-csBG4W5?n|}qvAr4guuv0eS1l0J+}k+GHn`BD(_Sbht^1x3LAU?-<(}{gjjpLFSS0wT z>?#kScso|!Db@6{8OAz$-uIH*O2r+Cm1QWgCh@}&YE)NDyx22g`{V-+&0FP{P?x0e zr6OZekRZoAcy_GOomYmuw)j1;`wbNnWzh*{R{fRM#nsfwLJh*4(&f>6)zAZ+55p2=YV=HTH@R*-3Fb;EKZ zZLGLV1EnW-_mBn|2TO{);Pi54;IPE5y1bDTkyI@7!duwy5$o}bWRN{){(#1KTr2kH z{jZT??QJ~yu-igk(#{Ky*?>9YZIvCZd;6xVLoukq5L5xZ-XqB+AmmHhRsC z_>8pVJ4Lx#B|US|Ko{lDkV&_6C?9~9jmamuNuKGXj86T6*H63EhAP$Z6Hhshl~j`E zI^GE6!%jDgb|cbkz{R1DVhy!vsL^WLnzb>1W-gMxu%h*%L%EakT&?Ek)et62eG^ZP z-KIe@&hp4EZs|p>Wun(I#-Tk6tD>sAmY*H7N!JJTh}8F`a2po1n|ipD%BP| zk)v~q9I6AHPX%|Y7o-iE$%h|)KlM~ia7^52H5qSNtP5J3IkNnND32cHGQQC`H5N)K zk>7Cspw0GIjaR-zok4sHJ}}oIvuQHy$K(7#RmTW#ov%mCcFy%$XM}pW&<`lRK={rV z{P`N9MbHij2<77SL9J3he-9gx)`8#FA$$L@wKiyF9j04GmL#MO$MCPh2@7}pmM5D> z%3CTM?Zwzt7L!t$Xs3fqr1001cUcWw(5qNuK~MXgl~s?Xa|Hf#9hYNH{Y*dU@7^`c zfvmjZA7m@gwWcD-+K@kwIM%M?nh;3R3zBzgpHaR*ZUtqLiB#hsP+!R#DR2V!>s}^jpnhl=7R!_Jy~oM6O_K zW^8n#v{!B3=)JsLx!q!oRnJ4XMhDXW3|bbp6Z_zz(+W=0e5rJ&jUwe5?8xXXb&p`A z{<DskL4D;?-r-G|atJC8m083L-Y?~)5ZH+4E&kLEmGhu$PimCzazHQ)I6mx|+ z3}5 zXR+{Z+`9gQ$oZFx18(6gF~Zkijp%nVcEzI~8Np5RVN2!s;^-Dq%8hOS{>c!_aiV{)$J zMMzpkT-@OVWxEP$*+>mc`UYtJJ0FRBuzgjl4aAt5H*pc3gp%`HI~B~5{qJw>E03l} ztn`1pUhUO2NIc#;EgpVHIva*+4>cON7<&*(xQ3+saBr?xad643bq=K4564p7(EaFU zC-6+!_g>F*0h`ggp)0#Xs6XG~!pM%==slM{5!R0)9At$S<_< zfG8EGLDFqUmd~)kAbtW-dY||114YpHlf>9mE!gI3QY0~kpda&$Y-P|d$_rZVREXji zUuY3V`U+M}>6eNjJftsOnOA66EU3QQRfe=D7%t)sI5q7cSPQFRWCd35QRzuq$cs7# z*H*w2e{cmn_Sb7SW$R-xf}Nu!?mDmp0Ij3-ma07VtI_-x-Lo|j@GX8WxS?1SfobaG z&_&mfnT!6a7s$e*Rcgi)pn84Kiib^iWK*&WN{HVWdz(j+UmMz%l zKlwNBsX8;!&2Smx4H9|TcYhb-UDmFKBgKe-B|dPYGbfxExhxEYB8L!^8GA-eWxtk~ z5qG8^R&=5D+jL&q9gIh=eJvxlIwBmM_HN!wPf+8o0kN=e@#}kcPb>`K2$V$RiKD zGH-k>foZ?U87390x)N`inrx|}T?B2N=Ww!ck{<_7RTuvOZVf&d+E5vG69%}MLW|@S zz{%XKd+Pc-ld2sK!U$^B;o7rNEAU>PkGqgRpbG7?^5HUrjeK}I{?c&1sG1=ujl_Bo z)5808EbDPJ0~jqOsy9@!c3r@vGN5bnVl^y)^J-e@k+ zI!|SM|K6)p@Z>j!)O79V`|7AB^y&5b@qcG_AD#jrBR4_!u7*X(Wog$et8C*ldrMpa z+y-SH3o&3J=>$ZAjvMB4aq0r6ghJ#FqKP~AYxZmob#!>J!tI(K`4~I951giLx;i?2 z(D%Ltbv2>JHs4BPbh^X8*hjJiNh|RMHbT2*-hSfNVGlF&FQp7BNjA=VH_I>0^7Gw- zeG(EGQ2(Hy2@hI)yfD_G_@1d2t9JlrSKOU7;yqkh0x3>(mit+#@CHCqw(Dt$VIW+Z zo-eZ(vpnw5?e~87GD%pR)=3l9ri&;T^Qms7PL$ow4=`N=IHu4p>6tewQDq+OsklwN zniLySU+JjC2EqB0ygw4^F3i>5wL2?x${Dxq`fK`lv*)v8((gX#j5f^6T zNw1x|J<--bTR9!wKkQp(e?K#v{cx7{dRd{Rkm9}s6sCm7KPS23p5}qG6oBAn(VnSK zUA24ZWLHEtBIJ#->+&G;E5(X9gQ-lTx>||?$kYzTh=xCNTeAu!3VPpOmRR%2%txfV zuPp%S2IVpJDj9d`fJYE%#u!m+ZvdlyP*=Z4d}62yMc2^g#aR0^zyv`WC#ZTD{=Lf2dt|=0b^c73y zk@9SW&4on(;C#j|eCwl{(r`-0%NnJa^{T4B#b?X0-N|qF4uaHngMNl82 zC}3`LLsZ=XD=-)b0hst@v!?r`Wt9|tHSW1NOw;o55Tbj_u8^gdE#vL@q4K%V8Mg?> zLq_O4)Z_H&LycRELW8*Nk89XDTKi{i)Ttm(DdbeJe)K=zI#cJtbtUi8`#m3i7f4hVHW9Bkoh`2V=Ab7CMPpg*)P)wn13DP?^U5!j!|KOa z&|{HgEMmtFJNj&Wg!hFKn8Y#gOKT8suzi3*lkrlf!WGJywoLm3f_6(8Au0i+|2e%W_Hs0hH0oez(a;wNz z<&r7!O5k1FRC!zu3{U=EZJWRAOvHzy25U2cYG3rp9&jo)189NsnC)tL^xTuY!OuJ9owMiL59=kBDyJ$*6*1ylGV@R7 zd|(dikQ>HA=zOF3#g^Y(So$R)Tom-%`R($|0Y|l?*^RdF#&K{;2r@qtLfr4t?_B z^W`-R#`o}r6?x3OLhY{!XO?ofRP6pUZAcEFi7kYNOvCdBJRkJel^g3|$nI0R@84W} z{z_C$mqb)1&*P~3n$8vfhYP^PqlJ%95fRsOiZNzf;t4QwEEK$)U%$|sCOna{K|B4u zAE$s;)A}s8!n#lve9@GAfqlR;_mP|P9*OaXQf?i$PkVj;qjskIX~Q^b7?IzWYD8sv zJD6(nx5K%Ed`#2RiVShKv7^qx7k?`8P(H9`?S)uSF;jC&46fzf^CH$*_DG8y=83~Y zUPm(bzD{LJ=+emAZ6~bgyy1WyCrl$6%ly_)91$gfj%0u(J$0QDl(*-#{!m8_Iyz{T zOj6`Ags~r@<8`pIS+%&z4nz9p4(AIhRye3mGgieDpM&(^cRk{ynp5lGR}!;;+*$&V zjWCZsh$x^%o43EcU%0Cjc@T8>2WujD5amWYq`u!O%Cr=juJ2L5QwDkMC&OnFC*z920YG%f zIg!5x5bU2LW?N;8tviF?!#x^87slePhmzc54~*~I66US*aX1YP9e8{BeSnT_`K>KL zNSv0k2>S5g%kLOZ7Bi?0C%a&po0~&v7tOXd3Oij`ojxZ2zz}O3OY4$DfklaJ%&BE584?@rLQecL>&WW<&CA}XMNe5 z$1w2kethf;v#eq7JByz@Ogm+*YI2S!To=X0v`t-^W$Cy@m#hl7;i#=aQl-2lLQC&* zNh(*i(0U-W8stQ+(()Y+_hS!0R`pl}(U0rtxn>|J5Q&h!B(gQ2pXJ=iM6w1H znN+_Q4HKyn$}JYG0i2@lSO+^5pucjj3vj(@YAYsvggzgNgTajafL6p@`%{#~bL;`d`#Y1%heEFw-x2FF_mke>k@t$-D<6JNT0D0#c7G~s z<$J<|I^#djLF7f^H_*y|*H~Yu-Mjm!u0Kg@g1M)E`v&In-=&vBEut8ArJJACihPwbNFxnz+bVGc^-#7dd= zEn_bfuYZ5v6cra2r)+>^B{UTBJTL=i^@6|O*xu+4Uk?!V_eLKN74mrf?UIk>t52UV zT7*5UxLSBM{d~d++j-SjDm$J6Z{hlW3&GiL%iy#c-~6M#!?v@2i3S@A#gm%Iee~SC zy#B0L8HI<_E)?0HI7X3B2IxXY;D2JmLK+Rv(GBAh8s(7efnzWoMYLqCzkk<6nepqR zN=gH(TP{_dPa$s3*&x#ez+d*JzuzRmVAHaccgSsK zg#8_R{Q=qdOG1hx;WJccTMeiA`W@ESH{bK4)x6}yX#PLkArp9vgy&DoL6YqrGqfZn z8fqq?s!F&5>0Z%O;&iqsMc(P_?!S}|;F}=l&mHOy`vu8%ZVW5AR_2sxqO+${cB7DO zx31-;Q{TuZ%{1hE)8dhj?-*6Z0TevWXENRUIJW>!mx_qiU1%5ntONF%{kPLK$i57{ zLmQoi-Kv|~12oD0P3*e%uN5%-0ly^s8K7wUlz-$|o7hn}O)g<=tx= z9+rD|ML(te3ep-q;VwveRex;o(PZ$$L%^@wHg$pj3JTq-=;68I<~y~&ZljdcZ_|6^ zg=@Ktr`mN5`Su8}&&~ksDi}ok%Y`44G0iV-X}+Kl4L|=t@A!rf=6J8BX8+^I;8-EZ zqC~$&!2Bfu_H^+oKKY=5o?^pJkanJ>dV{d4%!V5EP>c=!Q~hRut!3g$H0R>t4BbzB zpOl1LV^qM=jrT%G@~$I^ZN%F#U!Q(*^|wmaIkjkJ_@b*c)W^rNoG1nVmug+-_Qy+w zRGI$$)=5uaZg@ujR*8pI0mbcq%j$3QwBetBQz^`B6jlGrOr3Z6zu0^8c&OX9 zfBb6KB}ogFt>uzRNcLq=!c{^gJ0p8yNP}SpldGZ#ZMJM7`@YREmMKE^tb;Klgkj7K zX2uv}%=gp1JYJev{KUd%OD?a(VjYR?izkx5`sy6q3HVIJnhiZUs|K;ibIMfq7;LzD< z=dCL3|7U9_rhq4fq-S^jXN$cFh$h{qE$u%)`5Acfv`N?AtqJ)LmI&M62cWSgVnF}d z3wQ=RX^@h5=s$Y_Yyi8h8!L|Zf#Vc(Pz{)<4h%Ea8PIOmy#0qPMK@>W!Y>)}&WYW- zcSc5j>`AS29f-erZT#JZBOPtm0HnlhgX)5V;^MVf(AsQ7egyz>`#k#jt7${YTX)XZ z#2h?x(VbXY5$c?|2t;FG7PYtakA>dR(FA!c*wKm7*OD#)8O)OnQW+0}_tqi2e+9(0 z-}2E-)`MN6ys}-PT<7N(Ha)WebeW4Jt4>Pr%v$87JS6O#Ly6bd_2zVAW%D<1BG)6S zP+E{j65F=z)pN7iFSDN^+YWo|87O?n8c_>_09dYfGH*z^U%SUI z%sq#ccX0N}cA)j#&JBou{lNAl?WB~erS5y%Ecg+R@v@T7$=B^6zU2zH0SJxJN?2)X zsby{s_re$C^#z2*%kUKbE%XtfmH+&4`T*pM`?&*Rq~Q{4Oph3&W$G#0ErnV6AN_?>hi*7~)@qVjI|1j<7Q+Wy54@@SqaGq_eEHGj<8 zWPE{OQvA-`^#MCO`Sy6hBnZ=i(!NAtL*U87EQAqmpnj?(;2BHg?8tn`mK z8Osjla@8sS#Qa{%BM#nC{8%vZyDK_O4oZ+ukQJR1o|}gv zZQgm|-KZyBbMIVxrm7Q{eIpU$X99HJ6ys5NM4^S$Wv455%<#)m#xu*C++#y+vkPV{ z%Aw-JLphUfckbLf#6A5RC?Ygo-Y3noKB(kKMQF*Mt{}T35A5uUVClB6QP(Q=+Aue( z&kv{C_7=_oot^XvtWL=I4AAHUO&v`zCf72LGdAr8LdMyd(WWngVyh?<>1RA8VO1o`mkqTI>50Ju}lqZ}-3UtpzgO;G<(o*0*yD_$BB}3S=si{QV7O!wyP*xzNzx=j)_udfu zRv`A9}HWal(E| z#$rjnXQ*m-!hk#XV87ktxzG>|qv!(jdgl;2*Jadw`we6=_HH>T7L^mda4puG!Yu>< zjEgU^<|d4FYc=oI_T0LBu%Ry%9 zBy-7URK9{783#1Q7t-e|k*@?q4^axdQ}N%etT{8PhZ>-@)7?qDy5zSS)dig&LkWu; z-#zGmD0tMRYKIOAWuC0^bV!`OH*f-RbHe*lpBMQrNBa__*v)dMpwzb%&D$wUTgqG>*I@Slt!IbfxR1Z&cBMzHpv{oT#&1u`*x4d>2liV@5_s!hc`QC3K(0Azyh>QykwJK)1xg3upGmAmk z4vawZ6$t~Gi^!ChOn;B;4^$q#iE(p4;*X1}`-ALkTa#PfeQUwWZ`z)@kwo@)5U&UC z_~@%+EP|ZzTT;oGtsa9d)||6`=eeZj*e_;{@rpwudeFi(`mgghQe9ea?LR_VxC~43 zOn17{brVPJok)1+o0Jg2H#2QKLc3xjkcW2LSxDUFe&b#u)^{MI+*ee&NTmK++8h_? z`^OGHw#gLF6#rB6>~wCA0G}T>xfopcNvrMH$sP6tx%NBv$dded`H&3LH;p|URZGzz zTg6`?jlMec{Du>x_>Ub?3Zq zmc|#q9E!vZd8)vN;s)I0UOMV=MoQ8MCmCt2rfC%Wgn(+>Qm}CyFGgI`b?BYIYcK6; zS$mXCL2}6>(IoP4zwNkz2-%><15JY?+e=KXGW999-Q3$dw$AIbNjUak`- zzN+Xf;^22@joH&ug0St+vN#C*tkN=>X4F89uI|Sm5>#$i-*+8-UDF-@t)#%e&&McR zztUj!!46JPaDX4bg6tC>b@{oBBxwv zSxtZ@$R-f&>An1$jQy7QdJYAzqDs51Zf0MvFD!5ESj{Xl0XIR60&q%e9A&cG`0l8U<+KctX>uUOv1NzP{L?<6Awih^b^}eku=JN0|tlGRZ z{u`mx{^fG-+hcUdfzrx#Z4%Ufnpa@j79cx=Fmo*WR1+R&b_4x6D_npfdFn2vZvK9) z^_$(>I{gfGxU*7liN9eZb_Vc@@Bn6*g^ri!=qb?qAAtVD1+OITc-By^5EjlH2?|o~+ywh-@9EumnPhY{)q4wBwYy?mNbr)SHJ+oID9S z`E-Jv)?Ql+rKPstxTKiU9->n($70Y^SkN=PU@BcpAOhT|BYM2{tf8x;g%C*?zs@8l z$AH$qb);1Fbyl99X%uku6szMf@{6|M630~I(ie^BFzN7DF+omI z5;a3@(Vb0$24UV}hoHQeOc<(@3y7SLs0p)N^NbdD`_S)3HKHvZQ+11OmN;$ zBs~Y)TDbLs-!_IU7!JnPrkl3UE|>$Tk-Cq5+qQk@zkLWJ%G^xZFI>w&sH88qhV0kN=qZ~1smR+9#n|BiZ(?r9t1UkpL_cnD z@hq*ZCHFa3Vm^QUB7W``?dX2>>sqYZIUb0>`*=F2bUY>no9~>K_YMn8k%6426Nl4O zFY?P6MjyR3DyAo(dfp5LnP-pRbMV6ZkFCbpvk2I77}P6;GqSO9%vn8rA{2Ff--JD3 zpbjH3T`-#z!_IO}Tn@5sIP!mJ@DHloB@5-zR;!s>$eBr?M)$x) zxX@Ujhwjo_dPf1hAQpc{6jjqu(H!t*z+aX4Dgs@tcd<9wU!=!)^5c(iTD zSbgZuMorVy*SpBF{`QQ)*9>4dUq`H@LhwD6*p)S}#CdTtyc`{LS@Yi*=3gun*1s2k zQ^x(#ZJ%-UpjxDk23p z=?%K)z4`nilhiDDU9U0-tZC*%ozC1Ri7_r8S*pXZ777aJ$0f#FTN4Wd@kMQcj1K!s zH%NiRU+S|vVh-wTKdSuDx%8Wg9J2_b{QwJE$;hQ)Sf4hIMMi$UIBZ06k7`0y2e{J>OKHQYsmf>AHrU$vd)9KHdX*coLJ#6v}JB{zg>ADyKnbI+4V++F7?}vCg(x-F~`;WGyDuL`tkv?syp{ zikOpgXe`HhG*<56i8Qzu?jZDK8Mx3}_M7UVkG*yxO@)^BDJtK?~o<%&wy)KqJ%i&wo9gpEQ&(qF0{$oCS$oxrz$?BxRX9 zCyuZxZ{Lz2UyXq9Uc-kB6zYEKMh$zZJ!Cy+N5w^;>emH*?2?+`F3XbpNjj>tCDCPQ zxE0}Oe9&Az9%w>+(yE`Q>E`z&BYKVu@oPS5-pn=N6NlnZtl;R9z9aa^mzPSE>5o7I zgW?O1+tmfT2vfHDK4T55Bg&LG`*U5?23m$6Vz^P^GqlL?)&wx}x zJ3+1N=tEU_n{b1obKYd4CaU=0<>4tQqk-4il!zxS?CG{@1}2&rArV?MV#gBK+idlp zHtRAI-A4Uda2H)X7gff}G%CG@)TUMVQP~NW@S0)5ANaESdhZGM9I_xnCc@1}4NIp1 z%aEd~lZ>sY{GoEs%{D}vE_bykPl4-5Jk8V zQ<+*JYkli?Rksu9Dt4+R4Z$s~8Qz5mfwuZep@YNm9rB6&^@S+t9hwN6<@o#D?)(&o@=n`303LWY4H%Ktkj!*F)C*|F{A$Q<}VkbRjb z&Z>H0z9T!*F+WOx%klBTE)YMrY=&7A3iZAi$zfIM3_CC4S`>tyIXoQIIe&TWnWLVn zy6Hn-Z`+BXhUcZV)Zq>&MFYY?nVf4`C41M%`ovi{%7z3Ei=MyEBDM|ftvZ-kLHRt0MXLBfgvVOvri@CB-<)}2Jlz&; z(x-R{E-7cXc1K&1&9(EFI-3YJC z?^tVpb*L)_5RML8sHj*SRfXRf3t1oZYaigMf%5wZAM(vpjH zY(`z{tdMBEHTH4qJ>UxJRl0ViW@(3u6`V)Uo4P%LD<<>@7Ug}Ia}tp zJj46)_@kOuxJ!(w?aW6nDq%sQti{(*()Z@OkjW!#|4hsKj7_h>9ZK6rK>>w=rcva< zP{X@o+a`dzs#mng6RO(PQsFhAm9ib4s=22tAam{~>HV%UD|eNf=GF$|2^ATUq5|S# zAVWz+eaq?agisgiA+|e7MX%z3pA*G(VVE_FfMXadEOny^_Vas1KS6^7 zI^gyq8QxEZ+j`(8R1rO`(jd68#FEa^QvHI_Oz(rPTZ(2~b>l}|$Eqm(#^@?7OFQ|{ zdp8+@)JQU{O}W)gM|Z?~<;e!&8M!U?XaVxe&2hyhnx0#0S6gu>K-=O{x9BaUWPe!n zbX`E(ko_B7&Fy`PD{N`8SIj3VBi;{GT$aB1b-hv)-Hq{O^A*PEtg8pfj~Sq&*f-rJ z$_zC&)Hy>GD*Z-hj&{Cl-qhHR{i(G+k(01#iRx?zVQ*?Y^R?FUTC=UdUVAYSC|LqJ zcrvK8-N}{-)51AMEWTMKLgCEWj+M{L&I8c>W17)NwW}(M75V${Yfqf_8|y{v&)0+m z4)d$sFm!9kjOvfST#j8w;5;u8_e{e;o@5{e-;fCTe%a&uv*_NNVhMeg*Pr0TWi=^f_Jw-6mfZs5_YL=0 z78v7ykKo+l%8a9i*kI1E3r>Lb(Y!{5=Cwi ztBOjqNf|D+O^`nK}m`adL_g6{|i!e&E8`&mVJ zNgzP=)BDoMu6pW z_LIW7!&Fj8W`k22&Nwb`6)?KS;&oD-(uPS?$Gl?2WGTY=IZ7h6JGV~V)o7x!yEYg4 z^QAueEzFpo&tDbtop1Y2lv5aKwBbUsCOa%*Hb;6^z9U^J{6bne*~E6)4573oE2si4 zKElj1UuN5Od$|Ymak$(gqh%vQt`iNpXw6XLCB@U2Td&L5G|eXqIG4Fq$usq}^%*KqkW@}}jPrc`SR{qm&%^IsvDyipI^lB|Dw4G2h=Q`9|Sr+)cT z-P~PIFsWyt+yA+vpZ`<12|!xtaKo%guUFpuI!I!X!vjdY)qz7SzgVi!frWrr&(g+)Z6{j9<*HRfe+$`27(uj=vEFeN5>Dmin$b+<_{5S43({ zk}w|WzGChZzf`t|Ix9>#2T;(20E{=xz*lWJmVz5pifyGwDB0b4V_Pwg?jioGt%s~l z-vVFpBY8T-fO(`V1n|TYd){xr1VtnKJ`eUZxXQ&9H}Ubv)cTax*=u*s5Gb)*7V&qQA&UtTVuE8KVM}kNg4ao~i7@{>USq zD^Z5S1K4!6GIBOzGm?wgjHiy+?ljmZ`PQP;I$2n|`VtVAJ0l4TaX~@8>6RM%c<3?z z*oyG)^uEn2ll!Nn3j5cYvZ;*L7sp?pBHu#o-!?x!+!sSwJv`mE&scA_z@GrNWH(R9 zsw&VNm`h+Pu?VEFRC!c9+7wNgc=`*1F6o{}y(tG{61 z9NnF@3K7&to7^$2))?Xs9!jMQPglq2Y*Nld-;k-e2x}=&_82Ot9+lS_&Z+iHSHOA4 zqQgbEl%{UEueqk_KW-kF`@Bt$ukS-WNH4=Yl25|tyo+g1Z^Aqwqu%h6wYHBse1s?D zimiC_hiD(?V?fHf&uk?>|Jc{r=Re?~1Tv2Q>R<64xcA42LC6Ou(O>J1>!$$p&}({m zyMO)IaX^!b=8qU`O|^M1UPhI; z+GG_@7y-}+v_aW)%;)`R19`ROLb04%r z);|a$zfrR3w@+@tf=gZiAEe8&Ur(?;MM%v135dwr*s0GEIg)?!i)hD5Byp_f^$0*j zHzz_eDH#_6V5G#kkGy_LF2PEHHc0hV)BDZ(w{a-dQVHiNwcSfElAF@$ADicMY&Vm_ zy%qmReK7v2c)tUXOpqY80yqQks-eb;B8Hzhp8oqA*HOU>k=T}sqy9M(%R652%Won= zJLnZG$K=I^n_HN8T}yx^>#q39)VCU$289w{mg5KjItpph&}^bHWZ;~9FqmLQ!*mW} zAl;bBcVzDyK)bxpm^+Pt9=nM?mgZ|lqwNsXeht70&^(sDUG~qQjwodHd*r62csFo+ z{F=%QAq%&AJ2ulwoDtyO-*rVMl&%1iO)|xN*FIe#$gTRT|CE$Ul>pl&*n1&|*UN5yb9 zgVPAl54C0kQS6k~SkZx!uB_3o-LMHoX&o4Vvf~j!kSu(VOun{B zq^HlyTP6A+Piby;6qfcTz&faC%7?w|hs)T!0Sd2P6SVpHud2ZIex>{0pB0(Z<(zvX zeI&wf9nt>UHHh}L2F5rM?b)5!2tBU!;4Y!si8y`qpz5qpjEZ$*us(*I#xY~$y>Nd) z#JxeMjx5y2XiwY2CKA%R!oS7L#i+#60s5Cz{eVZ8&uushi{voKI92gWP@VgMK<}9%=AUf1d)^T0=Tpt1VwbQcH zngFr7+f`dQcdDR{$25O`90)@vS3rE>Gn^#%wD#B_(q!$qaB4IwI03k$($?R0C=Br@ z4}gc}RBgQPwCS75_DrwnyBeR?v9mMI>{x3qsJPW)AHULot*|%4mc7G$< zfHq5j;gyY#>YyIp6N84Ry#CZwaFXQg@>mGCA~uyhTnc}hHz$iGzM2JXUfrbi)s#E; z6A|5CCc?&?r$NsrdvGoi%QO?K@gN+KR$UYqd&5m_9iJ(eU`Z;%UB)1-a@7f6a3Vmy zg`>*c3=W!D)KKuMx$<*u-k=9~otk6$xZ#x~X77jejScjW z2^a>2#=9UG<_Yso-u1#KnBw7o*_q;7O;#{mvcxVocZlVd^IjX79anI&f;W4D!H7WD z5a6WdVeaY4avY9w9Hgbm2gyrNBIh;t8=0!-kGz$uAysJATu{-9-xY;j@0MH{N~kA& zw#c9!v9wR*IbIhs~*uRe<^AE9YW@;vAMX zru&s~#Kcnv^rv>L zA@O0>i^lorQbf=gasotNt!5FU+yANuR@NQ#UPRj90CLtESz>pZ_$D(=D8N8hBKzVq zc7UfIf$v)*qneh(H|c3q#X}I;t(f27(6Pc*pbs~CVeNtNr8fH2Kn=&H5ylKp6V#$; zk&rj7Nn9OM@*=4WC5y_z1`F4}*U}|S(|P@9GF23^Ooi2#PsU!E($3|ry|6&ewJ4iv z&yO6YkE2BRMB0QWgw7(#2pwZ!h*fWO$hd-`OY_(Cmy*XFebg)xuqg<~#^bE0yY-kV z^WMPR%sIb(czgR(N}KcY$ONCr6RQzAT;mqkE31#6^ZA$7&xZRoN27B#tq<_xwaihE&UP(CjHM}Z zGQ&SnVv(V4uAGlWu=zB^jnbW=^osX$Q4VZxVpdg_7!U<{y-BmxDcK1U`rfKMt+~CL z?E#S3tqVURwdd7+3Ikc+ePpw960A&_y@L6AkS8a*~n z7j|b@PjTUJ*p0V*8CYJHgKz|lqKMMNU6FNsjI3rB{5J5{&Fj3 z{6Ts>izm(+OcjR&5(Ln*c)<~5X$N#r{N9eAyGn0w>zWd7t8@;VVl+zzA__Agyro=h4!=Ab(L8W^@cARD>-!=^LGF75?jLIkWG>_mAVW6E z^Z8zhV}+Z(dgo`4#;mtW!&wC1xrQLM^;sM?bBKA`jy*3Qn(Pzxo}MKMchAN-E^>l~ zI~ikS@1Do)OEOnJScv3X?@i`=o^^HUFzZ6S?G=h-&aTmyUxoNWR?Q@f>f9K@G48=Q zP2x)wkR`;L>`UU*$_JlDYfAIG34*>q3Pu>FDd;?C=1nC{rI7l>np=gX!XL-Hyg0^@ z#1YWi2Io#T%<3SS*a=U#85t&942 zG9^*~OrDC2T3ccr$vSvy*>I+CMn&Uy zBM0x6_7LNEoY~lwyBn>^-bS63V4R+6pDhepKkVMHp|d&(Gl$PabjMbLdA_~1qu7%| z=MBFemkJl)EvSaRdvtb9dUV3JipCZJzjKqQF)fs!LxSuOT;n+V z^z}843^GgM@QNyy^Jasv!9M1m+Z(d3=MlJ?_4pp|sD$RGTW0+k@-az0U&{p7(F1t> zKP7aIuKj7ztB_?l6Y&{)4!g!2Wz)Gc_576@F{NZ{$vxrCqF|_v##uzn!X?O@xS1Wa zB{FU__F{<vFDD;fzG8E>mW!1HO zTyNbVNGlnM!q^4q8$CPTeBAJWmHnxzv*8*sjzOo#NA5g7ArD{GXD1{y+k!fmN-M^RR~R|b2SK-ir1}WZy#DO^ZxR{(T&P4$xBm>pC)8Z(Yjmmt zjC8FxIZje!(%(I;e0^%VqV~>dR<#0#q4c!OSgo=0)x5?4 z%0tF}B;csiyM<1Ogn4^CTh&>3rnds7luPK%pv*Ca4fkmxNLBs!qMTDNkV7&m``g6n zmtlrMt}3*L%-|kJGtj=kE_?g8Yuohe^?Yw^Jjl{;k+}FCDe;#uD1hfnX)QykVf$bk zH&0!!#}3hvZGwVC2FCIOtbxm%S4+eOS0X`@VnlZY~ zxE}kkWk?n|z`j1jo0@1D(^U;HY}k)5>BJVI3864;!G}X0>{wGLP>Ccj{`}9cr(f%S zlmrwu!0jQ(OTV7&D=a!&Xi-|S&k(Ve5sd&?nb(>DNl(On^MEP_8R`Wl1T<6RDF%-Z8FgtGVVW)9W$9}yjP{zC4vrgg@|ul4Ct1h;2KpL%Iu z;b$G1^whjWXtywZthK%{y2GeqiHFsp(}H{`1{}>wO4uIN@CAi7&#aZE3yT21RXbA& zWBsWVb42O>aqX!Y6{)$G5ws5c<@462{&9>nl zCEDtL5df4$(1a5D6UQOMtK3e@neiajam2Y~HuLJedi)Ff1$ey(2fr@&*A(f<#67iT zzOHn1M#9<-LGKN8;X2%R0(E_PIwEjlIznFGI=R~n%(yBab8eNrgA`4tPhV4oG{GNrha^Sy6pM4bJw4k zBDGmf(W?12kxQ4ZYw1CbX$J>Va)LvazQs@GIL{<`sf~A^)4zu&jc39pTab09(rI+_ zQZ*^TZ2ALESo~6@`^?_s|HJ|y2@yyeC{%ZQPs8eZa^<6qSBF6wQN&l#F|m%pQ5E^H z3^i|~MjHO>Y4zFL5OQjYm9ix*WpPa*OLa5xB$WUh5yva~O8?rVZty8ByMz!-)?uA1 zc?|*ktR;|-hd^yK!q-BT@Q%%IhB~&0>y3@e+)~~xy{tnqI;&q8ESb{obcJw2Oz+yV zv)RU}ryk{d-7EY0ide31 ziklRG(~cyFU2^%e+=|7`h01-IovbhNMsz_%GX`c?Z`V^+>-u5Hr6>&9;HHZ2)S8kH zxb3gpnvaV#kPdGsVqE);iu_$Y$1sAU;m_8Y1PaV|=vDoN|*=)6?XEjYf z68Lnd+e5%IJrr)d?xvEy%oV-TxbQeqBCR@OV?!V;aJ;bZK;ICK6gk7@w;|FKIn~7n z{hwdd8hg0;CYkz*NYWq-fupHRFCUrE!2`^ZLCz1*rv2us;j%nGmHL%ZBqx{At4VF| zeU8kMi#Aok1w6^+t)g(QVF*0M3X!EBWfT6FWP_swVT@a@T~W}s@x~gD3&%wFeeV@RAk+17T*7=6B7B(YTO_XDZvdgW74)rv!3Q00uf@4@*RWW` z8@=Qhs%~Nh_ia1-;)iM|%fkDu?C0R}=<7R60UaIo?RlGIYPWu^-a9qNV2K)ipRe)& zN~&n;7!^gzu-%CfB8tE1mK3|}_T;L5=@(c7PiL&bfZ3DCL7kOH&hwk?yNn0tr}TqtcS??V^hp9=?$_ zy&>p=jOEbKmhiszHZ;de;j^!y(a!fm<0W9OABNSqr{A76p3WMJmE3*RX9PF~!+A4F zghMi@#FKUi3O4K|x2fzSfa`RI3n!vbvm9?fa5-c)jPpIiyJ#YC8Z!UL>&yD7x5N}M zt;Ij&&`;AfA1i^FcSr!2&~W`d{LlWQa%h?GCW3E7G?ZoV=kUF=-|A>dX68}RQM~%f zY#8`SSUQIhVb;}YZJ(BieGjj0?iAX8WacpqVH?R-F6^9YF)FlFtrh$9;E8@;9jv7z zF6dEh`q}U@DxpNVLJ@bSJ>(wsC}lU8l67 zYkjg(f`-)v(wP`h?`!F7T4{DAkAVw^;)m1jJOOG>6R>PO3e~G*NO?Zfi!@;%wY~qW z&`uT&t8nx=L?M0795;R-O2A0L@;>wHmzJuA`Lw}4c@@jX(#^K$xS1Ha#n(?0 zZ@IaHZe>Y7fCQZ)@8Zn&hA4BVUQFZ$SqnCooTY%A-Aj>6mpQY!SA9kYkiiCxV$=Z` zA>SrMoVd^stV+S zsDVf<$AF-DJ7CGh`h%<8-owPA^K$ysE3J#PL#gRjk)oSsYNQ=P4`(bcNX4 z4i{M`|1Fw4q0XH#$@v+nVFSl6-`zU_#7xbe4E+A{OB%xj z$TR|DGK*2e@}ZyhvMWJrUr*2DCwSK9;l(9Aa4IplQ)j?5bQ2$(NbD?KGd!;L;Nux_ zr@YCdua!HZRSEG4~XWvKvHbZyV3=m$_CM;=1BtYlo*YR=Z77onhw;1)u zh6cE4i+MI?eBuR+l}o*RE|DPgM=SL39L+*mYbD8@EA=C`iM_J(v4}g1O|J!J(>QUG zW7OA|f@>BM6ISUC>lVLb&k7xAUBNZ7AJm``D<6-Me&jzIxPYE6s&xbKetcXNEQVX*@N}BlLA`#!}Y&9v$`5 zK80%E21Qb>Lh8WSdUddP5Q*Tv_*&3GqAhePt|9u3nO0D5R1RSs z8(0A|%QuoIxaxud(;?PqZ+i(9Bp0vKLleTOEw5!wm35y-xHd#ixBY%Aaxz7rq2Btf z$xoBmx*j`iVx?{0-OvBC^7ln7Ep0wqJ}6W}hQHrQ;!7-YJu0rOV(j~mh?rDW9+7yD zEl?U{tr9V_5ga&0+9i_Cr*-PL=!1?^gi*VsYS&mo?i@(Ud9zE$1*A4@76N8Iq||aK zb%q-50iEN;6TC@zIw3a|{!n68KvG5NM_3s{rgG@t&NgK&c$x$7#pq(@(M=|o77A5q zqs@B&Z3iph=lV5wp4j?Q%PZ58&$#O;!+xBy>fE}aD}BNO-3%2>9-Z$L3ng_0TaBwN z^BS31*FRbut#TFBlf(YOe={rBo8j%nAR70~5v(9N(&)EAQxx(C31AD=wT8C`a zrH>arq$z~hP#{G=H$b}b2fv!3MU;mt?T11`Y{O5Kh)32Gl9kC{^vnQT7_Wb>31<~^ zb9M(U$a4(Q8xO83hnPwI70=qliw<~O%hzTe#-$_)a5%H78%E{oE#>;7ZePAJ+G88h zLn-K%AffSw?Dcwq26`maS^FEGkJH+C<{d$PP7g99r0`=&jrYDC8yUcebYB3{F^2cN zwXBf_=ZN;N6`}9G<>QNb`M^r}5A6DpT$fKX^z%6Cmn+qVl;vc2>)5nvb))5Qj{XA` z$EKQk+;mP)K0#7%INU+Y=k5K+hhj7@i6gs&*sG1A#F=2%W?oFHf1rjG|NN=nqHb4R z+vywOHo1TWvSI$sI0Mru)8OwQkB+wxRXeHVL(2S5Rn4dB(T(%wY|Wcm&^`-atVoKV z-Ku(kSwcR30*n|EAMXh-!I)5FRc5NCSkaCJI%|#SIi19_RNE@YqlP}Kyo7E?LLcJl z+4US8_EfZ(`YEg(v+gjR&^iHwe39JK$c`@cQieeW9sA6TBG1n>dmxuWc<%xTuDKm3 zr;}7BN)?Og_iPwxRG%2~kDBROg-@g)G$MXpA%Zb|Z>sXa1^1$5EX04YTxKG)cie(C z2F0}(4;M3vbnD;or`f$_*4w^|2?;@j#6Vfc4gsTQy%9J&Ac@KN zl0{$9o2usv*0ga7oKZtENU!`^QSV88wXxZ8qrs(zq+j%I|FEtepb1Z3m=<<-Gj$8_ zGmxmkZ zqH!~$Si?SN1W+5!Mkt;^OkfJeLwZvfOdsA^?6|b{3Q@^ps-^@}MgDmzT6fRRo_2#Z zuhNv@DFq6p1dl6!n?+R;<@3YpGA={`wW#*y;jU10Yi^}fQ;LTsZDe#{W!lgs4Bt!w7#6b1`~}m zvHh`tZ!7<0TZBIR5RUhbqp>6KzKg2IQ3l(q6 zmzF^K6*?Ab`l?49ymvngsLWRa#c_=Z4+e_o`vgw&e=Z|$7`f^<#rT5}*91*FV4Y^G*GCVgD;;_g{+ri%I^=WB-#5|F2a3SC9QKE%7fI`LDY8 z7b*U$F8)7L7mQN8(~htk-};T@O?5WW8U22wuk*xOo zvi$R_`Zkci=G;(~p~EVg-wYedU75qO8ae$AJox4Hp<~$mz~K2#2cte`v}w9_97K4F z`oF*LXyoCx3~IcnO3RUeao-4_R=1OU$$ueczQ#HB8Za=<*nM-gXoH;~?~o=D;^#f) zU3bo3!c?2>vd%eTnOzH=%Vv^s*+BVPu3j4S!B{~52aI!}>Sv};EfeL(9OC_X+A!wN zJ>r47$#hnUEn1EX%(v;s_><{IHzxcO!rQz95%g_v$hJZ2eyQRX&}#St$8!y?3R%!_E9jps;KJh4;3#j(u8+oVJDR z#+37NbvXL#4EIeLVcR%T5{JqPelPbm`thj~+Vrl8Y7K1*r;)jYhQ;hSiilm{Et_&D zeOHjMHi<_8qyv$ZS*T2_~w0pBa8@IGx_6E$T}q^4Yz_BhvOmhrbrEGpynbq z?)T7nqjb|gThv*1fFO*g@}ad>#(NgA4sd3nL(*=+<8MPbb(Q@Sat&G&tSm|11>-a= zsfKBaPd83P&Mpzm3Rku4iF%4ev|)3&t9WUGKMn-&7~7`sE^7Uw2$r;qz3F7Tj~#qv zIJxGm2-xphd1Cl}@po?B8U+>JTg0LN#+SO*z+J@^lJt6rEa2m{*WR5-dnW=mOTmi87EwT;)hZ!EZbjFdUDQEyDO&owOR=jPb@)PWp$>|W%pz5YHJcDx11 z54*(f&BnPnK6v{k9eH~!1bu8?)(2tO2$HJSi)kUm@iTX^7 z{0*Q}wWP@QS6=^3i?C>WnNAx$=J{&fCuO;*s|9}0Rr|LM9ueIsi9+jkjlY=kh2ZO@@ERh3X)~_%Z&LD7&Q!}~dF}&&Y&DTI>e?qCwIw>oz zOjRZ2VMo;YHtSz5!VS16CfVj*_1EMSO?=SdE*EXkn+LGT;M+$cffRMQ-tc3#&WhEd$C0h90uMY0N z)>~L4@6f2FPZFD%GLkFyie)1O)dSsJ3BPKy3A+UJiFJ-^NEP6>?O9CUKfa`{Kn8KT zeS&4}Lr3-FjvG8W4sy=YS|^QntXe%gP>p(VOc67bV<-`%qv$4@ z*??T5Zg&=zV9q-LaXefH$|`W}m7z^>+jXHSVNEv|=#0T=2rIe)UfQ_+jseW#IvjDQ zQ4$#(>RQ{^l%Jb+dvs$?C;d(Q1?#bb+>(q08LeNbQg|3(8bp+CTNl>cA6oF6j#f1< zKs&W`1P4WkqfCK*&SIb&yr58~v!zLySA(+Z!m>sV%u=gyX>k<(wBSnwdqn_%BTi;u z5u4_qp3~Q~+$L^08q7;kpKsG)d$@+Im(+cj0>?%FY7u;It$=IpRO>nD5HR%T<>nmS z;f7GXuuq1NhIYTmip-b@8Ai5>;rSyrR>9cAhe~yi=%1ajZBd{``J^x(CmufF%S8|3%?YcucABG zS>e|UrYq&k+Q6LLlcIm&7EYisZk2B0_SPXZ1Tn5BxuM*Ua;q|?H{!koAUzta`q8*) zr^(Zj?3=EDIbAhT6x6tAk03DFs7j#n%&%EMHD`yQ)P+5UMojcYbg?cgA{VJD9{6!Hu7ldZ0?(t}Hw!8x z_M%Wkd|ndN=i?zJ?I@ibepVNA6TU z_%38vb$q)Xz_t(3rXHRm8DzSthC;}ip5&hib_|@~ z)N|>GmRRg?S zc`>7Q4M;T(+GDmWDGt&{N8dW8bnh;FK0mi=%zv!Y1XAt&^q=<_DBR@j22Tk z6+@%pVf1;6EmF9De}EPW3m{UQP^P;iyWv-o?+D z-aU?nXb_5qdN!gOdXQfPCCKiZrYvj5lKdq*|3ZU5p& z>K+(AKn0PS@3zueEaZqf-<(xDE;t_(`uf_YWws)`1$)U4UlF80K1O3Y%}46Lp1Md76Bh>+Mvwgvw(kHUR@F+`#d(`(4X+w z1waOs2YWfJ?W!an1WaPY-t!!i|5j~-A#hfpXm=S(SF{Q`2d*jE``Vw9K9dS%pE(X z1b6-VY|~#XYqRk>&@tnjH;0hoEYU^hFx+=}<#36Lmuv;!C=kK;vCIkbYIiQ)T z7S{MA@s(sTQkubtguDWpM87TpPo5@-dWip|%+Fc%;kU#p&P17nXftGjCcsF-UtApbp$cf;U}T2eesARVOoHxyP?o6}grFwNk&h z$dp*O4K>97nb-kTk|0kWY9}lfO{`(Rl8CFT*)|xxA`Wx_az1wfED8_qd*S3!lm=US2$^)bwRnnkf5p* zOOE2*zM8Xo)cH1)Lk2xyKS%;VC4pA|tJBXmkqOfVd585l9@q9H2F4# zP`bp4Vesnpf067zE;LVXop9{`QbZcy$SKDVz=X(pukLZC^p7+}d^yKy13)v&V>0F9 zdX6LBUiIrv!;nrKjc_IzAYrHC(=D9WcGU@T^Z>VUv~`-300-oF9^B1Y8j^s!T83!p zX&m{a6Y&24Fn!|U-;~|2h`$LavAw9K@*n^D`^$5Hasdg*h-!PQ`Y0Y9#Z{Ap+ae8M%6KXe5bgZ-s5xftwcMC$)923uJz3IC<| z?cmzkgNG~R&K=vFbwqR1J-OqZ2ZDAw@0!foOpVO!zMFZ>diQp-*!_>!8|^SsK4HG8 z^Fr*VPL<744`VgYT{?GZ)3u`o01^1Vk|HZ{K z0L&iMIJll8V2=eH3B~crY0en?8-T<=K`(~=Vw8V*#@_%a+Y(3%;^;=~4+NZz`9sE> zQSli-75StiaUA`YivTE2S$QnL8ThvX4oPZm3FxQo`>F1Ja`+!!1D8~*pqWc5fWNt1 zwJH%@0R;8|xVmapS#s4n;4Fl3Eg)d%xnN-xHT=(mg~Xsnqo1_^xEPBINB`$JjLTJA zuHteP*U9;FkBsZ&aGjh#10h@|hwJ408P?-EIje-=IywJ)oE$C$Ip+?3`*P%Z@h^SlCgQ+|~Y+;|liEO5aB7cBft&irxcj2o}w z#;bmE1UItqBeH@^ z3BZnAVsVM}hvMOK)(`37is2usg{!mv0A`w81^n5S<+l*6lgTMb6gRZF76p0>WEU4!5wEvCwvd`hvL+nF5o*! zp^XM5Vr9LN%}rt=i_qP=8B!c^?~aL0VQ%NJgZrroI!+BfGA%LdwN$Ju|XPW~g zWv@i2fAkWW#u!}LtIs(R49R07-3`9oIU@`n)t&47c1BdW$GHm^QDQ^6vdyC0EX0pm zdGkrYLiJSe#A*K6~eqB#w{fEfC$rV#eLPuL8>_g`-g!oUJjC?_C(19LF zyxp_B@5(>ijGqqc4@-&T!PcIm^V>mWD2RzUeLml5E1dO~M82iD(YcW?)Tt5*r*fnK zH%aZvqZz^iK*TV6vFPJ6DD2B7m7C+2uHs^zj%)0NgobGAShvdmh?lTgw~2c^CiJE6 zH48!w7Lb`0w3H%MagJHXHwr0vv4b@fWEx@*t-P5eW|EPu*!Pyek(ny8G)<01HI61| zK;CCxQuC;(NfLnCUAZVsY21k=1@}P}FI)?ML8kE$ zj^1f(q-M{UY4V^y8rx3ay(gG ziw~r};MggDBIaMR`k#aglUw)ZXg7F19yBs-rYf>k@YR~WlT^(>YucbT+#uLa%chV%}$d3m*sPQiGh z37{d11)l~X-Y0Q7X*-BG_t3-TPHizx>7sW2Xp@b+kI&xU5RY|qI3MPe9;o2hmeh5} zVbTibfxX$Kr%=3%y=^aK`#yUspPB2gnWa5v{WD&_@fN!si9^aYx_p_pi9#^Fn4Kww z0=j+%v;J6xZq$q!D#o=0exMjW1}mFu5~=)}1jpq^YJx~R>GAGvE%K(&V3wB|KwSla zB?<^B1VPc$A4#$n2ogdzJ2L1)=?*Zzo_N*TsauO$zt$KwHknqRx7(_FSSBKMVZF@g zzHzM%S6*GOabg)dO@M@?d+-vfbfKOo>>^GED{a`4N=DT9qzoJ?X;Ga|hI#y&(3!RC zfZ3tdf6uO!vodnmM<8cMo_G=YT0I{ood5MBKfdqVq1c&Gpgp^q%u#)h73nV&;g;I_ z!RW_QrZG|*s1ZGhcFGCI)Yb=1SuKpbk0>8$+UV3U+J+nuOLV`}`m%2_C*5okaqa%% zamaBT)Cv;FSX8{(`Rdc$L^iZBD(UpJrwe&`B!hL3GUP)|rY0*4-sVtT36NDko==Zz z?K1)p#UCjvrTAHs(F&VBH{XaJx|C=E)#^A!8Zk{tq}J`yKuqRn(<>GutuCvHS1sPH zQg?@^dY0=cMi@!RZ}W4NAv5VDG$|BfpXxOR%MKXw&iPJ)psez&Hlu?$1&3HWF9Nm- zvGyF+o?c9k#6@lZDMLc4QuEmk^38p_HNu4 zaIw)QBb1h;jVZ31N)BKwHid;!iP+KEdfo_!M4PG(*-A;Vz;7MZkUH z?RyKYx@D+%R!Q|@mC96*Rp>IZj7ghD1D)UP0lGz3_PVS<#RM0JwDKU+MKH8an})cS zL1WsGc<9oNZNjCO3z0OJvR38k1}FdJl4HdKg3T+-3!_d#cE+GL5&ROpVB4ko#XkIw z5(LE(JGEx*h6W@(Dvyrq4wpy|_?_uRs!mR~4PE~JLY>iLe&bGRPR zQ@AUe=^8yz_6>DD39Es;X8=$>b6MYsTG^2Cw9g)rrs^xR* zg2iyw7Rd^wZYi3^+^ef2Pdi873fU5mt?#dF?$cK}0<_l4J9ckT%O-M`(%CExJ^0FV z%7ZYt5ZxbKqV#pi-X5s4oo`cVjv8-cWsY1CQvZq=B}yjY&0w`oZRvWCYPH&fy7VBC zcDA&FRckX9BT4<5>Vs~GeSd%S;~_q1J+GQlg0=T2Z@9drq9?9y38*@~PsoPc70D94 z5OU4O>)uxtk}!JTLQcQqw1I-MU2u?G?Tg)P*9E@W*A;deHqro7Q#-AG>|qL_W*mGhl#WW^|P#?esX%%Tf$Y=#x zK;yK*$@P#`rP)YGLwp6QR!6iEnKf_2h#xA!4D#ub*z>5;i)+R{p#7Vu2MclFww(@Z zu@9%0Q6$!Wbr=;XYu^<0P%)knicW((F(AFQvYvmUD>N`lg;XE+-;30>_8}}fv<(bM zj((|Zq z4%J%rPN1$}$0@Yg_E!`*e>K9zW2z1jwCLjE^Cev^_Y)zl(yJ*dX%26v`dTZIg|Pvl zp%8DcCoz*zY4~6gLW%amUg*pnDVLMPF$Qjeq-aHy2@SN^7u5e$N*Tn6i&0+gR-$gS zpDLLmw`uK%kK1NIQA4W!WiH3Xx>k~GsE_kY>Wt@>gzSQjYe)5K*d{3yji|S{SAPYe zprlm!+8V4I+jIYJpl43WA%yBzeu0Nodc- zV7!|rI>x)}Bx{DM5(*`WG14Dww*C#B{TuVPSFU@u%}?cEf89vJaj&69gWeTutDtW0 znw(&$hioaS(=SCVrIQJY_rE~$+g`a4KEjI@38jWdnpyZn_XsW9WbZb3HvDLzjb(Jt zq*CvaQwCUnfWIYKUL{6KExEeJfpMe$W`Pv!@d%?*Ps(nkGZ85Kjl1oV$UES_{2dj6 zN))TdcE7#JVwMpUtkCU_xQ!ur2I~a&6Qf)^_XKmNrVnV1(75{is7RUCp4H(V0S!XVz3)?}b?RprPa-M_ zt7ZK4mFB)3CHadgxFLFNU!RZBm}$Rn|3pgND5!6KC?IgETZt8}7hc7uZocf%`+AF* zU*~48&Iokh%)I7gOg};c1sT9T*)jJtoa9;R9&u!fk)_bzNlv`aJET!HFc#NQ;8YUe zzp}K{p{3#O?WlFCCX@Vf@?i;R(jifCd1ClH-=00W5JtsBS1w5JY~z_o6$sF95#vx| zHgp8sCC=IxF7AJ^Yx~Ixza)o*nB#HjB~~i)!}XGn-rBdSNKo*e8MR;`Vt(G&6sOPv z5Bdl3$TQXf?_czLp$XFpyP@Xlgo>{0fHwD=ap&XbK+Td|8)64U|4L)R{<%RNMe85zG zZgxO}r%&_QjiT*C(rHM9b!JtY`k~9Di`a5EVG99k)xiMbP+%FkQ@663S$n-KDYnW3 zC203Gd#y(`acb$C1gy}itXVoEhC#tfP%w~NanRUwzy=GSx*lIU>cTVVT2eqq&V~cP zTR2;v1~RvS7v-_;GN{o9&Tl~D4p9nhu)|anGn=jvLzvQ8UAN>xY88ff+t7d^)0ox- z!v^{2-LZr)-mKl&R3d|t<5gMt`1ZZWP60f)P2=WLt4fb(Z#Udu5#t-D9p>RR4A?}$ zU}Blo%A5ftU&VkBe$Xvl)#0*@yWXOC@D&0nVa6&r3jc31__vKfP5RbV!#?><#jno_ zZjcIkSL;U;Pp~Zv9w|xBrvnicWjIxfP_!wRSEb zTlGB^PY&{3TDEV^->N56oWDuCO^ku=m}hAa;T+<%&677_~B-;p_V z#$zZXr2e5|;~Bh$N{j}xztg5yEgM9#?IEWY!owO&Y>H5;h~O+ zwT#c;7tE=G@1_#v#NnqKO$r@yML~JhMg6CWd~-b*4nx)SDTw=QV4E7q)xT9`rqt%X z{S+kd>qDVw2%)r1JY@Fl5MWPtmr(P+)=PRwDil@?X66ZKLuJ&)YME~bGtVxf6litR z9>I+f5^2UhX2e&WHp7i+9gW7SpJ@QLdm?|C^qSaLlA#HEn#vAHWKM57ob+aq*n=Q5 zJNcBY1HZ>7ModF7$7*Gkjb764qx2)apsh2dmXSC(%^Syu6mQH9y=oh&(@!B_a&Ja7 z%it9wb!G)YC(SU%WYcat=SiTI#x@&Jny|*#n#*uGa}6+!ya7KAIWs;aYgDIGm7jCG zeoqdl-oI(SNyJkwa3ES?pzaf)vFS1xG5@(@1KPtfsKMJucTQ81hUIdGjg7sTxV)kXSi=J_bgOX)^9P3z2y5Cv1xsTI_ zkax_jDFt>i##W7$r0Rv@S`bC>0LeC(C>Fji#89steo>-~pPjWdG~r33rj8zcL8B5o z8hWen-Js>1ktU;*24k#7?Rn~F`fIcdQ#GF;)B9zQN-fp#vvYZi)~p;62Y++0T`JiY z0M(d6YPWuOFG4S+ceb^wY6j$Z{5L|B!&npraek>q5%1F8tEjIb<=>B-x6c!qscTO> z_zf{NjX0oML|#+ zRoRURZsSz7KBN$=sswQM6r>s78|S(*7^e)ov+c!}Jtnxz!?j^tFhm`Aq5LeZJ(-ws{Qc8lLVxO}{oh zZek{CUPeB+g7*q1NP2jB)R*3h-QHJb~2pvy`$v@h2(>lKL4RzJ~X%)X|CXxta3O(NDSQF=%nf z!PVY3t2$sze(Fe%b%$@sfX{c!ETG!MOL_m{s{_+syvn&LaTSh5OO9chnF@=ufmvb7YD&3VLnyGs5c$s2BD+K7c6FYbT6ziGADs3h)E18 z8T&4RU$UH0yNQaF3ZcTC&=6qOMw3qw%~EE|(50{8;?akYhRklC@z#RPb)P*etJKz; z+W7TE=E~gr=wh87R?B7G~}wlfhD>4lr!A>c+&S2KB< z&ARu3Y}adHU9Z?%N7bd-QHQO^sw#b*U$|6}C;SId=x4eO=tty;@Qk4BwBj9Q=i11Y zcsIoN?BIN=i*2NepGJ9e?rJd7v?@9x?kL*C%uXa+H0aI%!Lh z$TXpQJy$N`79asP1jbu$Bmp|e*qvC>#k+gDhEgjs@**1=nU#a~GqWtNq0p+CG?AB{ zcx2hid~;$bO*=y!?1F@N7f9J779W`^SC~xW1L(CwmE~Fn5UiOxhC8F?)QZWWermM_H7!7+X5j5y4Hd?_HZtNGdWK+Px*N$PBC)#A6b9S}EK7ns1!^T)SRe z+Wa|I&^3b)zGziAYOFHRU6O7s+b!k7AX1q!+A|0suCK(C8D?{tx zvj?D-_FUau{?**3GvhH4)5R*@H*vi$M|q%@00RUNhH{WSaJ2hYkO5ASxcq@c;vnCmH z3oC{Pm+G~4B}fd^2;2fabm%W#e3=j5_XNI6X1Os(cIp-X-b$5QABVN4r%H~+sEvG- z=`EZZD0gZRjah_&;@eu(20?8Ibvu4HzP)nCaDn64qolorO>y^mmG_@`SldV=_zR2S zPpT!uH@!47&$3fpB%jVfJFq0BS&N=05@3KUmZRebsU4wc4V1PjyZ#Zp_V2sN7_)NY zS4m`sy(_dRAC0}w=Qb-gc(6jsCC}H%cc(VqA0wJG${RUC^6#A)nA4mDciN+wl_R1R zS_gDQ7x8{T?|L(7;$RUOx-0S>b=A4ZRj>33xmm8~iW{Zhp46wTb}K7hYKiw7w^*tV z0-|)YZ<0wxbH{?uNwRhFcvl0OqU}!k=01zIvR?D4ykQeFPXrLfL&5p2(%CJ=koi1* zN!)jH>u+_kLJc49^G2;%YwCQbg;0f65R@;J;=vWyk|ot1Rp)D#O~9FHnfPT&k~~z3 zcoKTB0fqF1k-=0}f!pTBLS!gyj|0raayh!z!Axhn5Quu``&;+L=~pYsb0bw=F?nA=0}OsxIT(;Z50zu9Id~?uH?gd8~Yf zC56f-vt*RL*hs(j2F7zoJLQf~x$Ms?rDi-LyKV`w8fpk9T+tcQ}VVvMw7#MUCzOew=(o|ILL zDwfaS6AQd90BTOOvYa*|rn2`A2{N(1dBH=oJ@(6?MewU7jLlY%hcD6DRpQ+={v-a6 zNPnA$HFj99i;Tiu={)Kl zC)U+lacS_|iw3z|X9JnCh^BzkD)@)!%%(V%#3O=QG?ci9z~#-1!&Q>pkYr9R^Oa1N+}@T!%}DOV-^FC z-Q`@ZGDsMQ5Fb@9x3O;ZyL|pC>-Js$pXT^4pK&*T-jpFMzf3xGd{Aq*NJ!Ux55z-+>gLvr7gL+zbu7=Oh@}ozOmYVudra^rZUJ~I-rQVH^OH@*b%4@w0<%WSl zH94o&JzmpAcETOMrC-EZS#8HSB--u*VFPvQ{II)oyVJB!l2y%>;HB4mF#$(r z3?a8-)p=+#>R_K&Su^==lj8eAzU$hl63d#`PP=%d3)?X}i=Gz0RqK&L^davwk7wsk zHb6F=wuD|KWK6T$<_)_l1WZa%v==U&6julGo6m=qelAH>0U0|-nc!Nk5^#TQVeY9a)w7Vorq8=h7$+lc0)hKNhF50K{aUCL&%2|(`J#A1t$q; z5`>_uanTt%neN&H%i;1^X z7h+-x9Dr?-R?(fkch60-k}()ewtPNH-npQ%QmWH_lBB^P$XL8p>QsmNOD3Xk)4#Ia z$+{j8mb}TYi-=$16R~eLuoVwIEFUm7bR-w8s8L$GA-K5tFIoB3#kV7|`1xw1n29kv z+r9iLBH9+Zi`F=~GIjOkVxKp;=Yu#N_|P=j(tRZlPL8@X=cJgPqAFH-LiDuX3DNpo zJY2Ok9h*9-{E*$s{oz+0OV@09P&?Uejqui98C!hf5}ME{YhCjt*w;1m;Pzkdtp1pW zCNGct?y1*eC{WJ_bC{zkuUx$IO~UeNUHiN%1eYW1tjDU%U9a2RZJn2*|IXV=^>6OJm4{KyQb#Uk^>}pzo^H~Ywr>_Hej$cOPTqUb zuf%J+CDm&tl4GZrJ5xMxKGlsE6W3a9SL(bSea9-x&SgWz-PT#a=T*s9k+t}?$z>n(89=i_Z{W4 z9BGMqR}Jt`hucu-e)ahtr<gq>;;LaPK(WBjZ zYk2)B4Q7z;y)ZmnjdzBmZW3o?0~&nZv=k5e0;LwYMtstfU;aE|6pe4>IJM_y*R3Dc zg5|>D!K2fBm5uIHwf7%8UF=+?A0uoN5T>pYyi4aa z9_HY=a>plFm3$?*jyafLG^_@mdQctG7**}^J*wJ!fP6cBcxN-XNu9FW1IVImRw7^h5II zfu=iSQpIYV$$4uvJ>#A6^M8+s{PXJqf%4)Df_-9~NBkY=&vyFyaZb%Mfx@tLKxy>A zC$1ctG_Nl79v}l{PpJS$Epk^A2jtk)HCF0yX1;B}UE9nf*~X~;pf*7JEDzksAY0V? zhwy1`0PfmwQi~%)?T>{4HR3(J2yAyLevEh@xNB{~%m1?2RzQXjteV1E_G8ZicdgMi z;=I`3qyWa@vKN=V{w3cZx$O04z>%xH{gqg=Ty@IU7GIw4u z0C~Q8>H!AZ$jJp5emHJe`+$wP6EFta#(i{dQ<#wZsP^np&81@whcvJI@=V%1#~G-7 z@}@T3`tDJCua7<2QF?ke=cYubmvm=O4fc~pSh4upu=y>osMpLu2FHh`JX>7Y8knY( zyM~~;mfL&KU9fYoD3dplzlGVaqlvkOez^f>Yb3%#fvIaelv%sJQ$i|N(${_6rfatQ z5q&|bxVrgvOLoz8`PDqoj)($ZSXa+|fUxuY6K6)!dX}ACBiPWUI{`@dtQwPq;Vk7} zh*Un>^nBfrPv|CgANKAJV0FLV+7hA)PArc8Eo^1|Q1Eh!>r-}bzX!Zs(DC@V`j!Om z4SoB<6xR&}hi+l}c0=IpS=Y9N7Ah8YOD!3^n?+xIhfvg>O=gD}Or(Jc&u`wFLhOmw zE4Msi7_f$F`xV0T8ymy=ZU->J0mI19JXqgl>`T^$D2N;IN%o_~CT!TykN`a4l5v2+ zc7<1m%4`SjI%j}-&(S^MzUwES{69jk=!as6_x!?Pnr3Dow}2pBH*8h;HQLLCM6|_| zvFPE;T5Q<#4>CmojeS&t&dW#nge{6>L<`w@5X8UNLp?83VCWoI(+1~UJ)(xKl${u4 zJ}JP@j9!XOI+Z1xoFdVbI&k{tT#{5rfBz{r3keQmG_4Ln@yXn1B3bS>(Z|I)ANB?)nk$qL}k2_Q-tH|c89x)KRSCFIIXjh zw+TyCOIH0H5L#$~IN6C7F>CJamOCI_b3G6Os;z}KxR#Khy`u1uMTRH?Egm{D`67ts z44i4~X4)hF1*iT)-ChgVTzqBF^EFFoo%YF7p2WhXq+312rj|Bz!Z<7e2Ztm4%nHvy zEK)0P;~r1v-+KSLsmZ+hI?+qd`o)8`Hn%|8^dQ3$aF~+k^2o*dE&u?0@f-7cUzl_??yjF%etsWCT)6w2 zZb^lfC#gfzzje>)N89``RH96DCFw(Y`k_yK*;&M}`=Vv`@DO0%?=U z>rNzC|?Y>!vlcKd?FBd`R|M=ks* zN1tc)el1WM8rZXa`=Xc8eCyW&T<9h1koWVquZY=UVL9)KwCFYpfySX@aKL%Zyy;xc z%yT@GDz`nW{cTe!Ylrki*&Dg!)Tdsc|BXUFe+$~VG)D(?UA$qlcsA$3d5eiI4$zJBks_&i{9 zLTh2XfsaKh>&H=C3NKL>26=t=MUwCfh7cdbC%T&oub;LV2*fHw$`mBX5a^aq+v1xO zFW8T!NcwbXCnqOA11+{j0#d2#?(ges`pP|?y^rq#^!l}GF3%;&OT;3b6x*c0ujYX5 zX@mY-U@+L)YjO&RC@bHn=}1pi_xl`c@(N8qhdp$LzHQ*ZM)oSj!Nw z=uL`(hIk6B?%H1S=9SZLT<+!?Bnk9c*C<$=wOVHFPE`o(jI}p7?;yfn`@Ngxi8t_m zh=c;EX-S@hXA$ITc`{}wX_x&n`;askl`wDpUu8> zm0`B$Y5`te?OE;kyU-4$GELAta!^9iJwnKK$o53Q;J2~rm1jM&u45JacIIK_dY`ro zmA9s9u!msb8A&k!hUwY2ABmtUnExjO9XZZ8a1o!rlULYfxq zRH+pwqfQ*SbM3m-bio`-BOp^?qPMTF@y&PL5n4fC^rcLdp;YTy$M2a}MHEpx&LgK4 z1ATq*Rjlhe_`b6lB}5PL3QzW2rJ1?HV>*?9zZSh-U}9z_DqJjB*~aZVWVkzQM4@DD3RhH#ih8on+OgMQ>pn|g&+!wx;P|^q@(TsdiWq7-G_WJ0z zu(w;y^R4`icMEC_55GVEX=*5X)dY9O3Q3TPZOVfzu3Wr_b-{P4rxq}Gba|rWq;*Xvde3EI6n6_1DoadF<5%o7Y3jp(C8earEc-a2XOg;TR4C(FFP> z4(*{v{>tzeq+;c#qM^!CB z+G2;3bgG$BB*4vw7)~7gjE`nOJg@}T>teXyCO)Vo-qp2qyq3eZ$|nHU1zk^;Uu-^fwc3CkilxN+e z9e1X;hmGuDXBu{#v(dPBU|mqS(im{hZlOEVCaLCY*}%n2L153IQpt5U(Z>c*fH!XT z@CzHiJF$GgVjnwr^APCeD#(<$qpAr;7*Ydv>i|)acL=jUd#Qh8=YN5fFiU|QQ@taF zCe>}YX^R`zfg!X3aJDU~p4~?c1CIPX)^CsYhSE0m2Yn(M%Ej!=dvQ0o_-4fkc9pv1 zWdOjie7x|>Z+rJXQ=H!7FL}Sfln1@(71c7RZGgS0Ilp<6U%0VXp}>Sf0Ib-KC(L?X zXK;(S(YJF&JAX3KKS*sD2Yg?0YE_7G8WMlCGzD5|8Y$V{Zzzt-u^L)d^k(zesa;`B zPX&x$SMzMod6%zP3ngm<(KxRIQK_0q>n}sC^_h3hWm-9!_psUA2=h92J%^~2+U?DE ze0xUW(UY(@w8)dO8)}I82U$E(?Aqqu;x9E;OfkEmD^cTd{J~Vdf$0o|tUYgcSQk`3 zi2cAkyiN7KW)SPb;R5ftwpw35V#nG&E{1Hkt&Y6~!bu;?AzSQa9vW@`1ot=iYMIDp z<$usE*5=)4VtGoS4FhWoBnd(WlUPp;$g#836c qcgA%0C^q)bhtJs$Ou(L|x*WOH63iQS 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

-scdQZZBt76Ond)ruyRJep9YyUpw_$zqI^kiKRKJ zRg#e5-+Oa6Rh|xedFyTEZ^P`cvK`TS@OO?^wG@6@W&1Ujb(P-T? zS~o#^Dx(c@ip%8D+%%e-MspLjdf%hDX*4$tOm52mm0q_wwbaJ)-Q}Gj$Rkh(IyD3K zMqL&De5iKat&b=A&aC&pABZ+0CJ+D`ro}au0vw}y{^!>h*-%*94eCQi&;p;!_2=>( zFvh$rbRffFRyFSnvQV@++yRZDP5Rk88#t_sI=Uz$1|IN>Z+|cAhdOoJAq^QNEG$+p zT!dm=!(qrU-|G*153fY_HUm>3Xh<74jQRMP-y;{KHDtiCJ zBfX%3H(Z+HKXh5{=eut`M+&9D5HN?V1;=g^==hZD53AdQQBPTXeGatl+GkvxSw$kg_+vvZGhq7Jh1foGA=;0%bF_jl}^Y!QfJ+<`>U zvgOG?OMl#Zcm-udvvG$YaJKrX<$hf8^bB|Cjrz#}Z#?~x4}HSiSaS7T4+9W*y85}S Ib4q9e0H)LZcmMzZ diff --git a/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/index.ts b/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/index.ts index 47500e713b0ff1..8c3454772fffaf 100644 --- a/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/index.ts +++ b/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/index.ts @@ -65,6 +65,7 @@ export default function ({ loadTestFile, getService }: FtrProviderContext) { loadTestFile(require.resolve('./servicenow_itom_connector')); loadTestFile(require.resolve('./servicenow_itsm_connector')); loadTestFile(require.resolve('./slack_connector')); + loadTestFile(require.resolve('./tines_connector')); loadTestFile(require.resolve('./webhook_connector')); loadTestFile(require.resolve('./xmatters_connector')); }); diff --git a/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/tines_connector.ts b/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/tines_connector.ts new file mode 100644 index 00000000000000..6c399f4b1b9ec4 --- /dev/null +++ b/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/tines_connector.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + ExternalServiceSimulator, + getExternalServiceSimulatorPath, +} from '@kbn/actions-simulators-plugin/server/plugin'; +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const commonScreenshots = getService('commonScreenshots'); + const screenshotDirectories = ['response_ops_docs', 'stack_connectors']; + const pageObjects = getPageObjects(['common', 'header']); + const actions = getService('actions'); + const kibanaServer = getService('kibanaServer'); + const testSubjects = getService('testSubjects'); + let simulatorUrl: string; + let editSimulatorUrl: string; + + describe('tines connector', function () { + before(async () => { + simulatorUrl = kibanaServer.resolveUrl( + getExternalServiceSimulatorPath(ExternalServiceSimulator.TINES) + ); + editSimulatorUrl = simulatorUrl.replace('/elastic:changeme@', '/'); + }); + + beforeEach(async () => { + await pageObjects.common.navigateToApp('connectors'); + await pageObjects.header.waitUntilLoadingHasFinished(); + }); + + it('tines connector screenshots', async () => { + await pageObjects.common.navigateToApp('connectors'); + await pageObjects.header.waitUntilLoadingHasFinished(); + await actions.common.openNewConnectorForm('tines'); + await testSubjects.setValue('nameInput', 'Tines test connector'); + await testSubjects.setValue('config.url-input', editSimulatorUrl); + await testSubjects.setValue('secrets.email-input', 'test@example.com'); + await testSubjects.setValue('secrets.token-input', 'tester'); + await commonScreenshots.takeScreenshot('tines-connector', screenshotDirectories); + await testSubjects.click('create-connector-flyout-save-test-btn'); + await pageObjects.common.clearAllToasts(); + await commonScreenshots.takeScreenshot('tines-params-test', screenshotDirectories); + await testSubjects.click('euiFlyoutCloseButton'); + }); + }); +} From 567249da5bf389ba415a684ec8d707a423795bca Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 20 Dec 2023 01:14:28 -0500 Subject: [PATCH 002/116] [api-docs] 2023-12-20 Daily api_docs build (#173706) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/557 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- .../ai_assistant_management_observability.mdx | 2 +- .../ai_assistant_management_selection.mdx | 2 +- api_docs/aiops.devdocs.json | 4 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.mdx | 2 +- api_docs/apm.mdx | 2 +- api_docs/apm_data_access.mdx | 2 +- api_docs/asset_manager.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.devdocs.json | 4 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/dataset_quality.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 2 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.devdocs.json | 31 +- api_docs/discover.mdx | 4 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/elastic_assistant.mdx | 2 +- api_docs/embeddable.devdocs.json | 4 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_annotation_listing.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/exploratory_view.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.devdocs.json | 183 +++ api_docs/expressions.mdx | 4 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_actions_types.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- .../kbn_alerting_api_integration_helpers.mdx | 2 +- api_docs/kbn_alerting_state_types.mdx | 2 +- api_docs/kbn_alerting_types.mdx | 2 +- api_docs/kbn_alerts_as_data_utils.mdx | 2 +- api_docs/kbn_alerts_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.devdocs.json | 4 - api_docs/kbn_analytics_client.mdx | 2 +- api_docs/kbn_analytics_collection_utils.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_analytics_shippers_gainsight.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_bfetch_error.mdx | 2 +- api_docs/kbn_calculate_auto.mdx | 2 +- .../kbn_calculate_width_from_char_count.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_owners.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_content_editor.mdx | 2 +- ...tent_management_tabbed_table_list_view.mdx | 2 +- ...kbn_content_management_table_list_view.mdx | 2 +- ...tent_management_table_list_view_common.mdx | 2 +- ...ntent_management_table_list_view_table.mdx | 2 +- api_docs/kbn_content_management_utils.mdx | 2 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_apps_server_internal.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.mdx | 2 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_custom_branding_browser.mdx | 2 +- ..._core_custom_branding_browser_internal.mdx | 2 +- ...kbn_core_custom_branding_browser_mocks.mdx | 2 +- api_docs/kbn_core_custom_branding_common.mdx | 2 +- api_docs/kbn_core_custom_branding_server.mdx | 2 +- ...n_core_custom_branding_server_internal.mdx | 2 +- .../kbn_core_custom_branding_server_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- ...kbn_core_deprecations_browser_internal.mdx | 2 +- .../kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- .../kbn_core_deprecations_server_internal.mdx | 2 +- .../kbn_core_deprecations_server_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_browser.mdx | 2 +- api_docs/kbn_core_doc_links_browser_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_server.mdx | 2 +- api_docs/kbn_core_doc_links_server_mocks.mdx | 2 +- ...e_elasticsearch_client_server_internal.mdx | 2 +- ...core_elasticsearch_client_server_mocks.mdx | 2 +- api_docs/kbn_core_elasticsearch_server.mdx | 2 +- ...kbn_core_elasticsearch_server_internal.mdx | 2 +- .../kbn_core_elasticsearch_server_mocks.mdx | 2 +- .../kbn_core_environment_server_internal.mdx | 2 +- .../kbn_core_environment_server_mocks.mdx | 2 +- .../kbn_core_execution_context_browser.mdx | 2 +- ...ore_execution_context_browser_internal.mdx | 2 +- ...n_core_execution_context_browser_mocks.mdx | 2 +- .../kbn_core_execution_context_common.mdx | 2 +- .../kbn_core_execution_context_server.mdx | 2 +- ...core_execution_context_server_internal.mdx | 2 +- ...bn_core_execution_context_server_mocks.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser.mdx | 2 +- .../kbn_core_fatal_errors_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_browser.mdx | 2 +- api_docs/kbn_core_http_browser_internal.mdx | 2 +- api_docs/kbn_core_http_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_common.mdx | 2 +- .../kbn_core_http_context_server_mocks.mdx | 2 +- ...re_http_request_handler_context_server.mdx | 2 +- api_docs/kbn_core_http_resources_server.mdx | 2 +- ...bn_core_http_resources_server_internal.mdx | 2 +- .../kbn_core_http_resources_server_mocks.mdx | 2 +- .../kbn_core_http_router_server_internal.mdx | 2 +- .../kbn_core_http_router_server_mocks.mdx | 2 +- api_docs/kbn_core_http_server.mdx | 2 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- .../kbn_core_lifecycle_browser.devdocs.json | 4 +- api_docs/kbn_core_lifecycle_browser.mdx | 2 +- ..._core_lifecycle_browser_mocks.devdocs.json | 8 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_server.mdx | 2 +- api_docs/kbn_core_lifecycle_server_mocks.mdx | 2 +- api_docs/kbn_core_logging_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_common_internal.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- .../kbn_core_plugins_contracts_browser.mdx | 2 +- .../kbn_core_plugins_contracts_server.mdx | 2 +- api_docs/kbn_core_plugins_server.mdx | 2 +- api_docs/kbn_core_plugins_server_mocks.mdx | 2 +- api_docs/kbn_core_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- .../kbn_core_rendering_server_internal.mdx | 2 +- api_docs/kbn_core_rendering_server_mocks.mdx | 2 +- api_docs/kbn_core_root_server_internal.mdx | 2 +- .../kbn_core_saved_objects_api_browser.mdx | 2 +- .../kbn_core_saved_objects_api_server.mdx | 2 +- ...bn_core_saved_objects_api_server_mocks.mdx | 2 +- ...ore_saved_objects_base_server_internal.mdx | 2 +- ...n_core_saved_objects_base_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_browser.mdx | 2 +- ...bn_core_saved_objects_browser_internal.mdx | 2 +- .../kbn_core_saved_objects_browser_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_common.mdx | 2 +- ..._objects_import_export_server_internal.mdx | 2 +- ...ved_objects_import_export_server_mocks.mdx | 2 +- ...aved_objects_migration_server_internal.mdx | 2 +- ...e_saved_objects_migration_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_server.mdx | 2 +- ...kbn_core_saved_objects_server_internal.mdx | 2 +- .../kbn_core_saved_objects_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_utils_server.mdx | 2 +- api_docs/kbn_core_status_common.mdx | 2 +- api_docs/kbn_core_status_common_internal.mdx | 2 +- api_docs/kbn_core_status_server.mdx | 2 +- api_docs/kbn_core_status_server_internal.mdx | 2 +- api_docs/kbn_core_status_server_mocks.mdx | 2 +- ...core_test_helpers_deprecations_getters.mdx | 2 +- ...n_core_test_helpers_http_setup_browser.mdx | 2 +- api_docs/kbn_core_test_helpers_kbn_server.mdx | 2 +- .../kbn_core_test_helpers_model_versions.mdx | 2 +- ...n_core_test_helpers_so_type_serializer.mdx | 2 +- api_docs/kbn_core_test_helpers_test_utils.mdx | 2 +- api_docs/kbn_core_theme_browser.devdocs.json | 64 +- api_docs/kbn_core_theme_browser.mdx | 7 +- .../kbn_core_theme_browser_mocks.devdocs.json | 103 +- api_docs/kbn_core_theme_browser_mocks.mdx | 4 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_core_user_settings_server.mdx | 2 +- ...kbn_core_user_settings_server_internal.mdx | 2 +- .../kbn_core_user_settings_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_custom_icons.mdx | 2 +- api_docs/kbn_custom_integrations.mdx | 2 +- api_docs/kbn_cypress_config.mdx | 2 +- api_docs/kbn_data_service.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_deeplinks_analytics.mdx | 2 +- api_docs/kbn_deeplinks_devtools.mdx | 2 +- api_docs/kbn_deeplinks_management.mdx | 2 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- api_docs/kbn_deeplinks_observability.mdx | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_discover_utils.mdx | 2 +- api_docs/kbn_doc_links.devdocs.json | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_dom_drag_drop.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_ecs.mdx | 2 +- api_docs/kbn_ecs_data_quality_dashboard.mdx | 2 +- api_docs/kbn_elastic_agent_utils.mdx | 2 +- api_docs/kbn_elastic_assistant.mdx | 2 +- api_docs/kbn_elastic_assistant_common.mdx | 2 +- api_docs/kbn_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.devdocs.json | 14 + api_docs/kbn_es_query.mdx | 4 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_event_annotation_common.mdx | 2 +- api_docs/kbn_event_annotation_components.mdx | 2 +- api_docs/kbn_expandable_flyout.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_field_utils.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- .../kbn_ftr_common_functional_ui_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_generate_console_definitions.mdx | 2 +- api_docs/kbn_generate_csv.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_lens_embeddable_utils.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_management_cards_navigation.mdx | 2 +- .../kbn_management_settings_application.mdx | 2 +- ...ent_settings_components_field_category.mdx | 2 +- ...gement_settings_components_field_input.mdx | 2 +- ...nagement_settings_components_field_row.mdx | 2 +- ...bn_management_settings_components_form.mdx | 2 +- ...n_management_settings_field_definition.mdx | 2 +- api_docs/kbn_management_settings_ids.mdx | 2 +- ...n_management_settings_section_registry.mdx | 2 +- api_docs/kbn_management_settings_types.mdx | 2 +- .../kbn_management_settings_utilities.mdx | 2 +- api_docs/kbn_management_storybook_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_maps_vector_tile_utils.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_anomaly_utils.mdx | 2 +- api_docs/kbn_ml_category_validator.mdx | 2 +- api_docs/kbn_ml_chi2test.mdx | 2 +- .../kbn_ml_data_frame_analytics_utils.mdx | 2 +- api_docs/kbn_ml_data_grid.mdx | 2 +- api_docs/kbn_ml_date_picker.devdocs.json | 4 +- api_docs/kbn_ml_date_picker.mdx | 2 +- api_docs/kbn_ml_date_utils.mdx | 2 +- api_docs/kbn_ml_error_utils.mdx | 2 +- api_docs/kbn_ml_in_memory_table.mdx | 2 +- api_docs/kbn_ml_is_defined.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_kibana_theme.devdocs.json | 16 +- api_docs/kbn_ml_kibana_theme.mdx | 2 +- api_docs/kbn_ml_local_storage.mdx | 2 +- api_docs/kbn_ml_nested_property.mdx | 2 +- api_docs/kbn_ml_number_utils.mdx | 2 +- api_docs/kbn_ml_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_ui_actions.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_object_versioning.mdx | 2 +- api_docs/kbn_observability_alert_details.mdx | 2 +- .../kbn_observability_alerting_test_data.mdx | 2 +- ...ility_get_padded_alert_time_range_util.mdx | 2 +- api_docs/kbn_openapi_bundler.mdx | 2 +- api_docs/kbn_openapi_generator.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- api_docs/kbn_panel_loader.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_profiling_utils.mdx | 2 +- api_docs/kbn_random_sampling.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_react_kibana_context_common.mdx | 2 +- api_docs/kbn_react_kibana_context_render.mdx | 2 +- api_docs/kbn_react_kibana_context_root.mdx | 2 +- api_docs/kbn_react_kibana_context_styled.mdx | 2 +- api_docs/kbn_react_kibana_context_theme.mdx | 2 +- api_docs/kbn_react_kibana_mount.mdx | 2 +- api_docs/kbn_repo_file_maps.mdx | 2 +- api_docs/kbn_repo_linter.mdx | 2 +- api_docs/kbn_repo_path.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_reporting_common.mdx | 2 +- api_docs/kbn_reporting_export_types_csv.mdx | 2 +- .../kbn_reporting_export_types_csv_common.mdx | 2 +- api_docs/kbn_reporting_export_types_pdf.mdx | 2 +- .../kbn_reporting_export_types_pdf_common.mdx | 2 +- api_docs/kbn_reporting_export_types_png.mdx | 2 +- .../kbn_reporting_export_types_png_common.mdx | 2 +- api_docs/kbn_reporting_mocks_server.mdx | 2 +- api_docs/kbn_reporting_public.mdx | 2 +- api_docs/kbn_reporting_server.mdx | 2 +- api_docs/kbn_resizable_layout.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_router_utils.mdx | 2 +- api_docs/kbn_rrule.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- api_docs/kbn_saved_objects_settings.mdx | 2 +- api_docs/kbn_search_api_panels.mdx | 2 +- api_docs/kbn_search_connectors.mdx | 2 +- api_docs/kbn_search_errors.mdx | 2 +- api_docs/kbn_search_index_documents.mdx | 2 +- api_docs/kbn_search_response_warnings.mdx | 2 +- api_docs/kbn_security_plugin_types_common.mdx | 2 +- api_docs/kbn_security_plugin_types_public.mdx | 2 +- api_docs/kbn_security_plugin_types_server.mdx | 2 +- api_docs/kbn_security_solution_features.mdx | 2 +- api_docs/kbn_security_solution_navigation.mdx | 2 +- api_docs/kbn_security_solution_side_nav.mdx | 2 +- ...kbn_security_solution_storybook_config.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_data_table.mdx | 2 +- api_docs/kbn_securitysolution_ecs.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_grouping.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_serverless_common_settings.mdx | 2 +- .../kbn_serverless_observability_settings.mdx | 2 +- api_docs/kbn_serverless_project_switcher.mdx | 2 +- api_docs/kbn_serverless_search_settings.mdx | 2 +- api_docs/kbn_serverless_security_settings.mdx | 2 +- api_docs/kbn_serverless_storybook_config.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- api_docs/kbn_shared_ux_avatar_solution.mdx | 2 +- .../kbn_shared_ux_button_exit_full_screen.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_chrome_navigation.mdx | 2 +- api_docs/kbn_shared_ux_error_boundary.mdx | 2 +- api_docs/kbn_shared_ux_file_context.mdx | 2 +- api_docs/kbn_shared_ux_file_image.mdx | 2 +- api_docs/kbn_shared_ux_file_image_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_picker.mdx | 2 +- api_docs/kbn_shared_ux_file_types.mdx | 2 +- api_docs/kbn_shared_ux_file_upload.mdx | 2 +- api_docs/kbn_shared_ux_file_util.mdx | 2 +- api_docs/kbn_shared_ux_link_redirect_app.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- api_docs/kbn_shared_ux_markdown.mdx | 2 +- api_docs/kbn_shared_ux_markdown_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_prompt_not_found.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_slo_schema.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_text_based_editor.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_triggers_actions_ui_types.mdx | 2 +- api_docs/kbn_ts_projects.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_actions_browser.mdx | 2 +- api_docs/kbn_ui_shared_deps_src.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_unified_data_table.mdx | 2 +- api_docs/kbn_unified_doc_viewer.mdx | 2 +- api_docs/kbn_unified_field_list.mdx | 2 +- api_docs/kbn_unsaved_changes_badge.mdx | 2 +- api_docs/kbn_url_state.mdx | 2 +- api_docs/kbn_use_tracked_promise.mdx | 2 +- .../kbn_user_profile_components.devdocs.json | 4 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_visualization_ui_components.mdx | 2 +- api_docs/kbn_visualization_utils.mdx | 2 +- api_docs/kbn_xstate_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kbn_zod_helpers.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.devdocs.json | 4 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.devdocs.json | 8 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.mdx | 2 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/links.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/log_explorer.devdocs.json | 8 +- api_docs/log_explorer.mdx | 2 +- api_docs/logs_shared.devdocs.json | 68 +- api_docs/logs_shared.mdx | 4 +- api_docs/management.mdx | 2 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/metrics_data_access.mdx | 2 +- api_docs/ml.mdx | 2 +- api_docs/mock_idp_plugin.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/no_data_page.mdx | 2 +- api_docs/notifications.mdx | 2 +- api_docs/observability.devdocs.json | 145 +- api_docs/observability.mdx | 4 +- .../observability_a_i_assistant.devdocs.json | 1434 +---------------- api_docs/observability_a_i_assistant.mdx | 10 +- api_docs/observability_log_explorer.mdx | 2 +- api_docs/observability_onboarding.mdx | 2 +- api_docs/observability_shared.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/painless_lab.mdx | 2 +- api_docs/plugin_directory.mdx | 20 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/profiling_data_access.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.devdocs.json | 41 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.devdocs.json | 128 +- api_docs/security_solution.mdx | 2 +- api_docs/security_solution_ess.mdx | 2 +- api_docs/security_solution_serverless.mdx | 2 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/text_based_languages.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.mdx | 2 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_doc_viewer.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/uptime.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 658 files changed, 1388 insertions(+), 2210 deletions(-) diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 4da6a11339828f..0d548cad85aba5 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index 8b8ab9242a0041..26b4be19693570 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/ai_assistant_management_observability.mdx b/api_docs/ai_assistant_management_observability.mdx index 4c7b626dd4597a..2039c9ac564b90 100644 --- a/api_docs/ai_assistant_management_observability.mdx +++ b/api_docs/ai_assistant_management_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiAssistantManagementObservability title: "aiAssistantManagementObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementObservability plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementObservability'] --- import aiAssistantManagementObservabilityObj from './ai_assistant_management_observability.devdocs.json'; diff --git a/api_docs/ai_assistant_management_selection.mdx b/api_docs/ai_assistant_management_selection.mdx index 8b2ab206b57c08..edcf581deb96fa 100644 --- a/api_docs/ai_assistant_management_selection.mdx +++ b/api_docs/ai_assistant_management_selection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiAssistantManagementSelection title: "aiAssistantManagementSelection" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementSelection plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementSelection'] --- import aiAssistantManagementSelectionObj from './ai_assistant_management_selection.devdocs.json'; diff --git a/api_docs/aiops.devdocs.json b/api_docs/aiops.devdocs.json index d8a0e3b50e2936..6a4ad90613be79 100644 --- a/api_docs/aiops.devdocs.json +++ b/api_docs/aiops.devdocs.json @@ -434,8 +434,8 @@ "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", - "section": "def-common.ThemeServiceStart", - "text": "ThemeServiceStart" + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" } ], "path": "x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts", diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 0cbb8e2642cda3..32f08c6a0e78ff 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index d02d81e0cf53a9..adc70de114502d 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 15b1a0c3b951b4..245012914fc855 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/apm_data_access.mdx b/api_docs/apm_data_access.mdx index 96a3a875b6441b..9a120eebe3ed4c 100644 --- a/api_docs/apm_data_access.mdx +++ b/api_docs/apm_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apmDataAccess title: "apmDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the apmDataAccess plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apmDataAccess'] --- import apmDataAccessObj from './apm_data_access.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index e4c70128e283d2..0ac5809fbca3b3 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetManager'] --- import assetManagerObj from './asset_manager.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 1f141caf3c9a66..e9816c6447a107 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] --- import bannersObj from './banners.devdocs.json'; diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index afe008618a7c07..93201fe1798411 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] --- import bfetchObj from './bfetch.devdocs.json'; diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index 8e4f9d8bfb14c0..cac829ab79309f 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index 25c83c9f699ef2..de2829ce93f0de 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index 506c4b022b9160..5196545d7539f7 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 3b1aedfce5c7cf..5867d5b8257059 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index deaabc42e8934c..c169145b714b7d 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDataMigration'] --- import cloudDataMigrationObj from './cloud_data_migration.devdocs.json'; diff --git a/api_docs/cloud_defend.mdx b/api_docs/cloud_defend.mdx index f86194816d447e..deac1416f138c8 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index c869aae3dccab8..b60f92510930af 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 75e3ed27713702..d8dac36a8e49e1 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index 391457d5379b0e..ba0a1ca7370a4c 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/content_management.mdx b/api_docs/content_management.mdx index 8036d0e2967dc9..f997d267fc3c58 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'contentManagement'] --- import contentManagementObj from './content_management.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index aed90aee8ba2b8..e28e0be933f77f 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index 4f695b8a383755..e1cd80030b4e80 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index 39611988cf6b8d..4ab19494bc12eb 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index 02869fa53800ca..c408255e9e4373 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.mdx b/api_docs/data.mdx index f51bbd6816385a..8de976a2674067 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 48b82a61a24132..cbae12b08c2768 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.devdocs.json b/api_docs/data_search.devdocs.json index 632c5c0c65c927..cfa083d446c5cb 100644 --- a/api_docs/data_search.devdocs.json +++ b/api_docs/data_search.devdocs.json @@ -39838,7 +39838,7 @@ "section": "def-common.Filter", "text": "Filter" }, - "[]; type: \"kibana_context\"; query?: ", + "[]; type: \"kibana_context\"; now?: number | undefined; query?: ", { "pluginId": "@kbn/es-query", "scope": "common", @@ -40181,7 +40181,7 @@ "section": "def-common.Filter", "text": "Filter" }, - "[]; type: \"kibana_context\"; query?: ", + "[]; type: \"kibana_context\"; now?: number | undefined; query?: ", { "pluginId": "@kbn/es-query", "scope": "common", diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 94b47782937b8a..fb8259e59b2a4f 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index cd8c70acb82183..e268263406505a 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index a5c2be2aa6634d..dfa448a4bf5c66 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index fc36c8f6b817d2..4c1454ea6e648c 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index 8620b0c7cd2360..64dfa575555f0d 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index c98018e6f3792a..74551d06871f4d 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/dataset_quality.mdx b/api_docs/dataset_quality.mdx index c90839b3f515a5..309a3527d3953d 100644 --- a/api_docs/dataset_quality.mdx +++ b/api_docs/dataset_quality.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/datasetQuality title: "datasetQuality" image: https://source.unsplash.com/400x175/?github description: API docs for the datasetQuality plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'datasetQuality'] --- import datasetQualityObj from './dataset_quality.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 6149473692b9f9..b2a7f60ba614fa 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index aea6a04dfd7a6c..1f71eaa96d1b42 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 11a116cd2c7986..d01634d94f307a 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 3f980b57ee13c6..05a42dfee4f9c8 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.devdocs.json b/api_docs/discover.devdocs.json index 222ba19a62be0c..d21ac358952644 100644 --- a/api_docs/discover.devdocs.json +++ b/api_docs/discover.devdocs.json @@ -133,11 +133,11 @@ ], "signature": [ { - "pluginId": "@kbn/unified-data-table", + "pluginId": "savedSearch", "scope": "common", - "docId": "kibKbnUnifiedDataTablePluginApi", - "section": "def-common.UnifiedDataTableSettings", - "text": "UnifiedDataTableSettings" + "docId": "kibSavedSearchPluginApi", + "section": "def-common.DiscoverGridSettings", + "text": "DiscoverGridSettings" }, " | undefined" ], @@ -2606,6 +2606,29 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "discover", + "id": "def-common.DiscoverAppLocatorParams.grid", + "type": "Object", + "tags": [], + "label": "grid", + "description": [ + "\nData Grid related state" + ], + "signature": [ + { + "pluginId": "savedSearch", + "scope": "common", + "docId": "kibSavedSearchPluginApi", + "section": "def-common.DiscoverGridSettings", + "text": "DiscoverGridSettings" + }, + " | undefined" + ], + "path": "src/plugins/discover/common/locator.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "discover", "id": "def-common.DiscoverAppLocatorParams.interval", diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 2cc3945fba056d..1623ea1ab919dd 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 136 | 0 | 91 | 21 | +| 137 | 0 | 91 | 21 | ## Client diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index 16b1c3d808b2d8..24a9c9bc9a03c2 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index 7af190927d645f..ee97616a9a10fe 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/elastic_assistant.mdx b/api_docs/elastic_assistant.mdx index cd65a2e37d3231..1df64189eba35c 100644 --- a/api_docs/elastic_assistant.mdx +++ b/api_docs/elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/elasticAssistant title: "elasticAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the elasticAssistant plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'elasticAssistant'] --- import elasticAssistantObj from './elastic_assistant.devdocs.json'; diff --git a/api_docs/embeddable.devdocs.json b/api_docs/embeddable.devdocs.json index 426bbd6909c686..c840f13b2782e0 100644 --- a/api_docs/embeddable.devdocs.json +++ b/api_docs/embeddable.devdocs.json @@ -1774,8 +1774,8 @@ "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", - "section": "def-common.ThemeServiceStart", - "text": "ThemeServiceStart" + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" } ], "path": "src/plugins/embeddable/public/embeddable_panel/panel_actions/customize_panel_action/customize_panel_action.tsx", diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 057014b818dfc5..466683e7542873 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index 22bbf44ebcf0f7..05c1f0c349e099 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index fb06097287248d..caace4728e9d94 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index cf844ada379ce2..42daa2becb86ca 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 90845ad4b2ed2f..654b46b0c5e4b2 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index ae4a01bdc817cf..8b2e0bcb53fb6e 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_annotation_listing.mdx b/api_docs/event_annotation_listing.mdx index 88c5fa1cdbe068..25a74bf46d0ea0 100644 --- a/api_docs/event_annotation_listing.mdx +++ b/api_docs/event_annotation_listing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotationListing title: "eventAnnotationListing" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotationListing plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotationListing'] --- import eventAnnotationListingObj from './event_annotation_listing.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index e2539a556c2868..a9b9113640bcbe 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/exploratory_view.mdx b/api_docs/exploratory_view.mdx index dce248fcf20620..a52100f992de4c 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'exploratoryView'] --- import exploratoryViewObj from './exploratory_view.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index e33e91622e2e9a..a9e936abeddf31 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index 09e404d5f40a32..4cca71abe07906 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index 3ad875c6bfc504..6b5b21f4fb2047 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index 4ef4283f8461c3..c77f8c64853d95 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index 196afb1a723dd5..0430d47a37baca 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index 0d650df9ebfb67..a255b55611268c 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index 709fcff3d9d6f6..5a123ab07f33ad 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index 20adbc2af5fa05..a856a46b6481e0 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index fcf581dc2c59fb..278599d9f35626 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index 26676f8e0aa79e..158fcfa11750f6 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index d6869a4d3e337c..2935d4c8b714da 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index 717f1e531aeda9..d2a4a1381c9776 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index b3da4ddabb6f67..232a524194c7fd 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; diff --git a/api_docs/expressions.devdocs.json b/api_docs/expressions.devdocs.json index d3440d35400cd6..93beda5bfdfba4 100644 --- a/api_docs/expressions.devdocs.json +++ b/api_docs/expressions.devdocs.json @@ -9020,6 +9020,67 @@ "path": "src/plugins/expressions/common/expression_functions/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "expressions", + "id": "def-public.ExpressionFunctionDefinitions.math_column", + "type": "Object", + "tags": [], + "label": "math_column", + "description": [], + "signature": [ + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExpressionFunctionDefinition", + "text": "ExpressionFunctionDefinition" + }, + "<\"mathColumn\", ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.Datatable", + "text": "Datatable" + }, + ", ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.MathColumnArguments", + "text": "MathColumnArguments" + }, + ", Promise<", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.Datatable", + "text": "Datatable" + }, + ">, ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExecutionContext", + "text": "ExecutionContext" + }, + "<", + { + "pluginId": "inspector", + "scope": "common", + "docId": "kibInspectorPluginApi", + "section": "def-common.Adapters", + "text": "Adapters" + }, + ">>" + ], + "path": "src/plugins/expressions/common/expression_functions/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -20315,6 +20376,67 @@ "path": "src/plugins/expressions/common/expression_functions/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "expressions", + "id": "def-server.ExpressionFunctionDefinitions.math_column", + "type": "Object", + "tags": [], + "label": "math_column", + "description": [], + "signature": [ + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExpressionFunctionDefinition", + "text": "ExpressionFunctionDefinition" + }, + "<\"mathColumn\", ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.Datatable", + "text": "Datatable" + }, + ", ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.MathColumnArguments", + "text": "MathColumnArguments" + }, + ", Promise<", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.Datatable", + "text": "Datatable" + }, + ">, ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExecutionContext", + "text": "ExecutionContext" + }, + "<", + { + "pluginId": "inspector", + "scope": "common", + "docId": "kibInspectorPluginApi", + "section": "def-common.Adapters", + "text": "Adapters" + }, + ">>" + ], + "path": "src/plugins/expressions/common/expression_functions/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -33114,6 +33236,67 @@ "path": "src/plugins/expressions/common/expression_functions/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "expressions", + "id": "def-common.ExpressionFunctionDefinitions.math_column", + "type": "Object", + "tags": [], + "label": "math_column", + "description": [], + "signature": [ + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExpressionFunctionDefinition", + "text": "ExpressionFunctionDefinition" + }, + "<\"mathColumn\", ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.Datatable", + "text": "Datatable" + }, + ", ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.MathColumnArguments", + "text": "MathColumnArguments" + }, + ", Promise<", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.Datatable", + "text": "Datatable" + }, + ">, ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExecutionContext", + "text": "ExecutionContext" + }, + "<", + { + "pluginId": "inspector", + "scope": "common", + "docId": "kibInspectorPluginApi", + "section": "def-common.Adapters", + "text": "Adapters" + }, + ">>" + ], + "path": "src/plugins/expressions/common/expression_functions/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index 8430995eb24c20..032e5d0349a130 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2208 | 17 | 1749 | 5 | +| 2211 | 17 | 1752 | 5 | ## Client diff --git a/api_docs/features.mdx b/api_docs/features.mdx index 7ae1f4334dcfc5..37a7f280f7a624 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index fc723632424c72..a2cd495db1062b 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index be3c119ee00547..4b9eaff4fd17fd 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.mdx b/api_docs/files.mdx index 4e18bd193ef2fd..c21eec2cbe5b87 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; diff --git a/api_docs/files_management.mdx b/api_docs/files_management.mdx index 2f787e46e8292e..d578eacf9ffe42 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'filesManagement'] --- import filesManagementObj from './files_management.devdocs.json'; diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index a2529488fea501..056dc4d6fb6071 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index cfe38afe6f1e7d..a19c4362e84b6c 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/guided_onboarding.mdx b/api_docs/guided_onboarding.mdx index dd3d5c34517c0e..61902a7030a953 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.mdx b/api_docs/home.mdx index 371246b624db7c..87256269da4567 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/image_embeddable.mdx b/api_docs/image_embeddable.mdx index 8c2cfc0e6478f5..1baf60cb540e10 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'imageEmbeddable'] --- import imageEmbeddableObj from './image_embeddable.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index df8a5fef4b6ff3..06a730d0ba9fdd 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 8ce83386a56292..1a450bb87e9bac 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index 81ff97012c029f..8216c86f9babbc 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index e2c5b4b9d23cac..b4632bcd58c026 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 252e160b616d43..73b04a3df72e27 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index c756601989eeb1..1cbd11dfd0d03f 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_actions_types.mdx b/api_docs/kbn_actions_types.mdx index 8fe3b21f248a5b..f51172b1a406b1 100644 --- a/api_docs/kbn_actions_types.mdx +++ b/api_docs/kbn_actions_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-actions-types title: "@kbn/actions-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/actions-types plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/actions-types'] --- import kbnActionsTypesObj from './kbn_actions_types.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index ed0a6db4ec0b7b..121f39152fd02d 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index fd698569ca4941..8f1195e363d75c 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_api_integration_helpers.mdx b/api_docs/kbn_alerting_api_integration_helpers.mdx index 97a48ce9208cac..7fb9322954dd36 100644 --- a/api_docs/kbn_alerting_api_integration_helpers.mdx +++ b/api_docs/kbn_alerting_api_integration_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-api-integration-helpers title: "@kbn/alerting-api-integration-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-api-integration-helpers plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-api-integration-helpers'] --- import kbnAlertingApiIntegrationHelpersObj from './kbn_alerting_api_integration_helpers.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 4c422b3bc080a3..e6904e0c59ffe3 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerting_types.mdx b/api_docs/kbn_alerting_types.mdx index d8bdba5c8b581e..31ec9aeb7e8559 100644 --- a/api_docs/kbn_alerting_types.mdx +++ b/api_docs/kbn_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-types title: "@kbn/alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-types plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-types'] --- import kbnAlertingTypesObj from './kbn_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index c6c2e697f40438..1fb4cd71832a91 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-as-data-utils'] --- import kbnAlertsAsDataUtilsObj from './kbn_alerts_as_data_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index 24fa8ff68db43a..5c12f240b701da 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-ui-shared'] --- import kbnAlertsUiSharedObj from './kbn_alerts_ui_shared.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index cbbcfa455aa759..59e01e8711ac5d 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.devdocs.json b/api_docs/kbn_analytics_client.devdocs.json index a940c2673439c2..19f35f51788c9c 100644 --- a/api_docs/kbn_analytics_client.devdocs.json +++ b/api_docs/kbn_analytics_client.devdocs.json @@ -738,10 +738,6 @@ "plugin": "observabilityAIAssistant", "path": "x-pack/plugins/observability_ai_assistant/public/analytics/index.ts" }, - { - "plugin": "observabilityAIAssistant", - "path": "x-pack/plugins/observability_ai_assistant/public/utils/storybook_decorator.tsx" - }, { "plugin": "apm", "path": "x-pack/plugins/apm/public/services/telemetry/telemetry_client.ts" diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index 416181f49c3111..1af70477162071 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_collection_utils.mdx b/api_docs/kbn_analytics_collection_utils.mdx index dba58985f7e87e..52d45c656ac9e3 100644 --- a/api_docs/kbn_analytics_collection_utils.mdx +++ b/api_docs/kbn_analytics_collection_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-collection-utils title: "@kbn/analytics-collection-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-collection-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-collection-utils'] --- import kbnAnalyticsCollectionUtilsObj from './kbn_analytics_collection_utils.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index 24a7528cb02b35..2f3eccb35f7ab1 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index e2d2380e865cf7..8f05e511bcacb9 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index 298857a4647f17..16e2cbff3383fc 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index b1e2330a7995eb..5ef08bb07042e1 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index 0f41d84f924808..d9fbce1b70916c 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index 11a93dcd52d3bc..7fd594402e9a76 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index f83bb9f9b3466b..bbf5c2e0afd8a8 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace_client.mdx b/api_docs/kbn_apm_synthtrace_client.mdx index 2a391fff631550..0a1418a7d31bff 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index 33ce87aa5ab241..d564479d022d42 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index 64d29795c1b8e8..ea5defb14a6d44 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_bfetch_error.mdx b/api_docs/kbn_bfetch_error.mdx index 8031118be4078f..e825eb91fee442 100644 --- a/api_docs/kbn_bfetch_error.mdx +++ b/api_docs/kbn_bfetch_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-bfetch-error title: "@kbn/bfetch-error" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/bfetch-error plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/bfetch-error'] --- import kbnBfetchErrorObj from './kbn_bfetch_error.devdocs.json'; diff --git a/api_docs/kbn_calculate_auto.mdx b/api_docs/kbn_calculate_auto.mdx index 4c905f367cdef2..9370ac0707dd98 100644 --- a/api_docs/kbn_calculate_auto.mdx +++ b/api_docs/kbn_calculate_auto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-auto title: "@kbn/calculate-auto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-auto plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-auto'] --- import kbnCalculateAutoObj from './kbn_calculate_auto.devdocs.json'; diff --git a/api_docs/kbn_calculate_width_from_char_count.mdx b/api_docs/kbn_calculate_width_from_char_count.mdx index fdc76dd7fa26ff..6faa4c4037efc9 100644 --- a/api_docs/kbn_calculate_width_from_char_count.mdx +++ b/api_docs/kbn_calculate_width_from_char_count.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-width-from-char-count title: "@kbn/calculate-width-from-char-count" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-width-from-char-count plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-width-from-char-count'] --- import kbnCalculateWidthFromCharCountObj from './kbn_calculate_width_from_char_count.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 6a59d149f59836..0f935c59087ff7 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index c792dc3ef7526e..a60ae4b0cedd95 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cell-actions'] --- import kbnCellActionsObj from './kbn_cell_actions.devdocs.json'; diff --git a/api_docs/kbn_chart_expressions_common.mdx b/api_docs/kbn_chart_expressions_common.mdx index 48046c35959a47..82f2b5d6cd2d2e 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-expressions-common'] --- import kbnChartExpressionsCommonObj from './kbn_chart_expressions_common.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index e782250378ad57..2e5e7e969b6cce 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] --- import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index 2e79dbdedfd6fb..3a28582b701264 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index 39b5cc2616cb66..51d84b58324770 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index 8864be86e08ac8..9b4cc2cba02f25 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index f3a65737a8370f..dfda5993535940 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index 75a478ca85892a..eda7e113728790 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_owners.mdx b/api_docs/kbn_code_owners.mdx index f7fa10cf127791..8f40b76f15167c 100644 --- a/api_docs/kbn_code_owners.mdx +++ b/api_docs/kbn_code_owners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-owners title: "@kbn/code-owners" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-owners plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-owners'] --- import kbnCodeOwnersObj from './kbn_code_owners.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 80f298a4632d14..eea5fdc3b63ae6 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index a0c3690b8183a8..1d61d5261d9509 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index f9cbc02ab134b6..ffee5680dff634 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index 67682b5517ef83..1dd83bb9e91950 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_editor.mdx b/api_docs/kbn_content_management_content_editor.mdx index a8a3928ed28574..7d26d795cc0b6e 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index 078ce66b2ad8cd..c6160456ba0c70 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-tabbed-table-list-view'] --- import kbnContentManagementTabbedTableListViewObj from './kbn_content_management_tabbed_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view.mdx b/api_docs/kbn_content_management_table_list_view.mdx index d3ab52966796de..7a08374bcf7bb8 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_common.mdx b/api_docs/kbn_content_management_table_list_view_common.mdx index 6dd3efe5031de2..13da50f3da458e 100644 --- a/api_docs/kbn_content_management_table_list_view_common.mdx +++ b/api_docs/kbn_content_management_table_list_view_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-common title: "@kbn/content-management-table-list-view-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-common'] --- import kbnContentManagementTableListViewCommonObj from './kbn_content_management_table_list_view_common.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index f3b2fd099d98bb..b734c8d7a18fb8 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-table'] --- import kbnContentManagementTableListViewTableObj from './kbn_content_management_table_list_view_table.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index 5003fe1e610264..548bf253a4c2d7 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-utils'] --- import kbnContentManagementUtilsObj from './kbn_content_management_utils.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 47e8575d7c83b3..646ac64e92f54b 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index e0e55eaf60e05f..a7879e4d3d8b7b 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index 643a0a668358bb..25289bfe400a2e 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index c1ae188448fd26..0f6cb5412babbe 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index 1f94d2b8a7bf39..56784937c528b3 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index ed98cc7b3b552c..f6fb22ca136932 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index f85047d0ffd554..d87a0916ddaadc 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index 49e15ca03242ef..ca7e995b042d6d 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index 9a1ad23e57b1d7..170a694892e354 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index 286d4523c5056d..8ee8a76549cb2f 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index 89be2a9efb8fc3..5b78000d8d91d8 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index 6faa5346f53f8b..31762b4cb59be0 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_apps_server_internal.mdx b/api_docs/kbn_core_apps_server_internal.mdx index 7d96c045c6039d..fb1b3ffddcd96d 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-server-internal'] --- import kbnCoreAppsServerInternalObj from './kbn_core_apps_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index 7a6cc1b5aadb02..7094d688d58daf 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index debc0943aeec7b..08dd066890f323 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index 2f5bae5058eb14..e6b8399a6fb259 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index 1cb44d6ce2e9b7..298111aa0fed3b 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index 705dfbf8070193..dbb476c98bb80d 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index d90dd44ce789a6..ebfa6afcb88ca6 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index 5c78e9036ec1c9..f1e5c2d4985ccf 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index 31a59a220b3a37..4170ccd2b6a611 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index 2a3bb515fe78d2..f0b86d81093881 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index d68114c93573cb..34236f3571dfd2 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index b8c610f43182da..c51fc1b3c8b8f3 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser.mdx b/api_docs/kbn_core_custom_branding_browser.mdx index ec9042f9baa01b..395a13be812fc6 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser'] --- import kbnCoreCustomBrandingBrowserObj from './kbn_core_custom_branding_browser.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_internal.mdx b/api_docs/kbn_core_custom_branding_browser_internal.mdx index 3cc6a0cd5ca122..3567c91b275099 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-internal'] --- import kbnCoreCustomBrandingBrowserInternalObj from './kbn_core_custom_branding_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_mocks.mdx b/api_docs/kbn_core_custom_branding_browser_mocks.mdx index b2c52617efb429..c82dbdfcda4bf8 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-mocks'] --- import kbnCoreCustomBrandingBrowserMocksObj from './kbn_core_custom_branding_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_common.mdx b/api_docs/kbn_core_custom_branding_common.mdx index 337d8d570fe75b..ea3c4459c636eb 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-common'] --- import kbnCoreCustomBrandingCommonObj from './kbn_core_custom_branding_common.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server.mdx b/api_docs/kbn_core_custom_branding_server.mdx index c51f4fd8995025..2936975bb78c65 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server'] --- import kbnCoreCustomBrandingServerObj from './kbn_core_custom_branding_server.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_internal.mdx b/api_docs/kbn_core_custom_branding_server_internal.mdx index fdb486f3a53dbd..a77dedb859eb49 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-internal'] --- import kbnCoreCustomBrandingServerInternalObj from './kbn_core_custom_branding_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_mocks.mdx b/api_docs/kbn_core_custom_branding_server_mocks.mdx index 4f85ec0782b46f..05866c562bb492 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-mocks'] --- import kbnCoreCustomBrandingServerMocksObj from './kbn_core_custom_branding_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index ffca83aec1c32b..630a23a542d7f3 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index b881a26ed525c9..ada0b777ba4f7f 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index abc6fcc53d83a7..4eb744e8a25895 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index 4b22619d5840fc..78c7b425cd391b 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index 2af7281cc8c2a3..cb208e9c0433c8 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index 698a635c845cdf..ecc04327dc53b8 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index f305ae0bb85546..30f5741da71ec9 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index bccaa3af128c66..edebce6161506c 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index 7d925496e3bfab..9b3b9769fd650b 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index 33c7d6131d6ba2..69f2a57657f42b 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index 3f3944abb9137c..d7175588a43e91 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index 472aea784f63bb..9a0d5e597f865e 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index 14730698e90fc4..42854703b4afe1 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index a81aa8800a343f..095a92a32b5c4a 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index 76ef47aa0136c8..f15aee88a3db33 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index f3b0abae643188..d9fe32a1d6138c 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index 34e5ff99c8d5b6..82abcf65127481 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index 49949886351d58..b4b55806818678 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index 94026d46f38ee7..e7ad84e90c8eca 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index 072c559b838181..4a6b4bfed4e517 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index 2d6910df5140db..6a5f735f86a281 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index 70f590ee65a44d..3a7991dbf5f4a4 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index 59f25bb7aa157e..51c751beed4159 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index b2053822cb3526..65cbfab2036ae3 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index f6534ddf932345..4c6a0b6bf4182f 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index 23d3f869bf1132..108457965b7b9c 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index 0830813a4c17b8..b0ce16df032341 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index beaed113982a85..75cc5baef38dea 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index d81b97929f7d73..7787852fd47b0a 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index 8923821b86b348..ba79a9400352ce 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index f8d9c4dda72482..073f3cd3d3d694 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index c1d4d65e6b3bd1..3d2d1b3cf60338 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_request_handler_context_server.mdx b/api_docs/kbn_core_http_request_handler_context_server.mdx index ac23a8f4f8e419..34383de09320bd 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-request-handler-context-server'] --- import kbnCoreHttpRequestHandlerContextServerObj from './kbn_core_http_request_handler_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server.mdx b/api_docs/kbn_core_http_resources_server.mdx index eae57c259bf2bb..bf4a485ef597fa 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server'] --- import kbnCoreHttpResourcesServerObj from './kbn_core_http_resources_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_internal.mdx b/api_docs/kbn_core_http_resources_server_internal.mdx index d856c895d875a2..1baff418e66861 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-internal'] --- import kbnCoreHttpResourcesServerInternalObj from './kbn_core_http_resources_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_mocks.mdx b/api_docs/kbn_core_http_resources_server_mocks.mdx index f8694b0d18e3bb..bf19251f985266 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-mocks'] --- import kbnCoreHttpResourcesServerMocksObj from './kbn_core_http_resources_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index 24950bd8422b31..c75f43c9091a0f 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index d1928d54c4a261..c9ac829505fdcd 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index b098b3a6370de7..efb5ca9a8627d6 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index 5f363498c13285..916f9228d6bcf5 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index a5c97a27bac39b..b0002eac4cde9c 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index 9110ceef27f953..2f480eac369743 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] --- import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index dac6807b165610..3c9c19fbe0ab0c 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] --- import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server.mdx b/api_docs/kbn_core_i18n_server.mdx index 617a6da45d4488..c3efefc42e35b4 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server'] --- import kbnCoreI18nServerObj from './kbn_core_i18n_server.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_internal.mdx b/api_docs/kbn_core_i18n_server_internal.mdx index 826199c29a862b..524fc3c56027ed 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-internal'] --- import kbnCoreI18nServerInternalObj from './kbn_core_i18n_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_mocks.mdx b/api_docs/kbn_core_i18n_server_mocks.mdx index 67411f732c09e8..fd742237c6162a 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-mocks'] --- import kbnCoreI18nServerMocksObj from './kbn_core_i18n_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index 168f4843c6a120..049cf5508ab0ae 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] --- import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx index 2d5d3338babf63..ff3398960d536d 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal'] --- import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx index 959aa8177c7fc8..bb7904f1a7e23e 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks'] --- import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser.devdocs.json b/api_docs/kbn_core_lifecycle_browser.devdocs.json index 9dea3ef5f788f2..f3489db3d9e66e 100644 --- a/api_docs/kbn_core_lifecycle_browser.devdocs.json +++ b/api_docs/kbn_core_lifecycle_browser.devdocs.json @@ -807,8 +807,8 @@ "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", - "section": "def-common.ThemeServiceStart", - "text": "ThemeServiceStart" + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" } ], "path": "packages/core/lifecycle/core-lifecycle-browser/src/core_start.ts", diff --git a/api_docs/kbn_core_lifecycle_browser.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index 01e85923144387..3359ce214df07f 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser'] --- import kbnCoreLifecycleBrowserObj from './kbn_core_lifecycle_browser.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser_mocks.devdocs.json b/api_docs/kbn_core_lifecycle_browser_mocks.devdocs.json index 62c07b0d498b6a..9c0e60e2cd9427 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.devdocs.json +++ b/api_docs/kbn_core_lifecycle_browser_mocks.devdocs.json @@ -233,8 +233,8 @@ "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", - "section": "def-common.ThemeServiceStart", - "text": "ThemeServiceStart" + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" }, ">; fatalErrors: jest.Mocked<", { @@ -478,8 +478,8 @@ "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", - "section": "def-common.ThemeServiceStart", - "text": "ThemeServiceStart" + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" }, ">; fatalErrors: jest.Mocked<", { diff --git a/api_docs/kbn_core_lifecycle_browser_mocks.mdx b/api_docs/kbn_core_lifecycle_browser_mocks.mdx index 1cf75966060d85..92e2cf6d02c50e 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser-mocks'] --- import kbnCoreLifecycleBrowserMocksObj from './kbn_core_lifecycle_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server.mdx b/api_docs/kbn_core_lifecycle_server.mdx index 4e868fc119569f..57f23b61974775 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server'] --- import kbnCoreLifecycleServerObj from './kbn_core_lifecycle_server.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server_mocks.mdx b/api_docs/kbn_core_lifecycle_server_mocks.mdx index 2f240b4a17fb85..427d68cd9ea417 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server-mocks'] --- import kbnCoreLifecycleServerMocksObj from './kbn_core_lifecycle_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_browser_mocks.mdx b/api_docs/kbn_core_logging_browser_mocks.mdx index 2e9297cee4e2c2..7585d0d2c23cc1 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-browser-mocks'] --- import kbnCoreLoggingBrowserMocksObj from './kbn_core_logging_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_common_internal.mdx b/api_docs/kbn_core_logging_common_internal.mdx index 581469cdbe3536..31a4b632509623 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-common-internal'] --- import kbnCoreLoggingCommonInternalObj from './kbn_core_logging_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index 96008363f31a62..c6c149b4a5998d 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] --- import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index a35247cdb1aa4f..3a893ec3a25015 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] --- import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index b88510626306b9..c2898a671ce2e4 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] --- import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx index 14200348b8b207..4a370c82f90980 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal'] --- import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx index e2a8d3af931fb7..3823aebb76ab96 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks'] --- import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx index be61455546c4f3..970d898d0d8c45 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server'] --- import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx index 4bdfa09c0d314b..ef230c858a6473 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal'] --- import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx index c595fa93a7e6a5..0738dc8f8c3dd2 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks'] --- import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx index 2361d996ddfe86..448876b7c2496b 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser'] --- import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json'; diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx index d5d98acccdb4f0..1a2e017640cac2 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server'] --- import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx index 4624e22edb25a4..56aa30dba4c5ea 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal'] --- import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx index 1e4a6590b80667..34fafde085c171 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks'] --- import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index 1c47750f196807..e09fba5618ddf5 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser'] --- import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx index 5538ce7e1b4701..a0349c9b53ed78 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal'] --- import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx index b376982053f612..d3bfa4169e5b16 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks'] --- import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx index 04569facbcbe7c..d4fb8e133a88ba 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser'] --- import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx index 1239c10d3978b9..e881c62aacd1c2 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal'] --- import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx index 842beedeb19942..8f16e6f81448d8 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks'] --- import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser.mdx b/api_docs/kbn_core_plugins_browser.mdx index 08b2603bbc73a3..4b0c81a1c50461 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser'] --- import kbnCorePluginsBrowserObj from './kbn_core_plugins_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser_mocks.mdx b/api_docs/kbn_core_plugins_browser_mocks.mdx index 372b522eb341b5..8c0dd9c9fe836a 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_contracts_browser.mdx b/api_docs/kbn_core_plugins_contracts_browser.mdx index 4a65561a81a389..6dc965a446f0c6 100644 --- a/api_docs/kbn_core_plugins_contracts_browser.mdx +++ b/api_docs/kbn_core_plugins_contracts_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-browser title: "@kbn/core-plugins-contracts-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-contracts-browser'] --- import kbnCorePluginsContractsBrowserObj from './kbn_core_plugins_contracts_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_contracts_server.mdx b/api_docs/kbn_core_plugins_contracts_server.mdx index 034a346b6d3542..1681c5f47a9b1a 100644 --- a/api_docs/kbn_core_plugins_contracts_server.mdx +++ b/api_docs/kbn_core_plugins_contracts_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-server title: "@kbn/core-plugins-contracts-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-contracts-server'] --- import kbnCorePluginsContractsServerObj from './kbn_core_plugins_contracts_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index 815fa4e7b7670e..0d978818515f9e 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server'] --- import kbnCorePluginsServerObj from './kbn_core_plugins_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server_mocks.mdx b/api_docs/kbn_core_plugins_server_mocks.mdx index 3016f85fc33148..9064da09b36292 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server-mocks'] --- import kbnCorePluginsServerMocksObj from './kbn_core_plugins_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index 56d82e2e0de9e2..7f88a8586bbb4c 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server'] --- import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx index 819fa334184ea2..71706e6fcfbeb6 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index 8a3b2b4f5550b0..e7ff92d28e49b6 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-browser-mocks'] --- import kbnCoreRenderingBrowserMocksObj from './kbn_core_rendering_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_internal.mdx b/api_docs/kbn_core_rendering_server_internal.mdx index f9964d0ee0815a..3babef55d3712f 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-internal'] --- import kbnCoreRenderingServerInternalObj from './kbn_core_rendering_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_mocks.mdx b/api_docs/kbn_core_rendering_server_mocks.mdx index b1e39adff34729..3de72e8ff41189 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-mocks'] --- import kbnCoreRenderingServerMocksObj from './kbn_core_rendering_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_root_server_internal.mdx b/api_docs/kbn_core_root_server_internal.mdx index 947e5d3c349005..d315bee07fc0bc 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-root-server-internal'] --- import kbnCoreRootServerInternalObj from './kbn_core_root_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index 7c7f7370b45837..99238dd4fd2a20 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index 6373b694a6a6c7..2f8b013711db75 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx index e8202b1e9bb87c..62b278170c193f 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-mocks'] --- import kbnCoreSavedObjectsApiServerMocksObj from './kbn_core_saved_objects_api_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.mdx b/api_docs/kbn_core_saved_objects_base_server_internal.mdx index ca5d32d718b8b3..4747c7f8fc142a 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-internal'] --- import kbnCoreSavedObjectsBaseServerInternalObj from './kbn_core_saved_objects_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx index 288216bae9032b..ae394f1cf33279 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-mocks'] --- import kbnCoreSavedObjectsBaseServerMocksObj from './kbn_core_saved_objects_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx index eb82fe8ff1683b..8f9a96801704eb 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser'] --- import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx index 55e760b442b36e..ff35430ad0409a 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal'] --- import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index 281f642c8275c6..74942dc0b4db56 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index 999cf237879941..d91a51016a033a 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common'] --- import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx index 2e1da87c202b4d..237e39632690b3 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-internal'] --- import kbnCoreSavedObjectsImportExportServerInternalObj from './kbn_core_saved_objects_import_export_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx index b4b0d55d1e868e..8cefa52d203b0d 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-mocks'] --- import kbnCoreSavedObjectsImportExportServerMocksObj from './kbn_core_saved_objects_import_export_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx index 5f1100e945c00e..82f4839ece5eb6 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-internal'] --- import kbnCoreSavedObjectsMigrationServerInternalObj from './kbn_core_saved_objects_migration_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx index d85aa3a4b97ec1..b43e84a8491a28 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-mocks'] --- import kbnCoreSavedObjectsMigrationServerMocksObj from './kbn_core_saved_objects_migration_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index 74fd1b9b6d5ec3..4e47164ec80c00 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server'] --- import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_internal.mdx b/api_docs/kbn_core_saved_objects_server_internal.mdx index 5e25cde7941e85..061fa4404deea8 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-internal'] --- import kbnCoreSavedObjectsServerInternalObj from './kbn_core_saved_objects_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_mocks.mdx b/api_docs/kbn_core_saved_objects_server_mocks.mdx index e87796cd6e71aa..1f39a2340d61cf 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-mocks'] --- import kbnCoreSavedObjectsServerMocksObj from './kbn_core_saved_objects_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_utils_server.mdx b/api_docs/kbn_core_saved_objects_utils_server.mdx index be41a13834cf09..6af81fdd637112 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index fac78d294c1d5b..0be162fcd23650 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common'] --- import kbnCoreStatusCommonObj from './kbn_core_status_common.devdocs.json'; diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index 44c611d6ce25a7..44e10756806e4b 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index d0252260f1317a..aa3e08fc99c666 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server'] --- import kbnCoreStatusServerObj from './kbn_core_status_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_internal.mdx b/api_docs/kbn_core_status_server_internal.mdx index e1c22722c55a9a..d129c2e9699e18 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-internal'] --- import kbnCoreStatusServerInternalObj from './kbn_core_status_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_mocks.mdx b/api_docs/kbn_core_status_server_mocks.mdx index 6d5d58ba2ea8d1..a4156eb3580d26 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-mocks'] --- import kbnCoreStatusServerMocksObj from './kbn_core_status_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx index 1d5f488286f360..dfd0ff5f563f33 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters'] --- import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx index cc3818fb4532b1..15efb3c0dfb0e9 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser'] --- import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_kbn_server.mdx b/api_docs/kbn_core_test_helpers_kbn_server.mdx index 27eb99418587ee..8a2bd0d4eef0ce 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_model_versions.mdx b/api_docs/kbn_core_test_helpers_model_versions.mdx index b3ff61e31f38c9..903efb2d211607 100644 --- a/api_docs/kbn_core_test_helpers_model_versions.mdx +++ b/api_docs/kbn_core_test_helpers_model_versions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-model-versions title: "@kbn/core-test-helpers-model-versions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-model-versions plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-model-versions'] --- import kbnCoreTestHelpersModelVersionsObj from './kbn_core_test_helpers_model_versions.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index 6a2cb3129381f5..5272b17ba6b546 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-so-type-serializer'] --- import kbnCoreTestHelpersSoTypeSerializerObj from './kbn_core_test_helpers_so_type_serializer.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_test_utils.mdx b/api_docs/kbn_core_test_helpers_test_utils.mdx index 1da3f33db73417..ae85352065c884 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-test-utils'] --- import kbnCoreTestHelpersTestUtilsObj from './kbn_core_test_helpers_test_utils.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser.devdocs.json b/api_docs/kbn_core_theme_browser.devdocs.json index 5df9c41bed591b..0986187fd6c1a0 100644 --- a/api_docs/kbn_core_theme_browser.devdocs.json +++ b/api_docs/kbn_core_theme_browser.devdocs.json @@ -66,7 +66,9 @@ "type": "Object", "tags": [], "label": "theme$", - "description": [], + "description": [ + "\nAn observable of the currently active theme.\nNote that the observable has a replay effect, so it will emit once during subscriptions." + ], "signature": [ "Observable", "<", @@ -82,50 +84,60 @@ "path": "packages/core/theme/core-theme-browser/src/types.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/core-theme-browser", - "id": "def-common.ThemeServiceStart", - "type": "Interface", - "tags": [], - "label": "ThemeServiceStart", - "description": [], - "path": "packages/core/theme/core-theme-browser/src/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ + }, { "parentPluginId": "@kbn/core-theme-browser", - "id": "def-common.ThemeServiceStart.theme$", - "type": "Object", + "id": "def-common.ThemeServiceSetup.getTheme", + "type": "Function", "tags": [], - "label": "theme$", - "description": [], + "label": "getTheme", + "description": [ + "\nReturns the theme currently in use.\nNote that when possible, using the `theme$` observable instead is strongly encouraged, as\nit will allow to react to dynamic theme switch (even if those are not implemented at the moment)" + ], "signature": [ - "Observable", - "<", + "() => ", { "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", "section": "def-common.CoreTheme", "text": "CoreTheme" - }, - ">" + } ], "path": "packages/core/theme/core-theme-browser/src/types.ts", "deprecated": false, - "trackAdoption": false + "trackAdoption": false, + "children": [], + "returnComment": [] } ], "initialIsOpen": false } ], "enums": [], - "misc": [], + "misc": [ + { + "parentPluginId": "@kbn/core-theme-browser", + "id": "def-common.ThemeServiceStart", + "type": "Type", + "tags": [], + "label": "ThemeServiceStart", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-theme-browser", + "scope": "common", + "docId": "kibKbnCoreThemeBrowserPluginApi", + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" + } + ], + "path": "packages/core/theme/core-theme-browser/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], "objects": [] } } \ No newline at end of file diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index 2314addf03f478..c403fd047b5c98 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; @@ -21,10 +21,13 @@ Contact [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 6 | 0 | 4 | 0 | +| 6 | 0 | 2 | 0 | ## Common ### Interfaces +### Consts, variables and types + + diff --git a/api_docs/kbn_core_theme_browser_mocks.devdocs.json b/api_docs/kbn_core_theme_browser_mocks.devdocs.json index 016a004c920b2c..fff0ee16833a25 100644 --- a/api_docs/kbn_core_theme_browser_mocks.devdocs.json +++ b/api_docs/kbn_core_theme_browser_mocks.devdocs.json @@ -58,7 +58,15 @@ "label": "createSetupContract", "description": [], "signature": [ - "() => jest.Mocked<", + "(theme?: ", + { + "pluginId": "@kbn/core-theme-browser", + "scope": "common", + "docId": "kibKbnCoreThemeBrowserPluginApi", + "section": "def-common.CoreTheme", + "text": "CoreTheme" + }, + ") => jest.Mocked<", { "pluginId": "@kbn/core-theme-browser", "scope": "common", @@ -72,7 +80,28 @@ "deprecated": false, "trackAdoption": false, "returnComment": [], - "children": [] + "children": [ + { + "parentPluginId": "@kbn/core-theme-browser-mocks", + "id": "def-common.themeServiceMock.createSetupContract.$1", + "type": "Object", + "tags": [], + "label": "theme", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-theme-browser", + "scope": "common", + "docId": "kibKbnCoreThemeBrowserPluginApi", + "section": "def-common.CoreTheme", + "text": "CoreTheme" + } + ], + "path": "packages/core/theme/core-theme-browser-mocks/src/theme_service.mock.ts", + "deprecated": false, + "trackAdoption": false + } + ] }, { "parentPluginId": "@kbn/core-theme-browser-mocks", @@ -82,13 +111,21 @@ "label": "createStartContract", "description": [], "signature": [ - "() => jest.Mocked<", + "(theme?: ", { "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", - "section": "def-common.ThemeServiceStart", - "text": "ThemeServiceStart" + "section": "def-common.CoreTheme", + "text": "CoreTheme" + }, + ") => jest.Mocked<", + { + "pluginId": "@kbn/core-theme-browser", + "scope": "common", + "docId": "kibKbnCoreThemeBrowserPluginApi", + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" }, ">" ], @@ -96,7 +133,28 @@ "deprecated": false, "trackAdoption": false, "returnComment": [], - "children": [] + "children": [ + { + "parentPluginId": "@kbn/core-theme-browser-mocks", + "id": "def-common.themeServiceMock.createStartContract.$1", + "type": "Object", + "tags": [], + "label": "theme", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-theme-browser", + "scope": "common", + "docId": "kibKbnCoreThemeBrowserPluginApi", + "section": "def-common.CoreTheme", + "text": "CoreTheme" + } + ], + "path": "packages/core/theme/core-theme-browser-mocks/src/theme_service.mock.ts", + "deprecated": false, + "trackAdoption": false + } + ] }, { "parentPluginId": "@kbn/core-theme-browser-mocks", @@ -129,7 +187,15 @@ "label": "createTheme$", "description": [], "signature": [ - "() => ", + "(theme?: ", + { + "pluginId": "@kbn/core-theme-browser", + "scope": "common", + "docId": "kibKbnCoreThemeBrowserPluginApi", + "section": "def-common.CoreTheme", + "text": "CoreTheme" + }, + ") => ", "Observable", "<", { @@ -145,7 +211,28 @@ "deprecated": false, "trackAdoption": false, "returnComment": [], - "children": [] + "children": [ + { + "parentPluginId": "@kbn/core-theme-browser-mocks", + "id": "def-common.themeServiceMock.createTheme$.$1", + "type": "Object", + "tags": [], + "label": "theme", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-theme-browser", + "scope": "common", + "docId": "kibKbnCoreThemeBrowserPluginApi", + "section": "def-common.CoreTheme", + "text": "CoreTheme" + } + ], + "path": "packages/core/theme/core-theme-browser-mocks/src/theme_service.mock.ts", + "deprecated": false, + "trackAdoption": false + } + ] } ], "initialIsOpen": false diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index c77212f34cc23e..de950736bfaff9 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] --- import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 6 | 0 | 6 | 0 | +| 9 | 0 | 9 | 0 | ## Common diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx index 9377e25bca8533..4f1d61590ae6a4 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser'] --- import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx index 01a53dbd7824e5..231f464db3db20 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal'] --- import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx index 6e60ab9cc92a12..3cf1536c2d9cdc 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks'] --- import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx index e03f0506fc95db..edaaacb4887dff 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common'] --- import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server.mdx b/api_docs/kbn_core_ui_settings_server.mdx index 5e188dd30ba4af..4ba5a4f944dd70 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server'] --- import kbnCoreUiSettingsServerObj from './kbn_core_ui_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_internal.mdx b/api_docs/kbn_core_ui_settings_server_internal.mdx index f2275a15870c1d..f0fad67938c8d6 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-internal'] --- import kbnCoreUiSettingsServerInternalObj from './kbn_core_ui_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_mocks.mdx b/api_docs/kbn_core_ui_settings_server_mocks.mdx index 405235278cf431..ac2b99490fca4f 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-mocks'] --- import kbnCoreUiSettingsServerMocksObj from './kbn_core_ui_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server.mdx b/api_docs/kbn_core_usage_data_server.mdx index 670019d88384e4..657d10ba32d61c 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server'] --- import kbnCoreUsageDataServerObj from './kbn_core_usage_data_server.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_internal.mdx b/api_docs/kbn_core_usage_data_server_internal.mdx index 32738d7554817c..dacb1a60213fd0 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-internal'] --- import kbnCoreUsageDataServerInternalObj from './kbn_core_usage_data_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_mocks.mdx b/api_docs/kbn_core_usage_data_server_mocks.mdx index a49b7080fd4413..c5c5a1863251a5 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index ea835caf267f05..9e0664a60a6b9e 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server'] --- import kbnCoreUserSettingsServerObj from './kbn_core_user_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_internal.mdx b/api_docs/kbn_core_user_settings_server_internal.mdx index 149f43efb4bffd..fbd7b533a17af4 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-internal'] --- import kbnCoreUserSettingsServerInternalObj from './kbn_core_user_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index ad0bbdb8ac59f2..82fde9834b40d8 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-mocks'] --- import kbnCoreUserSettingsServerMocksObj from './kbn_core_user_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index ed1d6b7ec9b201..832838b23cd60d 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] --- import kbnCryptoObj from './kbn_crypto.devdocs.json'; diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx index fc750253f1aaf4..32487c868527a2 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_custom_icons.mdx b/api_docs/kbn_custom_icons.mdx index 7e1b3b8b287c3d..2094394427370f 100644 --- a/api_docs/kbn_custom_icons.mdx +++ b/api_docs/kbn_custom_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-custom-icons title: "@kbn/custom-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/custom-icons plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/custom-icons'] --- import kbnCustomIconsObj from './kbn_custom_icons.devdocs.json'; diff --git a/api_docs/kbn_custom_integrations.mdx b/api_docs/kbn_custom_integrations.mdx index 53c0b5b8b26da6..fdc7d2b471a532 100644 --- a/api_docs/kbn_custom_integrations.mdx +++ b/api_docs/kbn_custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-custom-integrations title: "@kbn/custom-integrations" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/custom-integrations plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/custom-integrations'] --- import kbnCustomIntegrationsObj from './kbn_custom_integrations.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index 89188e54358267..a7a7b42edc5fe3 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index f6629261e90ca7..6851c44cd8d3ae 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index e734d920e375f1..168dac22f1c78c 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_analytics.mdx b/api_docs/kbn_deeplinks_analytics.mdx index 481a498ab4abb3..e93f9eb98e7d03 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-analytics'] --- import kbnDeeplinksAnalyticsObj from './kbn_deeplinks_analytics.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_devtools.mdx b/api_docs/kbn_deeplinks_devtools.mdx index 6714fd2602cb55..dcbb1e7e72b1ef 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index 321247d98dbd39..855973318b3bf0 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-management'] --- import kbnDeeplinksManagementObj from './kbn_deeplinks_management.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_ml.mdx b/api_docs/kbn_deeplinks_ml.mdx index fa4a891d8264f4..0dbf258601435d 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-ml'] --- import kbnDeeplinksMlObj from './kbn_deeplinks_ml.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_observability.mdx b/api_docs/kbn_deeplinks_observability.mdx index 76023dbad7e3eb..18e70293bd50a0 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-observability'] --- import kbnDeeplinksObservabilityObj from './kbn_deeplinks_observability.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_search.mdx b/api_docs/kbn_deeplinks_search.mdx index 759b2b92bf63a0..a9a7f53acc3157 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index fc4ccb1dbcc9e1..d3f6dd79f3df17 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-analytics'] --- import kbnDefaultNavAnalyticsObj from './kbn_default_nav_analytics.devdocs.json'; diff --git a/api_docs/kbn_default_nav_devtools.mdx b/api_docs/kbn_default_nav_devtools.mdx index ba3b5a9b78f4dd..90300109368ca3 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-devtools'] --- import kbnDefaultNavDevtoolsObj from './kbn_default_nav_devtools.devdocs.json'; diff --git a/api_docs/kbn_default_nav_management.mdx b/api_docs/kbn_default_nav_management.mdx index 08cdbe2a685718..e687ca4a1b4c5e 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-management'] --- import kbnDefaultNavManagementObj from './kbn_default_nav_management.devdocs.json'; diff --git a/api_docs/kbn_default_nav_ml.mdx b/api_docs/kbn_default_nav_ml.mdx index 6a1552f850131b..0542a938ccff96 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-ml'] --- import kbnDefaultNavMlObj from './kbn_default_nav_ml.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index b520779371260a..80cafa7dbbd6d2 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] --- import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index 1c85d879f5bb01..c9838a7a6fa4ce 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] --- import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index 7797b8ab752f15..5ecdf8cb813a1d 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] --- import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index e3318838305239..da8379cb1b7b37 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_discover_utils.mdx b/api_docs/kbn_discover_utils.mdx index 12cb482ab3f17c..6568e506746079 100644 --- a/api_docs/kbn_discover_utils.mdx +++ b/api_docs/kbn_discover_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-discover-utils title: "@kbn/discover-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/discover-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/discover-utils'] --- import kbnDiscoverUtilsObj from './kbn_discover_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.devdocs.json b/api_docs/kbn_doc_links.devdocs.json index 0120336a220ea8..6db8a4679d6ce0 100644 --- a/api_docs/kbn_doc_links.devdocs.json +++ b/api_docs/kbn_doc_links.devdocs.json @@ -644,7 +644,7 @@ "label": "apis", "description": [], "signature": [ - "{ readonly bulkIndexAlias: string; readonly indexStats: string; readonly byteSizeUnits: string; readonly createAutoFollowPattern: string; readonly createFollower: string; readonly createIndex: string; readonly createSnapshotLifecyclePolicy: string; readonly createRoleMapping: string; readonly createRoleMappingTemplates: string; readonly createRollupJobsRequest: string; readonly createApiKey: string; readonly createPipeline: string; readonly createTransformRequest: string; readonly cronExpressions: string; readonly executeWatchActionModes: string; readonly indexExists: string; readonly multiSearch: string; readonly openIndex: string; readonly putComponentTemplate: string; readonly painlessExecute: string; readonly painlessExecuteAPIContexts: string; readonly putComponentTemplateMetadata: string; readonly putSnapshotLifecyclePolicy: string; readonly putIndexTemplateV1: string; readonly putWatch: string; readonly restApis: string; readonly searchPreference: string; readonly securityApis: string; readonly simulatePipeline: string; readonly tasks: string; readonly timeUnits: string; readonly unfreezeIndex: string; readonly updateTransform: string; }" + "{ readonly bulkIndexAlias: string; readonly indexStats: string; readonly byteSizeUnits: string; readonly createAutoFollowPattern: string; readonly createFollower: string; readonly createIndex: string; readonly createSnapshotLifecyclePolicy: string; readonly createRoleMapping: string; readonly createRoleMappingTemplates: string; readonly createRollupJobsRequest: string; readonly createApiKey: string; readonly createPipeline: string; readonly createTransformRequest: string; readonly cronExpressions: string; readonly executeWatchActionModes: string; readonly indexExists: string; readonly inferTrainedModel: string; readonly multiSearch: string; readonly openIndex: string; readonly putComponentTemplate: string; readonly painlessExecute: string; readonly painlessExecuteAPIContexts: string; readonly putComponentTemplateMetadata: string; readonly putSnapshotLifecyclePolicy: string; readonly putIndexTemplateV1: string; readonly putWatch: string; readonly restApis: string; readonly searchPreference: string; readonly securityApis: string; readonly simulatePipeline: string; readonly tasks: string; readonly timeUnits: string; readonly unfreezeIndex: string; readonly updateTransform: string; }" ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false, diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 804d5929c2d42b..3774d8c765fe26 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index 6f2e9e99e0b01e..840cc94a4c2d05 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_dom_drag_drop.mdx b/api_docs/kbn_dom_drag_drop.mdx index 7a7f728b54a282..91490fd580eb9b 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dom-drag-drop'] --- import kbnDomDragDropObj from './kbn_dom_drag_drop.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index 9826ad9790f465..6bb9f301e847ed 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs.mdx b/api_docs/kbn_ecs.mdx index 0e07f4b5e1639b..2f466de40d4464 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 38c474ed3963c0..848e461f325c00 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_agent_utils.mdx b/api_docs/kbn_elastic_agent_utils.mdx index 255169e7b3e964..1c109848d555df 100644 --- a/api_docs/kbn_elastic_agent_utils.mdx +++ b/api_docs/kbn_elastic_agent_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-agent-utils title: "@kbn/elastic-agent-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-agent-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-agent-utils'] --- import kbnElasticAgentUtilsObj from './kbn_elastic_agent_utils.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index 471b2f2e1d41b6..ece431c0f2d58c 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant_common.mdx b/api_docs/kbn_elastic_assistant_common.mdx index 598b1f66f7c66a..a95c465a0d7605 100644 --- a/api_docs/kbn_elastic_assistant_common.mdx +++ b/api_docs/kbn_elastic_assistant_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant-common title: "@kbn/elastic-assistant-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant-common'] --- import kbnElasticAssistantCommonObj from './kbn_elastic_assistant_common.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 4afb3cd6365b88..78bc34211c6489 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es'] --- import kbnEsObj from './kbn_es.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index 8161fd4de58c52..da64a933321d3c 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] --- import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json'; diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx index a9d715cdf33748..1052a1a5c7e4e8 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors'] --- import kbnEsErrorsObj from './kbn_es_errors.devdocs.json'; diff --git a/api_docs/kbn_es_query.devdocs.json b/api_docs/kbn_es_query.devdocs.json index 60ee58badf7ceb..f8c36e7dbc2b17 100644 --- a/api_docs/kbn_es_query.devdocs.json +++ b/api_docs/kbn_es_query.devdocs.json @@ -5405,6 +5405,20 @@ "deprecated": false, "trackAdoption": false, "children": [ + { + "parentPluginId": "@kbn/es-query", + "id": "def-common.ExecutionContextSearch.now", + "type": "number", + "tags": [], + "label": "now", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/kbn-es-query/src/expressions/types.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "@kbn/es-query", "id": "def-common.ExecutionContextSearch.filters", diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index bc8a3db90c8eaa..7a560bdee78632 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 266 | 1 | 206 | 15 | +| 267 | 1 | 207 | 15 | ## Common diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index d9654bacd4b937..442cd2ca9b2975 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] --- import kbnEsTypesObj from './kbn_es_types.devdocs.json'; diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index 643a6c7091f598..a6fcc77473dca8 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index 56e39d86973cd4..d25b7bef1befa6 100644 --- a/api_docs/kbn_event_annotation_common.mdx +++ b/api_docs/kbn_event_annotation_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-common title: "@kbn/event-annotation-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-common'] --- import kbnEventAnnotationCommonObj from './kbn_event_annotation_common.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_components.mdx b/api_docs/kbn_event_annotation_components.mdx index 4563355191be4c..7a32fcc4327fdf 100644 --- a/api_docs/kbn_event_annotation_components.mdx +++ b/api_docs/kbn_event_annotation_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-components title: "@kbn/event-annotation-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-components plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-components'] --- import kbnEventAnnotationComponentsObj from './kbn_event_annotation_components.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index e74d01f85b3dbb..42a76bc1e64e73 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/expandable-flyout'] --- import kbnExpandableFlyoutObj from './kbn_expandable_flyout.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index 094eb66a2d12c3..de2220fb4f7554 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_field_utils.mdx b/api_docs/kbn_field_utils.mdx index 99bcb0504e83aa..433dd6f2d93d2c 100644 --- a/api_docs/kbn_field_utils.mdx +++ b/api_docs/kbn_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-utils title: "@kbn/field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-utils'] --- import kbnFieldUtilsObj from './kbn_field_utils.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 750922c91ce4c4..accdfc8e7091f4 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index ab3dbe081ea1c1..b14b6e2ff39d24 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_ui_services.mdx b/api_docs/kbn_ftr_common_functional_ui_services.mdx index ddd5dd02a4b459..b1dda159d95555 100644 --- a/api_docs/kbn_ftr_common_functional_ui_services.mdx +++ b/api_docs/kbn_ftr_common_functional_ui_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-ui-services title: "@kbn/ftr-common-functional-ui-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-ui-services plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-ui-services'] --- import kbnFtrCommonFunctionalUiServicesObj from './kbn_ftr_common_functional_ui_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index a6ddea7c9f3f52..ef0c710ee84237 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_generate_console_definitions.mdx b/api_docs/kbn_generate_console_definitions.mdx index 707af0569dc8cc..b1336050fd6b54 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-console-definitions'] --- import kbnGenerateConsoleDefinitionsObj from './kbn_generate_console_definitions.devdocs.json'; diff --git a/api_docs/kbn_generate_csv.mdx b/api_docs/kbn_generate_csv.mdx index 1f6d69bf32d87a..19bc6d526e10fb 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 5c56eb1d7bcee1..2730ec77cb851d 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/guided-onboarding'] --- import kbnGuidedOnboardingObj from './kbn_guided_onboarding.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index 0dfb572f2a3ebc..582082df34a82c 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index 1af65e34b65dfd..e7d10d60558700 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_health_gateway_server.mdx b/api_docs/kbn_health_gateway_server.mdx index 8eec5c23269fce..ef80f3ee46dc50 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/health-gateway-server'] --- import kbnHealthGatewayServerObj from './kbn_health_gateway_server.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index de0cfb3103d9df..3c12656bb148a0 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index cb585056dac1fc..c0ac5fba635db8 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index 27a1db78d70221..658352b079658a 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_i18n_react.mdx b/api_docs/kbn_i18n_react.mdx index 8bf4b62c49c273..8e6eb9761b126a 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n-react'] --- import kbnI18nReactObj from './kbn_i18n_react.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index f3a990652d5e45..2f50f11de3f440 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index 32748299fda9c8..80d0a8339770b2 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/infra-forge'] --- import kbnInfraForgeObj from './kbn_infra_forge.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index 879922e9153890..8a2fd89d07a8ac 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index a84c759b48ac6c..c500d50f9970ea 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 5974f9bac82317..f3ed34ef974f1e 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_journeys.mdx b/api_docs/kbn_journeys.mdx index a26e26c22622ad..8ca3b4cc686b15 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/journeys'] --- import kbnJourneysObj from './kbn_journeys.devdocs.json'; diff --git a/api_docs/kbn_json_ast.mdx b/api_docs/kbn_json_ast.mdx index d42b61c393e205..14175629d0de0c 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index cc4940d02ea80b..3de7135caca517 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index 61d980daa5ab22..e2934600310047 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_lens_embeddable_utils.mdx b/api_docs/kbn_lens_embeddable_utils.mdx index cd34b3605e8944..c328a9523f7fed 100644 --- a/api_docs/kbn_lens_embeddable_utils.mdx +++ b/api_docs/kbn_lens_embeddable_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-lens-embeddable-utils title: "@kbn/lens-embeddable-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/lens-embeddable-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/lens-embeddable-utils'] --- import kbnLensEmbeddableUtilsObj from './kbn_lens_embeddable_utils.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 4d39edf82167bb..d67369e99fb757 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index 9e59b4eaa45443..2deb751440b949 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index a415806e2b6249..db808a83e1293b 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_management_cards_navigation.mdx b/api_docs/kbn_management_cards_navigation.mdx index 8ff85097e9b629..cf8d4712ab857c 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_settings_application.mdx b/api_docs/kbn_management_settings_application.mdx index 60ac8fdc3af92a..025e2e2ac4ace6 100644 --- a/api_docs/kbn_management_settings_application.mdx +++ b/api_docs/kbn_management_settings_application.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-application title: "@kbn/management-settings-application" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-application plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-application'] --- import kbnManagementSettingsApplicationObj from './kbn_management_settings_application.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_category.mdx b/api_docs/kbn_management_settings_components_field_category.mdx index e2ef4ba7748134..9d66ef487abdf8 100644 --- a/api_docs/kbn_management_settings_components_field_category.mdx +++ b/api_docs/kbn_management_settings_components_field_category.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-category title: "@kbn/management-settings-components-field-category" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-category plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-category'] --- import kbnManagementSettingsComponentsFieldCategoryObj from './kbn_management_settings_components_field_category.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_input.mdx b/api_docs/kbn_management_settings_components_field_input.mdx index 9cbeb04b5d4507..e27fb8fde6adce 100644 --- a/api_docs/kbn_management_settings_components_field_input.mdx +++ b/api_docs/kbn_management_settings_components_field_input.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-input title: "@kbn/management-settings-components-field-input" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-input plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-input'] --- import kbnManagementSettingsComponentsFieldInputObj from './kbn_management_settings_components_field_input.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_row.mdx b/api_docs/kbn_management_settings_components_field_row.mdx index a8359188b8cb30..2587916d3eca32 100644 --- a/api_docs/kbn_management_settings_components_field_row.mdx +++ b/api_docs/kbn_management_settings_components_field_row.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-row title: "@kbn/management-settings-components-field-row" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-row plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-row'] --- import kbnManagementSettingsComponentsFieldRowObj from './kbn_management_settings_components_field_row.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_form.mdx b/api_docs/kbn_management_settings_components_form.mdx index e911f3598e4a32..e2e351e44a7aa2 100644 --- a/api_docs/kbn_management_settings_components_form.mdx +++ b/api_docs/kbn_management_settings_components_form.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-form title: "@kbn/management-settings-components-form" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-form plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-form'] --- import kbnManagementSettingsComponentsFormObj from './kbn_management_settings_components_form.devdocs.json'; diff --git a/api_docs/kbn_management_settings_field_definition.mdx b/api_docs/kbn_management_settings_field_definition.mdx index 224c22d8ba3043..03888667463b6d 100644 --- a/api_docs/kbn_management_settings_field_definition.mdx +++ b/api_docs/kbn_management_settings_field_definition.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-field-definition title: "@kbn/management-settings-field-definition" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-field-definition plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-field-definition'] --- import kbnManagementSettingsFieldDefinitionObj from './kbn_management_settings_field_definition.devdocs.json'; diff --git a/api_docs/kbn_management_settings_ids.mdx b/api_docs/kbn_management_settings_ids.mdx index 79f89734866b60..84a9ff0460b601 100644 --- a/api_docs/kbn_management_settings_ids.mdx +++ b/api_docs/kbn_management_settings_ids.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-ids title: "@kbn/management-settings-ids" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-ids plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-ids'] --- import kbnManagementSettingsIdsObj from './kbn_management_settings_ids.devdocs.json'; diff --git a/api_docs/kbn_management_settings_section_registry.mdx b/api_docs/kbn_management_settings_section_registry.mdx index 516894009b7111..7de2c8af8f74a2 100644 --- a/api_docs/kbn_management_settings_section_registry.mdx +++ b/api_docs/kbn_management_settings_section_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-section-registry title: "@kbn/management-settings-section-registry" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-section-registry plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-section-registry'] --- import kbnManagementSettingsSectionRegistryObj from './kbn_management_settings_section_registry.devdocs.json'; diff --git a/api_docs/kbn_management_settings_types.mdx b/api_docs/kbn_management_settings_types.mdx index a790b4a305bef1..581101683f9d98 100644 --- a/api_docs/kbn_management_settings_types.mdx +++ b/api_docs/kbn_management_settings_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-types title: "@kbn/management-settings-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-types plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-types'] --- import kbnManagementSettingsTypesObj from './kbn_management_settings_types.devdocs.json'; diff --git a/api_docs/kbn_management_settings_utilities.mdx b/api_docs/kbn_management_settings_utilities.mdx index f5e4a2148d8228..6f45cd582b1daf 100644 --- a/api_docs/kbn_management_settings_utilities.mdx +++ b/api_docs/kbn_management_settings_utilities.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-utilities title: "@kbn/management-settings-utilities" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-utilities plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-utilities'] --- import kbnManagementSettingsUtilitiesObj from './kbn_management_settings_utilities.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index 0c4d38b67b5eab..c0a82642b3e97b 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] --- import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index d2a931b730d5e4..b87a7f92012cb6 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_maps_vector_tile_utils.mdx b/api_docs/kbn_maps_vector_tile_utils.mdx index 953b186f4766d1..7e6eeabac50418 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/maps-vector-tile-utils'] --- import kbnMapsVectorTileUtilsObj from './kbn_maps_vector_tile_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index f44fe6ad4d1aa7..eca8ce4c0ed5e0 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_anomaly_utils.mdx b/api_docs/kbn_ml_anomaly_utils.mdx index 059033e032f94c..e52b8338d53550 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_category_validator.mdx b/api_docs/kbn_ml_category_validator.mdx index 60892c79dc3c12..96a8c10ce1221e 100644 --- a/api_docs/kbn_ml_category_validator.mdx +++ b/api_docs/kbn_ml_category_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-category-validator title: "@kbn/ml-category-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-category-validator plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-category-validator'] --- import kbnMlCategoryValidatorObj from './kbn_ml_category_validator.devdocs.json'; diff --git a/api_docs/kbn_ml_chi2test.mdx b/api_docs/kbn_ml_chi2test.mdx index a13bbfd0ef9908..4d8fe635e1206e 100644 --- a/api_docs/kbn_ml_chi2test.mdx +++ b/api_docs/kbn_ml_chi2test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-chi2test title: "@kbn/ml-chi2test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-chi2test plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-chi2test'] --- import kbnMlChi2testObj from './kbn_ml_chi2test.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index 92d9facafe82d5..1ac479cc9ad0c6 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-frame-analytics-utils'] --- import kbnMlDataFrameAnalyticsUtilsObj from './kbn_ml_data_frame_analytics_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_grid.mdx b/api_docs/kbn_ml_data_grid.mdx index 43d8172c0b13db..eb54b16550b286 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-grid'] --- import kbnMlDataGridObj from './kbn_ml_data_grid.devdocs.json'; diff --git a/api_docs/kbn_ml_date_picker.devdocs.json b/api_docs/kbn_ml_date_picker.devdocs.json index 333b007030ad41..fbe34158d29dfa 100644 --- a/api_docs/kbn_ml_date_picker.devdocs.json +++ b/api_docs/kbn_ml_date_picker.devdocs.json @@ -476,8 +476,8 @@ "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", - "section": "def-common.ThemeServiceStart", - "text": "ThemeServiceStart" + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" } ], "path": "x-pack/packages/ml/date_picker/src/hooks/use_date_picker_context.tsx", diff --git a/api_docs/kbn_ml_date_picker.mdx b/api_docs/kbn_ml_date_picker.mdx index d88c6395d4c16a..4b38a91390f3e7 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-picker'] --- import kbnMlDatePickerObj from './kbn_ml_date_picker.devdocs.json'; diff --git a/api_docs/kbn_ml_date_utils.mdx b/api_docs/kbn_ml_date_utils.mdx index efea2c91a3da70..c4e3ad459a8b62 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-utils'] --- import kbnMlDateUtilsObj from './kbn_ml_date_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_error_utils.mdx b/api_docs/kbn_ml_error_utils.mdx index ea604aa86091d7..8c5ab1329e5c13 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_in_memory_table.mdx b/api_docs/kbn_ml_in_memory_table.mdx index 7a1a2aaa9cb15d..33548ea5b09bfb 100644 --- a/api_docs/kbn_ml_in_memory_table.mdx +++ b/api_docs/kbn_ml_in_memory_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-in-memory-table title: "@kbn/ml-in-memory-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-in-memory-table plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-in-memory-table'] --- import kbnMlInMemoryTableObj from './kbn_ml_in_memory_table.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index 7ac72b537a8b3a..07e67b30d3ece7 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-defined'] --- import kbnMlIsDefinedObj from './kbn_ml_is_defined.devdocs.json'; diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index 5921482756730c..0b743eae485bdb 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_kibana_theme.devdocs.json b/api_docs/kbn_ml_kibana_theme.devdocs.json index 56668eebb20230..f8b71d98e19510 100644 --- a/api_docs/kbn_ml_kibana_theme.devdocs.json +++ b/api_docs/kbn_ml_kibana_theme.devdocs.json @@ -34,8 +34,8 @@ "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", - "section": "def-common.ThemeServiceStart", - "text": "ThemeServiceStart" + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" }, ") => { euiTheme: { euiZDataGrid: number; euiZHeaderBelowDataGrid: number; euiZDataGridCellPopover: number; euiDataGridCellPaddingS: string; euiDataGridCellPaddingM: string; euiDataGridCellPaddingL: string; euiTableHoverColor: string; euiTableSelectedColor: string; euiTableHoverSelectedColor: string; euiTableActionsBorderColor: string; euiTableHoverClickableColor: string; euiTableFocusClickableColor: string; euiContrastRatioText: number; euiContrastRatioGraphic: number; euiContrastRatioDisabled: number; euiAnimSlightBounce: string; euiAnimSlightResistance: string; euiAnimSpeedExtraFast: string; euiAnimSpeedFast: string; euiAnimSpeedNormal: string; euiAnimSpeedSlow: string; euiAnimSpeedExtraSlow: string; euiBorderWidthThin: string; euiBorderWidthThick: string; euiBorderColor: string; euiBorderRadius: string; euiBorderRadiusSmall: string; euiBorderThick: string; euiBorderThin: string; euiBorderEditable: string; euiButtonHeight: string; euiButtonHeightSmall: string; euiButtonHeightXSmall: string; euiButtonColorDisabled: string; euiButtonColorDisabledText: string; euiButtonColorGhostDisabled: string; euiButtonTypes: { primary: string; accent: string; success: string; warning: string; danger: string; ghost: string; text: string; }; euiPaletteColorBlind: { euiColorVis0: { graphic: string; behindText: string; }; euiColorVis1: { graphic: string; behindText: string; }; euiColorVis2: { graphic: string; behindText: string; }; euiColorVis3: { graphic: string; behindText: string; }; euiColorVis4: { graphic: string; behindText: string; }; euiColorVis5: { graphic: string; behindText: string; }; euiColorVis6: { graphic: string; behindText: string; }; euiColorVis7: { graphic: string; behindText: string; }; euiColorVis8: { graphic: string; behindText: string; }; euiColorVis9: { graphic: string; behindText: string; }; }; euiPaletteColorBlindKeys: string; euiColorVis0: string; euiColorVis1: string; euiColorVis2: string; euiColorVis3: string; euiColorVis4: string; euiColorVis5: string; euiColorVis6: string; euiColorVis7: string; euiColorVis8: string; euiColorVis9: string; euiColorVis0_behindText: string; euiColorVis1_behindText: string; euiColorVis2_behindText: string; euiColorVis3_behindText: string; euiColorVis4_behindText: string; euiColorVis5_behindText: string; euiColorVis6_behindText: string; euiColorVis7_behindText: string; euiColorVis8_behindText: string; euiColorVis9_behindText: string; euiFontWeightLight: number; euiFontWeightRegular: number; euiFontWeightMedium: number; euiFontWeightSemiBold: number; euiFontWeightBold: number; euiCodeFontWeightRegular: number; euiCodeFontWeightBold: number; euiFormMaxWidth: string; euiFormControlHeight: string; euiFormControlCompressedHeight: string; euiFormControlPadding: string; euiFormControlCompressedPadding: string; euiFormControlBorderRadius: string; euiFormControlCompressedBorderRadius: string; euiRadioSize: string; euiCheckBoxSize: string; euiCheckboxBorderRadius: string; euiSwitchHeight: string; euiSwitchWidth: string; euiSwitchThumbSize: string; euiSwitchIconHeight: string; euiSwitchHeightCompressed: string; euiSwitchWidthCompressed: string; euiSwitchThumbSizeCompressed: string; euiSwitchHeightMini: string; euiSwitchWidthMini: string; euiSwitchThumbSizeMini: string; euiFormBackgroundColor: string; euiFormBackgroundDisabledColor: string; euiFormBackgroundReadOnlyColor: string; euiFormBorderOpaqueColor: string; euiFormBorderColor: string; euiFormBorderDisabledColor: string; euiFormCustomControlDisabledIconColor: string; euiFormCustomControlBorderColor: string; euiFormControlDisabledColor: string; euiFormControlBoxShadow: string; euiFormControlPlaceholderText: string; euiFormInputGroupLabelBackground: string; euiFormInputGroupBorder: string; euiSwitchOffColor: string; euiFormControlIconSizes: { small: string; medium: string; large: string; xLarge: string; xxLarge: string; }; euiFormControlLayoutGroupInputHeight: string; euiFormControlLayoutGroupInputCompressedHeight: string; euiFormControlLayoutGroupInputCompressedBorderRadius: string; euiHeaderBackgroundColor: string; euiHeaderDarkBackgroundColor: string; euiHeaderBorderColor: string; euiHeaderBreadcrumbColor: string; euiHeaderHeight: string; euiHeaderChildSize: string; euiHeaderHeightCompensation: string; euiPageDefaultMaxWidth: string; euiPageSidebarMinWidth: string; euiPanelPaddingModifiers: { paddingSmall: string; paddingMedium: string; paddingLarge: string; }; euiPanelBorderRadiusModifiers: { borderRadiusNone: number; borderRadiusMedium: string; }; euiPanelBackgroundColorModifiers: { transparent: string; plain: string; subdued: string; accent: string; primary: string; success: string; warning: string; danger: string; }; euiBreakpoints: { xs: number; s: string; m: string; l: string; xl: string; }; euiBreakpointKeys: string; euiShadowColor: string; euiSize: string; euiSizeXS: string; euiSizeS: string; euiSizeM: string; euiSizeL: string; euiSizeXL: string; euiSizeXXL: string; euiScrollBar: string; euiScrollBarCorner: string; euiScrollBarCornerThin: string; euiFocusRingColor: string; euiFocusRingAnimStartColor: string; euiFocusRingAnimStartSize: string; euiFocusRingAnimStartSizeLarge: string; euiFocusRingSizeLarge: string; euiFocusRingSize: string; euiFocusTransparency: number; euiFocusTransparencyPercent: string; euiFocusBackgroundColor: string; euiFontFamily: string; euiCodeFontFamily: string; euiFontFeatureSettings: string; euiTextScale: string; euiFontSize: string; euiFontSizeXS: string; euiFontSizeS: string; euiFontSizeM: string; euiFontSizeL: string; euiFontSizeXL: string; euiFontSizeXXL: string; euiLineHeight: number; euiBodyLineHeight: number; euiTitles: { xxxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xxs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; xs: { 'font-size': string; 'line-height': string; 'font-weight': number; }; s: { 'font-size': string; 'line-height': string; 'font-weight': number; }; m: { 'font-size': string; 'line-height': string; 'font-weight': number; }; l: { 'font-size': string; 'line-height': string; 'font-weight': number; }; }; euiZLevel0: number; euiZLevel1: number; euiZLevel2: number; euiZLevel3: number; euiZLevel4: number; euiZLevel5: number; euiZLevel6: number; euiZLevel7: number; euiZLevel8: number; euiZLevel9: number; euiZToastList: number; euiZModal: number; euiZMask: number; euiZNavigation: number; euiZContentMenu: number; euiZHeader: number; euiZFlyout: number; euiZMaskBelowHeader: number; euiZContent: number; euiColorGhost: string; euiColorInk: string; euiColorPrimary: string; euiColorAccent: string; euiColorSuccess: string; euiColorWarning: string; euiColorDanger: string; euiColorEmptyShade: string; euiColorLightestShade: string; euiColorLightShade: string; euiColorMediumShade: string; euiColorDarkShade: string; euiColorDarkestShade: string; euiColorFullShade: string; euiPageBackgroundColor: string; euiColorHighlight: string; euiTextColor: string; euiTitleColor: string; euiTextSubduedColor: string; euiColorDisabled: string; euiColorPrimaryText: string; euiColorSuccessText: string; euiColorAccentText: string; euiColorWarningText: string; euiColorDangerText: string; euiColorDisabledText: string; euiLinkColor: string; euiColorChartLines: string; euiColorChartBand: string; }; }" ], @@ -55,8 +55,8 @@ "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", - "section": "def-common.ThemeServiceStart", - "text": "ThemeServiceStart" + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" } ], "path": "x-pack/packages/ml/kibana_theme/src/hooks.ts", @@ -85,8 +85,8 @@ "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", - "section": "def-common.ThemeServiceStart", - "text": "ThemeServiceStart" + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" }, ") => boolean" ], @@ -106,8 +106,8 @@ "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", - "section": "def-common.ThemeServiceStart", - "text": "ThemeServiceStart" + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" } ], "path": "x-pack/packages/ml/kibana_theme/src/hooks.ts", diff --git a/api_docs/kbn_ml_kibana_theme.mdx b/api_docs/kbn_ml_kibana_theme.mdx index 52b2bb6e964248..9939154aa79fa6 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-kibana-theme'] --- import kbnMlKibanaThemeObj from './kbn_ml_kibana_theme.devdocs.json'; diff --git a/api_docs/kbn_ml_local_storage.mdx b/api_docs/kbn_ml_local_storage.mdx index eb27f2dea70fa6..87746d0d4e8002 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-local-storage'] --- import kbnMlLocalStorageObj from './kbn_ml_local_storage.devdocs.json'; diff --git a/api_docs/kbn_ml_nested_property.mdx b/api_docs/kbn_ml_nested_property.mdx index 01f2bdfb887b74..554649dde0947d 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-nested-property'] --- import kbnMlNestedPropertyObj from './kbn_ml_nested_property.devdocs.json'; diff --git a/api_docs/kbn_ml_number_utils.mdx b/api_docs/kbn_ml_number_utils.mdx index ce90be4172809a..da82e1a0bb3155 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-number-utils'] --- import kbnMlNumberUtilsObj from './kbn_ml_number_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index 0ef6cbb1353889..6f150ba5c262fe 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-query-utils'] --- import kbnMlQueryUtilsObj from './kbn_ml_query_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_random_sampler_utils.mdx b/api_docs/kbn_ml_random_sampler_utils.mdx index eeb354c220342a..cf0c6b27a830a7 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-random-sampler-utils'] --- import kbnMlRandomSamplerUtilsObj from './kbn_ml_random_sampler_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_route_utils.mdx b/api_docs/kbn_ml_route_utils.mdx index bdc87845ab126c..1ef538818c1067 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-route-utils'] --- import kbnMlRouteUtilsObj from './kbn_ml_route_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_runtime_field_utils.mdx b/api_docs/kbn_ml_runtime_field_utils.mdx index 1374b48496a2f4..37f6d28a5e5421 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-runtime-field-utils'] --- import kbnMlRuntimeFieldUtilsObj from './kbn_ml_runtime_field_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index 0db3b18eabec3b..ce095c3cb18be5 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index 687ecbb5086cb7..7945bcea8513a3 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_ui_actions.mdx b/api_docs/kbn_ml_ui_actions.mdx index 07fa3f0f692f40..abf54b6acfab8c 100644 --- a/api_docs/kbn_ml_ui_actions.mdx +++ b/api_docs/kbn_ml_ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-ui-actions title: "@kbn/ml-ui-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-ui-actions plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-ui-actions'] --- import kbnMlUiActionsObj from './kbn_ml_ui_actions.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 8758bc9d405cf2..d4cbe6dde603e6 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 097f6158a271a3..d5878e4c69cdeb 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_object_versioning.mdx b/api_docs/kbn_object_versioning.mdx index 889b89f58b7134..fb0d42a4954e36 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index 5267c6518f50c3..f86fdb41710a9c 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_observability_alerting_test_data.mdx b/api_docs/kbn_observability_alerting_test_data.mdx index 3534a0032efe70..fe5a6ce52bee5d 100644 --- a/api_docs/kbn_observability_alerting_test_data.mdx +++ b/api_docs/kbn_observability_alerting_test_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alerting-test-data title: "@kbn/observability-alerting-test-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alerting-test-data plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alerting-test-data'] --- import kbnObservabilityAlertingTestDataObj from './kbn_observability_alerting_test_data.devdocs.json'; diff --git a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx index 18baac91738b2e..c468bf71c06a13 100644 --- a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx +++ b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-get-padded-alert-time-range-util title: "@kbn/observability-get-padded-alert-time-range-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-get-padded-alert-time-range-util plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-get-padded-alert-time-range-util'] --- import kbnObservabilityGetPaddedAlertTimeRangeUtilObj from './kbn_observability_get_padded_alert_time_range_util.devdocs.json'; diff --git a/api_docs/kbn_openapi_bundler.mdx b/api_docs/kbn_openapi_bundler.mdx index 1fe4c05337fc87..0b9989f5e6ee0c 100644 --- a/api_docs/kbn_openapi_bundler.mdx +++ b/api_docs/kbn_openapi_bundler.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-bundler title: "@kbn/openapi-bundler" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-bundler plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-bundler'] --- import kbnOpenapiBundlerObj from './kbn_openapi_bundler.devdocs.json'; diff --git a/api_docs/kbn_openapi_generator.mdx b/api_docs/kbn_openapi_generator.mdx index e91eb491c8099a..f4063c9da35db3 100644 --- a/api_docs/kbn_openapi_generator.mdx +++ b/api_docs/kbn_openapi_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-generator title: "@kbn/openapi-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-generator plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-generator'] --- import kbnOpenapiGeneratorObj from './kbn_openapi_generator.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index e03fda66b922f1..f8493369a76d7f 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index a4d93490f23a56..c5200492fde1b8 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_osquery_io_ts_types.mdx b/api_docs/kbn_osquery_io_ts_types.mdx index 0fc96187e5d1ef..fe239e48b1bb91 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_panel_loader.mdx b/api_docs/kbn_panel_loader.mdx index 95758f643a33d1..4f69417afdb49e 100644 --- a/api_docs/kbn_panel_loader.mdx +++ b/api_docs/kbn_panel_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-panel-loader title: "@kbn/panel-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/panel-loader plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/panel-loader'] --- import kbnPanelLoaderObj from './kbn_panel_loader.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index e485d9ce305858..684b35cc79146f 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 8e1fc68be9bf3d..780791e8fb99a0 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index d4868ebec7e741..a738b8145a3d10 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_profiling_utils.mdx b/api_docs/kbn_profiling_utils.mdx index 75843c6fe0ce57..cfeceaa90b0f4d 100644 --- a/api_docs/kbn_profiling_utils.mdx +++ b/api_docs/kbn_profiling_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-profiling-utils title: "@kbn/profiling-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/profiling-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/profiling-utils'] --- import kbnProfilingUtilsObj from './kbn_profiling_utils.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index 235821608a0d29..1f04d432111965 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/random-sampling'] --- import kbnRandomSamplingObj from './kbn_random_sampling.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index ecf8bf46eaac35..463cefa369ca4d 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_common.mdx b/api_docs/kbn_react_kibana_context_common.mdx index 938283f794947a..31f7c73d6d9ff2 100644 --- a/api_docs/kbn_react_kibana_context_common.mdx +++ b/api_docs/kbn_react_kibana_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-common title: "@kbn/react-kibana-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-common'] --- import kbnReactKibanaContextCommonObj from './kbn_react_kibana_context_common.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_render.mdx b/api_docs/kbn_react_kibana_context_render.mdx index 961a2c2a84c4a9..5f62263cf9abcc 100644 --- a/api_docs/kbn_react_kibana_context_render.mdx +++ b/api_docs/kbn_react_kibana_context_render.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-render title: "@kbn/react-kibana-context-render" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-render plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-render'] --- import kbnReactKibanaContextRenderObj from './kbn_react_kibana_context_render.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_root.mdx b/api_docs/kbn_react_kibana_context_root.mdx index c25271e33c22bd..e730837d061433 100644 --- a/api_docs/kbn_react_kibana_context_root.mdx +++ b/api_docs/kbn_react_kibana_context_root.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-root title: "@kbn/react-kibana-context-root" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-root plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-root'] --- import kbnReactKibanaContextRootObj from './kbn_react_kibana_context_root.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_styled.mdx b/api_docs/kbn_react_kibana_context_styled.mdx index dde8a04b2e3e8f..94f4da60f0299d 100644 --- a/api_docs/kbn_react_kibana_context_styled.mdx +++ b/api_docs/kbn_react_kibana_context_styled.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-styled title: "@kbn/react-kibana-context-styled" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-styled plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-styled'] --- import kbnReactKibanaContextStyledObj from './kbn_react_kibana_context_styled.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_theme.mdx b/api_docs/kbn_react_kibana_context_theme.mdx index d2cd397f9af52d..219366b71df2e2 100644 --- a/api_docs/kbn_react_kibana_context_theme.mdx +++ b/api_docs/kbn_react_kibana_context_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-theme title: "@kbn/react-kibana-context-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-theme plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-theme'] --- import kbnReactKibanaContextThemeObj from './kbn_react_kibana_context_theme.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_mount.mdx b/api_docs/kbn_react_kibana_mount.mdx index 0b90295b71a378..53845e86f97a0d 100644 --- a/api_docs/kbn_react_kibana_mount.mdx +++ b/api_docs/kbn_react_kibana_mount.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-mount title: "@kbn/react-kibana-mount" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-mount plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-mount'] --- import kbnReactKibanaMountObj from './kbn_react_kibana_mount.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index 00009a0d0ad8a9..c40beda979a852 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-file-maps'] --- import kbnRepoFileMapsObj from './kbn_repo_file_maps.devdocs.json'; diff --git a/api_docs/kbn_repo_linter.mdx b/api_docs/kbn_repo_linter.mdx index 2ff0f304b2fe71..5155ff29623954 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-linter'] --- import kbnRepoLinterObj from './kbn_repo_linter.devdocs.json'; diff --git a/api_docs/kbn_repo_path.mdx b/api_docs/kbn_repo_path.mdx index 82ec79a9e1db6f..ce1dc3c6496070 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-path'] --- import kbnRepoPathObj from './kbn_repo_path.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index 6fb8c317359bcf..cdd494995f0d31 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_reporting_common.mdx b/api_docs/kbn_reporting_common.mdx index 562b5c4ef320a8..6dc4b9176db772 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv.mdx b/api_docs/kbn_reporting_export_types_csv.mdx index 9e40723964917a..2afa6b59c815a0 100644 --- a/api_docs/kbn_reporting_export_types_csv.mdx +++ b/api_docs/kbn_reporting_export_types_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv title: "@kbn/reporting-export-types-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv'] --- import kbnReportingExportTypesCsvObj from './kbn_reporting_export_types_csv.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv_common.mdx b/api_docs/kbn_reporting_export_types_csv_common.mdx index 8257679d305375..dad19846883867 100644 --- a/api_docs/kbn_reporting_export_types_csv_common.mdx +++ b/api_docs/kbn_reporting_export_types_csv_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv-common title: "@kbn/reporting-export-types-csv-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv-common'] --- import kbnReportingExportTypesCsvCommonObj from './kbn_reporting_export_types_csv_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf.mdx b/api_docs/kbn_reporting_export_types_pdf.mdx index f8513ca012ff72..bc95c41a58d0bf 100644 --- a/api_docs/kbn_reporting_export_types_pdf.mdx +++ b/api_docs/kbn_reporting_export_types_pdf.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf title: "@kbn/reporting-export-types-pdf" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf'] --- import kbnReportingExportTypesPdfObj from './kbn_reporting_export_types_pdf.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf_common.mdx b/api_docs/kbn_reporting_export_types_pdf_common.mdx index 5ff8178af6b2c9..719d55649c8bf0 100644 --- a/api_docs/kbn_reporting_export_types_pdf_common.mdx +++ b/api_docs/kbn_reporting_export_types_pdf_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf-common title: "@kbn/reporting-export-types-pdf-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf-common'] --- import kbnReportingExportTypesPdfCommonObj from './kbn_reporting_export_types_pdf_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png.mdx b/api_docs/kbn_reporting_export_types_png.mdx index 7be5c17cb96682..06b238b11b93f4 100644 --- a/api_docs/kbn_reporting_export_types_png.mdx +++ b/api_docs/kbn_reporting_export_types_png.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png title: "@kbn/reporting-export-types-png" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png'] --- import kbnReportingExportTypesPngObj from './kbn_reporting_export_types_png.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png_common.mdx b/api_docs/kbn_reporting_export_types_png_common.mdx index 4d149b32aed94b..6e4772df950b08 100644 --- a/api_docs/kbn_reporting_export_types_png_common.mdx +++ b/api_docs/kbn_reporting_export_types_png_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png-common title: "@kbn/reporting-export-types-png-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png-common'] --- import kbnReportingExportTypesPngCommonObj from './kbn_reporting_export_types_png_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_mocks_server.mdx b/api_docs/kbn_reporting_mocks_server.mdx index 21d70be5c4e41d..57ed195534fede 100644 --- a/api_docs/kbn_reporting_mocks_server.mdx +++ b/api_docs/kbn_reporting_mocks_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-mocks-server title: "@kbn/reporting-mocks-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-mocks-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-mocks-server'] --- import kbnReportingMocksServerObj from './kbn_reporting_mocks_server.devdocs.json'; diff --git a/api_docs/kbn_reporting_public.mdx b/api_docs/kbn_reporting_public.mdx index a3378f717c3ca8..c6089a997ac4ec 100644 --- a/api_docs/kbn_reporting_public.mdx +++ b/api_docs/kbn_reporting_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-public title: "@kbn/reporting-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-public plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-public'] --- import kbnReportingPublicObj from './kbn_reporting_public.devdocs.json'; diff --git a/api_docs/kbn_reporting_server.mdx b/api_docs/kbn_reporting_server.mdx index ab219bdc011fd1..084a03b76449a6 100644 --- a/api_docs/kbn_reporting_server.mdx +++ b/api_docs/kbn_reporting_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-server title: "@kbn/reporting-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-server'] --- import kbnReportingServerObj from './kbn_reporting_server.devdocs.json'; diff --git a/api_docs/kbn_resizable_layout.mdx b/api_docs/kbn_resizable_layout.mdx index e4769ec720f4b2..ab6066ff08142b 100644 --- a/api_docs/kbn_resizable_layout.mdx +++ b/api_docs/kbn_resizable_layout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-resizable-layout title: "@kbn/resizable-layout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/resizable-layout plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/resizable-layout'] --- import kbnResizableLayoutObj from './kbn_resizable_layout.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 25d97621f0756e..65e8bd6973fa05 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_router_utils.mdx b/api_docs/kbn_router_utils.mdx index eca44a8cf7c240..2bbf09bde925fc 100644 --- a/api_docs/kbn_router_utils.mdx +++ b/api_docs/kbn_router_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-router-utils title: "@kbn/router-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/router-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/router-utils'] --- import kbnRouterUtilsObj from './kbn_router_utils.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index 31ebc7aa11bddd..7cec1b9b998bd6 100644 --- a/api_docs/kbn_rrule.mdx +++ b/api_docs/kbn_rrule.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rrule title: "@kbn/rrule" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rrule plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rrule'] --- import kbnRruleObj from './kbn_rrule.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index 5bab0397cb28a6..2b1e0683f309da 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_saved_objects_settings.mdx b/api_docs/kbn_saved_objects_settings.mdx index d9b21510b3ab5a..26de1a1841cbb7 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_search_api_panels.mdx b/api_docs/kbn_search_api_panels.mdx index 7f271aac8b80e8..732f1c5da93a09 100644 --- a/api_docs/kbn_search_api_panels.mdx +++ b/api_docs/kbn_search_api_panels.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-api-panels title: "@kbn/search-api-panels" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-api-panels plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-api-panels'] --- import kbnSearchApiPanelsObj from './kbn_search_api_panels.devdocs.json'; diff --git a/api_docs/kbn_search_connectors.mdx b/api_docs/kbn_search_connectors.mdx index 0d004bcaccc8ca..b5de70f4790aeb 100644 --- a/api_docs/kbn_search_connectors.mdx +++ b/api_docs/kbn_search_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-connectors title: "@kbn/search-connectors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-connectors plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-connectors'] --- import kbnSearchConnectorsObj from './kbn_search_connectors.devdocs.json'; diff --git a/api_docs/kbn_search_errors.mdx b/api_docs/kbn_search_errors.mdx index 61fac6e4982b73..28044c354967af 100644 --- a/api_docs/kbn_search_errors.mdx +++ b/api_docs/kbn_search_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-errors title: "@kbn/search-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-errors plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-errors'] --- import kbnSearchErrorsObj from './kbn_search_errors.devdocs.json'; diff --git a/api_docs/kbn_search_index_documents.mdx b/api_docs/kbn_search_index_documents.mdx index 5a7c63aa4674e1..4e80f1e09ae492 100644 --- a/api_docs/kbn_search_index_documents.mdx +++ b/api_docs/kbn_search_index_documents.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-index-documents title: "@kbn/search-index-documents" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-index-documents plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-index-documents'] --- import kbnSearchIndexDocumentsObj from './kbn_search_index_documents.devdocs.json'; diff --git a/api_docs/kbn_search_response_warnings.mdx b/api_docs/kbn_search_response_warnings.mdx index 340f50dfc63981..872d1241f4c790 100644 --- a/api_docs/kbn_search_response_warnings.mdx +++ b/api_docs/kbn_search_response_warnings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-response-warnings title: "@kbn/search-response-warnings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-response-warnings plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-response-warnings'] --- import kbnSearchResponseWarningsObj from './kbn_search_response_warnings.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_common.mdx b/api_docs/kbn_security_plugin_types_common.mdx index 8bc2b68a4171dc..7df39a20835e17 100644 --- a/api_docs/kbn_security_plugin_types_common.mdx +++ b/api_docs/kbn_security_plugin_types_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-common title: "@kbn/security-plugin-types-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-common plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-common'] --- import kbnSecurityPluginTypesCommonObj from './kbn_security_plugin_types_common.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_public.mdx b/api_docs/kbn_security_plugin_types_public.mdx index 952aaa3d69a109..0311d655af61b9 100644 --- a/api_docs/kbn_security_plugin_types_public.mdx +++ b/api_docs/kbn_security_plugin_types_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-public title: "@kbn/security-plugin-types-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-public plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-public'] --- import kbnSecurityPluginTypesPublicObj from './kbn_security_plugin_types_public.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_server.mdx b/api_docs/kbn_security_plugin_types_server.mdx index 07507bdf6810f3..07bf3b3b1d0531 100644 --- a/api_docs/kbn_security_plugin_types_server.mdx +++ b/api_docs/kbn_security_plugin_types_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-server title: "@kbn/security-plugin-types-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-server plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-server'] --- import kbnSecurityPluginTypesServerObj from './kbn_security_plugin_types_server.devdocs.json'; diff --git a/api_docs/kbn_security_solution_features.mdx b/api_docs/kbn_security_solution_features.mdx index 97bfe358dbfdb0..2bb23757570cf4 100644 --- a/api_docs/kbn_security_solution_features.mdx +++ b/api_docs/kbn_security_solution_features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-features title: "@kbn/security-solution-features" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-features plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-features'] --- import kbnSecuritySolutionFeaturesObj from './kbn_security_solution_features.devdocs.json'; diff --git a/api_docs/kbn_security_solution_navigation.mdx b/api_docs/kbn_security_solution_navigation.mdx index 2ea6cc41adc0af..f276821476701e 100644 --- a/api_docs/kbn_security_solution_navigation.mdx +++ b/api_docs/kbn_security_solution_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-navigation title: "@kbn/security-solution-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-navigation plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-navigation'] --- import kbnSecuritySolutionNavigationObj from './kbn_security_solution_navigation.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index 4c59b624135c15..f7419335104ce8 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-side-nav'] --- import kbnSecuritySolutionSideNavObj from './kbn_security_solution_side_nav.devdocs.json'; diff --git a/api_docs/kbn_security_solution_storybook_config.mdx b/api_docs/kbn_security_solution_storybook_config.mdx index 8a645d1ddbc8a9..daae2d1b00eec3 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-storybook-config'] --- import kbnSecuritySolutionStorybookConfigObj from './kbn_security_solution_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 25a9b2bc1a650d..e919e16c4fb9a3 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_data_table.mdx b/api_docs/kbn_securitysolution_data_table.mdx index 727c6a574826d8..c10215d400df3d 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-data-table'] --- import kbnSecuritysolutionDataTableObj from './kbn_securitysolution_data_table.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_ecs.mdx b/api_docs/kbn_securitysolution_ecs.mdx index f4a567a70eaff8..a1619d9228776a 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-ecs'] --- import kbnSecuritysolutionEcsObj from './kbn_securitysolution_ecs.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index 4286c5b9c9648e..2e9e3fda3bd739 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_exception_list_components.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index ddb253c6004f5c..2504bf49c085d7 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_grouping.mdx b/api_docs/kbn_securitysolution_grouping.mdx index f224c136aa7201..c8566604b272ed 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-grouping'] --- import kbnSecuritysolutionGroupingObj from './kbn_securitysolution_grouping.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 919cda06b82884..d55216dc82dc69 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index be01eefef4e584..aa9796b5717ac8 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index e093e781ea1dbc..b3ef203a1a3c01 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index c86fc8aeae1660..60abe223e006d1 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index 4add9df89302b6..9b45eb5442f017 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index ca1fda2120a4bc..9a894c867b6462 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index 2ac4d1be857edf..696893d05623a2 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index 4042efdb335018..38615542414866 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index f2da8062625f4a..67d118226936ed 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index f5e0ead135f7d7..e2c786980f7b8d 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index c14208f53c5275..731f71bba12612 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index e2639d9d07fe7c..80a6ecd781096c 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index 45e895447d1315..f56737b1185deb 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index 1f075b5381dde5..92366c91ca283b 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_common_settings.mdx b/api_docs/kbn_serverless_common_settings.mdx index df8244ef20d0e4..fba7e624924c96 100644 --- a/api_docs/kbn_serverless_common_settings.mdx +++ b/api_docs/kbn_serverless_common_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-common-settings title: "@kbn/serverless-common-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-common-settings plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-common-settings'] --- import kbnServerlessCommonSettingsObj from './kbn_serverless_common_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_observability_settings.mdx b/api_docs/kbn_serverless_observability_settings.mdx index 203ac911d7a147..bb819172290917 100644 --- a/api_docs/kbn_serverless_observability_settings.mdx +++ b/api_docs/kbn_serverless_observability_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-observability-settings title: "@kbn/serverless-observability-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-observability-settings plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-observability-settings'] --- import kbnServerlessObservabilitySettingsObj from './kbn_serverless_observability_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index a2d578fdfee3f9..d19c30dda087f7 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_search_settings.mdx b/api_docs/kbn_serverless_search_settings.mdx index 20f521277536da..d269700c68f445 100644 --- a/api_docs/kbn_serverless_search_settings.mdx +++ b/api_docs/kbn_serverless_search_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-search-settings title: "@kbn/serverless-search-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-search-settings plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-search-settings'] --- import kbnServerlessSearchSettingsObj from './kbn_serverless_search_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_security_settings.mdx b/api_docs/kbn_serverless_security_settings.mdx index 0ad3c61e9debc3..69fdcced5a23d1 100644 --- a/api_docs/kbn_serverless_security_settings.mdx +++ b/api_docs/kbn_serverless_security_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-security-settings title: "@kbn/serverless-security-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-security-settings plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-security-settings'] --- import kbnServerlessSecuritySettingsObj from './kbn_serverless_security_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index 1e658ebe23f4db..d10b95719787b4 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-storybook-config'] --- import kbnServerlessStorybookConfigObj from './kbn_serverless_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index f912adcc82687c..0ac8433ce61cb5 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_solution.mdx b/api_docs/kbn_shared_ux_avatar_solution.mdx index e6d9946bf8510c..49f1e02ff5c1e4 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index 9cbfbb081b215d..f65e8e2cbf415a 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 95271bebf4dbe3..39fc2505531366 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index 676eba9a4c1a2d..e71e76571b820e 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index daee8fd0085bf4..ffaa19fe356c1d 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_chrome_navigation.mdx b/api_docs/kbn_shared_ux_chrome_navigation.mdx index 7cdc5854334377..171e417021a5c8 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_error_boundary.mdx b/api_docs/kbn_shared_ux_error_boundary.mdx index 84f922380955d8..c50aae83d82f59 100644 --- a/api_docs/kbn_shared_ux_error_boundary.mdx +++ b/api_docs/kbn_shared_ux_error_boundary.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-error-boundary title: "@kbn/shared-ux-error-boundary" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-error-boundary plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-error-boundary'] --- import kbnSharedUxErrorBoundaryObj from './kbn_shared_ux_error_boundary.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index 483783a2e113b9..172e010a4c1dc7 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-context'] --- import kbnSharedUxFileContextObj from './kbn_shared_ux_file_context.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image.mdx b/api_docs/kbn_shared_ux_file_image.mdx index 773af38ee62623..0900aa85d5405c 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image'] --- import kbnSharedUxFileImageObj from './kbn_shared_ux_file_image.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image_mocks.mdx b/api_docs/kbn_shared_ux_file_image_mocks.mdx index e1f1d760777a72..ef67141bccf4b2 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image-mocks'] --- import kbnSharedUxFileImageMocksObj from './kbn_shared_ux_file_image_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_mocks.mdx b/api_docs/kbn_shared_ux_file_mocks.mdx index fd53ddb6ee586d..6b43a7bfaa4f01 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-mocks'] --- import kbnSharedUxFileMocksObj from './kbn_shared_ux_file_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_picker.mdx b/api_docs/kbn_shared_ux_file_picker.mdx index 41a1d82d91cdf1..b43071a29b928c 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-picker'] --- import kbnSharedUxFilePickerObj from './kbn_shared_ux_file_picker.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_types.mdx b/api_docs/kbn_shared_ux_file_types.mdx index aafebe07b62761..4cd8dafad7582b 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-types'] --- import kbnSharedUxFileTypesObj from './kbn_shared_ux_file_types.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_upload.mdx b/api_docs/kbn_shared_ux_file_upload.mdx index 6ae2f940ee5f53..46eb79de5c2edd 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-upload'] --- import kbnSharedUxFileUploadObj from './kbn_shared_ux_file_upload.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_util.mdx b/api_docs/kbn_shared_ux_file_util.mdx index 83a3bc810a8121..e4edf827ef2cdf 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-util'] --- import kbnSharedUxFileUtilObj from './kbn_shared_ux_file_util.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app.mdx b/api_docs/kbn_shared_ux_link_redirect_app.mdx index bda7c61a55595c..983664d389a812 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app'] --- import kbnSharedUxLinkRedirectAppObj from './kbn_shared_ux_link_redirect_app.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index f064dc1ce8c326..d62e92b1a1e043 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown.mdx b/api_docs/kbn_shared_ux_markdown.mdx index 813606d7fe4f69..5ae9195fabe127 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown'] --- import kbnSharedUxMarkdownObj from './kbn_shared_ux_markdown.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown_mocks.mdx b/api_docs/kbn_shared_ux_markdown_mocks.mdx index 35d32a35715e4a..48375e038a4af4 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown-mocks'] --- import kbnSharedUxMarkdownMocksObj from './kbn_shared_ux_markdown_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index 334d5dedf331a2..796aeae4062e18 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index 0f39ba0a6983a2..6d352e3966d99a 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index 9de368c36a62af..beb7f0bcab7892 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index 565e950e72b94b..a82ba439288328 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx index 5627b206928e11..51be93e9e9f2ef 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] --- import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx index c1362a374b242d..c61ba39a573981 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] --- import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx index decb3cdf50bd09..720dba137db810 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx index a76c44a23608fb..537dff4ff66e15 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx index cc8e13ea7d6428..2288c1079c75b7 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] --- import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx index 6e16f063ba754f..6c0ebc1013fa6f 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] --- import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index e6e0947624f0b8..725618eba93251 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index ab02252e8d617e..d72ca3b1a54060 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index bb5321661e4118..b1361b01291ee1 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_not_found.mdx b/api_docs/kbn_shared_ux_prompt_not_found.mdx index f3eccad586b37f..4c3e1c497c694d 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-not-found'] --- import kbnSharedUxPromptNotFoundObj from './kbn_shared_ux_prompt_not_found.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router.mdx b/api_docs/kbn_shared_ux_router.mdx index bce53eb890e0c0..e2c9d2f9413cc3 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router'] --- import kbnSharedUxRouterObj from './kbn_shared_ux_router.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router_mocks.mdx b/api_docs/kbn_shared_ux_router_mocks.mdx index 2e6de026b19f54..ee8b10c4ce756d 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router-mocks'] --- import kbnSharedUxRouterMocksObj from './kbn_shared_ux_router_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_config.mdx b/api_docs/kbn_shared_ux_storybook_config.mdx index 061d2ddb1ea0fb..9db659968e67ea 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-config'] --- import kbnSharedUxStorybookConfigObj from './kbn_shared_ux_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index 517f964e39f111..c089cd897f9bac 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index fdf6ec6e67325f..74b36dd06f4583 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_slo_schema.mdx b/api_docs/kbn_slo_schema.mdx index 11eed96017eea4..2230d89183b5fa 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/slo-schema'] --- import kbnSloSchemaObj from './kbn_slo_schema.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index 3d2f76883bdaa2..d3f8fb78d0d67e 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 98af8c79666c6e..768a8cd40f2e97 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index 057088a6a4f069..b93e1992899585 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index b4aea70a83c47a..bec40b1c04f32b 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 8f05560bbf3f48..0ac88141ae1ed7 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index 448022835f5968..b31ff349267def 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 4e160b6370f4a2..06f466e44a8200 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index ce2174dc13b0a2..1181ce81c9fe02 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index 8ddb863af8150e..7f126ebb94d9dc 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index f1f81a9613b6aa..0965a33c7bdd07 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_triggers_actions_ui_types.mdx b/api_docs/kbn_triggers_actions_ui_types.mdx index d9721df8ef064f..09935c9dec33d8 100644 --- a/api_docs/kbn_triggers_actions_ui_types.mdx +++ b/api_docs/kbn_triggers_actions_ui_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-triggers-actions-ui-types title: "@kbn/triggers-actions-ui-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/triggers-actions-ui-types plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/triggers-actions-ui-types'] --- import kbnTriggersActionsUiTypesObj from './kbn_triggers_actions_ui_types.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 48d52200d7b9b5..6f51d5f3a7c4d2 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ts-projects'] --- import kbnTsProjectsObj from './kbn_ts_projects.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index 4b7075ff79d579..df3bf00edb00f1 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_actions_browser.mdx b/api_docs/kbn_ui_actions_browser.mdx index 6d9ee3960407ee..1311abc8cb33bf 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-actions-browser'] --- import kbnUiActionsBrowserObj from './kbn_ui_actions_browser.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 42aa906ced28c9..9623a6b3c92fba 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-shared-deps-src'] --- import kbnUiSharedDepsSrcObj from './kbn_ui_shared_deps_src.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index 61ded720e88394..4fbced2ccff16a 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_data_table.mdx b/api_docs/kbn_unified_data_table.mdx index ed071e5d18601c..869008aef7bb30 100644 --- a/api_docs/kbn_unified_data_table.mdx +++ b/api_docs/kbn_unified_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-data-table title: "@kbn/unified-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-data-table plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-data-table'] --- import kbnUnifiedDataTableObj from './kbn_unified_data_table.devdocs.json'; diff --git a/api_docs/kbn_unified_doc_viewer.mdx b/api_docs/kbn_unified_doc_viewer.mdx index 5a0dc633d1edd7..02c1582cafe739 100644 --- a/api_docs/kbn_unified_doc_viewer.mdx +++ b/api_docs/kbn_unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-doc-viewer title: "@kbn/unified-doc-viewer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-doc-viewer plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-doc-viewer'] --- import kbnUnifiedDocViewerObj from './kbn_unified_doc_viewer.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index 697396ee7d6cc3..f70078f4c1cb96 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_unsaved_changes_badge.mdx b/api_docs/kbn_unsaved_changes_badge.mdx index 722bb74668663d..49242071d22cf1 100644 --- a/api_docs/kbn_unsaved_changes_badge.mdx +++ b/api_docs/kbn_unsaved_changes_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unsaved-changes-badge title: "@kbn/unsaved-changes-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unsaved-changes-badge plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unsaved-changes-badge'] --- import kbnUnsavedChangesBadgeObj from './kbn_unsaved_changes_badge.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index 941ef48209ce6b..375f32cca1a6b6 100644 --- a/api_docs/kbn_url_state.mdx +++ b/api_docs/kbn_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-url-state title: "@kbn/url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/url-state plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/url-state'] --- import kbnUrlStateObj from './kbn_url_state.devdocs.json'; diff --git a/api_docs/kbn_use_tracked_promise.mdx b/api_docs/kbn_use_tracked_promise.mdx index 39ff4379240a16..0e3f645e97affe 100644 --- a/api_docs/kbn_use_tracked_promise.mdx +++ b/api_docs/kbn_use_tracked_promise.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-use-tracked-promise title: "@kbn/use-tracked-promise" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/use-tracked-promise plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/use-tracked-promise'] --- import kbnUseTrackedPromiseObj from './kbn_use_tracked_promise.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.devdocs.json b/api_docs/kbn_user_profile_components.devdocs.json index e3e6876539109d..4ba06b83b3258c 100644 --- a/api_docs/kbn_user_profile_components.devdocs.json +++ b/api_docs/kbn_user_profile_components.devdocs.json @@ -875,8 +875,8 @@ "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", - "section": "def-common.ThemeServiceStart", - "text": "ThemeServiceStart" + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" }, "; }" ], diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 3fa957596dd5c0..eb981a467633f3 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index 28a91f585e8835..70a7d2a2a36fbf 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index 4a068cbca3973c..e865b4aa1aca30 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index a76610e6ee9f25..6cb0c354c7e42f 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_visualization_ui_components.mdx b/api_docs/kbn_visualization_ui_components.mdx index 6f58db9e72165f..d5892e8d250072 100644 --- a/api_docs/kbn_visualization_ui_components.mdx +++ b/api_docs/kbn_visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-ui-components title: "@kbn/visualization-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-ui-components plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-ui-components'] --- import kbnVisualizationUiComponentsObj from './kbn_visualization_ui_components.devdocs.json'; diff --git a/api_docs/kbn_visualization_utils.mdx b/api_docs/kbn_visualization_utils.mdx index 4fb2e91f6f3c2b..db9bce5caa52ff 100644 --- a/api_docs/kbn_visualization_utils.mdx +++ b/api_docs/kbn_visualization_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-utils title: "@kbn/visualization-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-utils'] --- import kbnVisualizationUtilsObj from './kbn_visualization_utils.devdocs.json'; diff --git a/api_docs/kbn_xstate_utils.mdx b/api_docs/kbn_xstate_utils.mdx index bfebbfd19bc91a..0322596c1aa40a 100644 --- a/api_docs/kbn_xstate_utils.mdx +++ b/api_docs/kbn_xstate_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-xstate-utils title: "@kbn/xstate-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/xstate-utils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/xstate-utils'] --- import kbnXstateUtilsObj from './kbn_xstate_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index eeec2e6e6dd737..c937220df66e18 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kbn_zod_helpers.mdx b/api_docs/kbn_zod_helpers.mdx index 6f8f072bac598b..bf8661b5e7b4d0 100644 --- a/api_docs/kbn_zod_helpers.mdx +++ b/api_docs/kbn_zod_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-zod-helpers title: "@kbn/zod-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/zod-helpers plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/zod-helpers'] --- import kbnZodHelpersObj from './kbn_zod_helpers.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 7a76aba27b04de..515a302398cec4 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.devdocs.json b/api_docs/kibana_react.devdocs.json index e23a4fb2f5783d..8d7cb865d9f39b 100644 --- a/api_docs/kibana_react.devdocs.json +++ b/api_docs/kibana_react.devdocs.json @@ -5010,8 +5010,8 @@ "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", - "section": "def-common.ThemeServiceStart", - "text": "ThemeServiceStart" + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" }, " | undefined; plugins?: ", { diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index eab29c588112f1..0b959dc7f193c0 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.devdocs.json b/api_docs/kibana_utils.devdocs.json index 96bf6a42450b05..936391892cf5b2 100644 --- a/api_docs/kibana_utils.devdocs.json +++ b/api_docs/kibana_utils.devdocs.json @@ -3350,8 +3350,8 @@ "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", - "section": "def-common.ThemeServiceStart", - "text": "ThemeServiceStart" + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" }, "; }) => (error: ", { @@ -3568,8 +3568,8 @@ "pluginId": "@kbn/core-theme-browser", "scope": "common", "docId": "kibKbnCoreThemeBrowserPluginApi", - "section": "def-common.ThemeServiceStart", - "text": "ThemeServiceStart" + "section": "def-common.ThemeServiceSetup", + "text": "ThemeServiceSetup" } ], "path": "src/plugins/kibana_utils/public/history/redirect_when_missing.tsx", diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index 35e1ab28fb3d49..c5f2f8fc2ee451 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index e58be7d1de8961..3288494857432f 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 90ff074e5a001f..dee02d6eee0138 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 708df91eb52259..65406175b3779c 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index 9e2867ab3824ef..028dc38a5a860e 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index fbe6b1f0194e6a..c63f1231b414d4 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/links.mdx b/api_docs/links.mdx index 39df2f5ed8f196..5a61455b54f899 100644 --- a/api_docs/links.mdx +++ b/api_docs/links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/links title: "links" image: https://source.unsplash.com/400x175/?github description: API docs for the links plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'links'] --- import linksObj from './links.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 00ede0d7442dea..9d0c651ee081d2 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/log_explorer.devdocs.json b/api_docs/log_explorer.devdocs.json index 77158fcd0051b0..2157d8b4abafe9 100644 --- a/api_docs/log_explorer.devdocs.json +++ b/api_docs/log_explorer.devdocs.json @@ -142,11 +142,11 @@ }, ") => ", { - "pluginId": "@kbn/unified-data-table", + "pluginId": "savedSearch", "scope": "common", - "docId": "kibKbnUnifiedDataTablePluginApi", - "section": "def-common.UnifiedDataTableSettings", - "text": "UnifiedDataTableSettings" + "docId": "kibSavedSearchPluginApi", + "section": "def-common.DiscoverGridSettings", + "text": "DiscoverGridSettings" }, " | undefined" ], diff --git a/api_docs/log_explorer.mdx b/api_docs/log_explorer.mdx index cdee6cfd133099..5ec0351c769a4e 100644 --- a/api_docs/log_explorer.mdx +++ b/api_docs/log_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logExplorer title: "logExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the logExplorer plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logExplorer'] --- import logExplorerObj from './log_explorer.devdocs.json'; diff --git a/api_docs/logs_shared.devdocs.json b/api_docs/logs_shared.devdocs.json index 61da0f6f1007c8..ee2ec077ebe072 100644 --- a/api_docs/logs_shared.devdocs.json +++ b/api_docs/logs_shared.devdocs.json @@ -2631,6 +2631,26 @@ "deprecated": false, "trackAdoption": false, "children": [ + { + "parentPluginId": "logsShared", + "id": "def-public.LogAIAssistantProps.observabilityAIAssistant", + "type": "Object", + "tags": [], + "label": "observabilityAIAssistant", + "description": [], + "signature": [ + { + "pluginId": "observabilityAIAssistant", + "scope": "public", + "docId": "kibObservabilityAIAssistantPluginApi", + "section": "def-public.ObservabilityAIAssistantPluginStart", + "text": "ObservabilityAIAssistantPluginStart" + } + ], + "path": "x-pack/plugins/logs_shared/public/components/log_ai_assistant/log_ai_assistant.tsx", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "logsShared", "id": "def-public.LogAIAssistantProps.doc", @@ -3315,24 +3335,50 @@ { "parentPluginId": "logsShared", "id": "def-public.LogsSharedClientStartExports.LogAIAssistant", - "type": "CompoundType", + "type": "Function", "tags": [], "label": "LogAIAssistant", "description": [], "signature": [ - "React.ComponentClass<", - "Optional", - "<", - "LogAIAssistantDeps", - ", \"observabilityAIAssistant\">, any> | React.FunctionComponent<", - "Optional", - "<", - "LogAIAssistantDeps", - ", \"observabilityAIAssistant\">>" + "(props: Omit<", + { + "pluginId": "logsShared", + "scope": "public", + "docId": "kibLogsSharedPluginApi", + "section": "def-public.LogAIAssistantProps", + "text": "LogAIAssistantProps" + }, + ", \"observabilityAIAssistant\">) => JSX.Element" ], "path": "x-pack/plugins/logs_shared/public/types.ts", "deprecated": false, - "trackAdoption": false + "trackAdoption": false, + "children": [ + { + "parentPluginId": "logsShared", + "id": "def-public.LogsSharedClientStartExports.LogAIAssistant.$1", + "type": "Object", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "Omit<", + { + "pluginId": "logsShared", + "scope": "public", + "docId": "kibLogsSharedPluginApi", + "section": "def-public.LogAIAssistantProps", + "text": "LogAIAssistantProps" + }, + ", \"observabilityAIAssistant\">" + ], + "path": "x-pack/plugins/logs_shared/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] } ], "lifecycle": "start", diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index 4516bb866f0a3f..abc6f480bf76bd 100644 --- a/api_docs/logs_shared.mdx +++ b/api_docs/logs_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsShared title: "logsShared" image: https://source.unsplash.com/400x175/?github description: API docs for the logsShared plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsShared'] --- import logsSharedObj from './logs_shared.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 289 | 11 | 274 | 27 | +| 291 | 11 | 276 | 26 | ## Client diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 27b0ec442692c4..ce0aac83f4b297 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index d9aa39d1491156..c90b38e41ad5b1 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index 6dac20d0d9caab..3be1cb138f6948 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/metrics_data_access.mdx b/api_docs/metrics_data_access.mdx index f5d983b5b3dfd4..b447b5fee0d23f 100644 --- a/api_docs/metrics_data_access.mdx +++ b/api_docs/metrics_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/metricsDataAccess title: "metricsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the metricsDataAccess plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'metricsDataAccess'] --- import metricsDataAccessObj from './metrics_data_access.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index f7b212e4bec46c..62bd3e5f384eb8 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/mock_idp_plugin.mdx b/api_docs/mock_idp_plugin.mdx index 555309035859b6..e1fe1f71f6d7f9 100644 --- a/api_docs/mock_idp_plugin.mdx +++ b/api_docs/mock_idp_plugin.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mockIdpPlugin title: "mockIdpPlugin" image: https://source.unsplash.com/400x175/?github description: API docs for the mockIdpPlugin plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mockIdpPlugin'] --- import mockIdpPluginObj from './mock_idp_plugin.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 9757bd03e27d58..f3f50e0bce9dfa 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index f3df3d670f0b3a..b6f63e843feb04 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index c03f835f59531f..3dd539ffa14baf 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 5a97365c2f9293..80236314935b73 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/no_data_page.mdx b/api_docs/no_data_page.mdx index d157b958d0b5e2..eb47ec2711c685 100644 --- a/api_docs/no_data_page.mdx +++ b/api_docs/no_data_page.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/noDataPage title: "noDataPage" image: https://source.unsplash.com/400x175/?github description: API docs for the noDataPage plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'noDataPage'] --- import noDataPageObj from './no_data_page.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index 385dacb9c00bf3..adcdf65421338e 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.devdocs.json b/api_docs/observability.devdocs.json index 10fc931bda74ae..deb64ecc9534ed 100644 --- a/api_docs/observability.devdocs.json +++ b/api_docs/observability.devdocs.json @@ -2693,6 +2693,27 @@ "path": "x-pack/plugins/observability/public/plugin.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-public.ObservabilityPublicPluginsSetup.presentationUtil", + "type": "Object", + "tags": [], + "label": "presentationUtil", + "description": [], + "signature": [ + { + "pluginId": "presentationUtil", + "scope": "public", + "docId": "kibPresentationUtilPluginApi", + "section": "def-public.PresentationUtilPluginStart", + "text": "PresentationUtilPluginStart" + }, + " | undefined" + ], + "path": "x-pack/plugins/observability/public/plugin.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -3455,6 +3476,27 @@ "path": "x-pack/plugins/observability/public/plugin.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-public.ObservabilityPublicPluginsStart.presentationUtil", + "type": "Object", + "tags": [], + "label": "presentationUtil", + "description": [], + "signature": [ + { + "pluginId": "presentationUtil", + "scope": "public", + "docId": "kibPresentationUtilPluginApi", + "section": "def-public.PresentationUtilPluginStart", + "text": "PresentationUtilPluginStart" + }, + " | undefined" + ], + "path": "x-pack/plugins/observability/public/plugin.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -8156,7 +8198,7 @@ "label": "config", "description": [], "signature": [ - "{ readonly enabled: boolean; readonly unsafe: Readonly<{} & { alertDetails: Readonly<{} & { uptime: Readonly<{} & { enabled: boolean; }>; observability: Readonly<{} & { enabled: boolean; }>; metrics: Readonly<{} & { enabled: boolean; }>; logs: Readonly<{} & { enabled: boolean; }>; }>; thresholdRule: Readonly<{} & { enabled: boolean; }>; }>; readonly annotations: Readonly<{} & { index: string; enabled: boolean; }>; readonly customThresholdRule: Readonly<{} & { groupByPageSize: number; }>; readonly createO11yGenericFeatureId: boolean; }" + "{ readonly enabled: boolean; readonly unsafe: Readonly<{} & { alertDetails: Readonly<{} & { uptime: Readonly<{} & { enabled: boolean; }>; observability: Readonly<{} & { enabled: boolean; }>; metrics: Readonly<{} & { enabled: boolean; }>; logs: Readonly<{} & { enabled: boolean; }>; }>; thresholdRule: Readonly<{} & { enabled: boolean; }>; }>; readonly annotations: Readonly<{} & { index: string; enabled: boolean; }>; readonly customThresholdRule: Readonly<{} & { groupByPageSize: number; }>; readonly createO11yGenericFeatureId: boolean; readonly sloOrphanSummaryCleanUpTaskEnabled: boolean; }" ], "path": "x-pack/plugins/observability/server/routes/types.ts", "deprecated": false, @@ -9956,7 +9998,7 @@ "label": "ObservabilityConfig", "description": [], "signature": [ - "{ readonly enabled: boolean; readonly unsafe: Readonly<{} & { alertDetails: Readonly<{} & { uptime: Readonly<{} & { enabled: boolean; }>; observability: Readonly<{} & { enabled: boolean; }>; metrics: Readonly<{} & { enabled: boolean; }>; logs: Readonly<{} & { enabled: boolean; }>; }>; thresholdRule: Readonly<{} & { enabled: boolean; }>; }>; readonly annotations: Readonly<{} & { index: string; enabled: boolean; }>; readonly customThresholdRule: Readonly<{} & { groupByPageSize: number; }>; readonly createO11yGenericFeatureId: boolean; }" + "{ readonly enabled: boolean; readonly unsafe: Readonly<{} & { alertDetails: Readonly<{} & { uptime: Readonly<{} & { enabled: boolean; }>; observability: Readonly<{} & { enabled: boolean; }>; metrics: Readonly<{} & { enabled: boolean; }>; logs: Readonly<{} & { enabled: boolean; }>; }>; thresholdRule: Readonly<{} & { enabled: boolean; }>; }>; readonly annotations: Readonly<{} & { index: string; enabled: boolean; }>; readonly customThresholdRule: Readonly<{} & { groupByPageSize: number; }>; readonly createO11yGenericFeatureId: boolean; readonly sloOrphanSummaryCleanUpTaskEnabled: boolean; }" ], "path": "x-pack/plugins/observability/server/index.ts", "deprecated": false, @@ -12905,6 +12947,90 @@ } ] }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableInfrastructureProfilingIntegration", + "type": "Object", + "tags": [], + "label": "[enableInfrastructureProfilingIntegration]", + "description": [], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableInfrastructureProfilingIntegration.category", + "type": "Array", + "tags": [], + "label": "category", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableInfrastructureProfilingIntegration.name", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableInfrastructureProfilingIntegration.value", + "type": "boolean", + "tags": [], + "label": "value", + "description": [], + "signature": [ + "true" + ], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableInfrastructureProfilingIntegration.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableInfrastructureProfilingIntegration.schema", + "type": "Object", + "tags": [], + "label": "schema", + "description": [], + "signature": [ + { + "pluginId": "@kbn/config-schema", + "scope": "common", + "docId": "kibKbnConfigSchemaPluginApi", + "section": "def-common.Type", + "text": "Type" + }, + "" + ], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + } + ] + }, { "parentPluginId": "observability", "id": "def-server.uiSettings.enableAwsLambdaMetrics", @@ -15905,6 +16031,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "observability", + "id": "def-common.enableInfrastructureProfilingIntegration", + "type": "string", + "tags": [], + "label": "enableInfrastructureProfilingIntegration", + "description": [], + "signature": [ + "\"observability:enableInfrastructureProfilingIntegration\"" + ], + "path": "x-pack/plugins/observability/common/ui_settings_keys.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "observability", "id": "def-common.enableInspectEsQueries", diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index d78e87accec3f4..f27da99a8627f4 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/ | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 600 | 2 | 591 | 17 | +| 609 | 2 | 600 | 17 | ## Client diff --git a/api_docs/observability_a_i_assistant.devdocs.json b/api_docs/observability_a_i_assistant.devdocs.json index e8ddc39eb1e867..9d3e36465047cb 100644 --- a/api_docs/observability_a_i_assistant.devdocs.json +++ b/api_docs/observability_a_i_assistant.devdocs.json @@ -2,185 +2,7 @@ "id": "observabilityAIAssistant", "client": { "classes": [], - "functions": [ - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.ContextualInsight", - "type": "Function", - "tags": [], - "label": "ContextualInsight", - "description": [], - "signature": [ - "React.ForwardRefExoticComponent<{ messages: ", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Message", - "text": "Message" - }, - "[]; title: string; dataTestSubj?: string | undefined; } & ", - { - "pluginId": "@kbn/shared-ux-utility", - "scope": "common", - "docId": "kibKbnSharedUxUtilityPluginApi", - "section": "def-common.WithSuspenseExtendedDeps", - "text": "WithSuspenseExtendedDeps" - }, - " & React.RefAttributes<{}>>" - ], - "path": "x-pack/plugins/observability_ai_assistant/public/index.ts", - "deprecated": false, - "trackAdoption": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.ContextualInsight.$1", - "type": "Uncategorized", - "tags": [], - "label": "props", - "description": [], - "signature": [ - "P" - ], - "path": "node_modules/@types/react/index.d.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.ObservabilityAIAssistantActionMenuItem", - "type": "Function", - "tags": [], - "label": "ObservabilityAIAssistantActionMenuItem", - "description": [], - "signature": [ - "React.ForwardRefExoticComponent<", - { - "pluginId": "@kbn/shared-ux-utility", - "scope": "common", - "docId": "kibKbnSharedUxUtilityPluginApi", - "section": "def-common.WithSuspenseExtendedDeps", - "text": "WithSuspenseExtendedDeps" - }, - " & React.RefAttributes<{}>>" - ], - "path": "x-pack/plugins/observability_ai_assistant/public/index.ts", - "deprecated": false, - "trackAdoption": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.ObservabilityAIAssistantActionMenuItem.$1", - "type": "Uncategorized", - "tags": [], - "label": "props", - "description": [], - "signature": [ - "P" - ], - "path": "node_modules/@types/react/index.d.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.ObservabilityAIAssistantProvider", - "type": "Function", - "tags": [], - "label": "ObservabilityAIAssistantProvider", - "description": [], - "signature": [ - "React.ProviderExoticComponent>" - ], - "path": "x-pack/plugins/observability_ai_assistant/public/context/observability_ai_assistant_provider.tsx", - "deprecated": false, - "trackAdoption": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.ObservabilityAIAssistantProvider.$1", - "type": "Uncategorized", - "tags": [], - "label": "props", - "description": [], - "signature": [ - "P" - ], - "path": "node_modules/@types/react/index.d.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.useObservabilityAIAssistant", - "type": "Function", - "tags": [], - "label": "useObservabilityAIAssistant", - "description": [], - "signature": [ - "() => ", - { - "pluginId": "observabilityAIAssistant", - "scope": "public", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-public.ObservabilityAIAssistantService", - "text": "ObservabilityAIAssistantService" - } - ], - "path": "x-pack/plugins/observability_ai_assistant/public/hooks/use_observability_ai_assistant.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.useObservabilityAIAssistantOptional", - "type": "Function", - "tags": [], - "label": "useObservabilityAIAssistantOptional", - "description": [], - "signature": [ - "() => ", - { - "pluginId": "observabilityAIAssistant", - "scope": "public", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-public.ObservabilityAIAssistantService", - "text": "ObservabilityAIAssistantService" - }, - " | undefined" - ], - "path": "x-pack/plugins/observability_ai_assistant/public/hooks/use_observability_ai_assistant.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - } - ], + "functions": [], "interfaces": [ { "parentPluginId": "observabilityAIAssistant", @@ -2846,1221 +2668,7 @@ "initialIsOpen": false } ], - "objects": [ - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.mockService", - "type": "Object", - "tags": [], - "label": "mockService", - "description": [], - "path": "x-pack/plugins/observability_ai_assistant/public/utils/storybook_decorator.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.mockService.isEnabled", - "type": "Function", - "tags": [], - "label": "isEnabled", - "description": [], - "signature": [ - "() => true" - ], - "path": "x-pack/plugins/observability_ai_assistant/public/utils/storybook_decorator.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.mockService.start", - "type": "Function", - "tags": [], - "label": "start", - "description": [], - "signature": [ - "() => Promise<", - "ObservabilityAIAssistantChatService", - ">" - ], - "path": "x-pack/plugins/observability_ai_assistant/public/utils/storybook_decorator.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.mockService.callApi", - "type": "Function", - "tags": [], - "label": "callApi", - "description": [], - "signature": [ - "(endpoint: TEndpoint, ...args: MaybeOptionalArgs<", - { - "pluginId": "@kbn/server-route-repository", - "scope": "common", - "docId": "kibKbnServerRouteRepositoryPluginApi", - "section": "def-common.ClientRequestParamsOf", - "text": "ClientRequestParamsOf" - }, - "<{ \"DELETE /internal/observability_ai_assistant/kb/entries/{entryId}\": { endpoint: \"DELETE /internal/observability_ai_assistant/kb/entries/{entryId}\"; params?: ", - "TypeC", - "<{ path: ", - "TypeC", - "<{ entryId: ", - "StringC", - "; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { path: { entryId: string; }; }; }) => Promise; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/kb/entries/save\": { endpoint: \"POST /internal/observability_ai_assistant/kb/entries/save\"; params?: ", - "TypeC", - "<{ body: ", - "IntersectionC", - "<[", - "TypeC", - "<{ id: ", - "StringC", - "; text: ", - "BrandC", - "<", - "StringC", - ", ", - { - "pluginId": "@kbn/io-ts-utils", - "scope": "common", - "docId": "kibKbnIoTsUtilsPluginApi", - "section": "def-common.NonEmptyStringBrand", - "text": "NonEmptyStringBrand" - }, - ">; }>, ", - "PartialC", - "<{ confidence: ", - "UnionC", - "<[", - "LiteralC", - "<\"low\">, ", - "LiteralC", - "<\"medium\">, ", - "LiteralC", - "<\"high\">]>; is_correction: ", - "Type", - "; public: ", - "Type", - "; labels: ", - "RecordC", - "<", - "StringC", - ", ", - "StringC", - ">; role: ", - "UnionC", - "<[", - "LiteralC", - "<\"assistant_summarization\">, ", - "LiteralC", - "<\"user_entry\">, ", - "LiteralC", - "<\"elastic\">]>; }>]>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { body: { id: string; text: ", - "Branded", - "; } & { confidence?: \"medium\" | \"high\" | \"low\" | undefined; is_correction?: boolean | undefined; public?: boolean | undefined; labels?: { [x: string]: string; } | undefined; role?: \"elastic\" | \"assistant_summarization\" | \"user_entry\" | undefined; }; }; }) => Promise; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/kb/entries/import\": { endpoint: \"POST /internal/observability_ai_assistant/kb/entries/import\"; params?: ", - "TypeC", - "<{ body: ", - "TypeC", - "<{ entries: ", - "ArrayC", - "<", - "TypeC", - "<{ id: ", - "StringC", - "; text: ", - "BrandC", - "<", - "StringC", - ", ", - { - "pluginId": "@kbn/io-ts-utils", - "scope": "common", - "docId": "kibKbnIoTsUtilsPluginApi", - "section": "def-common.NonEmptyStringBrand", - "text": "NonEmptyStringBrand" - }, - ">; }>>; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { body: { entries: { id: string; text: ", - "Branded", - "; }[]; }; }; }) => Promise; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"GET /internal/observability_ai_assistant/kb/entries\": { endpoint: \"GET /internal/observability_ai_assistant/kb/entries\"; params?: ", - "TypeC", - "<{ query: ", - "TypeC", - "<{ query: ", - "StringC", - "; sortBy: ", - "StringC", - "; sortDirection: ", - "UnionC", - "<[", - "LiteralC", - "<\"asc\">, ", - "LiteralC", - "<\"desc\">]>; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { query: { query: string; sortBy: string; sortDirection: \"asc\" | \"desc\"; }; }; }) => Promise<{ entries: ", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.KnowledgeBaseEntry", - "text": "KnowledgeBaseEntry" - }, - "[]; }>; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"GET /internal/observability_ai_assistant/kb/status\": { endpoint: \"GET /internal/observability_ai_assistant/kb/status\"; params?: undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - ") => Promise<{ ready: boolean; error?: any; deployment_state?: ", - "MlDeploymentState", - " | undefined; allocation_state?: ", - "MlDeploymentAllocationState", - " | undefined; model_name?: string | undefined; }>; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/kb/setup\": { endpoint: \"POST /internal/observability_ai_assistant/kb/setup\"; params?: undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - ") => Promise<{}>; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/functions/summarize\": { endpoint: \"POST /internal/observability_ai_assistant/functions/summarize\"; params?: ", - "TypeC", - "<{ body: ", - "TypeC", - "<{ id: ", - "StringC", - "; text: ", - "BrandC", - "<", - "StringC", - ", ", - { - "pluginId": "@kbn/io-ts-utils", - "scope": "common", - "docId": "kibKbnIoTsUtilsPluginApi", - "section": "def-common.NonEmptyStringBrand", - "text": "NonEmptyStringBrand" - }, - ">; confidence: ", - "UnionC", - "<[", - "LiteralC", - "<\"low\">, ", - "LiteralC", - "<\"medium\">, ", - "LiteralC", - "<\"high\">]>; is_correction: ", - "Type", - "; public: ", - "Type", - "; labels: ", - "RecordC", - "<", - "StringC", - ", ", - "StringC", - ">; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { body: { id: string; text: ", - "Branded", - "; confidence: \"medium\" | \"high\" | \"low\"; is_correction: boolean; public: boolean; labels: { [x: string]: string; }; }; }; }) => Promise; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/functions/recall\": { endpoint: \"POST /internal/observability_ai_assistant/functions/recall\"; params?: ", - "TypeC", - "<{ body: ", - "IntersectionC", - "<[", - "TypeC", - "<{ queries: ", - "ArrayC", - "<", - "BrandC", - "<", - "StringC", - ", ", - { - "pluginId": "@kbn/io-ts-utils", - "scope": "common", - "docId": "kibKbnIoTsUtilsPluginApi", - "section": "def-common.NonEmptyStringBrand", - "text": "NonEmptyStringBrand" - }, - ">>; }>, ", - "PartialC", - "<{ contexts: ", - "ArrayC", - "<", - "StringC", - ">; }>]>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { body: { queries: ", - "Branded", - "[]; } & { contexts?: string[] | undefined; }; }; }) => Promise<{ entries: ", - "RecalledEntry", - "[]; }>; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"GET /internal/observability_ai_assistant/functions\": { endpoint: \"GET /internal/observability_ai_assistant/functions\"; params?: undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - ") => Promise<{ functionDefinitions: ", - "FunctionDefinition", - "<", - "CompatibleJSONSchema", - ">[]; contextDefinitions: ", - "ContextDefinition", - "[]; }>; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"GET /internal/observability_ai_assistant/connectors\": { endpoint: \"GET /internal/observability_ai_assistant/connectors\"; params?: undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - ") => Promise<", - { - "pluginId": "actions", - "scope": "server", - "docId": "kibActionsPluginApi", - "section": "def-server.ConnectorWithExtraFindData", - "text": "ConnectorWithExtraFindData" - }, - "[]>; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"DELETE /internal/observability_ai_assistant/conversation/{conversationId}\": { endpoint: \"DELETE /internal/observability_ai_assistant/conversation/{conversationId}\"; params?: ", - "TypeC", - "<{ path: ", - "TypeC", - "<{ conversationId: ", - "StringC", - "; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { path: { conversationId: string; }; }; }) => Promise; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"PUT /internal/observability_ai_assistant/conversation/{conversationId}/title\": { endpoint: \"PUT /internal/observability_ai_assistant/conversation/{conversationId}/title\"; params?: ", - "TypeC", - "<{ path: ", - "TypeC", - "<{ conversationId: ", - "StringC", - "; }>; body: ", - "TypeC", - "<{ title: ", - "StringC", - "; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { path: { conversationId: string; }; body: { title: string; }; }; }) => Promise<", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Conversation", - "text": "Conversation" - }, - ">; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"PUT /internal/observability_ai_assistant/conversation/{conversationId}\": { endpoint: \"PUT /internal/observability_ai_assistant/conversation/{conversationId}\"; params?: ", - "TypeC", - "<{ path: ", - "TypeC", - "<{ conversationId: ", - "StringC", - "; }>; body: ", - "TypeC", - "<{ conversation: ", - "Type", - "<", - "ConversationUpdateRequest", - ", ", - "ConversationUpdateRequest", - ", unknown>; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { path: { conversationId: string; }; body: { conversation: ", - "ConversationUpdateRequest", - "; }; }; }) => Promise<", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Conversation", - "text": "Conversation" - }, - ">; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/conversation\": { endpoint: \"POST /internal/observability_ai_assistant/conversation\"; params?: ", - "TypeC", - "<{ body: ", - "TypeC", - "<{ conversation: ", - "Type", - "<", - "ConversationRequestBase", - ", ", - "ConversationRequestBase", - ", unknown>; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { body: { conversation: ", - "ConversationRequestBase", - "; }; }; }) => Promise<", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Conversation", - "text": "Conversation" - }, - ">; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/conversations\": { endpoint: \"POST /internal/observability_ai_assistant/conversations\"; params?: ", - "PartialC", - "<{ body: ", - "PartialC", - "<{ query: ", - "StringC", - "; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params?: { body?: { query?: string | undefined; } | undefined; } | undefined; }) => Promise<{ conversations: ", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Conversation", - "text": "Conversation" - }, - "[]; }>; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"GET /internal/observability_ai_assistant/conversation/{conversationId}\": { endpoint: \"GET /internal/observability_ai_assistant/conversation/{conversationId}\"; params?: ", - "TypeC", - "<{ path: ", - "TypeC", - "<{ conversationId: ", - "StringC", - "; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { path: { conversationId: string; }; }; }) => Promise<", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Conversation", - "text": "Conversation" - }, - ">; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/chat/complete\": { endpoint: \"POST /internal/observability_ai_assistant/chat/complete\"; params?: ", - "TypeC", - "<{ body: ", - "IntersectionC", - "<[", - "TypeC", - "<{ messages: ", - "ArrayC", - "<", - "Type", - "<", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Message", - "text": "Message" - }, - ", ", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Message", - "text": "Message" - }, - ", unknown>>; connectorId: ", - "StringC", - "; persist: ", - "Type", - "; }>, ", - "PartialC", - "<{ conversationId: ", - "StringC", - "; title: ", - "StringC", - "; }>]>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { body: { messages: ", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Message", - "text": "Message" - }, - "[]; connectorId: string; persist: boolean; } & { conversationId?: string | undefined; title?: string | undefined; }; }; }) => Promise<", - "Readable", - " | ", - "CreateChatCompletionResponse", - ">; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/chat\": { endpoint: \"POST /internal/observability_ai_assistant/chat\"; params?: ", - "IntersectionC", - "<[", - "TypeC", - "<{ body: ", - "IntersectionC", - "<[", - "TypeC", - "<{ messages: ", - "ArrayC", - "<", - "Type", - "<", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Message", - "text": "Message" - }, - ", ", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Message", - "text": "Message" - }, - ", unknown>>; connectorId: ", - "StringC", - "; functions: ", - "ArrayC", - "<", - "TypeC", - "<{ name: ", - "StringC", - "; description: ", - "StringC", - "; parameters: ", - "AnyC", - "; }>>; }>, ", - "PartialC", - "<{ functionCall: ", - "StringC", - "; }>]>; }>, ", - "PartialC", - "<{ query: ", - "TypeC", - "<{ stream: ", - "Type", - "; }>; }>]> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { body: { messages: ", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Message", - "text": "Message" - }, - "[]; connectorId: string; functions: { name: string; description: string; parameters: any; }[]; } & { functionCall?: string | undefined; }; } & { query?: { stream: boolean; } | undefined; }; }) => Promise<", - "Readable", - " | ", - "CreateChatCompletionResponse", - ">; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; }, TEndpoint> & Omit & { signal: AbortSignal | null; }>) => Promise<", - { - "pluginId": "@kbn/server-route-repository", - "scope": "common", - "docId": "kibKbnServerRouteRepositoryPluginApi", - "section": "def-common.ReturnOf", - "text": "ReturnOf" - }, - "<{ \"DELETE /internal/observability_ai_assistant/kb/entries/{entryId}\": { endpoint: \"DELETE /internal/observability_ai_assistant/kb/entries/{entryId}\"; params?: ", - "TypeC", - "<{ path: ", - "TypeC", - "<{ entryId: ", - "StringC", - "; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { path: { entryId: string; }; }; }) => Promise; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/kb/entries/save\": { endpoint: \"POST /internal/observability_ai_assistant/kb/entries/save\"; params?: ", - "TypeC", - "<{ body: ", - "IntersectionC", - "<[", - "TypeC", - "<{ id: ", - "StringC", - "; text: ", - "BrandC", - "<", - "StringC", - ", ", - { - "pluginId": "@kbn/io-ts-utils", - "scope": "common", - "docId": "kibKbnIoTsUtilsPluginApi", - "section": "def-common.NonEmptyStringBrand", - "text": "NonEmptyStringBrand" - }, - ">; }>, ", - "PartialC", - "<{ confidence: ", - "UnionC", - "<[", - "LiteralC", - "<\"low\">, ", - "LiteralC", - "<\"medium\">, ", - "LiteralC", - "<\"high\">]>; is_correction: ", - "Type", - "; public: ", - "Type", - "; labels: ", - "RecordC", - "<", - "StringC", - ", ", - "StringC", - ">; role: ", - "UnionC", - "<[", - "LiteralC", - "<\"assistant_summarization\">, ", - "LiteralC", - "<\"user_entry\">, ", - "LiteralC", - "<\"elastic\">]>; }>]>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { body: { id: string; text: ", - "Branded", - "; } & { confidence?: \"medium\" | \"high\" | \"low\" | undefined; is_correction?: boolean | undefined; public?: boolean | undefined; labels?: { [x: string]: string; } | undefined; role?: \"elastic\" | \"assistant_summarization\" | \"user_entry\" | undefined; }; }; }) => Promise; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/kb/entries/import\": { endpoint: \"POST /internal/observability_ai_assistant/kb/entries/import\"; params?: ", - "TypeC", - "<{ body: ", - "TypeC", - "<{ entries: ", - "ArrayC", - "<", - "TypeC", - "<{ id: ", - "StringC", - "; text: ", - "BrandC", - "<", - "StringC", - ", ", - { - "pluginId": "@kbn/io-ts-utils", - "scope": "common", - "docId": "kibKbnIoTsUtilsPluginApi", - "section": "def-common.NonEmptyStringBrand", - "text": "NonEmptyStringBrand" - }, - ">; }>>; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { body: { entries: { id: string; text: ", - "Branded", - "; }[]; }; }; }) => Promise; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"GET /internal/observability_ai_assistant/kb/entries\": { endpoint: \"GET /internal/observability_ai_assistant/kb/entries\"; params?: ", - "TypeC", - "<{ query: ", - "TypeC", - "<{ query: ", - "StringC", - "; sortBy: ", - "StringC", - "; sortDirection: ", - "UnionC", - "<[", - "LiteralC", - "<\"asc\">, ", - "LiteralC", - "<\"desc\">]>; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { query: { query: string; sortBy: string; sortDirection: \"asc\" | \"desc\"; }; }; }) => Promise<{ entries: ", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.KnowledgeBaseEntry", - "text": "KnowledgeBaseEntry" - }, - "[]; }>; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"GET /internal/observability_ai_assistant/kb/status\": { endpoint: \"GET /internal/observability_ai_assistant/kb/status\"; params?: undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - ") => Promise<{ ready: boolean; error?: any; deployment_state?: ", - "MlDeploymentState", - " | undefined; allocation_state?: ", - "MlDeploymentAllocationState", - " | undefined; model_name?: string | undefined; }>; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/kb/setup\": { endpoint: \"POST /internal/observability_ai_assistant/kb/setup\"; params?: undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - ") => Promise<{}>; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/functions/summarize\": { endpoint: \"POST /internal/observability_ai_assistant/functions/summarize\"; params?: ", - "TypeC", - "<{ body: ", - "TypeC", - "<{ id: ", - "StringC", - "; text: ", - "BrandC", - "<", - "StringC", - ", ", - { - "pluginId": "@kbn/io-ts-utils", - "scope": "common", - "docId": "kibKbnIoTsUtilsPluginApi", - "section": "def-common.NonEmptyStringBrand", - "text": "NonEmptyStringBrand" - }, - ">; confidence: ", - "UnionC", - "<[", - "LiteralC", - "<\"low\">, ", - "LiteralC", - "<\"medium\">, ", - "LiteralC", - "<\"high\">]>; is_correction: ", - "Type", - "; public: ", - "Type", - "; labels: ", - "RecordC", - "<", - "StringC", - ", ", - "StringC", - ">; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { body: { id: string; text: ", - "Branded", - "; confidence: \"medium\" | \"high\" | \"low\"; is_correction: boolean; public: boolean; labels: { [x: string]: string; }; }; }; }) => Promise; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/functions/recall\": { endpoint: \"POST /internal/observability_ai_assistant/functions/recall\"; params?: ", - "TypeC", - "<{ body: ", - "IntersectionC", - "<[", - "TypeC", - "<{ queries: ", - "ArrayC", - "<", - "BrandC", - "<", - "StringC", - ", ", - { - "pluginId": "@kbn/io-ts-utils", - "scope": "common", - "docId": "kibKbnIoTsUtilsPluginApi", - "section": "def-common.NonEmptyStringBrand", - "text": "NonEmptyStringBrand" - }, - ">>; }>, ", - "PartialC", - "<{ contexts: ", - "ArrayC", - "<", - "StringC", - ">; }>]>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { body: { queries: ", - "Branded", - "[]; } & { contexts?: string[] | undefined; }; }; }) => Promise<{ entries: ", - "RecalledEntry", - "[]; }>; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"GET /internal/observability_ai_assistant/functions\": { endpoint: \"GET /internal/observability_ai_assistant/functions\"; params?: undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - ") => Promise<{ functionDefinitions: ", - "FunctionDefinition", - "<", - "CompatibleJSONSchema", - ">[]; contextDefinitions: ", - "ContextDefinition", - "[]; }>; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"GET /internal/observability_ai_assistant/connectors\": { endpoint: \"GET /internal/observability_ai_assistant/connectors\"; params?: undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - ") => Promise<", - { - "pluginId": "actions", - "scope": "server", - "docId": "kibActionsPluginApi", - "section": "def-server.ConnectorWithExtraFindData", - "text": "ConnectorWithExtraFindData" - }, - "[]>; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"DELETE /internal/observability_ai_assistant/conversation/{conversationId}\": { endpoint: \"DELETE /internal/observability_ai_assistant/conversation/{conversationId}\"; params?: ", - "TypeC", - "<{ path: ", - "TypeC", - "<{ conversationId: ", - "StringC", - "; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { path: { conversationId: string; }; }; }) => Promise; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"PUT /internal/observability_ai_assistant/conversation/{conversationId}/title\": { endpoint: \"PUT /internal/observability_ai_assistant/conversation/{conversationId}/title\"; params?: ", - "TypeC", - "<{ path: ", - "TypeC", - "<{ conversationId: ", - "StringC", - "; }>; body: ", - "TypeC", - "<{ title: ", - "StringC", - "; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { path: { conversationId: string; }; body: { title: string; }; }; }) => Promise<", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Conversation", - "text": "Conversation" - }, - ">; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"PUT /internal/observability_ai_assistant/conversation/{conversationId}\": { endpoint: \"PUT /internal/observability_ai_assistant/conversation/{conversationId}\"; params?: ", - "TypeC", - "<{ path: ", - "TypeC", - "<{ conversationId: ", - "StringC", - "; }>; body: ", - "TypeC", - "<{ conversation: ", - "Type", - "<", - "ConversationUpdateRequest", - ", ", - "ConversationUpdateRequest", - ", unknown>; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { path: { conversationId: string; }; body: { conversation: ", - "ConversationUpdateRequest", - "; }; }; }) => Promise<", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Conversation", - "text": "Conversation" - }, - ">; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/conversation\": { endpoint: \"POST /internal/observability_ai_assistant/conversation\"; params?: ", - "TypeC", - "<{ body: ", - "TypeC", - "<{ conversation: ", - "Type", - "<", - "ConversationRequestBase", - ", ", - "ConversationRequestBase", - ", unknown>; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { body: { conversation: ", - "ConversationRequestBase", - "; }; }; }) => Promise<", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Conversation", - "text": "Conversation" - }, - ">; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/conversations\": { endpoint: \"POST /internal/observability_ai_assistant/conversations\"; params?: ", - "PartialC", - "<{ body: ", - "PartialC", - "<{ query: ", - "StringC", - "; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params?: { body?: { query?: string | undefined; } | undefined; } | undefined; }) => Promise<{ conversations: ", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Conversation", - "text": "Conversation" - }, - "[]; }>; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"GET /internal/observability_ai_assistant/conversation/{conversationId}\": { endpoint: \"GET /internal/observability_ai_assistant/conversation/{conversationId}\"; params?: ", - "TypeC", - "<{ path: ", - "TypeC", - "<{ conversationId: ", - "StringC", - "; }>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { path: { conversationId: string; }; }; }) => Promise<", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Conversation", - "text": "Conversation" - }, - ">; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/chat/complete\": { endpoint: \"POST /internal/observability_ai_assistant/chat/complete\"; params?: ", - "TypeC", - "<{ body: ", - "IntersectionC", - "<[", - "TypeC", - "<{ messages: ", - "ArrayC", - "<", - "Type", - "<", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Message", - "text": "Message" - }, - ", ", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Message", - "text": "Message" - }, - ", unknown>>; connectorId: ", - "StringC", - "; persist: ", - "Type", - "; }>, ", - "PartialC", - "<{ conversationId: ", - "StringC", - "; title: ", - "StringC", - "; }>]>; }> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { body: { messages: ", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Message", - "text": "Message" - }, - "[]; connectorId: string; persist: boolean; } & { conversationId?: string | undefined; title?: string | undefined; }; }; }) => Promise<", - "Readable", - " | ", - "CreateChatCompletionResponse", - ">; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; \"POST /internal/observability_ai_assistant/chat\": { endpoint: \"POST /internal/observability_ai_assistant/chat\"; params?: ", - "IntersectionC", - "<[", - "TypeC", - "<{ body: ", - "IntersectionC", - "<[", - "TypeC", - "<{ messages: ", - "ArrayC", - "<", - "Type", - "<", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Message", - "text": "Message" - }, - ", ", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Message", - "text": "Message" - }, - ", unknown>>; connectorId: ", - "StringC", - "; functions: ", - "ArrayC", - "<", - "TypeC", - "<{ name: ", - "StringC", - "; description: ", - "StringC", - "; parameters: ", - "AnyC", - "; }>>; }>, ", - "PartialC", - "<{ functionCall: ", - "StringC", - "; }>]>; }>, ", - "PartialC", - "<{ query: ", - "TypeC", - "<{ stream: ", - "Type", - "; }>; }>]> | undefined; handler: ({}: ", - "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { body: { messages: ", - { - "pluginId": "observabilityAIAssistant", - "scope": "common", - "docId": "kibObservabilityAIAssistantPluginApi", - "section": "def-common.Message", - "text": "Message" - }, - "[]; connectorId: string; functions: { name: string; description: string; parameters: any; }[]; } & { functionCall?: string | undefined; }; } & { query?: { stream: boolean; } | undefined; }; }) => Promise<", - "Readable", - " | ", - "CreateChatCompletionResponse", - ">; } & ", - "ObservabilityAIAssistantRouteCreateOptions", - "; }, TEndpoint>>" - ], - "path": "x-pack/plugins/observability_ai_assistant/public/utils/storybook_decorator.tsx", - "deprecated": false, - "trackAdoption": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.mockService.callApi.$1", - "type": "Uncategorized", - "tags": [], - "label": "endpoint", - "description": [], - "signature": [ - "TEndpoint" - ], - "path": "packages/kbn-server-route-repository/src/typings.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.mockService.callApi.$2", - "type": "Uncategorized", - "tags": [], - "label": "args", - "description": [], - "signature": [ - "RequiredKeys", - "<", - { - "pluginId": "@kbn/server-route-repository", - "scope": "common", - "docId": "kibKbnServerRouteRepositoryPluginApi", - "section": "def-common.ClientRequestParamsOf", - "text": "ClientRequestParamsOf" - }, - " & TAdditionalClientOptions> extends never ? [] | [", - { - "pluginId": "@kbn/server-route-repository", - "scope": "common", - "docId": "kibKbnServerRouteRepositoryPluginApi", - "section": "def-common.ClientRequestParamsOf", - "text": "ClientRequestParamsOf" - }, - " & TAdditionalClientOptions] : [", - { - "pluginId": "@kbn/server-route-repository", - "scope": "common", - "docId": "kibKbnServerRouteRepositoryPluginApi", - "section": "def-common.ClientRequestParamsOf", - "text": "ClientRequestParamsOf" - }, - " & TAdditionalClientOptions]" - ], - "path": "packages/kbn-server-route-repository/src/typings.ts", - "deprecated": false, - "trackAdoption": false - } - ] - }, - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.mockService.getCurrentUser", - "type": "Function", - "tags": [], - "label": "getCurrentUser", - "description": [], - "signature": [ - "() => Promise<", - { - "pluginId": "@kbn/security-plugin-types-common", - "scope": "common", - "docId": "kibKbnSecurityPluginTypesCommonPluginApi", - "section": "def-common.AuthenticatedUser", - "text": "AuthenticatedUser" - }, - ">" - ], - "path": "x-pack/plugins/observability_ai_assistant/public/utils/storybook_decorator.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.mockService.getLicense", - "type": "Function", - "tags": [], - "label": "getLicense", - "description": [], - "signature": [ - "() => ", - "Observable", - "<", - "ILicense", - ">" - ], - "path": "x-pack/plugins/observability_ai_assistant/public/utils/storybook_decorator.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.mockService.getLicenseManagementLocator", - "type": "Function", - "tags": [], - "label": "getLicenseManagementLocator", - "description": [], - "signature": [ - "() => ", - { - "pluginId": "share", - "scope": "public", - "docId": "kibSharePluginApi", - "section": "def-public.SharePublicStart", - "text": "SharePublicStart" - } - ], - "path": "x-pack/plugins/observability_ai_assistant/public/utils/storybook_decorator.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "observabilityAIAssistant", - "id": "def-public.mockService.register", - "type": "Function", - "tags": [], - "label": "register", - "description": [], - "signature": [ - "() => void" - ], - "path": "x-pack/plugins/observability_ai_assistant/public/utils/storybook_decorator.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] - } - ], - "initialIsOpen": false - } - ], + "objects": [], "setup": { "parentPluginId": "observabilityAIAssistant", "id": "def-public.ObservabilityAIAssistantPluginSetup", @@ -4106,6 +2714,44 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "observabilityAIAssistant", + "id": "def-public.ObservabilityAIAssistantPluginStart.ObservabilityAIAssistantContextualInsight", + "type": "CompoundType", + "tags": [], + "label": "ObservabilityAIAssistantContextualInsight", + "description": [], + "signature": [ + "React.ForwardRefExoticComponent<", + "InsightProps", + "> | null" + ], + "path": "x-pack/plugins/observability_ai_assistant/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observabilityAIAssistant", + "id": "def-public.ObservabilityAIAssistantPluginStart.ObservabilityAIAssistantActionMenuItem", + "type": "CompoundType", + "tags": [], + "label": "ObservabilityAIAssistantActionMenuItem", + "description": [], + "signature": [ + "React.ForwardRefExoticComponent & ", + { + "pluginId": "@kbn/shared-ux-utility", + "scope": "common", + "docId": "kibKbnSharedUxUtilityPluginApi", + "section": "def-common.WithSuspenseExtendedDeps", + "text": "WithSuspenseExtendedDeps" + }, + ", \"key\" | \"css\" | \"analytics\"> & React.RefAttributes<{}>> | null" + ], + "path": "x-pack/plugins/observability_ai_assistant/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "observabilityAIAssistant", "id": "def-public.ObservabilityAIAssistantPluginStart.useGenAIConnectors", diff --git a/api_docs/observability_a_i_assistant.mdx b/api_docs/observability_a_i_assistant.mdx index 90ad0891e35169..c32c8a3b28b8da 100644 --- a/api_docs/observability_a_i_assistant.mdx +++ b/api_docs/observability_a_i_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAIAssistant title: "observabilityAIAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAIAssistant plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistant'] --- import observabilityAIAssistantObj from './observability_a_i_assistant.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs- | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 91 | 0 | 86 | 12 | +| 75 | 0 | 73 | 13 | ## Client @@ -31,12 +31,6 @@ Contact [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs- ### Start -### Objects - - -### Functions - - ### Interfaces diff --git a/api_docs/observability_log_explorer.mdx b/api_docs/observability_log_explorer.mdx index 81d42a1361eece..9f33390c3e3fd2 100644 --- a/api_docs/observability_log_explorer.mdx +++ b/api_docs/observability_log_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityLogExplorer title: "observabilityLogExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityLogExplorer plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityLogExplorer'] --- import observabilityLogExplorerObj from './observability_log_explorer.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index f87755100a6d4e..aba1582e714bb8 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityOnboarding'] --- import observabilityOnboardingObj from './observability_onboarding.devdocs.json'; diff --git a/api_docs/observability_shared.mdx b/api_docs/observability_shared.mdx index 5334dab9e511c5..1cb30444ed9157 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityShared'] --- import observabilitySharedObj from './observability_shared.devdocs.json'; diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index 49504c2b52e393..7c844e7c20890f 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/painless_lab.mdx b/api_docs/painless_lab.mdx index e2c31190e4daf5..f402851a03758f 100644 --- a/api_docs/painless_lab.mdx +++ b/api_docs/painless_lab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/painlessLab title: "painlessLab" image: https://source.unsplash.com/400x175/?github description: API docs for the painlessLab plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'painlessLab'] --- import painlessLabObj from './painless_lab.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 5b4629b0ff00c5..17f08e2dbc8893 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 77945 | 234 | 66664 | 1632 | +| 77948 | 234 | 66667 | 1632 | ## Plugin Directory @@ -66,7 +66,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 31 | 3 | 25 | 1 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin introduces the concept of dataset quality, where users can easily get an overview on the datasets they have. | 8 | 0 | 8 | 2 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 12 | 0 | 10 | 3 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 136 | 0 | 91 | 21 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 137 | 0 | 91 | 21 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 2 | | | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | APIs used to assess the quality of data in Elasticsearch indexes | 2 | 0 | 0 | 0 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | Server APIs for the Elastic AI Assistant | 36 | 0 | 28 | 0 | @@ -92,7 +92,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'shape' function and renderer to expressions | 148 | 0 | 146 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Expression Tagcloud plugin adds a `tagcloud` renderer and function to the expression plugin. The renderer will display the `Wordcloud` chart. | 6 | 0 | 6 | 2 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Expression XY plugin adds a `xy` renderer and function to the expression plugin. The renderer will display the `xy` chart. | 177 | 0 | 167 | 13 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Adds expression runtime to Kibana | 2208 | 17 | 1749 | 5 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Adds expression runtime to Kibana | 2211 | 17 | 1752 | 5 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 235 | 0 | 99 | 2 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Index pattern fields and ambiguous values formatters | 292 | 5 | 253 | 3 | | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 59 | 0 | 59 | 2 | @@ -127,7 +127,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | A dashboard panel for creating links to dashboards or external links. | 57 | 0 | 57 | 6 | | | [@elastic/security-detection-engine](https://github.com/orgs/elastic/teams/security-detection-engine) | - | 224 | 0 | 96 | 51 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin provides a LogExplorer component using the Discover customization framework, offering several affordances specifically designed for log consumption. | 87 | 0 | 87 | 16 | -| | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | Exposes the shared components and APIs to access and visualize logs. | 289 | 11 | 274 | 27 | +| | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | Exposes the shared components and APIs to access and visualize logs. | 291 | 11 | 276 | 26 | | logstash | [@elastic/logstash](https://github.com/orgs/elastic/teams/logstash) | - | 0 | 0 | 0 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 45 | 0 | 45 | 7 | | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 260 | 0 | 259 | 28 | @@ -141,8 +141,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 17 | 0 | 17 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 3 | 0 | 3 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 1 | -| | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 600 | 2 | 591 | 17 | -| | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 91 | 0 | 86 | 12 | +| | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 609 | 2 | 600 | 17 | +| | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 75 | 0 | 73 | 13 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin exposes and registers observability log consumption features. | 18 | 0 | 18 | 1 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 14 | 0 | 14 | 0 | | | [@elastic/observability-ui](https://github.com/orgs/elastic/teams/observability-ui) | - | 307 | 1 | 303 | 15 | @@ -410,8 +410,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 29 | 0 | 4 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 15 | 0 | 14 | 1 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 9 | 0 | 9 | 0 | -| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 6 | 0 | 4 | 0 | -| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 6 | 0 | 6 | 0 | +| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 6 | 0 | 2 | 0 | +| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 9 | 0 | 9 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 33 | 2 | 20 | 1 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 11 | 1 | 11 | 3 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 8 | 0 | 8 | 0 | @@ -459,7 +459,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 48 | 0 | 33 | 7 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 27 | 0 | 14 | 1 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 7 | 0 | 3 | 0 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 266 | 1 | 206 | 15 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 267 | 1 | 207 | 15 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 19 | 0 | 19 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 2 | 0 | 1 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 39 | 0 | 39 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index ed057a0b4f5aa2..82c72d0602be1a 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index c836cb04e869c6..d86926dbc61249 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/profiling_data_access.mdx b/api_docs/profiling_data_access.mdx index 6a589ce2676afd..a4dfcf9221f7a1 100644 --- a/api_docs/profiling_data_access.mdx +++ b/api_docs/profiling_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profilingDataAccess title: "profilingDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the profilingDataAccess plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profilingDataAccess'] --- import profilingDataAccessObj from './profiling_data_access.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index 30269acaa86c21..0e3fc6069c67ef 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index 7b80f41e0e5fe6..f777f625117c2f 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index e7dda68fbad27d..02240413d6193b 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index 939baee853ff30..20f9ca21e639c4 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index 7ef08731980978..79e5feb5fdcfe3 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index be4b9ffc5ce5eb..23c28ea734930f 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index cfed8116573dff..a0b3d295f0609d 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index aa70fd180d11a4..ac7ac641a56a84 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 59754589c90320..10b8f4ef1b30c7 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index abfa72674be233..2d2c31c35d6d42 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.devdocs.json b/api_docs/saved_search.devdocs.json index 1268c90a7f3315..776e14b13ce0b9 100644 --- a/api_docs/saved_search.devdocs.json +++ b/api_docs/saved_search.devdocs.json @@ -928,6 +928,23 @@ "tags": [], "label": "DiscoverGridSettings", "description": [], + "signature": [ + { + "pluginId": "savedSearch", + "scope": "common", + "docId": "kibSavedSearchPluginApi", + "section": "def-common.DiscoverGridSettings", + "text": "DiscoverGridSettings" + }, + " extends ", + { + "pluginId": "@kbn/utility-types", + "scope": "common", + "docId": "kibKbnUtilityTypesPluginApi", + "section": "def-common.SerializableRecord", + "text": "SerializableRecord" + } + ], "path": "src/plugins/saved_search/common/types.ts", "deprecated": false, "trackAdoption": false, @@ -964,6 +981,23 @@ "tags": [], "label": "DiscoverGridSettingsColumn", "description": [], + "signature": [ + { + "pluginId": "savedSearch", + "scope": "common", + "docId": "kibSavedSearchPluginApi", + "section": "def-common.DiscoverGridSettingsColumn", + "text": "DiscoverGridSettingsColumn" + }, + " extends ", + { + "pluginId": "@kbn/utility-types", + "scope": "common", + "docId": "kibKbnUtilityTypesPluginApi", + "section": "def-common.SerializableRecord", + "text": "SerializableRecord" + } + ], "path": "src/plugins/saved_search/common/types.ts", "deprecated": false, "trackAdoption": false, @@ -1331,15 +1365,14 @@ "label": "grid", "description": [], "signature": [ - "{ columns?: Record | undefined; } | undefined" + " | undefined" ], "path": "src/plugins/saved_search/common/types.ts", "deprecated": false, diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index ccb907e95990fa..080da486d6653e 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index a5ac9e386f2af4..78133a696a9996 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index 4387682d42e00e..dc5de4e95bdc1c 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 382f2f708ec208..d89c9efeeed036 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.devdocs.json b/api_docs/security_solution.devdocs.json index 945b6393db3450..a709f1d217625e 100644 --- a/api_docs/security_solution.devdocs.json +++ b/api_docs/security_solution.devdocs.json @@ -881,7 +881,7 @@ "tags": [], "label": "TimelineModel", "description": [], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false, "children": [ @@ -897,7 +897,7 @@ "signature": [ "TimelineTabs" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -911,7 +911,7 @@ "signature": [ "TimelineTabs" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -928,7 +928,7 @@ "ScrollToTopEvent", " | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -944,7 +944,7 @@ "signature": [ "string | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -957,7 +957,7 @@ "description": [ "A summary of the events and notes in this timeline" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -977,7 +977,7 @@ "text": "EqlOptionsSelected" } ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -994,7 +994,7 @@ "TimelineEventsType", " | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1010,7 +1010,7 @@ "signature": [ "{ [x: string]: string[]; }" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1026,7 +1026,7 @@ "signature": [ "string[]" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1039,7 +1039,7 @@ "description": [ "The chronological history of actions related to this timeline" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1052,7 +1052,7 @@ "description": [ "When true, this timeline was marked as \"favorite\" by the user" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1065,7 +1065,7 @@ "description": [ "When true, the timeline will update as new data arrives" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1081,7 +1081,7 @@ "signature": [ "\"search\" | \"filter\"" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1094,7 +1094,7 @@ "description": [ "Title" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1110,7 +1110,7 @@ "signature": [ "TimelineType" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1126,7 +1126,7 @@ "signature": [ "string | null" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1142,7 +1142,7 @@ "signature": [ "number | null" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1158,7 +1158,7 @@ "signature": [ "string[]" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1174,7 +1174,7 @@ "signature": [ "{ [x: string]: boolean; }" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1190,7 +1190,7 @@ "PinnedEvent", "; }" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1205,7 +1205,7 @@ "ResolveTimelineConfig", " | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1219,7 +1219,7 @@ "signature": [ "boolean | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1233,7 +1233,7 @@ "signature": [ "string | null | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1248,7 +1248,7 @@ "SessionViewConfig", " | null" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1261,7 +1261,7 @@ "description": [ "When true, show the timeline flyover" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1277,7 +1277,7 @@ "signature": [ "TimelineStatus" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1293,7 +1293,7 @@ "signature": [ "number | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1309,7 +1309,7 @@ "signature": [ "string | null | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1322,7 +1322,7 @@ "description": [ "timeline is saving" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1336,7 +1336,7 @@ "signature": [ "string | null" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1350,7 +1350,7 @@ "signature": [ "boolean | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1364,7 +1364,7 @@ "signature": [ "string | null" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1381,7 +1381,7 @@ "SortColumnTimeline", "[]" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1398,7 +1398,7 @@ "ColumnHeaderOptions", "[]" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1413,7 +1413,7 @@ "ColumnHeaderOptions", "[]" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1436,7 +1436,7 @@ }, "[]" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1452,7 +1452,7 @@ "signature": [ "string | null" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1468,7 +1468,7 @@ "signature": [ "string[]" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1479,7 +1479,7 @@ "tags": [], "label": "documentType", "description": [], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1494,7 +1494,7 @@ "RowRendererId", "[]" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1515,7 +1515,7 @@ }, " | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1529,7 +1529,7 @@ "signature": [ "boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | null | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1543,7 +1543,7 @@ "signature": [ "boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | null | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1557,7 +1557,7 @@ "signature": [ "string[]" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1589,7 +1589,7 @@ "ExpandedDetailType", " | undefined; }" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1605,7 +1605,7 @@ "signature": [ "string | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1619,7 +1619,7 @@ "signature": [ "string[]" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1632,7 +1632,7 @@ "description": [ "The number of items to show in a single page of results" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1648,7 +1648,7 @@ "signature": [ "number[]" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1666,7 +1666,7 @@ "SerializedFilterQuery", " | null; }" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1682,7 +1682,7 @@ "signature": [ "string[]" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1698,7 +1698,7 @@ "signature": [ "{ start: string; end: string; }" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1711,7 +1711,7 @@ "description": [ "Uniquely identifies the timeline" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1732,7 +1732,7 @@ }, "[] | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1754,7 +1754,7 @@ }, "[]; }" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1767,7 +1767,7 @@ "description": [ "If selectAll checkbox in header is checked" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1778,7 +1778,7 @@ "tags": [], "label": "isLoading", "description": [], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1789,7 +1789,7 @@ "tags": [], "label": "selectAll", "description": [], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1803,7 +1803,7 @@ "signature": [ "string | null" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1824,7 +1824,7 @@ }, " | null" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1838,7 +1838,7 @@ "signature": [ "boolean | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1849,7 +1849,7 @@ "tags": [], "label": "isDataProviderVisible", "description": [], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false }, @@ -1865,7 +1865,7 @@ "signature": [ "boolean | undefined" ], - "path": "x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts", + "path": "x-pack/plugins/security_solution/public/timelines/store/model.ts", "deprecated": false, "trackAdoption": false } diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 11de42d6c6e150..06711003763721 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/security_solution_ess.mdx b/api_docs/security_solution_ess.mdx index 3d3df5185d3e4b..dc8561d3b52e3f 100644 --- a/api_docs/security_solution_ess.mdx +++ b/api_docs/security_solution_ess.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionEss title: "securitySolutionEss" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionEss plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionEss'] --- import securitySolutionEssObj from './security_solution_ess.devdocs.json'; diff --git a/api_docs/security_solution_serverless.mdx b/api_docs/security_solution_serverless.mdx index c56836a2b3f9e5..5a65ce9ac7880f 100644 --- a/api_docs/security_solution_serverless.mdx +++ b/api_docs/security_solution_serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionServerless title: "securitySolutionServerless" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionServerless plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionServerless'] --- import securitySolutionServerlessObj from './security_solution_serverless.devdocs.json'; diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index 66d91140c9a82a..79c8072a32a1c5 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverless'] --- import serverlessObj from './serverless.devdocs.json'; diff --git a/api_docs/serverless_observability.mdx b/api_docs/serverless_observability.mdx index bff7ebf553d98e..7968fb6705e856 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessObservability'] --- import serverlessObservabilityObj from './serverless_observability.devdocs.json'; diff --git a/api_docs/serverless_search.mdx b/api_docs/serverless_search.mdx index 2eaf6275c8683d..000e66ee1ef3b2 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 4dd9c30b26cd79..7c69e1e1525817 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index cace61074af40a..42447b167842d6 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 2b9c2b1c5ba2ee..95286a9e821905 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index 85cc6c588b4900..01cd1d29fd4e64 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index da709cb8a10f78..c1c347c643dfc5 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/stack_connectors.mdx b/api_docs/stack_connectors.mdx index 245fd16ac6034f..ebbce17be89c19 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index 6c9bb7b1dc5ca6..f5720acb909f0f 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index 8846f5ba1a25f2..2c7e34966b6780 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index aa3e1742b08f10..b3ece3658ff6c3 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index cd71b1a1ca1094..a249b1bc0d5777 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 8b3d7d81948505..93af855b77f7f5 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/text_based_languages.mdx b/api_docs/text_based_languages.mdx index 92f7b53ebb2c7f..1b843089f13610 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'textBasedLanguages'] --- import textBasedLanguagesObj from './text_based_languages.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 5942395bbc8292..63e264031d3617 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 8d1f14dc7e6674..8bda84c44e806e 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index 337d19283987e1..964343655f031b 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index 4ebd2dbdbb494b..0050e9ce95a4ea 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 4be2c7d874ecc6..6214a4ddeaefa5 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index 5120a5a6eb086a..45c4c1d21ffeda 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_doc_viewer.mdx b/api_docs/unified_doc_viewer.mdx index 28f070fe360386..2e786d70f2f717 100644 --- a/api_docs/unified_doc_viewer.mdx +++ b/api_docs/unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedDocViewer title: "unifiedDocViewer" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedDocViewer plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedDocViewer'] --- import unifiedDocViewerObj from './unified_doc_viewer.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 697fbffe5c3b7c..b7dfd2a6c836bc 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index b898a070d19245..39c37940556043 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 9b68141f8522fd..19d4782ec7d6bc 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/uptime.mdx b/api_docs/uptime.mdx index 82eec26d156bab..4c3129b133478e 100644 --- a/api_docs/uptime.mdx +++ b/api_docs/uptime.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uptime title: "uptime" image: https://source.unsplash.com/400x175/?github description: API docs for the uptime plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uptime'] --- import uptimeObj from './uptime.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index bff9ba3c43a1ba..5fcc62642813ae 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index 7aea5969874bc5..f71b562a622185 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index f8873435bea7a3..8a6ba03021b09b 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index 2b8600f50197c2..f24bee0440e988 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index f79890da6271f5..4c67dd85451ac6 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index c03a6f74fe8cc8..74cfe13aba5874 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index 442d2d5f72c743..750aaaf624e5bb 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index ed6a569057afed..93db8c2d945cba 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index 87bfde401b952e..56292f6063c338 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index b7a9e411e74d6b..7902ca81031435 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index 4108de2dd9ff4b..5b0bd3b1753aff 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 753c3bfe5e7155..333d3ec33541bc 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index 76b4076f2d5ab4..12a82eb484d4c3 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index d3a0ca23afaab4..e10f3831933777 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2023-12-19 +date: 2023-12-20 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From 87fb64c788ad2a98dea603ca59cbc92816526739 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 20 Dec 2023 09:21:57 +0200 Subject: [PATCH 003/116] [Lens] Displays the suggestions on the dataview mode (#172924) ## Summary Enables the suggestions for the dataview mode charts in the in-app flyout. It works exactly as in ES|QL mode. In Discover we still hide them from the flyout as they appear on the breakdown above the chart. We are going to add them in Discover too but in a follow up PR propably. image ### Checklist - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../public/chart/chart_config_panel.tsx | 1 + .../edit_on_the_fly/get_edit_lens_configuration.tsx | 2 ++ .../edit_on_the_fly/lens_configuration_flyout.test.tsx | 7 +++++++ .../shared/edit_on_the_fly/lens_configuration_flyout.tsx | 9 +++++---- .../public/app_plugin/shared/edit_on_the_fly/types.ts | 2 ++ 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/plugins/unified_histogram/public/chart/chart_config_panel.tsx b/src/plugins/unified_histogram/public/chart/chart_config_panel.tsx index 5ed329f251a972..314226525296e6 100644 --- a/src/plugins/unified_histogram/public/chart/chart_config_panel.tsx +++ b/src/plugins/unified_histogram/public/chart/chart_config_panel.tsx @@ -74,6 +74,7 @@ export function ChartConfigPanel({ }} wrapInFlyout datasourceId="textBased" + hidesSuggestions /> ); setEditLensConfigPanel(panel); diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx index 91b094c1411618..2421f303d7b3a3 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx @@ -114,6 +114,7 @@ export async function getEditLensConfiguration( navigateToLensEditor, displayFlyoutHeader, canEditTextBasedQuery, + hidesSuggestions, }: EditLensConfigurationProps) => { if (!lensServices || !datasourceMap || !visualizationMap) { return ; @@ -205,6 +206,7 @@ export async function getEditLensConfiguration( navigateToLensEditor, displayFlyoutHeader, canEditTextBasedQuery, + hidesSuggestions, setCurrentAttributes, }; diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx index 0462e4ad251de9..adc0b83861b9ce 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx @@ -166,6 +166,13 @@ describe('LensEditConfigurationFlyout', () => { expect(screen.queryByTestId('TextBasedLangEditor')).toBeNull(); }); + it('should not display the suggestions if hidesSuggestions prop is true', async () => { + renderConfigFlyout({ + hidesSuggestions: true, + }); + expect(screen.queryByTestId('InlineEditingSuggestions')).toBeNull(); + }); + it('should display the suggestions if canEditTextBasedQuery prop is true', async () => { renderConfigFlyout( { diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx index 4c361f37029c66..13fedcf5cd7e0d 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx @@ -61,6 +61,7 @@ export function LensEditConfigurationFlyout({ navigateToLensEditor, displayFlyoutHeader, canEditTextBasedQuery, + hidesSuggestions, }: EditConfigPanelProps) { const euiTheme = useEuiTheme(); const previousAttributes = useRef(attributes); @@ -267,8 +268,8 @@ export function LensEditConfigurationFlyout({ const textBasedMode = isOfAggregateQueryType(query) ? getAggregateQueryMode(query) : undefined; if (isLoading) return null; - // Example is the Discover editing where we dont want to render the text based editor on the panel - if (!canEditTextBasedQuery) { + // Example is the Discover editing where we dont want to render the text based editor on the panel, neither the suggestions (for now) + if (!canEditTextBasedQuery && hidesSuggestions) { return ( - {isOfAggregateQueryType(query) && ( + {isOfAggregateQueryType(query) && canEditTextBasedQuery && ( Date: Wed, 20 Dec 2023 09:33:07 +0100 Subject: [PATCH 004/116] [UnifiedDataTable] Fix rendering of multi-line content (#173524) - Resolves https://github.com/elastic/kibana/issues/173019 ## Summary This PR fixes a recent bug with multi line content and adds functional tests. 50x https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4608 ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../src/components/data_table.scss | 7 +- .../discover/group2/_data_grid_new_line.ts | 109 ++++++++++++++++++ test/functional/apps/discover/group2/index.ts | 1 + 3 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 test/functional/apps/discover/group2/_data_grid_new_line.ts diff --git a/packages/kbn-unified-data-table/src/components/data_table.scss b/packages/kbn-unified-data-table/src/components/data_table.scss index 25bce5cdf88c57..2f614f1133bb16 100644 --- a/packages/kbn-unified-data-table/src/components/data_table.scss +++ b/packages/kbn-unified-data-table/src/components/data_table.scss @@ -54,6 +54,11 @@ .euiDataGrid__scrollOverlay .euiDataGrid__scrollBarOverlayRight { background-color: transparent; // otherwise the grid scrollbar border visually conflicts with the grid toolbar controls } + + .euiDataGridRowCell__autoHeight, + .euiDataGridRowCell__lineCountHeight { + white-space: pre-wrap; + } } .unifiedDataTable__table { @@ -169,4 +174,4 @@ [data-euiportal='true'], [data-euiportal='true'] *) { z-index: unset !important; -} \ No newline at end of file +} diff --git a/test/functional/apps/discover/group2/_data_grid_new_line.ts b/test/functional/apps/discover/group2/_data_grid_new_line.ts new file mode 100644 index 00000000000000..34855d14e10bed --- /dev/null +++ b/test/functional/apps/discover/group2/_data_grid_new_line.ts @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../ftr_provider_context'; + +const INDEX_NAME = 'newline'; +const VALUE_WITH_NEW_LINES = "Newline!\nHere's a newline.\nHere's a newline again."; +const VALUE_WITHOUT_NEW_LINES = VALUE_WITH_NEW_LINES.replaceAll('\n', ' '); + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const browser = getService('browser'); + const es = getService('es'); + const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); + const dataGrid = getService('dataGrid'); + const PageObjects = getPageObjects([ + 'settings', + 'common', + 'discover', + 'header', + 'timePicker', + 'unifiedFieldList', + ]); + const defaultSettings = { defaultIndex: 'logstash-*' }; + const security = getService('security'); + + describe('discover data grid new line support', function describeIndexTests() { + before(async () => { + await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader']); + await browser.setWindowSize(1200, 2000); + await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); + await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); + + await es.transport.request({ + path: `/${INDEX_NAME}/_doc`, + method: 'POST', + body: { + message: VALUE_WITH_NEW_LINES, + }, + }); + }); + + after(async () => { + await es.transport.request({ + path: `/${INDEX_NAME}`, + method: 'DELETE', + }); + + await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover'); + await kibanaServer.uiSettings.replace({}); + await kibanaServer.savedObjects.cleanStandardList(); + }); + + beforeEach(async function () { + await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); + await kibanaServer.uiSettings.update(defaultSettings); + await PageObjects.common.navigateToApp('discover'); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await PageObjects.discover.createAdHocDataView(INDEX_NAME, false); + await PageObjects.discover.waitUntilSearchingHasFinished(); + }); + + it('should not show new lines for Document column', async () => { + const rows = await dataGrid.getDocTableRows(); + expect(rows.length).to.be.above(0); + + const cell = await dataGrid.getCellElement(0, 2); + const content = await cell.findByCssSelector('.unifiedDataTable__descriptionListDescription'); + expect(await content.getVisibleText()).to.be(VALUE_WITHOUT_NEW_LINES); + expect(await content.getComputedStyle('white-space')).to.be('normal'); + }); + + it('should show new lines for "message" column except for Single row height setting', async () => { + await PageObjects.unifiedFieldList.clickFieldListItemAdd('message'); + await PageObjects.discover.waitUntilSearchingHasFinished(); + + let cell = await dataGrid.getCellElement(0, 2); + let content = await cell.findByCssSelector('.unifiedDataTable__cellValue'); + expect(await content.getVisibleText()).to.be(VALUE_WITH_NEW_LINES); + expect(await content.getComputedStyle('white-space')).to.be('pre-wrap'); + + await dataGrid.clickGridSettings(); + expect(await dataGrid.getCurrentRowHeightValue()).to.be('Custom'); + await dataGrid.changeRowHeightValue('Auto fit'); + await dataGrid.clickGridSettings(); + + cell = await dataGrid.getCellElement(0, 2); + content = await cell.findByCssSelector('.unifiedDataTable__cellValue'); + expect(await content.getVisibleText()).to.be(VALUE_WITH_NEW_LINES); + expect(await content.getComputedStyle('white-space')).to.be('pre-wrap'); + + await dataGrid.clickGridSettings(); + expect(await dataGrid.getCurrentRowHeightValue()).to.be('Auto fit'); + await dataGrid.changeRowHeightValue('Single'); + await dataGrid.clickGridSettings(); + + cell = await dataGrid.getCellElement(0, 2); + content = await cell.findByCssSelector('.unifiedDataTable__cellValue'); + expect(await content.getVisibleText()).to.be(VALUE_WITHOUT_NEW_LINES); + expect(await content.getComputedStyle('white-space')).to.be('nowrap'); + }); + }); +} diff --git a/test/functional/apps/discover/group2/index.ts b/test/functional/apps/discover/group2/index.ts index 6b35f6707bb78b..2639601e12c171 100644 --- a/test/functional/apps/discover/group2/index.ts +++ b/test/functional/apps/discover/group2/index.ts @@ -28,6 +28,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./_data_grid_doc_table')); loadTestFile(require.resolve('./_data_grid_copy_to_clipboard')); loadTestFile(require.resolve('./_data_grid_row_height')); + loadTestFile(require.resolve('./_data_grid_new_line')); loadTestFile(require.resolve('./_data_grid_sample_size')); loadTestFile(require.resolve('./_data_grid_pagination')); loadTestFile(require.resolve('./_data_grid_footer')); From 735db7e7180f5c97cf7568f9be5814efe1cae69d Mon Sep 17 00:00:00 2001 From: Pablo Machado Date: Wed, 20 Dec 2023 09:45:35 +0100 Subject: [PATCH 005/116] [Security Solution] Merge risk input and asset integration expandable panels (#173028) ## Summary Update the user expandable flyout left panel to be consistent with Alerts flyout implementation. After this change, we always display the same left panel but dynamically create tabs for different sub-panels. This issue can be considered a UI/UX bug because the user's experience of navigating between the tabs was poor and had some edge cases. This PR also moves flyout files and folders to match the Alert flyout structure. The new folder structure looks like this: ``` public/flyout ... entity_details shared user_right user_details_left ... tabs ... asset_document.tsx risk_inputs.tsx ``` **No tab** **One tab** **Two tabs** **Okta tab with table** **Okta tab with json** ### How to test it Please check the same section on this PR: https://github.com/elastic/kibana/pull/171629 ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) --- .../asset_document_left/index.test.tsx | 74 ---- .../asset_document_left/index.tsx | 91 ----- .../entity_details/risk_inputs_left/index.tsx | 28 -- .../components/risk_summary.stories.tsx | 6 +- .../shared/components/risk_summary.test.tsx | 19 +- .../shared/components/risk_summary.tsx | 370 +++++++++--------- .../components/action_column.test.tsx | 0 .../components/action_column.tsx | 2 +- .../components/utility_bar.test.tsx | 2 +- .../components/utility_bar.tsx | 2 +- .../user_detais_left/content.tsx | 40 ++ .../user_detais_left/header.tsx | 64 +++ .../hooks/use_risk_input_actions.ts | 2 +- .../use_risk_input_actions_panels.test.tsx | 0 .../hooks/use_risk_input_actions_panels.tsx | 2 +- .../entity_details/user_detais_left/index.tsx | 84 ++++ .../mocks/index.ts | 2 +- .../entity_details/user_detais_left/tabs.tsx | 109 ++++++ .../tabs/asset_document.test.tsx | 74 ++++ .../user_detais_left/tabs/asset_document.tsx | 96 +++++ .../tabs/risk_inputs.test.tsx} | 37 +- .../tabs/risk_inputs.tsx} | 90 ++--- .../tabs}/test_ids.ts | 3 +- .../user_detais_left/test_ids.ts | 12 + .../user_right/content.stories.tsx | 5 + .../entity_details/user_right/content.tsx | 16 +- .../entity_details/user_right/header.test.tsx | 2 +- .../entity_details/user_right/index.tsx | 45 ++- .../security_solution/public/flyout/index.tsx | 22 +- .../shared/components/flyout_navigation.tsx | 4 +- .../hooks/use_managed_user.test.ts | 35 +- .../new_user_detail/hooks/use_managed_user.ts | 29 +- .../new_user_detail/managed_user.test.tsx | 1 + .../new_user_detail/managed_user.tsx | 15 +- .../managed_user_accordion.test.tsx | 5 +- .../managed_user_accordion.tsx | 32 +- 36 files changed, 847 insertions(+), 573 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/flyout/entity_details/asset_document_left/index.test.tsx delete mode 100644 x-pack/plugins/security_solution/public/flyout/entity_details/asset_document_left/index.tsx delete mode 100644 x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/index.tsx rename x-pack/plugins/security_solution/public/flyout/entity_details/{risk_inputs_left => user_detais_left}/components/action_column.test.tsx (100%) rename x-pack/plugins/security_solution/public/flyout/entity_details/{risk_inputs_left => user_detais_left}/components/action_column.tsx (96%) rename x-pack/plugins/security_solution/public/flyout/entity_details/{risk_inputs_left => user_detais_left}/components/utility_bar.test.tsx (98%) rename x-pack/plugins/security_solution/public/flyout/entity_details/{risk_inputs_left => user_detais_left}/components/utility_bar.tsx (98%) create mode 100644 x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/content.tsx create mode 100644 x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/header.tsx rename x-pack/plugins/security_solution/public/flyout/entity_details/{risk_inputs_left => user_detais_left}/hooks/use_risk_input_actions.ts (98%) rename x-pack/plugins/security_solution/public/flyout/entity_details/{risk_inputs_left => user_detais_left}/hooks/use_risk_input_actions_panels.test.tsx (100%) rename x-pack/plugins/security_solution/public/flyout/entity_details/{risk_inputs_left => user_detais_left}/hooks/use_risk_input_actions_panels.tsx (98%) create mode 100644 x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/index.tsx rename x-pack/plugins/security_solution/public/flyout/entity_details/{risk_inputs_left => user_detais_left}/mocks/index.ts (91%) create mode 100644 x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs.tsx create mode 100644 x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/asset_document.test.tsx create mode 100644 x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/asset_document.tsx rename x-pack/plugins/security_solution/public/flyout/entity_details/{risk_inputs_left/content.test.tsx => user_detais_left/tabs/risk_inputs.test.tsx} (57%) rename x-pack/plugins/security_solution/public/flyout/entity_details/{risk_inputs_left/content.tsx => user_detais_left/tabs/risk_inputs.tsx} (55%) rename x-pack/plugins/security_solution/public/flyout/entity_details/{asset_document_left => user_detais_left/tabs}/test_ids.ts (76%) create mode 100644 x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/test_ids.ts diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/asset_document_left/index.test.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/asset_document_left/index.test.tsx deleted file mode 100644 index ad3629a244af1e..00000000000000 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/asset_document_left/index.test.tsx +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { render } from '@testing-library/react'; -import { TestProviders } from '../../../common/mock'; -import { AssetDocumentLeftPanel } from '.'; -import { JSON_TAB_TEST_ID, TABLE_TAB_TEST_ID } from './test_ids'; -import { RightPanelContext } from '../../document_details/right/context'; -import { mockContextValue } from '../../document_details/right/mocks/mock_context'; - -describe('', () => { - it('renders', () => { - const { getByTestId } = render( - - - - - - ); - - expect(getByTestId(TABLE_TAB_TEST_ID)).toBeInTheDocument(); - expect(getByTestId(JSON_TAB_TEST_ID)).toBeInTheDocument(); - }); - - it('should preselect the table tab', () => { - const { getByTestId } = render( - - - - - - ); - - expect(getByTestId('securitySolutionFlyoutAssetTableTab')).toHaveAttribute( - 'aria-selected', - 'true' - ); - }); - - it('should select json tab when path tab is json', () => { - const { getByTestId } = render( - - - - - - ); - - expect(getByTestId('securitySolutionFlyoutAssetJsonTab')).toHaveAttribute( - 'aria-selected', - 'true' - ); - }); - - it('should select table tab when path tab is table', () => { - const { getByTestId } = render( - - - - - - ); - - expect(getByTestId('securitySolutionFlyoutAssetTableTab')).toHaveAttribute( - 'aria-selected', - 'true' - ); - }); -}); diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/asset_document_left/index.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/asset_document_left/index.tsx deleted file mode 100644 index 2c9b4f4975fe0e..00000000000000 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/asset_document_left/index.tsx +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { FC } from 'react'; -import React, { memo, useMemo } from 'react'; -import type { FlyoutPanelProps, PanelPath } from '@kbn/expandable-flyout'; -import { useExpandableFlyoutContext } from '@kbn/expandable-flyout'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { useRightPanelContext } from '../../document_details/right/context'; -import { PanelHeader } from '../../document_details/right/header'; -import type { RightPanelTabsType } from '../../document_details/right/tabs'; -import { PanelContent } from '../../document_details/right/content'; -import { JsonTab } from '../../document_details/right/tabs/json_tab'; -import { TableTab } from '../../document_details/right/tabs/table_tab'; -import { JSON_TAB_TEST_ID, TABLE_TAB_TEST_ID } from './test_ids'; -export type RightPanelPaths = 'overview' | 'table' | 'json'; -export const AssetDocumentLeftPanelKey: AssetDocumentLeftPanelProps['key'] = - 'asset-document-details-left'; - -export interface AssetDocumentLeftPanelProps extends FlyoutPanelProps { - key: 'asset-document-details-left'; - path?: PanelPath; - params?: { - id: string; - indexName: string; - scopeId: string; - }; -} - -const tabs: RightPanelTabsType = [ - { - id: 'table', - 'data-test-subj': TABLE_TAB_TEST_ID, - name: ( - - ), - content: , - }, - { - id: 'json', - 'data-test-subj': JSON_TAB_TEST_ID, - name: ( - - ), - content: , - }, -]; - -export const AssetDocumentLeftPanel: FC> = memo(({ path }) => { - const { openLeftPanel } = useExpandableFlyoutContext(); - const { eventId, indexName, scopeId } = useRightPanelContext(); - - const selectedTabId = useMemo(() => { - const defaultTab = tabs[0].id; - if (!path) return defaultTab; - return tabs.map((tab) => tab.id).find((tabId) => tabId === path.tab) ?? defaultTab; - }, [path]); - - const setSelectedTabId = (tabId: string) => { - openLeftPanel({ - id: AssetDocumentLeftPanelKey, - path: { - tab: tabId, - }, - params: { - id: eventId, - indexName, - scopeId, - }, - }); - }; - - return ( - <> - - - - ); -}); - -AssetDocumentLeftPanel.displayName = 'AssetDocumentLeftPanel'; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/index.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/index.tsx deleted file mode 100644 index de926204236ba7..00000000000000 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/index.tsx +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import type { FlyoutPanelProps } from '@kbn/expandable-flyout'; -import type { RiskInputs } from '../../../../common/entity_analytics/risk_engine'; -import { RiskInputsPanelContent } from './content'; - -export interface RiskInputsPanelProps extends Record { - riskInputs: RiskInputs; -} - -export interface RiskInputsExpandableFlyoutProps extends FlyoutPanelProps { - key: 'all-risk-inputs'; - params: RiskInputsPanelProps; -} - -export const RiskInputsPanelKey: RiskInputsExpandableFlyoutProps['key'] = 'all-risk-inputs'; - -export const RiskInputsPanel = ({ riskInputs }: RiskInputsPanelProps) => { - return ; -}; - -RiskInputsPanel.displayName = 'RiskInputsPanel'; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.stories.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.stories.tsx index d6988ca10fff14..06828be073f32f 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.stories.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.stories.tsx @@ -28,7 +28,11 @@ export const Default: Story = () => {

- + {}} + riskScoreData={{ ...mockRiskScoreState, data: [] }} + queryId={'testQuery'} + />
diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.test.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.test.tsx index 774a7c8a8458e1..fb89ef61ad79f6 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.test.tsx @@ -17,7 +17,11 @@ describe('RiskSummary', () => { it('renders risk summary table', () => { const { getByTestId } = render( - + {}} + /> ); @@ -32,6 +36,7 @@ describe('RiskSummary', () => { {}} /> ); @@ -41,7 +46,11 @@ describe('RiskSummary', () => { it('renders visualization embeddable', () => { const { getByTestId } = render( - + {}} + /> ); @@ -51,7 +60,11 @@ describe('RiskSummary', () => { it('renders updated at', () => { const { getByTestId } = render( - + {}} + /> ); diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.tsx index c4eaa362731669..09c57cc61e02b5 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useCallback, useMemo } from 'react'; +import React, { useMemo } from 'react'; import type { EuiBasicTableColumn } from '@elastic/eui'; import { useEuiTheme, @@ -20,7 +20,6 @@ import { import { css } from '@emotion/react'; import { FormattedMessage } from '@kbn/i18n-react'; import { euiThemeVars } from '@kbn/ui-theme'; -import { useExpandableFlyoutContext } from '@kbn/expandable-flyout'; import { i18n } from '@kbn/i18n'; import { InspectButton, InspectButtonContainer } from '../../../../common/components/inspect'; import { ONE_WEEK_IN_HOURS } from '../../../../timelines/components/side_panel/new_user_detail/constants'; @@ -30,11 +29,12 @@ import type { RiskScoreState } from '../../../../explore/containers/risk_score'; import { VisualizationEmbeddable } from '../../../../common/components/visualization_actions/visualization_embeddable'; import { getRiskScoreSummaryAttributes } from '../../../../common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_summary'; import { ExpandablePanel } from '../../../shared/components/expandable_panel'; -import { RiskInputsPanelKey } from '../../risk_inputs_left'; +import { UserDetailsLeftPanelTab } from '../../user_detais_left/tabs'; export interface RiskSummaryProps { riskScoreData: RiskScoreState; queryId: string; + openDetailsPanel: (tab: UserDetailsLeftPanelTab) => void; } interface TableItem { @@ -44,211 +44,203 @@ interface TableItem { const LENS_VISUALIZATION_HEIGHT = 126; // Static height in pixels specified by design const LAST_30_DAYS = { from: 'now-30d', to: 'now' }; -export const RiskSummary = React.memo(({ riskScoreData, queryId }: RiskSummaryProps) => { - const { data: userRisk } = riskScoreData; - const userRiskData = userRisk && userRisk.length > 0 ? userRisk[0] : undefined; - const { euiTheme } = useEuiTheme(); +export const RiskSummary = React.memo( + ({ riskScoreData, queryId, openDetailsPanel }: RiskSummaryProps) => { + const { data: userRisk } = riskScoreData; + const userRiskData = userRisk && userRisk.length > 0 ? userRisk[0] : undefined; + const { euiTheme } = useEuiTheme(); - const { openLeftPanel } = useExpandableFlyoutContext(); - const openPanel = useCallback(() => { - openLeftPanel({ - id: RiskInputsPanelKey, - params: { - riskInputs: userRiskData?.user.risk.inputs, - }, - }); - }, [openLeftPanel, userRiskData?.user.risk.inputs]); + const lensAttributes = useMemo(() => { + return getRiskScoreSummaryAttributes({ + severity: userRiskData?.user?.risk?.calculated_level, + query: `user.name: ${userRiskData?.user?.name}`, + spaceId: 'default', + riskEntity: RiskScoreEntity.user, + }); + }, [userRiskData]); - const lensAttributes = useMemo(() => { - return getRiskScoreSummaryAttributes({ - severity: userRiskData?.user?.risk?.calculated_level, - query: `user.name: ${userRiskData?.user?.name}`, - spaceId: 'default', - riskEntity: RiskScoreEntity.user, - }); - }, [userRiskData]); - - const columns: Array> = useMemo( - () => [ - { - field: 'category', - name: ( - - ), - truncateText: false, - mobileOptions: { show: true }, - sortable: true, - }, - { - field: 'count', - name: ( - - ), - truncateText: false, - mobileOptions: { show: true }, - sortable: true, - dataType: 'number', - }, - ], - [] - ); - - const xsFontSize = useEuiFontSize('xxs').fontSize; - - const items: TableItem[] = useMemo( - () => [ - { - category: i18n.translate('xpack.securitySolution.flyout.entityDetails.alertsGroupLabel', { - defaultMessage: 'Alerts', - }), - count: userRiskData?.user.risk.inputs?.length ?? 0, - }, - ], - [userRiskData?.user.risk.inputs?.length] - ); - - return ( - -

- -

- - } - extraAction={ - - {userRiskData && ( + const columns: Array> = useMemo( + () => [ + { + field: 'category', + name: ( - ), - }} + id="xpack.securitySolution.flyout.entityDetails.categoryColumnLabel" + defaultMessage="Category" /> - )} - - } - > - - - ), - link: { - callback: openPanel, - tooltip: ( + truncateText: false, + mobileOptions: { show: true }, + sortable: true, + dataType: 'number', + }, + ], + [] + ); + + const xsFontSize = useEuiFontSize('xxs').fontSize; + + const items: TableItem[] = useMemo( + () => [ + { + category: i18n.translate('xpack.securitySolution.flyout.entityDetails.alertsGroupLabel', { + defaultMessage: 'Alerts', + }), + count: userRiskData?.user.risk.inputs?.length ?? 0, + }, + ], + [userRiskData?.user.risk.inputs?.length] + ); + + return ( + +

- ), - }, - iconType: 'arrowStart', - }} - expand={{ - expandable: false, - }} - > - - -
- {userRiskData && ( - + + } + extraAction={ + + {userRiskData && ( + - } + ), + }} + /> + )} + + } + > + + + + ), + link: { + callback: () => openDetailsPanel(UserDetailsLeftPanelTab.RISK_INPUTS), + tooltip: ( + - )} -
-
- - + ), + }, + iconType: 'arrowStart', + }} + expand={{ + expandable: false, + }} + > + +
+ {userRiskData && ( + + } + /> + )} +
+
+ +
- - } +
+ + } + /> +
+
- - -
-
-
- - - - ); -}); +
+
+
+ + + + ); + } +); RiskSummary.displayName = 'RiskSummary'; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/components/action_column.test.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/action_column.test.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/components/action_column.test.tsx rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/action_column.test.tsx diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/components/action_column.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/action_column.tsx similarity index 96% rename from x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/components/action_column.tsx rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/action_column.tsx index 35b25d69fffce0..27c7ba3fcfaf95 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/components/action_column.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/action_column.tsx @@ -8,7 +8,7 @@ import { EuiButtonIcon, EuiContextMenu, EuiPopover } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useCallback, useMemo, useState } from 'react'; -import type { AlertRawData } from '../content'; +import type { AlertRawData } from '../tabs/risk_inputs'; import { useRiskInputActionsPanels } from '../hooks/use_risk_input_actions_panels'; interface ActionColumnProps { diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/components/utility_bar.test.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/utility_bar.test.tsx similarity index 98% rename from x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/components/utility_bar.test.tsx rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/utility_bar.test.tsx index aeb244e537bda2..02c32d3b0ecc66 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/components/utility_bar.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/utility_bar.test.tsx @@ -11,7 +11,7 @@ import { TestProviders } from '../../../../common/mock'; import { alertDataMock } from '../mocks'; import { RiskInputsUtilityBar } from './utility_bar'; -describe('RiskInputsPanel', () => { +describe('RiskInputsUtilityBar', () => { it('renders', () => { const { getByTestId } = render( diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/components/utility_bar.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/utility_bar.tsx similarity index 98% rename from x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/components/utility_bar.tsx rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/utility_bar.tsx index 40e3497a049454..fc56a7f227b36b 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/components/utility_bar.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/utility_bar.tsx @@ -20,7 +20,7 @@ import { import { FormattedMessage } from '@kbn/i18n-react'; import { css } from '@emotion/react'; import { useRiskInputActionsPanels } from '../hooks/use_risk_input_actions_panels'; -import type { AlertRawData } from '../content'; +import type { AlertRawData } from '../tabs/risk_inputs'; interface Props { selectedAlerts: AlertRawData[]; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/content.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/content.tsx new file mode 100644 index 00000000000000..991592bd1ea0ce --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/content.tsx @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useEuiBackgroundColor } from '@elastic/eui'; +import type { VFC } from 'react'; +import React, { useMemo } from 'react'; +import { css } from '@emotion/react'; +import type { LeftPanelTabsType, UserDetailsLeftPanelTab } from './tabs'; +import { FlyoutBody } from '../../shared/components/flyout_body'; + +export interface PanelContentProps { + selectedTabId: UserDetailsLeftPanelTab; + tabs: LeftPanelTabsType; +} + +/** + * User details expandable flyout left section. + * Appears after the user clicks on the expand details button in the right section. + */ +export const PanelContent: VFC = ({ selectedTabId, tabs }) => { + const selectedTabContent = useMemo(() => { + return tabs.find((tab) => tab.id === selectedTabId)?.content; + }, [selectedTabId, tabs]); + + return ( + + {selectedTabContent} + + ); +}; + +PanelContent.displayName = 'PanelContent'; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/header.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/header.tsx new file mode 100644 index 00000000000000..2f807ca1d0a7d7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/header.tsx @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiTab, EuiTabs, useEuiBackgroundColor } from '@elastic/eui'; +import type { VFC } from 'react'; +import React, { memo } from 'react'; +import { css } from '@emotion/react'; +import type { LeftPanelTabsType, UserDetailsLeftPanelTab } from './tabs'; +import { FlyoutHeader } from '../../shared/components/flyout_header'; + +export interface PanelHeaderProps { + /** + * Id of the tab selected in the parent component to display its content + */ + selectedTabId: UserDetailsLeftPanelTab; + /** + * Callback to set the selected tab id in the parent component + */ + setSelectedTabId: (selected: UserDetailsLeftPanelTab) => void; + /** + * List of tabs to display in the header + */ + tabs: LeftPanelTabsType; +} + +/** + * Header at the top of the left section. + * Displays the investigation and insights tabs (visualize is hidden for 8.9). + */ +export const PanelHeader: VFC = memo( + ({ selectedTabId, setSelectedTabId, tabs }) => { + const onSelectedTabChanged = (id: UserDetailsLeftPanelTab) => setSelectedTabId(id); + const renderTabs = tabs.map((tab, index) => ( + onSelectedTabChanged(tab.id)} + isSelected={tab.id === selectedTabId} + key={index} + data-test-subj={tab['data-test-subj']} + > + {tab.name} + + )); + + return ( + + + {renderTabs} + + + ); + } +); + +PanelHeader.displayName = 'PanelHeader'; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/hooks/use_risk_input_actions.ts b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/hooks/use_risk_input_actions.ts similarity index 98% rename from x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/hooks/use_risk_input_actions.ts rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/hooks/use_risk_input_actions.ts index 6a8643c7fd9f33..a5c89b864b84db 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/hooks/use_risk_input_actions.ts +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/hooks/use_risk_input_actions.ts @@ -15,7 +15,7 @@ import { useGlobalTime } from '../../../../common/containers/use_global_time'; import { SourcererScopeName } from '../../../../common/store/sourcerer/model'; import { useAddBulkToTimelineAction } from '../../../../detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline'; import { useKibana } from '../../../../common/lib/kibana/kibana_react'; -import type { AlertRawData } from '../content'; +import type { AlertRawData } from '../tabs/risk_inputs'; /** * The returned actions only support alerts risk inputs. diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/hooks/use_risk_input_actions_panels.test.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/hooks/use_risk_input_actions_panels.test.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/hooks/use_risk_input_actions_panels.test.tsx rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/hooks/use_risk_input_actions_panels.test.tsx diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/hooks/use_risk_input_actions_panels.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/hooks/use_risk_input_actions_panels.tsx similarity index 98% rename from x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/hooks/use_risk_input_actions_panels.tsx rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/hooks/use_risk_input_actions_panels.tsx index 176b2a13db72d6..5e79fe1f820023 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/hooks/use_risk_input_actions_panels.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/hooks/use_risk_input_actions_panels.tsx @@ -15,7 +15,7 @@ import { i18n } from '@kbn/i18n'; import { get } from 'lodash/fp'; import { ALERT_RULE_NAME } from '@kbn/rule-data-utils'; import { useRiskInputActions } from './use_risk_input_actions'; -import type { AlertRawData } from '../content'; +import type { AlertRawData } from '../tabs/risk_inputs'; export const useRiskInputActionsPanels = (alerts: AlertRawData[], closePopover: () => void) => { const { cases: casesService } = useKibana<{ cases?: CasesService }>().services; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/index.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/index.tsx new file mode 100644 index 00000000000000..ae96a76c68d4e6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/index.tsx @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useMemo } from 'react'; +import type { FlyoutPanelProps, PanelPath } from '@kbn/expandable-flyout'; +import { useExpandableFlyoutContext } from '@kbn/expandable-flyout'; +import { useManagedUser } from '../../../timelines/components/side_panel/new_user_detail/hooks/use_managed_user'; +import { PanelHeader } from './header'; +import { PanelContent } from './content'; +import type { LeftPanelTabsType, UserDetailsLeftPanelTab } from './tabs'; +import { useTabs } from './tabs'; +import { FlyoutLoading } from '../../shared/components/flyout_loading'; + +interface RiskInputsParam { + alertIds: string[]; +} + +interface UserParam { + name: string; + email: string[]; +} + +export interface UserDetailsPanelProps extends Record { + riskInputs: RiskInputsParam; + user: UserParam; + path?: PanelPath; +} +export interface UserDetailsExpandableFlyoutProps extends FlyoutPanelProps { + key: 'user_details'; + params: UserDetailsPanelProps; +} +export const UserDetailsPanelKey: UserDetailsExpandableFlyoutProps['key'] = 'user_details'; + +export const UserDetailsPanel = ({ riskInputs, user, path }: UserDetailsPanelProps) => { + const managedUser = useManagedUser(user.name, user.email); + const tabs = useTabs(managedUser.data, riskInputs.alertIds); + const { selectedTabId, setSelectedTabId } = useSelectedTab(riskInputs, user, tabs, path); + + if (managedUser.isLoading) return ; + + return ( + <> + + + + ); +}; + +const useSelectedTab = ( + riskInputs: RiskInputsParam, + user: UserParam, + tabs: LeftPanelTabsType, + path: PanelPath | undefined +) => { + const { openLeftPanel } = useExpandableFlyoutContext(); + + const selectedTabId = useMemo(() => { + const defaultTab = tabs[0].id; + if (!path) return defaultTab; + + return tabs.find((tab) => tab.id === path.tab)?.id ?? defaultTab; + }, [path, tabs]); + + const setSelectedTabId = (tabId: UserDetailsLeftPanelTab) => { + openLeftPanel({ + id: UserDetailsPanelKey, + path: { + tab: tabId, + }, + params: { + riskInputs, + user, + }, + }); + }; + + return { setSelectedTabId, selectedTabId }; +}; + +UserDetailsPanel.displayName = 'UserDetailsPanel'; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/mocks/index.ts b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/mocks/index.ts similarity index 91% rename from x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/mocks/index.ts rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/mocks/index.ts index 9e6f5db17034cf..a38382b90627b4 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/mocks/index.ts +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/mocks/index.ts @@ -6,7 +6,7 @@ */ import { ALERT_RULE_NAME, ALERT_RULE_UUID } from '@kbn/rule-data-utils'; -import type { AlertRawData } from '../content'; +import type { AlertRawData } from '../tabs/risk_inputs'; export const alertDataMock: AlertRawData = { _id: 'test-id', diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs.tsx new file mode 100644 index 00000000000000..f86dc25ffe2195 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs.tsx @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ReactElement } from 'react'; +import React, { useMemo } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { UserAssetTableType } from '../../../explore/users/store/model'; +import { ManagedUserDatasetKey } from '../../../../common/search_strategy/security_solution/users/managed_details'; +import type { + ManagedUserHits, + ManagedUserHit, +} from '../../../../common/search_strategy/security_solution/users/managed_details'; +import { ENTRA_TAB_TEST_ID, OKTA_TAB_TEST_ID, RISK_INPUTS_TAB_TEST_ID } from './test_ids'; +import { RiskInputsTab } from './tabs/risk_inputs'; +import { AssetDocumentTab } from './tabs/asset_document'; +import { RightPanelProvider } from '../../document_details/right/context'; + +export type LeftPanelTabsType = Array<{ + id: UserDetailsLeftPanelTab; + 'data-test-subj': string; + name: ReactElement; + content: React.ReactElement; +}>; + +export enum UserDetailsLeftPanelTab { + RISK_INPUTS = 'risk_inputs', + OKTA = 'okta_document', + ENTRA = 'entra_document', +} + +export const useTabs = (managedUser: ManagedUserHits, alertIds: string[]): LeftPanelTabsType => + useMemo(() => { + const tabs: LeftPanelTabsType = []; + const entraManagedUser = managedUser[ManagedUserDatasetKey.ENTRA]; + const oktaManagedUser = managedUser[ManagedUserDatasetKey.OKTA]; + + if (alertIds.length > 0) { + tabs.push(getRiskInputTab(alertIds)); + } + + if (oktaManagedUser) { + tabs.push(getOktaTab(oktaManagedUser)); + } + + if (entraManagedUser) { + tabs.push(getEntraTab(entraManagedUser)); + } + + return tabs; + }, [alertIds, managedUser]); + +const getRiskInputTab = (alertIds: string[]) => ({ + id: UserDetailsLeftPanelTab.RISK_INPUTS, + 'data-test-subj': RISK_INPUTS_TAB_TEST_ID, + name: ( + + ), + content: , +}); + +const getOktaTab = (oktaManagedUser: ManagedUserHit) => ({ + id: UserDetailsLeftPanelTab.OKTA, + 'data-test-subj': OKTA_TAB_TEST_ID, + name: ( + + ), + content: ( + + + + ), +}); + +const getEntraTab = (entraManagedUser: ManagedUserHit) => { + return { + id: UserDetailsLeftPanelTab.ENTRA, + 'data-test-subj': ENTRA_TAB_TEST_ID, + name: ( + + ), + content: ( + + + + ), + }; +}; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/asset_document.test.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/asset_document.test.tsx new file mode 100644 index 00000000000000..6289fa0a66cd8e --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/asset_document.test.tsx @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render } from '@testing-library/react'; +import { TestProviders } from '../../../../common/mock'; +import { AssetDocumentTab } from './asset_document'; +import { FLYOUT_BODY_TEST_ID } from './test_ids'; +import { RightPanelContext } from '../../../document_details/right/context'; +import { mockContextValue } from '../../../document_details/right/mocks/mock_context'; +import userEvent from '@testing-library/user-event'; +import { + JSON_TAB_CONTENT_TEST_ID, + TABLE_TAB_CONTENT_TEST_ID, +} from '../../../document_details/right/tabs/test_ids'; + +describe('AssetDocumentTab', () => { + it('renders', () => { + const { getByTestId } = render( + + + + + + ); + + expect(getByTestId(FLYOUT_BODY_TEST_ID)).toBeInTheDocument(); + }); + + it('should preselect the table tab', () => { + const { getByTestId } = render( + + + + + + ); + + expect(getByTestId(TABLE_TAB_CONTENT_TEST_ID)).toBeInTheDocument(); + }); + + it('should select json tab when clicked', async () => { + const { getByTestId, getByTitle } = render( + + + + + + ); + + await userEvent.click(getByTitle('JSON')); + + expect(getByTestId(JSON_TAB_CONTENT_TEST_ID)).toBeInTheDocument(); + }); + + it('should select table tab when path tab is table', async () => { + const { getByTestId, getByTitle } = render( + + + + + + ); + + await userEvent.click(getByTitle('JSON')); // make sure Table isn't selected + await userEvent.click(getByTitle('Table')); + + expect(getByTestId(TABLE_TAB_CONTENT_TEST_ID)).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/asset_document.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/asset_document.tsx new file mode 100644 index 00000000000000..3aa4a72ffe8983 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/asset_document.tsx @@ -0,0 +1,96 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { FC } from 'react'; +import React, { memo, useState, useMemo } from 'react'; +import type { FlyoutPanelProps, PanelPath } from '@kbn/expandable-flyout'; +import { FormattedMessage } from '@kbn/i18n-react'; +import type { EuiButtonGroupOptionProps } from '@elastic/eui'; +import { EuiButtonGroup } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { JsonTab } from '../../../document_details/right/tabs/json_tab'; +import { TableTab } from '../../../document_details/right/tabs/table_tab'; +import { FLYOUT_BODY_TEST_ID, JSON_TAB_TEST_ID, TABLE_TAB_TEST_ID } from './test_ids'; +import { FlyoutBody } from '../../../shared/components/flyout_body'; +export type RightPanelPaths = 'overview' | 'table' | 'json'; + +export interface AssetDocumentPanelProps extends FlyoutPanelProps { + path?: PanelPath; + params?: { + id: string; + indexName: string; + scopeId: string; + }; +} + +const tabs = [ + { + id: TABLE_TAB_TEST_ID, + 'data-test-subj': TABLE_TAB_TEST_ID, + name: ( + + ), + content: , + }, + { + id: JSON_TAB_TEST_ID, + 'data-test-subj': JSON_TAB_TEST_ID, + name: ( + + ), + content: , + }, +]; + +const useFilterOptions = (): EuiButtonGroupOptionProps[] => + useMemo( + () => + tabs.map((tab) => { + return { + id: tab.id, + label: tab.name, + }; + }), + [] + ); + +export const AssetDocumentTab: FC> = memo(() => { + const [selectedTabId, setSelectedTabId] = useState(tabs[0].id); + const buttonButtons = useFilterOptions(); + const selectedTab = useMemo(() => { + return tabs.find((tab) => tab.id === selectedTabId); + }, [selectedTabId]); + + return ( + <> + + {selectedTab?.content} + + ); +}); + +AssetDocumentTab.displayName = 'AssetDocumentLeftPanel'; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/content.test.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/risk_inputs.test.tsx similarity index 57% rename from x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/content.test.tsx rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/risk_inputs.test.tsx index a5138dc035dc85..efd47e50009c97 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/content.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/risk_inputs.test.tsx @@ -5,31 +5,22 @@ * 2.0. */ -import type { SimpleRiskInput } from '../../../../common/entity_analytics/risk_engine'; -import { RiskCategories } from '../../../../common/entity_analytics/risk_engine'; import { fireEvent, render } from '@testing-library/react'; import React from 'react'; -import { RiskInputsPanel } from '.'; -import { TestProviders } from '../../../common/mock'; +import { TestProviders } from '../../../../common/mock'; import { times } from 'lodash/fp'; -import { alertDataMock } from './mocks'; +import { alertDataMock } from '../mocks'; +import { RiskInputsTab } from './risk_inputs'; const mockUseAlertsByIds = jest.fn().mockReturnValue({ loading: false, data: [] }); -jest.mock('../../../common/containers/alerts/use_alerts_by_ids', () => ({ +jest.mock('../../../../common/containers/alerts/use_alerts_by_ids', () => ({ useAlertsByIds: () => mockUseAlertsByIds(), })); -const TEST_RISK_INPUT: SimpleRiskInput = { - id: '123', - index: '_test_index', - category: RiskCategories.category_1, - description: 'test description', - risk_score: 70, - timestamp: '2023-05-15T16:12:14.967Z', -}; +const ALERT_IDS = ['123']; -describe('RiskInputsPanel', () => { +describe('RiskInputsTab', () => { it('renders', () => { mockUseAlertsByIds.mockReturnValue({ loading: false, @@ -39,19 +30,25 @@ describe('RiskInputsPanel', () => { const { getByTestId } = render( - + ); - expect(getByTestId('risk-inputs-panel')).toBeInTheDocument(); + expect(getByTestId('risk-input-tab-title')).toBeInTheDocument(); expect(getByTestId('risk-input-table-description-cell')).toHaveTextContent( 'Risk inputRule Name' ); }); it('paginates', () => { - const riskInputs = times((index) => ({ ...TEST_RISK_INPUT, id: index.toString() }), 11); - const alerts = times((index) => ({ ...alertDataMock, _id: index.toString() }), 11); + const alertsIds = times((number) => number.toString(), 11); + const alerts = times( + (number) => ({ + ...alertDataMock, + _id: number.toString(), + }), + 11 + ); mockUseAlertsByIds.mockReturnValue({ loading: false, @@ -61,7 +58,7 @@ describe('RiskInputsPanel', () => { const { getAllByTestId, getByLabelText } = render( - + ); diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/content.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/risk_inputs.tsx similarity index 55% rename from x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/content.tsx rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/risk_inputs.tsx index 34b81d26e8888b..b45f47306c08d6 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/risk_inputs_left/content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/risk_inputs.tsx @@ -6,21 +6,18 @@ */ import type { EuiBasicTableColumn, Pagination } from '@elastic/eui'; -import { useEuiBackgroundColor, EuiSpacer, EuiInMemoryTable, EuiTitle } from '@elastic/eui'; +import { EuiSpacer, EuiInMemoryTable, EuiTitle } from '@elastic/eui'; import React, { useCallback, useMemo, useState } from 'react'; -import { css } from '@emotion/react'; import { FormattedMessage } from '@kbn/i18n-react'; import { get } from 'lodash/fp'; import { ALERT_RULE_NAME } from '@kbn/rule-data-utils'; -import type { RiskInputs } from '../../../../common/entity_analytics/risk_engine'; -import { ActionColumn } from './components/action_column'; -import { PreferenceFormattedDate } from '../../../common/components/formatted_date'; -import { RiskInputsUtilityBar } from './components/utility_bar'; -import { useAlertsByIds } from '../../../common/containers/alerts/use_alerts_by_ids'; -import { FlyoutBody } from '../../shared/components/flyout_body'; +import { useAlertsByIds } from '../../../../common/containers/alerts/use_alerts_by_ids'; +import { PreferenceFormattedDate } from '../../../../common/components/formatted_date'; +import { ActionColumn } from '../components/action_column'; +import { RiskInputsUtilityBar } from '../components/utility_bar'; -export interface RiskInputsPanelContentProps extends Record { - riskInputs: RiskInputs; +export interface RiskInputsTabProps extends Record { + alertIds: string[]; } export interface AlertRawData { @@ -29,9 +26,8 @@ export interface AlertRawData { _id: string; } -export const RiskInputsPanelContent = ({ riskInputs }: RiskInputsPanelContentProps) => { +export const RiskInputsTab = ({ alertIds }: RiskInputsTabProps) => { const [selectedItems, setSelectedItems] = useState([]); - const alertIds = useMemo(() => riskInputs.map(({ id }) => id), [riskInputs]); const { loading, data: alertsData } = useAlertsByIds({ alertIds }); const euiTableSelectionProps = useMemo( @@ -102,57 +98,41 @@ export const RiskInputsPanelContent = ({ riskInputs }: RiskInputsPanelContentPro const pagination: Pagination = useMemo( () => ({ - totalItemCount: riskInputs.length, + totalItemCount: alertIds.length, pageIndex: currentPage.index, pageSize: currentPage.size, }), - [currentPage.index, currentPage.size, riskInputs.length] + [currentPage.index, currentPage.size, alertIds.length] ); return ( <> - - -

- -

-
- - {/* Temporary label. It will be replaced by a filter */} - -

- -

-
- - - - -
+ {/* Temporary label. It will be replaced by a filter */} + +

+ +

+
+ + + + ); }; -RiskInputsPanelContent.displayName = 'RiskInputsPanelContent'; +RiskInputsTab.displayName = 'RiskInputsTab'; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/asset_document_left/test_ids.ts b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/test_ids.ts similarity index 76% rename from x-pack/plugins/security_solution/public/flyout/entity_details/asset_document_left/test_ids.ts rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/test_ids.ts index 6e0138f8177192..14daf659a5aa05 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/asset_document_left/test_ids.ts +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/test_ids.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { PREFIX } from '../../shared/test_ids'; +import { PREFIX } from '../../../shared/test_ids'; export const TABLE_TAB_TEST_ID = `${PREFIX}AssetTableTab` as const; export const JSON_TAB_TEST_ID = `${PREFIX}AssetJsonTab` as const; +export const FLYOUT_BODY_TEST_ID = `${PREFIX}AssetBody` as const; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/test_ids.ts b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/test_ids.ts new file mode 100644 index 00000000000000..b67efe48dca673 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/test_ids.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { PREFIX } from '../../shared/test_ids'; + +export const RISK_INPUTS_TAB_TEST_ID = `${PREFIX}RiskInputsTab` as const; +export const OKTA_TAB_TEST_ID = `${PREFIX}OktaTab` as const; +export const ENTRA_TAB_TEST_ID = `${PREFIX}EntraTab` as const; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.stories.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.stories.tsx index b8975b747ea448..f4a88ce1c7cd39 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.stories.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.stories.tsx @@ -43,6 +43,7 @@ storiesOf('Components/UserPanelContent', module) contextID={'test-user-details'} scopeId={'test-scopeId'} isDraggable={false} + openDetailsPanel={() => {}} /> )) .add('integration disabled', () => ( @@ -57,6 +58,7 @@ storiesOf('Components/UserPanelContent', module) contextID={'test-user-details'} scopeId={'test-scopeId'} isDraggable={false} + openDetailsPanel={() => {}} /> )) .add('no managed data', () => ( @@ -71,6 +73,7 @@ storiesOf('Components/UserPanelContent', module) contextID={'test-user-details'} scopeId={'test-scopeId'} isDraggable={false} + openDetailsPanel={() => {}} /> )) .add('no observed data', () => ( @@ -105,6 +108,7 @@ storiesOf('Components/UserPanelContent', module) contextID={'test-user-details'} scopeId={'test-scopeId'} isDraggable={false} + openDetailsPanel={() => {}} /> )) .add('loading', () => ( @@ -143,5 +147,6 @@ storiesOf('Components/UserPanelContent', module) contextID={'test-user-details'} scopeId={'test-scopeId'} isDraggable={false} + openDetailsPanel={() => {}} /> )); diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx index 49823024a6b892..d782849ce5ee43 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx @@ -19,6 +19,7 @@ import type { RiskScoreState } from '../../../explore/containers/risk_score'; import { RiskSummary } from '../shared/components/risk_summary'; import { USER_PANEL_RISK_SCORE_QUERY_ID } from '.'; import { FlyoutBody } from '../../shared/components/flyout_body'; +import type { UserDetailsLeftPanelTab } from '../user_detais_left/tabs'; interface UserPanelContentProps { observedUser: ObservedUserData; @@ -27,6 +28,7 @@ interface UserPanelContentProps { contextID: string; scopeId: string; isDraggable: boolean; + openDetailsPanel: (tab: UserDetailsLeftPanelTab) => void; } export const UserPanelContent = ({ @@ -36,12 +38,17 @@ export const UserPanelContent = ({ contextID, scopeId, isDraggable, + openDetailsPanel, }: UserPanelContentProps) => { return ( {riskScoreState.isModuleEnabled && riskScoreState.data?.length !== 0 && ( <> - + )} @@ -52,7 +59,12 @@ export const UserPanelContent = ({ isDraggable={isDraggable} /> - + ); }; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/header.test.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/header.test.tsx index 2f1ada7447dd63..861c9b2e2c1fba 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/header.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/header.test.tsx @@ -24,7 +24,7 @@ const mockProps = { jest.mock('../../../common/components/visualization_actions/visualization_embeddable'); -describe('UserDetailsContent', () => { +describe('UserPanelHeader', () => { it('renders', () => { const { getByTestId } = render( diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.tsx index ff9add6011d054..fdc4c9fa703520 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.tsx @@ -8,6 +8,7 @@ import React, { useCallback, useMemo } from 'react'; import type { FlyoutPanelProps } from '@kbn/expandable-flyout'; import { useExpandableFlyoutContext } from '@kbn/expandable-flyout'; +import { ManagedUserDatasetKey } from '../../../../common/search_strategy/security_solution/users/managed_details'; import { useManagedUser } from '../../../timelines/components/side_panel/new_user_detail/hooks/use_managed_user'; import { useObservedUser } from '../../../timelines/components/side_panel/new_user_detail/hooks/use_observed_user'; import { useQueryInspector } from '../../../common/components/page/manage_query'; @@ -19,10 +20,11 @@ import { buildUserNamesFilter } from '../../../../common/search_strategy'; import { useRiskScore } from '../../../explore/containers/risk_score'; import { RiskScoreEntity } from '../../../../common/entity_analytics/risk_engine'; import { FlyoutLoading } from '../../shared/components/flyout_loading'; -import { RiskInputsPanelKey } from '../risk_inputs_left'; import { FlyoutNavigation } from '../../shared/components/flyout_navigation'; import { UserPanelContent } from './content'; import { UserPanelHeader } from './header'; +import { UserDetailsPanelKey } from '../user_detais_left'; +import type { UserDetailsLeftPanelTab } from '../user_detais_left/tabs'; export interface UserPanelProps extends Record { contextID: string; @@ -60,7 +62,8 @@ export const UserPanel = ({ contextID, scopeId, userName, isDraggable }: UserPan const { to, from, isInitializing, setQuery, deleteQuery } = useGlobalTime(); const observedUser = useObservedUser(userName); - const managedUser = useManagedUser(userName, observedUser); + const email = observedUser.details.user?.email; + const managedUser = useManagedUser(userName, email, observedUser.isLoading); const { data: userRisk } = riskScoreState; const userRiskData = userRisk && userRisk.length > 0 ? userRisk[0] : undefined; @@ -75,14 +78,31 @@ export const UserPanel = ({ contextID, scopeId, userName, isDraggable }: UserPan }); const { openLeftPanel } = useExpandableFlyoutContext(); - const openPanel = useCallback(() => { - openLeftPanel({ - id: RiskInputsPanelKey, - params: { - riskInputs: userRiskData?.user.risk.inputs, - }, - }); - }, [openLeftPanel, userRiskData?.user.risk.inputs]); + const openPanelTab = useCallback( + (tab?: UserDetailsLeftPanelTab) => { + openLeftPanel({ + id: UserDetailsPanelKey, + params: { + riskInputs: { + alertIds: userRiskData?.user.risk.inputs?.map(({ id }) => id) ?? [], + }, + user: { + name: userName, + email, + }, + }, + path: tab ? { tab } : undefined, + }); + }, + [email, openLeftPanel, userName, userRiskData?.user.risk.inputs] + ); + + const openPanelFirstTab = useCallback(() => openPanelTab(), [openPanelTab]); + + const hasUserDetailsData = + !!userRiskData?.user.risk || + !!managedUser.data?.[ManagedUserDatasetKey.OKTA] || + !!managedUser.data?.[ManagedUserDatasetKey.ENTRA]; if (riskScoreState.loading || observedUser.isLoading || managedUser.isLoading) { return ; @@ -107,8 +127,8 @@ export const UserPanel = ({ contextID, scopeId, userName, isDraggable }: UserPan return ( <> ); diff --git a/x-pack/plugins/security_solution/public/flyout/index.tsx b/x-pack/plugins/security_solution/public/flyout/index.tsx index 71ea03d18572a2..01c14b3d3ed293 100644 --- a/x-pack/plugins/security_solution/public/flyout/index.tsx +++ b/x-pack/plugins/security_solution/public/flyout/index.tsx @@ -24,14 +24,8 @@ import { PreviewPanel, DocumentDetailsPreviewPanelKey } from './document_details import { PreviewPanelProvider } from './document_details/preview/context'; import type { UserPanelExpandableFlyoutProps } from './entity_details/user_right'; import { UserPanel, UserPanelKey } from './entity_details/user_right'; -import type { RiskInputsExpandableFlyoutProps } from './entity_details/risk_inputs_left'; -import { RiskInputsPanel, RiskInputsPanelKey } from './entity_details/risk_inputs_left'; -import type { AssetDocumentLeftPanelProps } from './entity_details/asset_document_left'; -import { - AssetDocumentLeftPanel, - AssetDocumentLeftPanelKey, -} from './entity_details/asset_document_left'; - +import type { UserDetailsPanelProps } from './entity_details/user_detais_left'; +import { UserDetailsPanel, UserDetailsPanelKey } from './entity_details/user_detais_left'; /** * List of all panels that will be used within the document details expandable flyout. * This needs to be passed to the expandable flyout registeredPanels property. @@ -45,14 +39,6 @@ const expandableFlyoutDocumentsPanels: ExpandableFlyoutProps['registeredPanels'] ), }, - { - key: AssetDocumentLeftPanelKey, - component: (props) => ( - - - - ), - }, { key: DocumentDetailsLeftPanelKey, component: (props) => ( @@ -82,9 +68,9 @@ const expandableFlyoutDocumentsPanels: ExpandableFlyoutProps['registeredPanels'] component: (props) => , }, { - key: RiskInputsPanelKey, + key: UserDetailsPanelKey, component: (props) => ( - + ), }, ]; diff --git a/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_navigation.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_navigation.tsx index cc969988a16a48..11429979139df2 100644 --- a/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_navigation.tsx +++ b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_navigation.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import type { FC } from 'react'; +import type { FC, SyntheticEvent } from 'react'; import React, { memo, useCallback, useMemo } from 'react'; import { EuiFlyoutHeader, @@ -32,7 +32,7 @@ export interface FlyoutNavigationProps { /** * If flyoutIsExpandable is true, pass a callback to open left panel */ - expandDetails?: () => void; + expandDetails?: (e: SyntheticEvent) => void; /** * Optional actions to be placed on the right hand side of navigation */ diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/hooks/use_managed_user.test.ts b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/hooks/use_managed_user.test.ts index c33528b99b576d..1e40f66b702428 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/hooks/use_managed_user.test.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/hooks/use_managed_user.test.ts @@ -10,7 +10,6 @@ import type { InstalledIntegration } from '../../../../../../common/api/detectio import { TestProviders } from '../../../../../common/mock'; import { ENTRA_ID_PACKAGE_NAME } from '../constants'; import { useManagedUser } from './use_managed_user'; -import type { ObserverUser } from './use_observed_user'; const makeInstalledIntegration = ( pkgName = 'testPkg', @@ -53,19 +52,6 @@ jest.mock('../../../../../common/containers/use_search_strategy', () => ({ }), })); -const observedUser: ObserverUser = { - isLoading: false, - details: {}, - firstSeen: { - date: undefined, - isLoading: false, - }, - lastSeen: { - date: undefined, - isLoading: false, - }, -}; - describe('useManagedUser', () => { beforeEach(() => { mockSearch.mockClear(); @@ -75,7 +61,7 @@ describe('useManagedUser', () => { data: [makeInstalledIntegration(ENTRA_ID_PACKAGE_NAME, true)], }); - const { result } = renderHook(() => useManagedUser('test-userName', observedUser), { + const { result } = renderHook(() => useManagedUser('test-userName', undefined, false), { wrapper: TestProviders, }); @@ -87,7 +73,7 @@ describe('useManagedUser', () => { data: [makeInstalledIntegration('fake-name', true)], }); - const { result } = renderHook(() => useManagedUser('test-userName', observedUser), { + const { result } = renderHook(() => useManagedUser('test-userName', undefined, false), { wrapper: TestProviders, }); @@ -95,7 +81,7 @@ describe('useManagedUser', () => { }); it('should search', () => { - renderHook(() => useManagedUser('test-userName', observedUser), { + renderHook(() => useManagedUser('test-userName', undefined, false), { wrapper: TestProviders, }); @@ -103,7 +89,7 @@ describe('useManagedUser', () => { }); it('should not search while observed user is loading', () => { - renderHook(() => useManagedUser('test-userName', { ...observedUser, isLoading: true }), { + renderHook(() => useManagedUser('test-userName', undefined, true), { wrapper: TestProviders, }); @@ -112,16 +98,9 @@ describe('useManagedUser', () => { it('should search by email if the field is available', () => { const email = ['test@email.com']; - renderHook( - () => - useManagedUser('test-userName', { - ...observedUser, - details: { user: { email } }, - }), - { - wrapper: TestProviders, - } - ); + renderHook(() => useManagedUser('test-userName', email, false), { + wrapper: TestProviders, + }); expect(mockSearch).toBeCalledWith( expect.objectContaining({ diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/hooks/use_managed_user.ts b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/hooks/use_managed_user.ts index 61e8b7e7e961c3..c3001c30d8cc29 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/hooks/use_managed_user.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/hooks/use_managed_user.ts @@ -6,6 +6,7 @@ */ import { useEffect, useMemo } from 'react'; +import type { ManagedUserHits } from '../../../../../../common/search_strategy/security_solution/users/managed_details'; import { useInstalledIntegrations } from '../../../../../detections/components/rules/related_integrations/use_installed_integrations'; import { UsersQueries } from '../../../../../../common/search_strategy'; import { useSpaceId } from '../../../../../common/hooks/use_space_id'; @@ -20,11 +21,20 @@ import { MANAGED_USER_QUERY_ID, } from '../constants'; import * as i18n from '../translations'; -import type { ObserverUser } from './use_observed_user'; const packages = [ENTRA_ID_PACKAGE_NAME, OKTA_PACKAGE_NAME]; -export const useManagedUser = (userName: string, observedUser: ObserverUser) => { +interface ManagedUserData { + data: ManagedUserHits; + isLoading: boolean; + isIntegrationEnabled: boolean; +} + +export const useManagedUser = ( + userName: string, + email: string[] | undefined, + isLoading?: boolean +): ManagedUserData => { const { to, from, isInitializing, deleteQuery, setQuery } = useGlobalTime(); const spaceId = useSpaceId(); const { @@ -47,23 +57,14 @@ export const useManagedUser = (userName: string, observedUser: ObserverUser) => ); useEffect(() => { - if (!isInitializing && defaultIndex.length > 0 && !observedUser.isLoading && userName) { + if (!isInitializing && defaultIndex.length > 0 && !isLoading && userName) { search({ defaultIndex, - userEmail: observedUser.details.user?.email, + userEmail: email, userName, }); } - }, [ - from, - search, - to, - isInitializing, - defaultIndex, - userName, - observedUser.isLoading, - observedUser.details.user?.email, - ]); + }, [from, search, to, isInitializing, defaultIndex, userName, isLoading, email]); const { data: installedIntegrations, isLoading: loadingIntegrations } = useInstalledIntegrations({ packages, diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user.test.tsx index 70363853b9101e..33349129471524 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user.test.tsx @@ -19,6 +19,7 @@ describe('ManagedUser', () => { contextID: '', scopeId: '', isDraggable: false, + openDetailsPanel: () => {}, }; it('renders', () => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user.tsx index 35a9a78011982b..a208a9ae3f41f1 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user.tsx @@ -17,6 +17,8 @@ import { import React, { useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; +import { css } from '@emotion/css'; +import type { UserDetailsLeftPanelTab } from '../../../../flyout/entity_details/user_detais_left/tabs'; import { UserAssetTableType } from '../../../../explore/users/store/model'; import type { ManagedUserFields } from '../../../../../common/search_strategy/security_solution/users/managed_details'; import { ManagedUserDatasetKey } from '../../../../../common/search_strategy/security_solution/users/managed_details'; @@ -32,14 +34,20 @@ import { useAppUrl } from '../../../../common/lib/kibana'; import { ManagedUserAccordion } from './managed_user_accordion'; import { useManagedUserItems } from './hooks/use_managed_user_items'; +const accordionStyle = css` + width: 100%; +`; + export const ManagedUser = ({ managedUser, contextID, isDraggable, + openDetailsPanel, }: { managedUser: ManagedUserData; contextID: string; isDraggable: boolean; + openDetailsPanel: (tab: UserDetailsLeftPanelTab) => void; }) => { const entraManagedUser = managedUser.data?.[ManagedUserDatasetKey.ENTRA]; const oktaManagedUser = managedUser.data?.[ManagedUserDatasetKey.OKTA]; @@ -71,6 +79,7 @@ export const ManagedUser = ({ title={i18n.MANAGED_USER_INSPECT_TITLE} /> } + className={accordionStyle} > @@ -115,9 +124,8 @@ export const ManagedUser = ({ { +describe('ManagedUserAccordion', () => { it('it renders children', () => { const { getByTestId } = render( {}} >
diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user_accordion.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user_accordion.tsx index 26bef6232735b3..9ae5a6433f0413 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user_accordion.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user_accordion.tsx @@ -7,50 +7,35 @@ import { useEuiFontSize } from '@elastic/eui'; -import React, { useCallback } from 'react'; +import React from 'react'; import { css } from '@emotion/react'; import { FormattedMessage } from '@kbn/i18n-react'; import { get } from 'lodash/fp'; -import { useExpandableFlyoutContext } from '@kbn/expandable-flyout'; +import { UserDetailsLeftPanelTab } from '../../../../flyout/entity_details/user_detais_left/tabs'; import { ExpandablePanel } from '../../../../flyout/shared/components/expandable_panel'; import type { ManagedUserFields } from '../../../../../common/search_strategy/security_solution/users/managed_details'; import { FormattedRelativePreferenceDate } from '../../../../common/components/formatted_date'; import { ONE_WEEK_IN_HOURS } from './constants'; -import { AssetDocumentLeftPanelKey } from '../../../../flyout/entity_details/asset_document_left'; -import type { UserAssetTableType } from '../../../../explore/users/store/model'; +import { UserAssetTableType } from '../../../../explore/users/store/model'; interface ManagedUserAccordionProps { children: React.ReactNode; title: string; managedUser: ManagedUserFields; - indexName: string; - eventId: string; tableType: UserAssetTableType; + openDetailsPanel: (tab: UserDetailsLeftPanelTab) => void; } export const ManagedUserAccordion: React.FC = ({ children, title, managedUser, - indexName, - eventId, tableType, + openDetailsPanel, }) => { const xsFontSize = useEuiFontSize('xxs').fontSize; const timestamp = get('@timestamp[0]', managedUser) as unknown as string | undefined; - const { openLeftPanel } = useExpandableFlyoutContext(); - const toggleDetails = useCallback(() => { - openLeftPanel({ - id: AssetDocumentLeftPanelKey, - params: { - id: eventId, - indexName, - scopeId: tableType, - }, - }); - }, [openLeftPanel, eventId, indexName, tableType]); - return ( = ({ ), link: { - callback: toggleDetails, + callback: () => + openDetailsPanel( + tableType === UserAssetTableType.assetOkta + ? UserDetailsLeftPanelTab.OKTA + : UserDetailsLeftPanelTab.ENTRA + ), tooltip: ( Date: Wed, 20 Dec 2023 09:50:02 +0100 Subject: [PATCH 006/116] [SLO] Improve equivalent API View (#173503) ## Summary Instead of copy JSON button, show JSON in flyout with option to copy as well image --- .../common/equivalent_api_request.tsx | 128 ++++++++++++++++++ .../slo_edit/components/slo_edit_form.tsx | 18 +-- .../pages/slo_edit/hooks/use_copy_to_json.ts | 52 ------- .../translations/translations/fr-FR.json | 3 - .../translations/translations/ja-JP.json | 3 - .../translations/translations/zh-CN.json | 3 - 6 files changed, 133 insertions(+), 74 deletions(-) create mode 100644 x-pack/plugins/observability/public/pages/slo_edit/components/common/equivalent_api_request.tsx delete mode 100644 x-pack/plugins/observability/public/pages/slo_edit/hooks/use_copy_to_json.ts diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/common/equivalent_api_request.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/common/equivalent_api_request.tsx new file mode 100644 index 00000000000000..6bf597b12d9a93 --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/common/equivalent_api_request.tsx @@ -0,0 +1,128 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { i18n } from '@kbn/i18n'; + +import React, { useEffect, useState } from 'react'; +import { + EuiButtonEmpty, + EuiCodeBlock, + EuiFlyout, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlyoutHeader, + EuiSpacer, + EuiText, + EuiTitle, +} from '@elastic/eui'; +import { useFormContext } from 'react-hook-form'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { CreateSLOInput } from '@kbn/slo-schema'; +import { CreateSLOForm } from '../../types'; +import { transformCreateSLOFormToCreateSLOInput } from '../../helpers/process_slo_form_values'; + +export function EquivalentApiRequest({ + isCreateSloLoading, + isUpdateSloLoading, +}: { + isCreateSloLoading: boolean; + isUpdateSloLoading: boolean; +}) { + const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); + + const { getValues, trigger } = useFormContext(); + + const [sloData, setSloData] = useState(); + + useEffect(() => { + if (!isFlyoutVisible) { + return; + } + trigger().then((isValid) => { + if (isValid) { + setSloData(transformCreateSLOFormToCreateSLOInput(getValues())); + } + }); + }, [getValues, trigger, isFlyoutVisible]); + + let flyout; + + if (isFlyoutVisible) { + flyout = ( + setIsFlyoutVisible(false)}> + + +

+ {i18n.translate( + 'xpack.observability.equivalentApiRequest.h2.equivalentAPIRequestToLabel', + { defaultMessage: 'Equivalent API request' } + )} +

+
+
+ + + + + + + {'POST /api/observability/slos'} + + + + + + {sloData ? ( + + {JSON.stringify(sloData, null, 2)} + + ) : ( + + {i18n.translate( + 'xpack.observability.equivalentApiRequest.formIsNotValidCodeBlockLabel', + { defaultMessage: 'Form is not valid' } + )} + + )} + + + setIsFlyoutVisible(false)} + flush="left" + > + {i18n.translate('xpack.observability.equivalentApiRequest.closeButtonEmptyLabel', { + defaultMessage: 'Close', + })} + + +
+ ); + } + return ( + <> + setIsFlyoutVisible(true)} + > + {i18n.translate('xpack.observability.slo.sloEdit.equivalentApiRequest', { + defaultMessage: 'Equivalent API request', + })} + + {flyout} + + ); +} diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx index e5f8e9b02ce2a0..0e3c491bdd7c2f 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx @@ -18,6 +18,7 @@ import { i18n } from '@kbn/i18n'; import type { GetSLOResponse } from '@kbn/slo-schema'; import React, { useCallback, useEffect, useState } from 'react'; import { FormProvider, useForm } from 'react-hook-form'; +import { EquivalentApiRequest } from './common/equivalent_api_request'; import { BurnRateRuleFlyout } from '../../slos/components/common/burn_rate_rule_flyout'; import { paths } from '../../../../common/locators/paths'; import { useCreateSlo } from '../../../hooks/slo/use_create_slo'; @@ -34,7 +35,6 @@ import { CREATE_RULE_SEARCH_PARAM, useAddRuleFlyoutState, } from '../hooks/use_add_rule_flyout_state'; -import { useCopyToJson } from '../hooks/use_copy_to_json'; import { useParseUrlState } from '../hooks/use_parse_url_state'; import { useSectionFormValidation } from '../hooks/use_section_form_validation'; import { useShowSections } from '../hooks/use_show_sections'; @@ -78,7 +78,6 @@ export function SloEditForm({ slo }: Props) { mode: 'all', }); const { watch, getFieldState, getValues, formState, trigger } = methods; - const handleCopyToJson = useCopyToJson({ trigger, getValues }); const { isIndicatorSectionValid, isObjectiveSectionValid, isDescriptionSectionValid } = useSectionFormValidation({ @@ -235,17 +234,10 @@ export function SloEditForm({ slo }: Props) { })} - - {i18n.translate('xpack.observability.slo.sloEdit.copyJsonButton', { - defaultMessage: 'Copy JSON', - })} - + diff --git a/x-pack/plugins/observability/public/pages/slo_edit/hooks/use_copy_to_json.ts b/x-pack/plugins/observability/public/pages/slo_edit/hooks/use_copy_to_json.ts deleted file mode 100644 index c2c59eaeb5361a..00000000000000 --- a/x-pack/plugins/observability/public/pages/slo_edit/hooks/use_copy_to_json.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; -import { UseFormGetValues, UseFormTrigger } from 'react-hook-form'; -import { useKibana } from '../../../utils/kibana_react'; -import { transformCreateSLOFormToCreateSLOInput } from '../helpers/process_slo_form_values'; -import { CreateSLOForm } from '../types'; - -interface Props { - trigger: UseFormTrigger; - getValues: UseFormGetValues; -} - -export function useCopyToJson({ trigger, getValues }: Props): () => Promise { - const { notifications } = useKibana().services; - - const handleCopyToJson = async () => { - const isValid = await trigger(); - if (!isValid) { - return; - } - const values = transformCreateSLOFormToCreateSLOInput(getValues()); - try { - await copyTextToClipboard(JSON.stringify(values, null, 2)); - notifications.toasts.add({ - title: i18n.translate('xpack.observability.slo.sloEdit.copyJsonNotification', { - defaultMessage: 'JSON copied to clipboard', - }), - }); - } catch (e) { - notifications.toasts.add({ - title: i18n.translate('xpack.observability.slo.sloEdit.copyJsonFailedNotification', { - defaultMessage: 'Could not copy JSON to clipboard', - }), - }); - } - }; - - const copyTextToClipboard = async (text: string) => { - if (!window.navigator?.clipboard) { - throw new Error('Could not copy to clipboard!'); - } - await window.navigator.clipboard.writeText(text); - }; - - return handleCopyToJson; -} diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index ed4999bec73341..00510fafcbb58a 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -29263,9 +29263,6 @@ "xpack.observability.slo.sloEdit.calendarTimeWindow.monthly": "Mensuel", "xpack.observability.slo.sloEdit.calendarTimeWindow.weekly": "Hebdomadaire", "xpack.observability.slo.sloEdit.cancelButton": "Annuler", - "xpack.observability.slo.sloEdit.copyJsonButton": "Copier le JSON", - "xpack.observability.slo.sloEdit.copyJsonFailedNotification": "Échec de la copie du JSON dans le presse-papiers", - "xpack.observability.slo.sloEdit.copyJsonNotification": "JSON copié dans le presse-papiers", "xpack.observability.slo.sloEdit.createAlert.ruleName": "Règle d'alerte de taux d'avancement du SLO", "xpack.observability.slo.sloEdit.createAlert.title": "Créer", "xpack.observability.slo.sloEdit.createSloButton": "Créer un SLO", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index c8fb3f513fa9b1..8d313440282b55 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -29263,9 +29263,6 @@ "xpack.observability.slo.sloEdit.calendarTimeWindow.monthly": "月ごと", "xpack.observability.slo.sloEdit.calendarTimeWindow.weekly": "週ごと", "xpack.observability.slo.sloEdit.cancelButton": "キャンセル", - "xpack.observability.slo.sloEdit.copyJsonButton": "JSONをコピー", - "xpack.observability.slo.sloEdit.copyJsonFailedNotification": "JSONをクリップボードにコピーできませんでした", - "xpack.observability.slo.sloEdit.copyJsonNotification": "JSONがクリップボードにコピーされました", "xpack.observability.slo.sloEdit.createAlert.ruleName": "SLOバーンレートアラートルール", "xpack.observability.slo.sloEdit.createAlert.title": "作成", "xpack.observability.slo.sloEdit.createSloButton": "SLOの作成", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 2d4e05c06f1a49..3cd194aabd49e3 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -29260,9 +29260,6 @@ "xpack.observability.slo.sloEdit.calendarTimeWindow.monthly": "每月", "xpack.observability.slo.sloEdit.calendarTimeWindow.weekly": "每周", "xpack.observability.slo.sloEdit.cancelButton": "取消", - "xpack.observability.slo.sloEdit.copyJsonButton": "复制 JSON", - "xpack.observability.slo.sloEdit.copyJsonFailedNotification": "无法将 JSON 复制到剪贴板", - "xpack.observability.slo.sloEdit.copyJsonNotification": "JSON 已复制到剪贴板", "xpack.observability.slo.sloEdit.createAlert.ruleName": "SLO 消耗速度告警规则", "xpack.observability.slo.sloEdit.createAlert.title": "创建", "xpack.observability.slo.sloEdit.createSloButton": "创建 SLO", From 5c5c72d4bac78b6964c2b23ec63a45b0d8ba8e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Kopyci=C5=84ski?= Date: Wed, 20 Dec 2023 10:54:58 +0100 Subject: [PATCH 007/116] [Sentinel One] Disable connector params field (#173610) ## Summary Currently, we don't support automated response actions, so we don't want to expose it to the user in the Connector's Test tab Zrzut ekranu 2023-12-19 o 12 38 37 --- .../connector_types/sentinelone/sentinelone.ts | 4 +++- .../sentinelone/sentinelone_params_empty.tsx | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone_params_empty.tsx diff --git a/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone.ts b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone.ts index a65fc6a4f011c6..b01fa9fbaed5d5 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone.ts +++ b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone.ts @@ -60,6 +60,8 @@ export function getConnectorType(): ConnectorTypeModel< return { errors }; }, actionConnectorFields: lazy(() => import('./sentinelone_connector')), - actionParamsFields: lazy(() => import('./sentinelone_params')), + actionParamsFields: lazy(() => import('./sentinelone_params_empty')), + // TODO: Enable once we add support for automated response actions + // actionParamsFields: lazy(() => import('./sentinelone_params')), }; } diff --git a/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone_params_empty.tsx b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone_params_empty.tsx new file mode 100644 index 00000000000000..35895d35bcebf6 --- /dev/null +++ b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone_params_empty.tsx @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +const SentinelOneParamsFields = () => <>; + +// eslint-disable-next-line import/no-default-export +export { SentinelOneParamsFields as default }; From e4c1a799fb65d78a25808ae84617a20ac13ef788 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Wed, 20 Dec 2023 11:36:29 +0100 Subject: [PATCH 008/116] fix dark theme in global search bar (#173613) ## Summary partially address https://github.com/elastic/kibana/issues/173529 --- x-pack/plugins/global_search_bar/kibana.jsonc | 3 -- .../public/components/popover_placeholder.tsx | 9 +++--- .../public/components/search_bar.test.tsx | 6 ---- .../public/components/search_bar.tsx | 6 ++-- .../public/components/types.ts | 1 - .../global_search_bar/public/plugin.tsx | 28 ++++++++----------- .../public/telemetry/telmetry.test.tsx | 8 ------ .../plugins/global_search_bar/tsconfig.json | 2 +- 8 files changed, 21 insertions(+), 42 deletions(-) diff --git a/x-pack/plugins/global_search_bar/kibana.jsonc b/x-pack/plugins/global_search_bar/kibana.jsonc index 44689ddc5bdfd4..552ee46e6e41d8 100644 --- a/x-pack/plugins/global_search_bar/kibana.jsonc +++ b/x-pack/plugins/global_search_bar/kibana.jsonc @@ -16,9 +16,6 @@ "optionalPlugins": [ "usageCollection", "savedObjectsTagging" - ], - "requiredBundles": [ - "kibanaReact" ] } } diff --git a/x-pack/plugins/global_search_bar/public/components/popover_placeholder.tsx b/x-pack/plugins/global_search_bar/public/components/popover_placeholder.tsx index ecd4b2aee8f02c..7783cc94cfdba7 100644 --- a/x-pack/plugins/global_search_bar/public/components/popover_placeholder.tsx +++ b/x-pack/plugins/global_search_bar/public/components/popover_placeholder.tsx @@ -6,16 +6,17 @@ */ import React, { FC } from 'react'; -import { EuiImage, EuiText, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiImage, EuiText, EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; interface PopoverPlaceholderProps { - darkMode: boolean; basePath: string; } -export const PopoverPlaceholder: FC = ({ basePath, darkMode }) => { +export const PopoverPlaceholder: FC = ({ basePath }) => { + const { colorMode } = useEuiTheme(); + return ( = ({ basePath, dark })} size="fullWidth" url={`${basePath}illustration_product_no_search_results_${ - darkMode ? 'dark' : 'light' + colorMode === 'DARK' ? 'dark' : 'light' }.svg`} /> diff --git a/x-pack/plugins/global_search_bar/public/components/search_bar.test.tsx b/x-pack/plugins/global_search_bar/public/components/search_bar.test.tsx index fec5c4c008c090..1caa636e86cb5a 100644 --- a/x-pack/plugins/global_search_bar/public/components/search_bar.test.tsx +++ b/x-pack/plugins/global_search_bar/public/components/search_bar.test.tsx @@ -52,7 +52,6 @@ describe('SearchBar', () => { const core = coreMock.createStart(); const basePathUrl = '/plugins/globalSearchBar/assets/'; - const darkMode = false; const eventReporter = new EventReporter({ analytics: core.analytics, usageCollection }); let searchService: ReturnType; let applications: ReturnType; @@ -109,7 +108,6 @@ describe('SearchBar', () => { globalSearch={searchService} navigateToUrl={applications.navigateToUrl} basePathUrl={basePathUrl} - darkMode={darkMode} chromeStyle$={chromeStyle$} reportEvent={eventReporter} /> @@ -138,7 +136,6 @@ describe('SearchBar', () => { globalSearch={searchService} navigateToUrl={applications.navigateToUrl} basePathUrl={basePathUrl} - darkMode={darkMode} chromeStyle$={chromeStyle$} reportEvent={eventReporter} /> @@ -171,7 +168,6 @@ describe('SearchBar', () => { globalSearch={searchService} navigateToUrl={applications.navigateToUrl} basePathUrl={basePathUrl} - darkMode={darkMode} chromeStyle$={chromeStyle$} reportEvent={eventReporter} /> @@ -203,7 +199,6 @@ describe('SearchBar', () => { globalSearch={searchService} navigateToUrl={applications.navigateToUrl} basePathUrl={basePathUrl} - darkMode={darkMode} chromeStyle$={chromeStyle$} reportEvent={eventReporter} /> @@ -227,7 +222,6 @@ describe('SearchBar', () => { globalSearch={searchService} navigateToUrl={applications.navigateToUrl} basePathUrl={basePathUrl} - darkMode={darkMode} chromeStyle$={chromeStyle$} reportEvent={eventReporter} /> diff --git a/x-pack/plugins/global_search_bar/public/components/search_bar.tsx b/x-pack/plugins/global_search_bar/public/components/search_bar.tsx index f911b2bc18a4cc..821a6efad3491b 100644 --- a/x-pack/plugins/global_search_bar/public/components/search_bar.tsx +++ b/x-pack/plugins/global_search_bar/public/components/search_bar.tsx @@ -36,9 +36,9 @@ import { PopoverPlaceholder } from './popover_placeholder'; import './search_bar.scss'; import { SearchBarProps } from './types'; -const NoMatchesMessage = (props: { basePathUrl: string; darkMode: boolean }) => ( - -); +const NoMatchesMessage = (props: { basePathUrl: string }) => { + return ; +}; const EmptyMessage = () => ( diff --git a/x-pack/plugins/global_search_bar/public/components/types.ts b/x-pack/plugins/global_search_bar/public/components/types.ts index c56cde3bf443fe..de0af36624db28 100644 --- a/x-pack/plugins/global_search_bar/public/components/types.ts +++ b/x-pack/plugins/global_search_bar/public/components/types.ts @@ -19,6 +19,5 @@ export interface SearchBarProps { reportEvent: EventReporter; taggingApi?: SavedObjectTaggingPluginStart; basePathUrl: string; - darkMode: boolean; chromeStyle$: Observable; } diff --git a/x-pack/plugins/global_search_bar/public/plugin.tsx b/x-pack/plugins/global_search_bar/public/plugin.tsx index 12f15036886c46..00cddfb65534fa 100644 --- a/x-pack/plugins/global_search_bar/public/plugin.tsx +++ b/x-pack/plugins/global_search_bar/public/plugin.tsx @@ -7,8 +7,7 @@ import { ChromeNavControl, CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; import { GlobalSearchPluginStart } from '@kbn/global-search-plugin/public'; -import { I18nProvider } from '@kbn/i18n-react'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; +import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; import { SavedObjectTaggingPluginStart } from '@kbn/saved-objects-tagging-plugin/public'; import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public'; import React from 'react'; @@ -38,26 +37,23 @@ export class GlobalSearchBarPlugin implements Plugin<{}, {}, {}, GlobalSearchBar private getNavControl(deps: { core: CoreStart } & GlobalSearchBarPluginStartDeps) { const { core, globalSearch, savedObjectsTagging, usageCollection } = deps; - const { application, http, theme, uiSettings } = core; + const { application, http, theme, i18n } = core; const reportEvent = new EventReporter({ analytics: core.analytics, usageCollection }); const navControl: ChromeNavControl = { order: 1000, mount: (container) => { ReactDOM.render( - - - - - , + + + , container ); diff --git a/x-pack/plugins/global_search_bar/public/telemetry/telmetry.test.tsx b/x-pack/plugins/global_search_bar/public/telemetry/telmetry.test.tsx index 6eec366dc5ab20..f44612a3829726 100644 --- a/x-pack/plugins/global_search_bar/public/telemetry/telmetry.test.tsx +++ b/x-pack/plugins/global_search_bar/public/telemetry/telmetry.test.tsx @@ -50,7 +50,6 @@ describe('SearchBar', () => { const usageCollection = usageCollectionPluginMock.createSetupContract(); const core = coreMock.createStart(); const basePathUrl = '/plugins/globalSearchBar/assets/'; - const darkMode = false; let searchService: ReturnType; let applications: ReturnType; let mockReportUiCounter: typeof usageCollection.reportUiCounter; @@ -114,7 +113,6 @@ describe('SearchBar', () => { globalSearch={searchService} navigateToUrl={applications.navigateToUrl} basePathUrl={basePathUrl} - darkMode={darkMode} chromeStyle$={chromeStyle$} reportEvent={eventReporter} /> @@ -137,7 +135,6 @@ describe('SearchBar', () => { globalSearch={searchService} navigateToUrl={applications.navigateToUrl} basePathUrl={basePathUrl} - darkMode={darkMode} chromeStyle$={chromeStyle$} reportEvent={eventReporter} /> @@ -165,7 +162,6 @@ describe('SearchBar', () => { globalSearch={searchService} navigateToUrl={applications.navigateToUrl} basePathUrl={basePathUrl} - darkMode={darkMode} chromeStyle$={chromeStyle$} reportEvent={eventReporter} /> @@ -203,7 +199,6 @@ describe('SearchBar', () => { globalSearch={searchService} navigateToUrl={applications.navigateToUrl} basePathUrl={basePathUrl} - darkMode={darkMode} chromeStyle$={chromeStyle$} reportEvent={eventReporter} /> @@ -240,7 +235,6 @@ describe('SearchBar', () => { globalSearch={searchService} navigateToUrl={applications.navigateToUrl} basePathUrl={basePathUrl} - darkMode={darkMode} chromeStyle$={chromeStyle$} reportEvent={eventReporter} /> @@ -270,7 +264,6 @@ describe('SearchBar', () => { globalSearch={searchService} navigateToUrl={applications.navigateToUrl} basePathUrl={basePathUrl} - darkMode={darkMode} chromeStyle$={chromeStyle$} reportEvent={eventReporter} /> @@ -300,7 +293,6 @@ describe('SearchBar', () => { globalSearch={searchService} navigateToUrl={applications.navigateToUrl} basePathUrl={basePathUrl} - darkMode={darkMode} chromeStyle$={chromeStyle$} reportEvent={eventReporter} /> diff --git a/x-pack/plugins/global_search_bar/tsconfig.json b/x-pack/plugins/global_search_bar/tsconfig.json index 1084a9b1139d6a..1e66c8225abeae 100644 --- a/x-pack/plugins/global_search_bar/tsconfig.json +++ b/x-pack/plugins/global_search_bar/tsconfig.json @@ -11,11 +11,11 @@ "@kbn/saved-objects-tagging-plugin", "@kbn/analytics", "@kbn/i18n-react", - "@kbn/kibana-react-plugin", "@kbn/i18n", "@kbn/saved-objects-tagging-oss-plugin", "@kbn/core-chrome-browser", "@kbn/analytics-client", + "@kbn/react-kibana-context-render", ], "exclude": [ "target/**/*", From 8e29ce82429f2d5c20884d488753ef908d550890 Mon Sep 17 00:00:00 2001 From: Pete Harverson Date: Wed, 20 Dec 2023 10:43:59 +0000 Subject: [PATCH 009/116] [ML] Adds warning for legacy method for installing pre-configured APM transaction job (#173375) ## Summary Adds text to the anomaly detection job creation wizard card for the pre-configured job for APM transaction data that the job should be created inside the APM app. The APM UI adds metadata and an additional `service.environment` filter term to the datafeed query, and these extra properties are not added when creating the APM transaction job from within the ML job wizard image Closes #172160 ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../data_recognizer/modules/apm_transaction/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/manifest.json index f07c9dcba94a4a..46f7f7362eb214 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/manifest.json @@ -1,7 +1,7 @@ { "id": "apm_transaction", "title": "APM", - "description": "Detect anomalies in transaction latency, throughput and failure rate from your APM services for metric data.", + "description": "Legacy job for detecting anomalies in transaction latency, throughput and failure rate from your APM services for metric data. The latest version can be installed from the APM app in Observability.", "type": "Transaction data", "logoFile": "logo.json", "defaultIndexPattern": "apm-*-metric,metrics-apm*", From 50f67699f7a6183ba770e24a7a4575567150ad05 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Wed, 20 Dec 2023 11:46:12 +0100 Subject: [PATCH 010/116] [Fleet] Do not write to metrics-fleet_server.usage* if .fleet-agents is not yet created (#173689) --- .../metrics/fetch_agent_metrics.test.ts | 8 ++++++++ .../services/metrics/fetch_agent_metrics.ts | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/x-pack/plugins/fleet/server/services/metrics/fetch_agent_metrics.test.ts b/x-pack/plugins/fleet/server/services/metrics/fetch_agent_metrics.test.ts index fee9e7497e0ef3..d8e8030279620e 100644 --- a/x-pack/plugins/fleet/server/services/metrics/fetch_agent_metrics.test.ts +++ b/x-pack/plugins/fleet/server/services/metrics/fetch_agent_metrics.test.ts @@ -29,6 +29,14 @@ describe('fetchAgentMetrics', () => { esClient = elasticsearch.client.asInternalUser as ElasticsearchClientMock; }); + it('should not fetch agent if .fleet-agents is not created', async () => { + esClient.indices.get.mockRejectedValue({ statusCode: 404 }); + + const result = await fetchAgentMetrics(mockCore, abortController); + + expect(result).toBeUndefined(); + }); + it('should fetch agent metrics', async () => { esClient.search.mockResolvedValue({ took: 5, diff --git a/x-pack/plugins/fleet/server/services/metrics/fetch_agent_metrics.ts b/x-pack/plugins/fleet/server/services/metrics/fetch_agent_metrics.ts index b768213986f3ab..6fc0966e266edc 100644 --- a/x-pack/plugins/fleet/server/services/metrics/fetch_agent_metrics.ts +++ b/x-pack/plugins/fleet/server/services/metrics/fetch_agent_metrics.ts @@ -42,6 +42,23 @@ export const fetchAgentMetrics = async ( if (!soClient || !esClient) { return; } + + const fleetAgentsIndexExists = await esClient.indices + .get({ + index: AGENTS_INDEX, + }) + .catch((error) => { + if (error.statusCode === 404) { + return; + } + + throw error; + }); + + if (!fleetAgentsIndexExists) { + return; + } + const usage = { agents: await getAgentUsage(soClient, esClient), agents_per_version: await getAgentsPerVersion(esClient, abortController), From fc367aaaa405aaeb8905490bb27b0c80eac4a132 Mon Sep 17 00:00:00 2001 From: Konrad Szwarc Date: Wed, 20 Dec 2023 11:58:54 +0100 Subject: [PATCH 011/116] [EDR Workflows][Osquery] Proper schema generation for rules (#173611) https://github.com/elastic/kibana/issues/172452 Proper way of generating schema (`.schema.yaml` as source). https://github.com/elastic/kibana/assets/29123534/d7be0f71-62ad-4afb-aa43-98b6af7bfd47 --- .../model/rule_response_actions/response_actions.gen.ts | 2 ++ .../model/rule_response_actions/response_actions.schema.yaml | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/response_actions.gen.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/response_actions.gen.ts index eebcde55a03012..e6d00181a7a4ea 100644 --- a/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/response_actions.gen.ts +++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/response_actions.gen.ts @@ -52,6 +52,7 @@ export const OsqueryParams = z.object({ queries: z.array(OsqueryQuery).optional(), pack_id: z.string().optional(), saved_query_id: z.string().optional(), + timeout: z.number().optional(), }); export type OsqueryParamsCamelCase = z.infer; @@ -61,6 +62,7 @@ export const OsqueryParamsCamelCase = z.object({ queries: z.array(OsqueryQuery).optional(), packId: z.string().optional(), savedQueryId: z.string().optional(), + timeout: z.number().optional(), }); export type OsqueryResponseAction = z.infer; diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/response_actions.schema.yaml b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/response_actions.schema.yaml index 9d27bb6e4a97ce..3e4b37e115adde 100644 --- a/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/response_actions.schema.yaml +++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/response_actions.schema.yaml @@ -65,6 +65,8 @@ components: type: string saved_query_id: type: string + timeout: + type: number OsqueryParamsCamelCase: type: object @@ -81,6 +83,8 @@ components: type: string savedQueryId: type: string + timeout: + type: number OsqueryResponseAction: type: object From 643aa605cd803a3f323db323a679d207bd098544 Mon Sep 17 00:00:00 2001 From: Pete Harverson Date: Wed, 20 Dec 2023 11:02:57 +0000 Subject: [PATCH 012/116] [ML] Fixes display of actions column in the datafeed chart flyout (#173365) ## Summary Fixes the 'Actions' column in the datafeed chart flyout, opened from the anomaly detection jobs list, so that the 'Toggle in chart' action is only shown once per row. #### Before: datafeed_flyout_actions_before #### After: datafeed_flyout_actions_after Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../components/job_messages/job_messages.tsx | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/x-pack/plugins/ml/public/application/components/job_messages/job_messages.tsx b/x-pack/plugins/ml/public/application/components/job_messages/job_messages.tsx index c5a7826ac0ee98..adc56c54671334 100644 --- a/x-pack/plugins/ml/public/application/components/job_messages/job_messages.tsx +++ b/x-pack/plugins/ml/public/application/components/job_messages/job_messages.tsx @@ -48,7 +48,7 @@ export const JobMessages: FC = ({ }) => { const { showNodeInfo } = useEnabledFeatures(); const columns: Array> = useMemo(() => { - const cols = [ + const cols: Array> = [ { name: refreshMessage ? ( = ({ }); } - return cols; - }, [showNodeInfo, refreshMessage]); - - if (typeof actionHandler === 'function') { - columns.push({ - name: i18n.translate('xpack.ml.jobMessages.actionsLabel', { - defaultMessage: 'Actions', - }), - width: '10%', - actions: [ - { - render: (message: JobMessage) => { - return ( - { + return ( + + } + > + actionHandler(message)} /> - } - > - actionHandler(message)} - /> - - ); + + ); + }, }, - }, - ], - }); - } + ], + }); + } + + return cols; + }, [showNodeInfo, refreshMessage, actionHandler]); const defaultSorting = { sort: { From 4e049fa010e7e425455d6ad5d4464f146c0d2cb1 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Wed, 20 Dec 2023 12:41:48 +0100 Subject: [PATCH 013/116] Remove outdated code comment (#173711) --- packages/kbn-apm-config-loader/src/config.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/kbn-apm-config-loader/src/config.ts b/packages/kbn-apm-config-loader/src/config.ts index 0dbff5b2385caa..7430454cc4c2aa 100644 --- a/packages/kbn-apm-config-loader/src/config.ts +++ b/packages/kbn-apm-config-loader/src/config.ts @@ -9,7 +9,6 @@ import { join } from 'path'; import { merge } from 'lodash'; import { execSync } from 'child_process'; -// deep import to avoid loading the whole package import { getDataPath } from '@kbn/utils'; import { readFileSync } from 'fs'; import type { AgentConfigOptions } from 'elastic-apm-node'; From 730e53cb5ccde513e82a49c2c1f1fcef7ca67d07 Mon Sep 17 00:00:00 2001 From: Marco Liberati Date: Wed, 20 Dec 2023 12:46:29 +0100 Subject: [PATCH 014/116] [ES|QL] Add missing functions to the supported definition list (#173656) ## Summary Added `ceil`, `least` and `to_cartesianpoint` functions to the supported list. Tests are automatically generated fro them. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../src/esql/lib/ast/definitions/functions.ts | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/packages/kbn-monaco/src/esql/lib/ast/definitions/functions.ts b/packages/kbn-monaco/src/esql/lib/ast/definitions/functions.ts index 6cabc530883aa4..820ab04fea3bf5 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/definitions/functions.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/definitions/functions.ts @@ -37,6 +37,19 @@ export const evalFunctionsDefinitions: FunctionDefinition[] = [ }, ], }, + { + name: 'ceil', + description: i18n.translate('monaco.esql.definitions.ceilDoc', { + defaultMessage: 'Round a number up to the nearest integer.', + }), + signatures: [ + { + params: [{ name: 'field', type: 'number' }], + returnType: 'number', + examples: [`from index | eval ceil_value = ceil(field)`], + }, + ], + }, { name: 'log10', description: i18n.translate('monaco.esql.definitions.log10Doc', { @@ -209,6 +222,19 @@ export const evalFunctionsDefinitions: FunctionDefinition[] = [ }, ], }, + { + name: 'to_cartesianpoint', + description: i18n.translate('monaco.esql.definitions.toCartesianPointDoc', { + defaultMessage: 'Converts an input value to a `point` value.', + }), + signatures: [ + { + params: [{ name: 'field', type: 'any' }], + returnType: 'cartesian_point', + examples: [`from index | EVAL point = to_cartesianpoint(field)`], + }, + ], + }, { name: 'to_datetime', alias: ['to_dt'], @@ -645,6 +671,22 @@ export const evalFunctionsDefinitions: FunctionDefinition[] = [ }, ], }, + { + name: 'least', + description: i18n.translate('monaco.esql.definitions.leastDoc', { + defaultMessage: 'Returns the minimum value from many columns.', + }), + signatures: [ + { + params: [ + { name: 'first', type: 'number' }, + { name: 'rest', type: 'number' }, + ], + returnType: 'number', + examples: ['from index | eval l = least(a, b)'], + }, + ], + }, { name: 'left', description: i18n.translate('monaco.esql.definitions.leftDoc', { From fcab43fcd0901ed82bbf9097457fa7e480322a14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20St=C3=BCrmer?= Date: Wed, 20 Dec 2023 12:46:50 +0100 Subject: [PATCH 015/116] [Logs Explorer] Avoid unreliable time range expansion in functional test (#173665) --- .../observability/observability_log_explorer/header_menu.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/x-pack/test_serverless/functional/test_suites/observability/observability_log_explorer/header_menu.ts b/x-pack/test_serverless/functional/test_suites/observability/observability_log_explorer/header_menu.ts index 90aea100989cc5..14d8dd94376de6 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/observability_log_explorer/header_menu.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/observability_log_explorer/header_menu.ts @@ -22,8 +22,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'svlCommonNavigation', ]); - // FLAKY: https://github.com/elastic/kibana/issues/173165 - describe.skip('Header menu', () => { + describe('Header menu', () => { before(async () => { await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); await esArchiver.load( @@ -143,9 +142,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); expect(await browser.getCurrentUrl()).contain('/app/discover'); - await PageObjects.discover.expandTimeRangeAsSuggestedInNoResultsMessage(); - await PageObjects.discover.waitForDocTableLoadingComplete(); - await retry.try(async () => { expect(await PageObjects.discover.getCurrentlySelectedDataView()).not.to.eql('All logs'); }); From 6a43e94e6c3de4378c583a266611f30049332662 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Wed, 20 Dec 2023 12:00:55 +0000 Subject: [PATCH 016/116] [ML] Sharing install elastic model service (#171918) Shares our [recently added](https://github.com/elastic/kibana/pull/169939) install elastic model endpoint as a shared service. --- .../providers/__mocks__/trained_models.ts | 1 + .../shared_services/providers/trained_models.ts | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/x-pack/plugins/ml/server/shared_services/providers/__mocks__/trained_models.ts b/x-pack/plugins/ml/server/shared_services/providers/__mocks__/trained_models.ts index fa37f3d468fc39..ea935aa9cb61d8 100644 --- a/x-pack/plugins/ml/server/shared_services/providers/__mocks__/trained_models.ts +++ b/x-pack/plugins/ml/server/shared_services/providers/__mocks__/trained_models.ts @@ -18,6 +18,7 @@ const trainedModelsServiceMock = { putTrainedModel: jest.fn(), getELSER: jest.fn().mockResolvedValue({ model_id: '.elser_model_2' }), getCuratedModelConfig: jest.fn().mockResolvedValue({ model_id: '.elser_model_2' }), + installElasticModel: jest.fn(), } as jest.Mocked; export const createTrainedModelsProviderMock = () => diff --git a/x-pack/plugins/ml/server/shared_services/providers/trained_models.ts b/x-pack/plugins/ml/server/shared_services/providers/trained_models.ts index 6b04a3e7580d92..36d639066f97a7 100644 --- a/x-pack/plugins/ml/server/shared_services/providers/trained_models.ts +++ b/x-pack/plugins/ml/server/shared_services/providers/trained_models.ts @@ -53,6 +53,7 @@ export interface TrainedModelsProvider { ): Promise; getELSER(params?: GetModelDownloadConfigOptions): Promise; getCuratedModelConfig(...params: GetCuratedModelConfigParams): Promise; + installElasticModel(modelId: string): Promise; }; } @@ -144,6 +145,17 @@ export function getTrainedModelsProvider( return modelsProvider(scopedClient, mlClient, cloud).getCuratedModelConfig(...params); }); }, + async installElasticModel(modelId: string) { + return await guards + .isFullLicense() + .hasMlCapabilities(['canGetTrainedModels']) + .ok(async ({ scopedClient, mlClient, mlSavedObjectService }) => { + return modelsProvider(scopedClient, mlClient, cloud).installElasticModel( + modelId, + mlSavedObjectService + ); + }); + }, }; }, }; From 7450a252c57f39ca4b100f6720af6a0917d0e5bf Mon Sep 17 00:00:00 2001 From: Julia Rechkunova Date: Wed, 20 Dec 2023 13:12:50 +0100 Subject: [PATCH 017/116] [UnifiedFieldList] Hide "Empty fields" section if there are no fields in it (#172956) ## Summary This PR hides "Empty fields" section when it's empty. Screenshot 2023-12-08 at 16 05 47 Screenshot 2023-12-08 at 16 06 09 ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Stratoula Kalafateli --- .../field_list_grouped.test.tsx | 74 +++++++++---------- .../use_grouped_fields.test.tsx.snap | 6 +- .../src/hooks/use_grouped_fields.ts | 2 +- .../discover_sidebar_responsive.test.tsx | 2 +- .../field_stats.ts | 2 +- .../apps/discover/group3/_drag_drop.ts | 4 +- .../apps/discover/group3/_sidebar.ts | 60 ++++++--------- .../datasources/form_based/datapanel.test.tsx | 2 +- .../common/discover/group3/_sidebar.ts | 58 ++++++--------- .../field_stats.ts | 2 +- 10 files changed, 94 insertions(+), 118 deletions(-) diff --git a/packages/kbn-unified-field-list/src/components/field_list_grouped/field_list_grouped.test.tsx b/packages/kbn-unified-field-list/src/components/field_list_grouped/field_list_grouped.test.tsx index 9a86b56f52dc77..6744fb92db152b 100644 --- a/packages/kbn-unified-field-list/src/components/field_list_grouped/field_list_grouped.test.tsx +++ b/packages/kbn-unified-field-list/src/components/field_list_grouped/field_list_grouped.test.tsx @@ -22,7 +22,7 @@ import { FieldsAccordion } from './fields_accordion'; import { NoFieldsCallout } from './no_fields_callout'; import { useGroupedFields, type GroupedFieldsParams } from '../../hooks/use_grouped_fields'; -describe('UnifiedFieldList + useGroupedFields()', () => { +describe('UnifiedFieldList FieldListGrouped + useGroupedFields()', () => { let defaultProps: FieldListGroupedProps; let mockedServices: GroupedFieldsParams['services']; const allFields = dataView.fields; @@ -123,11 +123,11 @@ describe('UnifiedFieldList + useGroupedFields()', () => { ExistenceFetchStatus.unknown ); expect(wrapper.find(`#${defaultProps.screenReaderDescriptionId}`).first().text()).toBe(''); - expect(wrapper.find(FieldsAccordion)).toHaveLength(3); - expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(3); + expect(wrapper.find(FieldsAccordion)).toHaveLength(2); + expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(2); expect( wrapper.find(FieldsAccordion).map((accordion) => accordion.prop('hasLoaded')) - ).toStrictEqual([false, false, false]); + ).toStrictEqual([false, false]); expect(wrapper.find(NoFieldsCallout)).toHaveLength(0); await act(async () => { @@ -144,17 +144,17 @@ describe('UnifiedFieldList + useGroupedFields()', () => { ExistenceFetchStatus.succeeded ); expect(wrapper.find(`#${defaultProps.screenReaderDescriptionId}`).first().text()).toBe( - '25 available fields. 0 empty fields. 3 meta fields.' + '25 available fields. 3 meta fields.' ); - expect(wrapper.find(FieldsAccordion)).toHaveLength(3); + expect(wrapper.find(FieldsAccordion)).toHaveLength(2); expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(0); expect( wrapper.find(FieldsAccordion).map((accordion) => accordion.prop('hasLoaded')) - ).toStrictEqual([true, true, true]); + ).toStrictEqual([true, true]); expect( wrapper.find(FieldsAccordion).map((accordion) => accordion.prop('paginatedFields').length) - ).toStrictEqual([25, 0, 0]); - expect(wrapper.find(NoFieldsCallout)).toHaveLength(1); + ).toStrictEqual([25, 0]); + expect(wrapper.find(NoFieldsCallout)).toHaveLength(0); }); it('renders correctly in failed state', async () => { @@ -173,16 +173,16 @@ describe('UnifiedFieldList + useGroupedFields()', () => { ExistenceFetchStatus.failed ); expect(wrapper.find(`#${defaultProps.screenReaderDescriptionId}`).first().text()).toBe( - '25 available fields. 0 empty fields. 3 meta fields.' + '25 available fields. 3 meta fields.' ); - expect(wrapper.find(FieldsAccordion)).toHaveLength(3); + expect(wrapper.find(FieldsAccordion)).toHaveLength(2); expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(0); expect( wrapper.find(FieldsAccordion).map((accordion) => accordion.prop('hasLoaded')) - ).toStrictEqual([true, true, true]); + ).toStrictEqual([true, true]); expect( wrapper.find(FieldsAccordion).map((accordion) => accordion.prop('showExistenceFetchError')) - ).toStrictEqual([true, true, true]); + ).toStrictEqual([true, true]); }); it('renders correctly in no fields state', async () => { @@ -199,13 +199,13 @@ describe('UnifiedFieldList + useGroupedFields()', () => { }); expect(wrapper.find(`#${defaultProps.screenReaderDescriptionId}`).first().text()).toBe( - '0 available fields. 0 empty fields. 0 meta fields.' + '0 available fields. 0 meta fields.' ); - expect(wrapper.find(FieldsAccordion)).toHaveLength(3); + expect(wrapper.find(FieldsAccordion)).toHaveLength(2); expect(wrapper.find(EuiLoadingSpinner)).toHaveLength(0); expect( wrapper.find(NoFieldsCallout).map((callout) => callout.prop('fieldsExistInIndex')) - ).toStrictEqual([false, false, false]); + ).toStrictEqual([false, false]); }); it('renders correctly for text-based queries (no data view)', async () => { @@ -242,11 +242,11 @@ describe('UnifiedFieldList + useGroupedFields()', () => { }); expect(wrapper.find(`#${defaultProps.screenReaderDescriptionId}`).first().text()).toBe( - '25 available fields. 0 empty fields. 3 meta fields.' + '25 available fields. 3 meta fields.' ); expect( wrapper.find(FieldsAccordion).map((accordion) => accordion.prop('paginatedFields').length) - ).toStrictEqual([25, 0, 0]); + ).toStrictEqual([25, 0]); await act(async () => { await wrapper @@ -259,7 +259,7 @@ describe('UnifiedFieldList + useGroupedFields()', () => { expect( wrapper.find(FieldsAccordion).map((accordion) => accordion.prop('paginatedFields').length) - ).toStrictEqual([25, 0, 3]); + ).toStrictEqual([25, 3]); }); it('renders correctly when paginated', async () => { @@ -275,11 +275,11 @@ describe('UnifiedFieldList + useGroupedFields()', () => { }); expect(wrapper.find(`#${defaultProps.screenReaderDescriptionId}`).first().text()).toBe( - '25 available fields. 112 unmapped fields. 0 empty fields. 3 meta fields.' + '25 available fields. 112 unmapped fields. 3 meta fields.' ); expect( wrapper.find(FieldsAccordion).map((accordion) => accordion.prop('paginatedFields').length) - ).toStrictEqual([25, 0, 0, 0]); + ).toStrictEqual([25, 0, 0]); await act(async () => { await wrapper @@ -292,11 +292,11 @@ describe('UnifiedFieldList + useGroupedFields()', () => { expect( wrapper.find(FieldsAccordion).map((accordion) => accordion.prop('paginatedFields').length) - ).toStrictEqual([25, 50, 0, 0]); + ).toStrictEqual([25, 50, 0]); await act(async () => { await wrapper - .find('[data-test-subj="fieldListGroupedEmptyFields"]') + .find('[data-test-subj="fieldListGroupedMetaFields"]') .find('button') .first() .simulate('click'); @@ -305,7 +305,7 @@ describe('UnifiedFieldList + useGroupedFields()', () => { expect( wrapper.find(FieldsAccordion).map((accordion) => accordion.prop('paginatedFields').length) - ).toStrictEqual([25, 88, 0, 0]); + ).toStrictEqual([25, 88, 0]); }); it('renders correctly when fields are searched and filtered', async () => { @@ -322,7 +322,7 @@ describe('UnifiedFieldList + useGroupedFields()', () => { }); expect(wrapper.find(`#${defaultProps.screenReaderDescriptionId}`).first().text()).toBe( - '25 available fields. 112 unmapped fields. 0 empty fields. 3 meta fields.' + '25 available fields. 112 unmapped fields. 3 meta fields.' ); await act(async () => { @@ -336,7 +336,7 @@ describe('UnifiedFieldList + useGroupedFields()', () => { }); expect(wrapper.find(`#${defaultProps.screenReaderDescriptionId}`).first().text()).toBe( - '2 available fields. 8 unmapped fields. 0 empty fields. 0 meta fields.' + '2 available fields. 8 unmapped fields. 0 meta fields.' ); await act(async () => { @@ -350,7 +350,7 @@ describe('UnifiedFieldList + useGroupedFields()', () => { }); expect(wrapper.find(`#${defaultProps.screenReaderDescriptionId}`).first().text()).toBe( - '3 available fields. 24 unmapped fields. 0 empty fields. 3 meta fields.' + '3 available fields. 24 unmapped fields. 3 meta fields.' ); await act(async () => { @@ -367,7 +367,7 @@ describe('UnifiedFieldList + useGroupedFields()', () => { }); expect(wrapper.find(`#${defaultProps.screenReaderDescriptionId}`).first().text()).toBe( - '1 available field. 4 unmapped fields. 0 empty fields. 0 meta fields.' + '1 available field. 4 unmapped fields. 0 meta fields.' ); }, 10000); @@ -385,7 +385,7 @@ describe('UnifiedFieldList + useGroupedFields()', () => { }); expect(wrapper.find(`#${defaultProps.screenReaderDescriptionId}`).first().text()).toBe( - '25 available fields. 112 unmapped fields. 0 empty fields. 3 meta fields.' + '25 available fields. 112 unmapped fields. 3 meta fields.' ); await act(async () => { @@ -399,7 +399,7 @@ describe('UnifiedFieldList + useGroupedFields()', () => { }); expect(wrapper.find(`#${defaultProps.screenReaderDescriptionId}`).first().text()).toBe( - '23 available fields. 104 unmapped fields. 0 empty fields. 3 meta fields.' + '23 available fields. 104 unmapped fields. 3 meta fields.' ); }); @@ -417,7 +417,7 @@ describe('UnifiedFieldList + useGroupedFields()', () => { }); expect(wrapper.find(`#${defaultProps.screenReaderDescriptionId}`).first().text()).toBe( - '25 available fields. 112 unmapped fields. 0 empty fields. 3 meta fields.' + '25 available fields. 112 unmapped fields. 3 meta fields.' ); await act(async () => { @@ -432,7 +432,7 @@ describe('UnifiedFieldList + useGroupedFields()', () => { }); expect(wrapper.find(`#${defaultProps.screenReaderDescriptionId}`).first().text()).toBe( - '2 selected fields. 25 available fields. 112 unmapped fields. 0 empty fields. 3 meta fields.' + '2 selected fields. 25 available fields. 112 unmapped fields. 3 meta fields.' ); }); @@ -452,7 +452,7 @@ describe('UnifiedFieldList + useGroupedFields()', () => { }); expect(wrapper.find(`#${defaultProps.screenReaderDescriptionId}`).first().text()).toBe( - '2 selected fields. 10 popular fields. 25 available fields. 112 unmapped fields. 0 empty fields. 3 meta fields.' + '2 selected fields. 10 popular fields. 25 available fields. 112 unmapped fields. 3 meta fields.' ); }); @@ -472,11 +472,11 @@ describe('UnifiedFieldList + useGroupedFields()', () => { // only Available is open expect( wrapper.find(FieldsAccordion).map((accordion) => accordion.prop('initialIsOpen')) - ).toStrictEqual([true, false, false, false]); + ).toStrictEqual([true, false, false]); await act(async () => { await wrapper - .find('[data-test-subj="fieldListGroupedEmptyFields"]') + .find('[data-test-subj="fieldListGroupedMetaFields"]') .find('button') .first() .simulate('click'); @@ -486,7 +486,7 @@ describe('UnifiedFieldList + useGroupedFields()', () => { // now Empty is open too expect( wrapper.find(FieldsAccordion).map((accordion) => accordion.prop('initialIsOpen')) - ).toStrictEqual([true, false, true, false]); + ).toStrictEqual([true, false, true]); const wrapper2 = await mountGroupedList({ listProps: { @@ -503,6 +503,6 @@ describe('UnifiedFieldList + useGroupedFields()', () => { // both Available and Empty are open for the second instance expect( wrapper2.find(FieldsAccordion).map((accordion) => accordion.prop('initialIsOpen')) - ).toStrictEqual([true, false, true, false]); + ).toStrictEqual([true, false, true]); }); }); diff --git a/packages/kbn-unified-field-list/src/hooks/__snapshots__/use_grouped_fields.test.tsx.snap b/packages/kbn-unified-field-list/src/hooks/__snapshots__/use_grouped_fields.test.tsx.snap index d3c95c363695d4..bf62c67deafc3d 100644 --- a/packages/kbn-unified-field-list/src/hooks/__snapshots__/use_grouped_fields.test.tsx.snap +++ b/packages/kbn-unified-field-list/src/hooks/__snapshots__/use_grouped_fields.test.tsx.snap @@ -19,7 +19,7 @@ Object { "fields": Array [], "helpText": "Fields that don't have any values based on your filters.", "hideDetails": false, - "hideIfEmpty": false, + "hideIfEmpty": true, "isAffectedByGlobalFilter": false, "isAffectedByTimeFilter": false, "isInitiallyOpen": false, @@ -105,7 +105,7 @@ Object { "fields": Array [], "helpText": "Fields that don't have any values based on your filters.", "hideDetails": false, - "hideIfEmpty": false, + "hideIfEmpty": true, "isAffectedByGlobalFilter": false, "isAffectedByTimeFilter": false, "isInitiallyOpen": false, @@ -191,7 +191,7 @@ Object { "fields": Array [], "helpText": "Fields that don't have any values based on your filters.", "hideDetails": false, - "hideIfEmpty": false, + "hideIfEmpty": true, "isAffectedByGlobalFilter": false, "isAffectedByTimeFilter": false, "isInitiallyOpen": false, diff --git a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts index f51f9b0fffb2d8..16758ea4ee7f2c 100644 --- a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts +++ b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts @@ -252,7 +252,7 @@ export function useGroupedFields({ isInitiallyOpen: false, showInAccordion: true, hideDetails: false, - hideIfEmpty: !dataViewId, + hideIfEmpty: true, title: i18n.translate('unifiedFieldList.useGroupedFields.emptyFieldsLabel', { defaultMessage: 'Empty fields', }), diff --git a/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.test.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.test.tsx index 723c19b5b3d990..c4558f4590c5b0 100644 --- a/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.test.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.test.tsx @@ -471,7 +471,7 @@ describe('discover responsive sidebar', function () { expect(findTestSubject(comp, 'fieldListGroupedAvailableFields-count').text()).toBe('1'); expect(findTestSubject(comp, 'fieldListGrouped__ariaDescription').text()).toBe( - '1 popular field. 1 available field. 0 empty fields. 0 meta fields.' + '1 popular field. 1 available field. 0 meta fields.' ); expect(mockCalcFieldCounts.mock.calls.length).toBe(1); }); diff --git a/test/examples/unified_field_list_examples/field_stats.ts b/test/examples/unified_field_list_examples/field_stats.ts index de662e737cb2da..9ed28ee618bf31 100644 --- a/test/examples/unified_field_list_examples/field_stats.ts +++ b/test/examples/unified_field_list_examples/field_stats.ts @@ -54,7 +54,7 @@ export default ({ getService, getPageObjects }: FtrProviderContext) => { describe('field distribution', () => { before(async () => { - await PageObjects.unifiedFieldList.toggleSidebarSection('empty'); // it will allow to render more fields in Available fields section + await PageObjects.unifiedFieldList.toggleSidebarSection('meta'); // it will allow to render more fields in Available fields section }); it('should return an auto histogram for numbers and top values', async () => { diff --git a/test/functional/apps/discover/group3/_drag_drop.ts b/test/functional/apps/discover/group3/_drag_drop.ts index 386844e82322ff..3988daa287bd69 100644 --- a/test/functional/apps/discover/group3/_drag_drop.ts +++ b/test/functional/apps/discover/group3/_drag_drop.ts @@ -48,7 +48,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '53 available fields. 0 empty fields. 3 meta fields.' + '53 available fields. 3 meta fields.' ); expect((await PageObjects.discover.getColumnHeaders()).join(', ')).to.be( '@timestamp, Document' @@ -72,7 +72,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '53 available fields. 0 empty fields. 3 meta fields.' + '53 available fields. 3 meta fields.' ); expect((await PageObjects.discover.getColumnHeaders()).join(', ')).to.be( '@timestamp, Document' diff --git a/test/functional/apps/discover/group3/_sidebar.ts b/test/functional/apps/discover/group3/_sidebar.ts index 01e357b7f01e63..313c350209930b 100644 --- a/test/functional/apps/discover/group3/_sidebar.ts +++ b/test/functional/apps/discover/group3/_sidebar.ts @@ -28,7 +28,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const fieldEditor = getService('fieldEditor'); const retry = getService('retry'); const dataGrid = getService('dataGrid'); - const INITIAL_FIELD_LIST_SUMMARY = '53 available fields. 0 empty fields. 3 meta fields.'; + const INITIAL_FIELD_LIST_SUMMARY = '53 available fields. 3 meta fields.'; describe('discover sidebar', function describeIndexTests() { before(async function () { @@ -72,7 +72,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.waitFor('first updates', async () => { return ( (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '7 available fields. 0 empty fields. 2 meta fields.' + '7 available fields. 2 meta fields.' ); }); @@ -81,7 +81,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.waitFor('second updates', async () => { return ( (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '13 available fields. 0 empty fields. 3 meta fields.' + '13 available fields. 3 meta fields.' ); }); @@ -155,7 +155,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.waitFor('first updates', async () => { return ( (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '30 available fields. 0 empty fields. 2 meta fields.' + '30 available fields. 2 meta fields.' ); }); @@ -164,7 +164,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.waitFor('second updates', async () => { return ( (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '4 available fields. 0 empty fields. 0 meta fields.' + '4 available fields. 0 meta fields.' ); }); @@ -179,7 +179,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.waitFor('updates', async () => { return ( (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '2 available fields. 0 empty fields. 0 meta fields.' + '2 available fields. 0 meta fields.' ); }); @@ -194,7 +194,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.waitFor('updates', async () => { return ( (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '4 available fields. 0 empty fields. 0 meta fields.' + '4 available fields. 0 meta fields.' ); }); @@ -300,10 +300,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(availableFields.join(', ')).to.be(expectedInitialAvailableFields); // Available fields after scrolling down - const emptySectionButton = await find.byCssSelector( - PageObjects.unifiedFieldList.getSidebarSectionSelector('empty', true) + const metaSectionButton = await find.byCssSelector( + PageObjects.unifiedFieldList.getSidebarSectionSelector('meta', true) ); - await emptySectionButton.scrollIntoViewIfNecessary(); + await metaSectionButton.scrollIntoViewIfNecessary(); await retry.waitFor('list to update after scrolling', async () => { availableFields = await PageObjects.unifiedFieldList.getSidebarSectionFieldNames( @@ -316,12 +316,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { `${expectedInitialAvailableFields}, url, utc_time, xss` ); - // Expand Empty section - await PageObjects.unifiedFieldList.toggleSidebarSection('empty'); - expect( - (await PageObjects.unifiedFieldList.getSidebarSectionFieldNames('empty')).join(', ') - ).to.be(''); - // Expand Meta section await PageObjects.unifiedFieldList.toggleSidebarSection('meta'); expect( @@ -354,16 +348,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ).to.be(true); // Available fields after scrolling down - const emptySectionButton = await find.byCssSelector( - PageObjects.unifiedFieldList.getSidebarSectionSelector('empty', true) + const metaSectionButton = await find.byCssSelector( + PageObjects.unifiedFieldList.getSidebarSectionSelector('meta', true) ); - await emptySectionButton.scrollIntoViewIfNecessary(); - - // Expand Empty section - await PageObjects.unifiedFieldList.toggleSidebarSection('empty'); - expect( - (await PageObjects.unifiedFieldList.getSidebarSectionFieldNames('empty')).join(', ') - ).to.be(''); + await metaSectionButton.scrollIntoViewIfNecessary(); // Expand Meta section await PageObjects.unifiedFieldList.toggleSidebarSection('meta'); @@ -378,7 +366,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ).to.be('relatedContent'); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '53 available fields. 1 unmapped field. 0 empty fields. 3 meta fields.' + '53 available fields. 1 unmapped field. 3 meta fields.' ); }); @@ -399,7 +387,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(availableFields.includes('@message')).to.be(true); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '2 selected fields. 2 popular fields. 53 available fields. 0 empty fields. 3 meta fields.' + '2 selected fields. 2 popular fields. 53 available fields. 3 meta fields.' ); await PageObjects.unifiedFieldList.clickFieldListItemRemove('@message'); @@ -419,7 +407,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ).to.be('@message, _id, extension'); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '3 selected fields. 3 popular fields. 53 available fields. 0 empty fields. 3 meta fields.' + '3 selected fields. 3 popular fields. 53 available fields. 3 meta fields.' ); }); @@ -471,7 +459,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '53 available fields. 0 empty fields. 3 meta fields.' + '53 available fields. 3 meta fields.' ); }); @@ -493,7 +481,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '0 available fields. 0 empty fields. 0 meta fields.' + '0 available fields. 0 meta fields.' ); await testSubjects.missingOrFail( `${PageObjects.unifiedFieldList.getSidebarSectionSelector('available')}-fetchWarning` @@ -538,7 +526,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '6 available fields. 0 empty fields. 3 meta fields.' + '6 available fields. 3 meta fields.' ); await PageObjects.discover.selectIndexPattern('with-timefield'); @@ -617,7 +605,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '6873 available fields. 0 empty fields. 3 meta fields.' + '6873 available fields. 3 meta fields.' ); await PageObjects.discover.selectIndexPattern('logstash-*'); @@ -656,7 +644,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '54 available fields. 0 empty fields. 3 meta fields.' + '54 available fields. 3 meta fields.' ); let allFields = await PageObjects.unifiedFieldList.getAllFieldNames(); @@ -675,7 +663,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '54 available fields. 0 empty fields. 3 meta fields.' + '54 available fields. 3 meta fields.' ); allFields = await PageObjects.unifiedFieldList.getAllFieldNames(); @@ -712,7 +700,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // check that the sidebar is rendered expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '54 available fields. 0 empty fields. 3 meta fields.' + '54 available fields. 3 meta fields.' ); let allFields = await PageObjects.unifiedFieldList.getAllFieldNames(); expect(allFields.includes('_invalid-runtimefield')).to.be(true); @@ -769,7 +757,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '7 available fields. 0 empty fields. 3 meta fields.' + '7 available fields. 3 meta fields.' ); await kibanaServer.importExport.unload( diff --git a/x-pack/plugins/lens/public/datasources/form_based/datapanel.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/datapanel.test.tsx index 01a31f98000f9d..c7b6a2bcf6e905 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/datapanel.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/datapanel.test.tsx @@ -990,7 +990,7 @@ describe('FormBased Data Panel', () => { expect(wrapper.find(FieldItem).map((fieldItem) => fieldItem.prop('field').name)).toEqual([ DOCUMENT_FIELD_NAME, ]); - expect(wrapper.find(EuiCallOut).length).toEqual(3); + expect(wrapper.find(EuiCallOut).length).toEqual(2); }); it('should toggle type if clicked again', async () => { diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group3/_sidebar.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group3/_sidebar.ts index 17606ac87a4296..0435fdffa7ede4 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group3/_sidebar.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group3/_sidebar.ts @@ -26,7 +26,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const fieldEditor = getService('fieldEditor'); const retry = getService('retry'); const dataGrid = getService('dataGrid'); - const INITIAL_FIELD_LIST_SUMMARY = '53 available fields. 0 empty fields. 3 meta fields.'; + const INITIAL_FIELD_LIST_SUMMARY = '53 available fields. 3 meta fields.'; describe('discover sidebar', function describeIndexTests() { before(async function () { @@ -70,7 +70,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.waitFor('first updates', async () => { return ( (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '7 available fields. 0 empty fields. 2 meta fields.' + '7 available fields. 2 meta fields.' ); }); @@ -79,7 +79,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.waitFor('second updates', async () => { return ( (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '13 available fields. 0 empty fields. 3 meta fields.' + '13 available fields. 3 meta fields.' ); }); @@ -124,7 +124,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.waitFor('first updates', async () => { return ( (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '30 available fields. 0 empty fields. 2 meta fields.' + '30 available fields. 2 meta fields.' ); }); @@ -133,7 +133,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.waitFor('second updates', async () => { return ( (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '4 available fields. 0 empty fields. 0 meta fields.' + '4 available fields. 0 meta fields.' ); }); @@ -148,7 +148,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.waitFor('updates', async () => { return ( (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '2 available fields. 0 empty fields. 0 meta fields.' + '2 available fields. 0 meta fields.' ); }); @@ -163,7 +163,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.waitFor('updates', async () => { return ( (await PageObjects.unifiedFieldList.getSidebarAriaDescription()) === - '4 available fields. 0 empty fields. 0 meta fields.' + '4 available fields. 0 meta fields.' ); }); @@ -269,10 +269,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(availableFields.join(', ')).to.be(expectedInitialAvailableFields); // Available fields after scrolling down - const emptySectionButton = await find.byCssSelector( - PageObjects.unifiedFieldList.getSidebarSectionSelector('empty', true) + const metaSectionButton = await find.byCssSelector( + PageObjects.unifiedFieldList.getSidebarSectionSelector('meta', true) ); - await emptySectionButton.scrollIntoViewIfNecessary(); + await metaSectionButton.scrollIntoViewIfNecessary(); await retry.waitFor('list to update after scrolling', async () => { availableFields = await PageObjects.unifiedFieldList.getSidebarSectionFieldNames( @@ -285,12 +285,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { `${expectedInitialAvailableFields}, url, utc_time, xss` ); - // Expand Empty section - await PageObjects.unifiedFieldList.toggleSidebarSection('empty'); - expect( - (await PageObjects.unifiedFieldList.getSidebarSectionFieldNames('empty')).join(', ') - ).to.be(''); - // Expand Meta section await PageObjects.unifiedFieldList.toggleSidebarSection('meta'); expect( @@ -323,16 +317,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ).to.be(true); // Available fields after scrolling down - const emptySectionButton = await find.byCssSelector( - PageObjects.unifiedFieldList.getSidebarSectionSelector('empty', true) + const metaSectionButton = await find.byCssSelector( + PageObjects.unifiedFieldList.getSidebarSectionSelector('meta', true) ); - await emptySectionButton.scrollIntoViewIfNecessary(); - - // Expand Empty section - await PageObjects.unifiedFieldList.toggleSidebarSection('empty'); - expect( - (await PageObjects.unifiedFieldList.getSidebarSectionFieldNames('empty')).join(', ') - ).to.be(''); + await metaSectionButton.scrollIntoViewIfNecessary(); // Expand Meta section await PageObjects.unifiedFieldList.toggleSidebarSection('meta'); @@ -347,7 +335,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ).to.be('relatedContent'); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '53 available fields. 1 unmapped field. 0 empty fields. 3 meta fields.' + '53 available fields. 1 unmapped field. 3 meta fields.' ); }); @@ -368,7 +356,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(availableFields.includes('@message')).to.be(true); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '2 selected fields. 2 popular fields. 53 available fields. 0 empty fields. 3 meta fields.' + '2 selected fields. 2 popular fields. 53 available fields. 3 meta fields.' ); await PageObjects.unifiedFieldList.clickFieldListItemRemove('@message'); @@ -388,7 +376,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ).to.be('@message, _id, extension'); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '3 selected fields. 3 popular fields. 53 available fields. 0 empty fields. 3 meta fields.' + '3 selected fields. 3 popular fields. 53 available fields. 3 meta fields.' ); }); @@ -412,7 +400,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '0 available fields. 0 empty fields. 0 meta fields.' + '0 available fields. 0 meta fields.' ); await testSubjects.missingOrFail( `${PageObjects.unifiedFieldList.getSidebarSectionSelector('available')}-fetchWarning` @@ -457,7 +445,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '6 available fields. 0 empty fields. 3 meta fields.' + '6 available fields. 3 meta fields.' ); await PageObjects.discover.selectIndexPattern('with-timefield'); @@ -536,7 +524,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '6873 available fields. 0 empty fields. 3 meta fields.' + '6873 available fields. 3 meta fields.' ); await PageObjects.discover.selectIndexPattern('logstash-*'); @@ -575,7 +563,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '54 available fields. 0 empty fields. 3 meta fields.' + '54 available fields. 3 meta fields.' ); let allFields = await PageObjects.unifiedFieldList.getAllFieldNames(); @@ -594,7 +582,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '54 available fields. 0 empty fields. 3 meta fields.' + '54 available fields. 3 meta fields.' ); allFields = await PageObjects.unifiedFieldList.getAllFieldNames(); @@ -631,7 +619,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // check that the sidebar is rendered expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '54 available fields. 0 empty fields. 3 meta fields.' + '54 available fields. 3 meta fields.' ); let allFields = await PageObjects.unifiedFieldList.getAllFieldNames(); expect(allFields.includes('_invalid-runtimefield')).to.be(true); @@ -688,7 +676,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded(); expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be( - '7 available fields. 0 empty fields. 3 meta fields.' + '7 available fields. 3 meta fields.' ); await kibanaServer.importExport.unload( diff --git a/x-pack/test_serverless/functional/test_suites/common/examples/unified_field_list_examples/field_stats.ts b/x-pack/test_serverless/functional/test_suites/common/examples/unified_field_list_examples/field_stats.ts index 6b5529e7936eb6..47bbefa0dc8d67 100644 --- a/x-pack/test_serverless/functional/test_suites/common/examples/unified_field_list_examples/field_stats.ts +++ b/x-pack/test_serverless/functional/test_suites/common/examples/unified_field_list_examples/field_stats.ts @@ -68,7 +68,7 @@ export default ({ getService, getPageObjects }: FtrProviderContext) => { describe('field distribution', () => { before(async () => { - await PageObjects.unifiedFieldList.toggleSidebarSection('empty'); // it will allow to render more fields in Available fields section + await PageObjects.unifiedFieldList.toggleSidebarSection('meta'); // it will allow to render more fields in Available fields section }); it('should return an auto histogram for numbers and top values', async () => { From 04b93f92cc412d01d3482715749db7413810dc15 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Wed, 20 Dec 2023 13:17:18 +0100 Subject: [PATCH 018/116] flag more packages without side effects (#173602) ## Summary Follow-up of https://github.com/elastic/kibana/pull/173351 `-1.8MB` more on async chunks --- .../analytics/utils/analytics_collection_utils/package.json | 3 ++- packages/home/sample_data_card/package.json | 3 ++- packages/home/sample_data_tab/package.json | 3 ++- packages/home/sample_data_types/package.json | 3 ++- packages/kbn-alerts-as-data-utils/package.json | 3 ++- packages/serverless/project_switcher/package.json | 3 ++- x-pack/packages/kbn-elastic-assistant-common/package.json | 3 ++- x-pack/packages/kbn-elastic-assistant/package.json | 3 ++- x-pack/packages/ml/aiops_components/package.json | 5 ++++- x-pack/packages/ml/anomaly_utils/package.json | 3 ++- x-pack/packages/ml/creation_wizard_utils/package.json | 3 ++- x-pack/packages/ml/data_frame_analytics_utils/package.json | 3 ++- x-pack/packages/ml/data_grid/package.json | 3 ++- x-pack/packages/ml/date_picker/package.json | 3 ++- x-pack/packages/ml/date_utils/package.json | 3 ++- x-pack/packages/ml/in_memory_table/package.json | 3 ++- x-pack/packages/observability/alert_details/package.json | 3 ++- x-pack/packages/security-solution/data_table/package.json | 3 ++- .../ecs_data_quality_dashboard/package.json | 3 ++- x-pack/packages/security-solution/navigation/package.json | 3 ++- x-pack/packages/security-solution/side_nav/package.json | 3 ++- x-pack/packages/security-solution/upselling/package.json | 3 ++- 22 files changed, 46 insertions(+), 22 deletions(-) diff --git a/packages/analytics/utils/analytics_collection_utils/package.json b/packages/analytics/utils/analytics_collection_utils/package.json index eb10b67ce94dd6..7f8c62ab714c23 100644 --- a/packages/analytics/utils/analytics_collection_utils/package.json +++ b/packages/analytics/utils/analytics_collection_utils/package.json @@ -2,5 +2,6 @@ "name": "@kbn/analytics-collection-utils", "private": true, "version": "1.0.0", - "license": "SSPL-1.0 OR Elastic License 2.0" + "license": "SSPL-1.0 OR Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/packages/home/sample_data_card/package.json b/packages/home/sample_data_card/package.json index c82ba35d94238d..af6b307173f482 100644 --- a/packages/home/sample_data_card/package.json +++ b/packages/home/sample_data_card/package.json @@ -2,5 +2,6 @@ "name": "@kbn/home-sample-data-card", "private": true, "version": "1.0.0", - "license": "SSPL-1.0 OR Elastic License 2.0" + "license": "SSPL-1.0 OR Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/packages/home/sample_data_tab/package.json b/packages/home/sample_data_tab/package.json index 435df25207ff8e..9e51f80d68388d 100644 --- a/packages/home/sample_data_tab/package.json +++ b/packages/home/sample_data_tab/package.json @@ -2,5 +2,6 @@ "name": "@kbn/home-sample-data-tab", "private": true, "version": "1.0.0", - "license": "SSPL-1.0 OR Elastic License 2.0" + "license": "SSPL-1.0 OR Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/packages/home/sample_data_types/package.json b/packages/home/sample_data_types/package.json index e18945e544a5e8..b56eeff7bf1866 100644 --- a/packages/home/sample_data_types/package.json +++ b/packages/home/sample_data_types/package.json @@ -2,5 +2,6 @@ "name": "@kbn/home-sample-data-types", "private": true, "version": "1.0.0", - "license": "SSPL-1.0 OR Elastic License 2.0" + "license": "SSPL-1.0 OR Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/packages/kbn-alerts-as-data-utils/package.json b/packages/kbn-alerts-as-data-utils/package.json index 25aa26b3d435c4..bfb3dbda073a47 100644 --- a/packages/kbn-alerts-as-data-utils/package.json +++ b/packages/kbn-alerts-as-data-utils/package.json @@ -2,5 +2,6 @@ "name": "@kbn/alerts-as-data-utils", "private": true, "version": "1.0.0", - "license": "SSPL-1.0 OR Elastic License 2.0" + "license": "SSPL-1.0 OR Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/packages/serverless/project_switcher/package.json b/packages/serverless/project_switcher/package.json index 5910a823783d53..06240351496c71 100644 --- a/packages/serverless/project_switcher/package.json +++ b/packages/serverless/project_switcher/package.json @@ -2,5 +2,6 @@ "name": "@kbn/serverless-project-switcher", "private": true, "version": "1.0.0", - "license": "SSPL-1.0 OR Elastic License 2.0" + "license": "SSPL-1.0 OR Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/x-pack/packages/kbn-elastic-assistant-common/package.json b/x-pack/packages/kbn-elastic-assistant-common/package.json index 0f3f3f36814ccf..9ecfbc4c81a07f 100644 --- a/x-pack/packages/kbn-elastic-assistant-common/package.json +++ b/x-pack/packages/kbn-elastic-assistant-common/package.json @@ -2,5 +2,6 @@ "name": "@kbn/elastic-assistant-common", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/x-pack/packages/kbn-elastic-assistant/package.json b/x-pack/packages/kbn-elastic-assistant/package.json index 7bc41b6dffe649..7b944a6b2021ca 100644 --- a/x-pack/packages/kbn-elastic-assistant/package.json +++ b/x-pack/packages/kbn-elastic-assistant/package.json @@ -2,5 +2,6 @@ "name": "@kbn/elastic-assistant", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/x-pack/packages/ml/aiops_components/package.json b/x-pack/packages/ml/aiops_components/package.json index fd64c49c074d3f..ee8841277f96fa 100644 --- a/x-pack/packages/ml/aiops_components/package.json +++ b/x-pack/packages/ml/aiops_components/package.json @@ -5,5 +5,8 @@ "homepage": "https://docs.elastic.dev/kibana-dev-docs/api/kbn-aiops-components", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": [ + "*.scss" + ] } \ No newline at end of file diff --git a/x-pack/packages/ml/anomaly_utils/package.json b/x-pack/packages/ml/anomaly_utils/package.json index f49b343d58cd15..3bd52876b8cda6 100644 --- a/x-pack/packages/ml/anomaly_utils/package.json +++ b/x-pack/packages/ml/anomaly_utils/package.json @@ -2,5 +2,6 @@ "name": "@kbn/ml-anomaly-utils", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/x-pack/packages/ml/creation_wizard_utils/package.json b/x-pack/packages/ml/creation_wizard_utils/package.json index c48eab9641bde2..adbca67cdfbaff 100644 --- a/x-pack/packages/ml/creation_wizard_utils/package.json +++ b/x-pack/packages/ml/creation_wizard_utils/package.json @@ -2,5 +2,6 @@ "name": "@kbn/ml-creation-wizard-utils", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/x-pack/packages/ml/data_frame_analytics_utils/package.json b/x-pack/packages/ml/data_frame_analytics_utils/package.json index 1377dab2d1814e..d2817a1edf1a4f 100644 --- a/x-pack/packages/ml/data_frame_analytics_utils/package.json +++ b/x-pack/packages/ml/data_frame_analytics_utils/package.json @@ -2,5 +2,6 @@ "name": "@kbn/ml-data-frame-analytics-utils", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": false } diff --git a/x-pack/packages/ml/data_grid/package.json b/x-pack/packages/ml/data_grid/package.json index 337af96195a8fa..0df121b27abbbb 100644 --- a/x-pack/packages/ml/data_grid/package.json +++ b/x-pack/packages/ml/data_grid/package.json @@ -2,5 +2,6 @@ "name": "@kbn/ml-data-grid", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/x-pack/packages/ml/date_picker/package.json b/x-pack/packages/ml/date_picker/package.json index 720cc013c10eee..62eece475d16d9 100644 --- a/x-pack/packages/ml/date_picker/package.json +++ b/x-pack/packages/ml/date_picker/package.json @@ -2,5 +2,6 @@ "name": "@kbn/ml-date-picker", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": false } diff --git a/x-pack/packages/ml/date_utils/package.json b/x-pack/packages/ml/date_utils/package.json index fcd9fd7bc3b5a6..7d3e7515296f51 100644 --- a/x-pack/packages/ml/date_utils/package.json +++ b/x-pack/packages/ml/date_utils/package.json @@ -2,5 +2,6 @@ "name": "@kbn/ml-date-utils", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/x-pack/packages/ml/in_memory_table/package.json b/x-pack/packages/ml/in_memory_table/package.json index 54cf41c738653d..59a73fb1d78709 100644 --- a/x-pack/packages/ml/in_memory_table/package.json +++ b/x-pack/packages/ml/in_memory_table/package.json @@ -2,5 +2,6 @@ "name": "@kbn/ml-in-memory-table", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/x-pack/packages/observability/alert_details/package.json b/x-pack/packages/observability/alert_details/package.json index 2764095b1074f0..607fe22afa7f7e 100644 --- a/x-pack/packages/observability/alert_details/package.json +++ b/x-pack/packages/observability/alert_details/package.json @@ -3,5 +3,6 @@ "descriptio": "Helper and components related to alert details", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/x-pack/packages/security-solution/data_table/package.json b/x-pack/packages/security-solution/data_table/package.json index 53c640c3d9c6a6..c4a1c789b3c5cf 100644 --- a/x-pack/packages/security-solution/data_table/package.json +++ b/x-pack/packages/security-solution/data_table/package.json @@ -2,5 +2,6 @@ "name": "@kbn/securitysolution-data-table", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": false } diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/package.json b/x-pack/packages/security-solution/ecs_data_quality_dashboard/package.json index 32fc5f7572c89a..14601e6ea35909 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/package.json +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/package.json @@ -2,5 +2,6 @@ "name": "@kbn/ecs-data-quality-dashboard", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/x-pack/packages/security-solution/navigation/package.json b/x-pack/packages/security-solution/navigation/package.json index 8170a942224b40..34ad9f45d71abe 100644 --- a/x-pack/packages/security-solution/navigation/package.json +++ b/x-pack/packages/security-solution/navigation/package.json @@ -2,5 +2,6 @@ "name": "@kbn/security-solution-navigation", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/x-pack/packages/security-solution/side_nav/package.json b/x-pack/packages/security-solution/side_nav/package.json index c80baa25af3e2f..6d5af1d22427f7 100644 --- a/x-pack/packages/security-solution/side_nav/package.json +++ b/x-pack/packages/security-solution/side_nav/package.json @@ -2,5 +2,6 @@ "name": "@kbn/security-solution-side-nav", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": false } \ No newline at end of file diff --git a/x-pack/packages/security-solution/upselling/package.json b/x-pack/packages/security-solution/upselling/package.json index 92bd9e35078fa3..737e14b89c9329 100644 --- a/x-pack/packages/security-solution/upselling/package.json +++ b/x-pack/packages/security-solution/upselling/package.json @@ -2,5 +2,6 @@ "name": "@kbn/security-solution-upselling", "private": true, "version": "1.0.0", - "license": "Elastic License 2.0" + "license": "Elastic License 2.0", + "sideEffects": false } \ No newline at end of file From 19b82f8b61b284dd55308eed15f3fc37ea41c1ac Mon Sep 17 00:00:00 2001 From: Dima Arnautov Date: Wed, 20 Dec 2023 13:31:21 +0100 Subject: [PATCH 019/116] [ML] Fix registering of the ML alerting rules with the basic license (#173644) ## Summary Fixes the license checks for registering ML alerting rules, so that if the user doesn't have the required license to create a rule instance, we still show the entry in the list. The alerting framework disables the rule type if license requirements aren't met. image --- x-pack/plugins/ml/public/plugin.ts | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/ml/public/plugin.ts b/x-pack/plugins/ml/public/plugin.ts index 90d107882f7bb3..a4f0e6e2305417 100644 --- a/x-pack/plugins/ml/public/plugin.ts +++ b/x-pack/plugins/ml/public/plugin.ts @@ -232,6 +232,19 @@ export class MlPlugin implements Plugin { } = await import('./register_helper'); registerSearchLinks(this.appUpdater$, fullLicense, mlCapabilities, !this.isServerless); + if ( + pluginsSetup.triggersActionsUi && + ((fullLicense && mlCapabilities.canUseMlAlerts && mlCapabilities.canGetJobs) || + // Register rules for basic license to show them in the UI as disabled + !fullLicense) + ) { + registerMlAlerts( + pluginsSetup.triggersActionsUi, + core.getStartServices, + pluginsSetup.alerting + ); + } + if (fullLicense) { registerMlUiActions(pluginsSetup.uiActions, core); @@ -242,18 +255,6 @@ export class MlPlugin implements Plugin { registerCasesAttachments(pluginsSetup.cases, coreStart, pluginStart); } - if ( - pluginsSetup.triggersActionsUi && - mlCapabilities.canUseMlAlerts && - mlCapabilities.canGetJobs - ) { - registerMlAlerts( - pluginsSetup.triggersActionsUi, - core.getStartServices, - pluginsSetup.alerting - ); - } - if (pluginsSetup.maps) { // Pass canGetJobs as minimum permission to show anomalies card in maps layers await registerMapExtension(pluginsSetup.maps, core, { From fbd3601ced7ab4411d3a2d71a3f9fbe137696f48 Mon Sep 17 00:00:00 2001 From: ruhshan <5312918+Ruhshan@users.noreply.github.com> Date: Wed, 20 Dec 2023 18:38:57 +0600 Subject: [PATCH 020/116] [Observability][Infra] Add parent link in host detail's breadcrumb (#170792) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Fixes #170642 Added link to hosts in the breadcrumb for host details page. ![image](https://github.com/elastic/kibana/assets/5312918/273c3b86-bfbd-485c-9bfe-92559caed847) ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: Cauê Marcondes <55978943+cauemarcondes@users.noreply.github.com> Co-authored-by: jennypavlova Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../metric_detail/asset_detail_page.tsx | 15 +++++ .../hooks/use_parent_breadcrumb_resolver.ts | 59 +++++++++++++++++++ .../pages/metrics/metric_detail/index.tsx | 11 +--- .../metric_detail/metric_detail_page.tsx | 19 ++++-- .../pages/metrics/metric_detail/types.ts | 6 ++ .../test/functional/apps/infra/home_page.ts | 6 +- .../test_suites/observability/infra/infra.ts | 6 +- 7 files changed, 103 insertions(+), 19 deletions(-) create mode 100644 x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_parent_breadcrumb_resolver.ts diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/asset_detail_page.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/asset_detail_page.tsx index e52008e2a90abf..81f577f1d553fb 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/asset_detail_page.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/asset_detail_page.tsx @@ -8,6 +8,7 @@ import React from 'react'; import { useRouteMatch } from 'react-router-dom'; import type { InventoryItemType } from '@kbn/metrics-data-access-plugin/common'; +import { useMetricsBreadcrumbs } from '../../../hooks/use_metrics_breadcrumbs'; import { NoRemoteCluster } from '../../../components/empty_states'; import { SourceErrorPage } from '../../../components/source_error_page'; import { SourceLoadingPage } from '../../../components/source_loading_page'; @@ -15,6 +16,7 @@ import { useSourceContext } from '../../../containers/metrics_source'; import { AssetDetails } from '../../../components/asset_details/asset_details'; import { MetricsPageTemplate } from '../page_template'; import { commonFlyoutTabs } from '../../../common/asset_details_config/asset_details_tabs'; +import { useParentBreadcrumbResolver } from './hooks/use_parent_breadcrumb_resolver'; export const AssetDetailPage = () => { const { isLoading, loadSourceFailureMessage, loadSource, source } = useSourceContext(); @@ -24,6 +26,19 @@ export const AssetDetailPage = () => { const { metricIndicesExist, remoteClustersExist } = source?.status ?? {}; + const parentBreadcrumbResolver = useParentBreadcrumbResolver(); + + const breadcrumbOptions = parentBreadcrumbResolver.getBreadcrumbOptions(nodeType); + useMetricsBreadcrumbs([ + { + ...breadcrumbOptions.link, + text: breadcrumbOptions.text, + }, + { + text: nodeId, + }, + ]); + if (isLoading || !source) return ; if (!remoteClustersExist) { diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_parent_breadcrumb_resolver.ts b/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_parent_breadcrumb_resolver.ts new file mode 100644 index 00000000000000..a0d5160e874721 --- /dev/null +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/hooks/use_parent_breadcrumb_resolver.ts @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { InventoryItemType } from '@kbn/metrics-data-access-plugin/common/inventory_models/types'; +import { useLinkProps } from '@kbn/observability-shared-plugin/public'; +import { useLocation } from 'react-router-dom'; +import { hostsTitle, inventoryTitle } from '../../../../translations'; +import { BreadcrumbOptions } from '../types'; + +interface LocationStateProps { + originPathname: string; +} + +export function useParentBreadcrumbResolver() { + const hostsLinkProps = useLinkProps({ + app: 'metrics', + pathname: 'hosts', + }); + + const inventoryLinkProps = useLinkProps({ + app: 'metrics', + pathname: 'inventory', + }); + + const breadcrumbMap = new Map([ + ['/hosts', { text: hostsTitle, link: hostsLinkProps }], + ['/inventory', { text: inventoryTitle, link: inventoryLinkProps }], + ]); + + const defaultOption: BreadcrumbOptions = breadcrumbMap.get('/inventory')!; + + const { state } = useLocation(); + const locationState: LocationStateProps = state as LocationStateProps; + + function getOptionsByNodeType(nodeType: InventoryItemType): BreadcrumbOptions { + if (nodeType === 'host') { + return breadcrumbMap.get('/hosts')!; + } + return defaultOption; + } + + function getBreadcrumbOptions(nodeType: InventoryItemType) { + if (locationState === undefined) { + return getOptionsByNodeType(nodeType); + } + + const originalPathBreadcrumb = locationState.originPathname + ? breadcrumbMap.get(locationState.originPathname) + : undefined; + + return originalPathBreadcrumb ?? defaultOption; + } + + return { getBreadcrumbOptions }; +} diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx index f05a5d3d2dc2ee..24fb24af5c9826 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx @@ -9,21 +9,14 @@ import { EuiErrorBoundary } from '@elastic/eui'; import React from 'react'; import { useRouteMatch } from 'react-router-dom'; import type { InventoryItemType } from '@kbn/metrics-data-access-plugin/common'; -import { useMetricsBreadcrumbs } from '../../../hooks/use_metrics_breadcrumbs'; import { AssetDetailPage } from './asset_detail_page'; import { MetricDetailPage } from './metric_detail_page'; import { MetricsTimeProvider } from './hooks/use_metrics_time'; export const NodeDetail = () => { const { - params: { type: nodeType, node: nodeName }, - } = useRouteMatch<{ type: InventoryItemType; node: string }>(); - - useMetricsBreadcrumbs([ - { - text: nodeName, - }, - ]); + params: { type: nodeType }, + } = useRouteMatch<{ type: InventoryItemType }>(); return ( diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/metric_detail_page.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/metric_detail_page.tsx index 4dd0da57536e2d..9e51d316dd0ec1 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/metric_detail_page.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/metric_detail_page.tsx @@ -11,6 +11,7 @@ import { useRouteMatch } from 'react-router-dom'; import { findInventoryModel } from '@kbn/metrics-data-access-plugin/common'; import type { InventoryItemType } from '@kbn/metrics-data-access-plugin/common'; import { useMetricsBreadcrumbs } from '../../../hooks/use_metrics_breadcrumbs'; +import { useParentBreadcrumbResolver } from './hooks/use_parent_breadcrumb_resolver'; import { useMetadata } from '../../../components/asset_details/hooks/use_metadata'; import { useSourceContext } from '../../../containers/metrics_source'; import { InfraLoadingPanel } from '../../../components/loading'; @@ -25,6 +26,7 @@ export const MetricDetailPage = () => { } = useRouteMatch<{ type: InventoryItemType; node: string }>(); const inventoryModel = findInventoryModel(nodeType); const { sourceId, metricIndicesExist } = useSourceContext(); + const parentBreadcrumbResolver = useParentBreadcrumbResolver(); const { timeRange, @@ -50,6 +52,17 @@ export const MetricDetailPage = () => { timeRange: parsedTimeRange, }); + const breadcrumbOptions = parentBreadcrumbResolver.getBreadcrumbOptions(nodeType); + useMetricsBreadcrumbs([ + { + ...breadcrumbOptions.link, + text: breadcrumbOptions.text, + }, + { + text: name, + }, + ]); + const [sideNav, setSideNav] = useState([]); const addNavItem = React.useCallback( @@ -61,12 +74,6 @@ export const MetricDetailPage = () => { [sideNav] ); - useMetricsBreadcrumbs([ - { - text: name, - }, - ]); - if (metadataLoading && !filteredRequiredMetrics.length) { return ( diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/types.ts b/x-pack/plugins/infra/public/pages/metrics/metric_detail/types.ts index 2cf5c8844d726f..545b09c2fe00ef 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/types.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/types.ts @@ -8,6 +8,7 @@ import rt from 'io-ts'; import { EuiTheme } from '@kbn/kibana-react-plugin/common'; import { InventoryFormatterTypeRT } from '@kbn/metrics-data-access-plugin/common'; +import { LinkProps } from '@kbn/observability-shared-plugin/public/hooks/use_link_props'; import { MetricsTimeInput } from './hooks/use_metrics_time'; import { NodeDetailsMetricData } from '../../../../common/http_api/node_details_api'; @@ -61,3 +62,8 @@ export type VisSectionProps = rt.TypeOf & { isLiveStreaming?: boolean; stopLiveStreaming?: () => void; }; + +export interface BreadcrumbOptions { + text: string; + link: LinkProps; +} diff --git a/x-pack/test/functional/apps/infra/home_page.ts b/x-pack/test/functional/apps/infra/home_page.ts index 6637b7d42d2227..a41c12e0d833d8 100644 --- a/x-pack/test/functional/apps/infra/home_page.ts +++ b/x-pack/test/functional/apps/infra/home_page.ts @@ -331,7 +331,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await retry.try(async () => { const documentTitle = await browser.getTitle(); expect(documentTitle).to.contain( - 'demo-stack-redis-01 - Infrastructure - Observability - Elastic' + 'demo-stack-redis-01 - Inventory - Infrastructure - Observability - Elastic' ); }); @@ -346,7 +346,9 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await retry.try(async () => { const documentTitle = await browser.getTitle(); - expect(documentTitle).to.contain('pod-0 - Infrastructure - Observability - Elastic'); + expect(documentTitle).to.contain( + 'pod-0 - Inventory - Infrastructure - Observability - Elastic' + ); }); await returnTo(INVENTORY_PATH); diff --git a/x-pack/test_serverless/functional/test_suites/observability/infra/infra.ts b/x-pack/test_serverless/functional/test_suites/observability/infra/infra.ts index 94e9f35393e7fe..7b0b7828ec65c9 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/infra/infra.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/infra/infra.ts @@ -89,7 +89,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await retry.try(async () => { const documentTitle = await browser.getTitle(); expect(documentTitle).to.contain( - 'demo-stack-redis-01 - Infrastructure - Observability - Elastic' + 'demo-stack-redis-01 - Inventory - Infrastructure - Observability - Elastic' ); }); @@ -104,7 +104,9 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await retry.try(async () => { const documentTitle = await browser.getTitle(); - expect(documentTitle).to.contain('pod-0 - Infrastructure - Observability - Elastic'); + expect(documentTitle).to.contain( + 'pod-0 - Inventory - Infrastructure - Observability - Elastic' + ); }); await returnTo(INVENTORY_PATH); From 62f873a90ecc270bd3ae1c5bb24c18e25759fd9e Mon Sep 17 00:00:00 2001 From: Luke G <11671118+lgestc@users.noreply.github.com> Date: Wed, 20 Dec 2023 14:13:35 +0100 Subject: [PATCH 021/116] =?UTF-8?q?[Security=20Solution][Serverless]=20Col?= =?UTF-8?q?d=20and=20frozen=20tier=20toggle=20for=20analy=E2=80=A6=20(#173?= =?UTF-8?q?638)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …zer settings ## Summary This enables missing security solution setting in serverless offering, as per https://github.com/elastic/security-docs/issues/4387 . I did not realize that we have a separate config entry for the SLS listing available options there. --- packages/serverless/settings/security_project/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/serverless/settings/security_project/index.ts b/packages/serverless/settings/security_project/index.ts index 276a1e87e4b7e2..c150e764de054b 100644 --- a/packages/serverless/settings/security_project/index.ts +++ b/packages/serverless/settings/security_project/index.ts @@ -24,4 +24,5 @@ export const SECURITY_PROJECT_SETTINGS = [ settings.SECURITY_SOLUTION_ENABLE_NEWS_FEED_ID, settings.SECURITY_SOLUTION_DEFAULT_ALERT_TAGS_KEY, settings.SECURITY_SOLUTION_ENABLE_EXPANDABLE_FLYOUT_SETTING, + settings.SECURITY_SOLUTION_EXCLUDE_COLD_AND_FROZEN_TIERS_IN_ANALYZER, ]; From 04adfa2ebbbdc6999c14e9fb6a39cfb447843f2b Mon Sep 17 00:00:00 2001 From: Marco Liberati Date: Wed, 20 Dec 2023 14:28:34 +0100 Subject: [PATCH 022/116] [ES|QL] Update grammar based on ES changes (#172789) ## Summary This PR aligns the (new) Kibana grammar to the newer ES grammar changes proposed in https://github.com/elastic/elasticsearch/pull/100740 . `EXPAND` and `INLINESTATS` has been reinstated here (even when not used) to exactly match the ES grammar. Most of the changes are due to `TOKEN` renaming plus few other changes on how identifiers are now parsed. Revisit the validation logic helped also to find a couple of bugs on our validation side, but they were very minimal and limited. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Stratoula Kalafateli Co-authored-by: Abdon Pijpelink --- .../src/antlr/.antlr/esql_lexer.interp | 307 ++ .../kbn-esql/src/antlr/.antlr/esql_lexer.java | 1150 +++++ .../src/antlr/.antlr/esql_lexer.tokens | 98 + .../src/antlr/.antlr/esql_parser.interp | 256 ++ .../src/antlr/.antlr/esql_parser.java | 3914 +++++++++++++++++ .../src/antlr/.antlr/esql_parser.tokens | 117 + .../kbn-monaco/src/esql/antlr/esql_lexer.g4 | 286 +- .../src/esql/antlr/esql_lexer.interp | 167 +- .../src/esql/antlr/esql_lexer.tokens | 202 +- .../kbn-monaco/src/esql/antlr/esql_lexer.ts | 1230 +++--- .../kbn-monaco/src/esql/antlr/esql_parser.g4 | 50 +- .../src/esql/antlr/esql_parser.interp | 77 +- .../src/esql/antlr/esql_parser.tokens | 202 +- .../kbn-monaco/src/esql/antlr/esql_parser.ts | 1913 ++++---- .../src/esql/antlr/esql_parser_listener.ts | 266 +- .../src/esql/lib/ast/ast_helpers.ts | 27 +- .../kbn-monaco/src/esql/lib/ast/ast_walker.ts | 36 +- .../src/esql/lib/ast/definitions/commands.ts | 2 +- .../src/esql/lib/ast/shared/variables.ts | 2 +- .../lib/ast/validation/validation.test.ts | 81 +- 20 files changed, 8695 insertions(+), 1688 deletions(-) create mode 100644 packages/kbn-esql/src/antlr/.antlr/esql_lexer.interp create mode 100644 packages/kbn-esql/src/antlr/.antlr/esql_lexer.java create mode 100644 packages/kbn-esql/src/antlr/.antlr/esql_lexer.tokens create mode 100644 packages/kbn-esql/src/antlr/.antlr/esql_parser.interp create mode 100644 packages/kbn-esql/src/antlr/.antlr/esql_parser.java create mode 100644 packages/kbn-esql/src/antlr/.antlr/esql_parser.tokens diff --git a/packages/kbn-esql/src/antlr/.antlr/esql_lexer.interp b/packages/kbn-esql/src/antlr/.antlr/esql_lexer.interp new file mode 100644 index 00000000000000..8cd048fa4e8c3b --- /dev/null +++ b/packages/kbn-esql/src/antlr/.antlr/esql_lexer.interp @@ -0,0 +1,307 @@ +token literal names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +'by' +null +'and' +null +null +'.' +'(' +null +']' +null +null +null +null +null +null +null +'or' +')' +'_' +'info' +'functions' +null +null +'+' +'-' +'*' +'/' +'%' +'10' +null +'nulls' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +DISSECT +GROK +EVAL +EXPLAIN +FROM +ROW +STATS +WHERE +SORT +MV_EXPAND +LIMIT +PROJECT +DROP +RENAME +SHOW +ENRICH +KEEP +LINE_COMMENT +MULTILINE_COMMENT +WS +EXPLAIN_WS +EXPLAIN_LINE_COMMENT +EXPLAIN_MULTILINE_COMMENT +PIPE +STRING +INTEGER_LITERAL +DECIMAL_LITERAL +BY +DATE_LITERAL +AND +ASSIGN +COMMA +DOT +LP +OPENING_BRACKET +CLOSING_BRACKET +NOT +LIKE +RLIKE +IN +IS +AS +NULL +OR +RP +UNDERSCORE +INFO +FUNCTIONS +BOOLEAN_VALUE +COMPARISON_OPERATOR +PLUS +MINUS +ASTERISK +SLASH +PERCENT +TEN +ORDERING +NULLS_ORDERING +NULLS_ORDERING_DIRECTION +MATH_FUNCTION +UNARY_FUNCTION +WHERE_FUNCTIONS +UNQUOTED_IDENTIFIER +QUOTED_IDENTIFIER +EXPR_LINE_COMMENT +EXPR_MULTILINE_COMMENT +EXPR_WS +METADATA +SRC_UNQUOTED_IDENTIFIER +SRC_QUOTED_IDENTIFIER +SRC_LINE_COMMENT +SRC_MULTILINE_COMMENT +SRC_WS +ON +WITH +ENR_UNQUOTED_IDENTIFIER +ENR_QUOTED_IDENTIFIER +ENR_LINE_COMMENT +ENR_MULTILINE_COMMENT +ENR_WS +EXPLAIN_PIPE + +rule names: +DISSECT +GROK +EVAL +EXPLAIN +FROM +ROW +STATS +WHERE +SORT +MV_EXPAND +LIMIT +PROJECT +DROP +RENAME +SHOW +ENRICH +KEEP +LINE_COMMENT +MULTILINE_COMMENT +WS +EXPLAIN_OPENING_BRACKET +EXPLAIN_PIPE +EXPLAIN_WS +EXPLAIN_LINE_COMMENT +EXPLAIN_MULTILINE_COMMENT +PIPE +DIGIT +LETTER +ESCAPE_SEQUENCE +UNESCAPED_CHARS +EXPONENT +STRING +INTEGER_LITERAL +DECIMAL_LITERAL +BY +DATE_LITERAL +AND +ASSIGN +COMMA +DOT +LP +OPENING_BRACKET +CLOSING_BRACKET +NOT +LIKE +RLIKE +IN +IS +AS +NULL +OR +RP +UNDERSCORE +INFO +FUNCTIONS +BOOLEAN_VALUE +COMPARISON_OPERATOR +PLUS +MINUS +ASTERISK +SLASH +PERCENT +TEN +ORDERING +NULLS_ORDERING +NULLS_ORDERING_DIRECTION +MATH_FUNCTION +UNARY_FUNCTION +WHERE_FUNCTIONS +UNQUOTED_IDENTIFIER +QUOTED_IDENTIFIER +EXPR_LINE_COMMENT +EXPR_MULTILINE_COMMENT +EXPR_WS +SRC_PIPE +SRC_OPENING_BRACKET +SRC_CLOSING_BRACKET +SRC_COMMA +SRC_ASSIGN +METADATA +SRC_UNQUOTED_IDENTIFIER +SRC_UNQUOTED_IDENTIFIER_PART +SRC_QUOTED_IDENTIFIER +SRC_LINE_COMMENT +SRC_MULTILINE_COMMENT +SRC_WS +ON +WITH +ENR_PIPE +ENR_CLOSING_BRACKET +ENR_COMMA +ENR_ASSIGN +ENR_UNQUOTED_IDENTIFIER +ENR_UNQUOTED_IDENTIFIER_PART +ENR_QUOTED_IDENTIFIER +ENR_LINE_COMMENT +ENR_MULTILINE_COMMENT +ENR_WS +A +B +C +D +E +F +G +H +I +J +K +L +M +N +O +P +Q +R +S +T +U +V +W +X +Y +Z + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE +EXPLAIN_MODE +EXPRESSION +SOURCE_IDENTIFIERS +ENRICH_IDENTIFIERS + +atn: +[4, 0, 81, 1610, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 2, 98, 7, 98, 2, 99, 7, 99, 2, 100, 7, 100, 2, 101, 7, 101, 2, 102, 7, 102, 2, 103, 7, 103, 2, 104, 7, 104, 2, 105, 7, 105, 2, 106, 7, 106, 2, 107, 7, 107, 2, 108, 7, 108, 2, 109, 7, 109, 2, 110, 7, 110, 2, 111, 7, 111, 2, 112, 7, 112, 2, 113, 7, 113, 2, 114, 7, 114, 2, 115, 7, 115, 2, 116, 7, 116, 2, 117, 7, 117, 2, 118, 7, 118, 2, 119, 7, 119, 2, 120, 7, 120, 2, 121, 7, 121, 2, 122, 7, 122, 2, 123, 7, 123, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 5, 17, 397, 8, 17, 10, 17, 12, 17, 400, 9, 17, 1, 17, 3, 17, 403, 8, 17, 1, 17, 3, 17, 406, 8, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 5, 18, 415, 8, 18, 10, 18, 12, 18, 418, 9, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 4, 19, 426, 8, 19, 11, 19, 12, 19, 427, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 3, 30, 469, 8, 30, 1, 30, 4, 30, 472, 8, 30, 11, 30, 12, 30, 473, 1, 31, 1, 31, 1, 31, 5, 31, 479, 8, 31, 10, 31, 12, 31, 482, 9, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 5, 31, 490, 8, 31, 10, 31, 12, 31, 493, 9, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 3, 31, 500, 8, 31, 1, 31, 3, 31, 503, 8, 31, 3, 31, 505, 8, 31, 1, 32, 4, 32, 508, 8, 32, 11, 32, 12, 32, 509, 1, 33, 4, 33, 513, 8, 33, 11, 33, 12, 33, 514, 1, 33, 1, 33, 5, 33, 519, 8, 33, 10, 33, 12, 33, 522, 9, 33, 1, 33, 1, 33, 4, 33, 526, 8, 33, 11, 33, 12, 33, 527, 1, 33, 4, 33, 531, 8, 33, 11, 33, 12, 33, 532, 1, 33, 1, 33, 5, 33, 537, 8, 33, 10, 33, 12, 33, 540, 9, 33, 3, 33, 542, 8, 33, 1, 33, 1, 33, 1, 33, 1, 33, 4, 33, 548, 8, 33, 11, 33, 12, 33, 549, 1, 33, 1, 33, 3, 33, 554, 8, 33, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 3, 35, 653, 8, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 38, 1, 38, 1, 39, 1, 39, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 3, 55, 737, 8, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 3, 56, 749, 8, 56, 1, 57, 1, 57, 1, 58, 1, 58, 1, 59, 1, 59, 1, 60, 1, 60, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 3, 63, 771, 8, 63, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 3, 65, 788, 8, 65, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 3, 66, 1232, 8, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 3, 67, 1385, 8, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 5, 69, 1403, 8, 69, 10, 69, 12, 69, 1406, 9, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 4, 69, 1413, 8, 69, 11, 69, 12, 69, 1414, 3, 69, 1417, 8, 69, 1, 70, 1, 70, 1, 70, 1, 70, 5, 70, 1423, 8, 70, 10, 70, 12, 70, 1426, 9, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 1, 77, 1, 77, 1, 78, 1, 78, 1, 78, 1, 78, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 80, 4, 80, 1477, 8, 80, 11, 80, 12, 80, 1478, 1, 81, 4, 81, 1482, 8, 81, 11, 81, 12, 81, 1483, 1, 81, 1, 81, 3, 81, 1488, 8, 81, 1, 82, 1, 82, 1, 83, 1, 83, 1, 83, 1, 83, 1, 84, 1, 84, 1, 84, 1, 84, 1, 85, 1, 85, 1, 85, 1, 85, 1, 86, 1, 86, 1, 86, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 1, 88, 1, 88, 1, 88, 1, 88, 1, 88, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 90, 1, 90, 1, 90, 1, 90, 1, 91, 1, 91, 1, 91, 1, 91, 1, 92, 4, 92, 1532, 8, 92, 11, 92, 12, 92, 1533, 1, 93, 4, 93, 1537, 8, 93, 11, 93, 12, 93, 1538, 1, 93, 1, 93, 3, 93, 1543, 8, 93, 1, 94, 1, 94, 1, 95, 1, 95, 1, 95, 1, 95, 1, 96, 1, 96, 1, 96, 1, 96, 1, 97, 1, 97, 1, 97, 1, 97, 1, 98, 1, 98, 1, 99, 1, 99, 1, 100, 1, 100, 1, 101, 1, 101, 1, 102, 1, 102, 1, 103, 1, 103, 1, 104, 1, 104, 1, 105, 1, 105, 1, 106, 1, 106, 1, 107, 1, 107, 1, 108, 1, 108, 1, 109, 1, 109, 1, 110, 1, 110, 1, 111, 1, 111, 1, 112, 1, 112, 1, 113, 1, 113, 1, 114, 1, 114, 1, 115, 1, 115, 1, 116, 1, 116, 1, 117, 1, 117, 1, 118, 1, 118, 1, 119, 1, 119, 1, 120, 1, 120, 1, 121, 1, 121, 1, 122, 1, 122, 1, 123, 1, 123, 2, 416, 491, 0, 124, 5, 1, 7, 2, 9, 3, 11, 4, 13, 5, 15, 6, 17, 7, 19, 8, 21, 9, 23, 10, 25, 11, 27, 12, 29, 13, 31, 14, 33, 15, 35, 16, 37, 17, 39, 18, 41, 19, 43, 20, 45, 0, 47, 81, 49, 21, 51, 22, 53, 23, 55, 24, 57, 0, 59, 0, 61, 0, 63, 0, 65, 0, 67, 25, 69, 26, 71, 27, 73, 28, 75, 29, 77, 30, 79, 31, 81, 32, 83, 33, 85, 34, 87, 35, 89, 36, 91, 37, 93, 38, 95, 39, 97, 40, 99, 41, 101, 42, 103, 43, 105, 44, 107, 45, 109, 46, 111, 47, 113, 48, 115, 49, 117, 50, 119, 51, 121, 52, 123, 53, 125, 54, 127, 55, 129, 56, 131, 57, 133, 58, 135, 59, 137, 60, 139, 61, 141, 62, 143, 63, 145, 64, 147, 65, 149, 66, 151, 67, 153, 0, 155, 0, 157, 0, 159, 0, 161, 0, 163, 68, 165, 69, 167, 0, 169, 70, 171, 71, 173, 72, 175, 73, 177, 74, 179, 75, 181, 0, 183, 0, 185, 0, 187, 0, 189, 76, 191, 0, 193, 77, 195, 78, 197, 79, 199, 80, 201, 0, 203, 0, 205, 0, 207, 0, 209, 0, 211, 0, 213, 0, 215, 0, 217, 0, 219, 0, 221, 0, 223, 0, 225, 0, 227, 0, 229, 0, 231, 0, 233, 0, 235, 0, 237, 0, 239, 0, 241, 0, 243, 0, 245, 0, 247, 0, 249, 0, 251, 0, 5, 0, 1, 2, 3, 4, 37, 2, 0, 10, 10, 13, 13, 3, 0, 9, 10, 13, 13, 32, 32, 1, 0, 48, 57, 2, 0, 65, 90, 97, 122, 5, 0, 34, 34, 92, 92, 110, 110, 114, 114, 116, 116, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 2, 0, 64, 64, 95, 95, 1, 0, 96, 96, 10, 0, 9, 10, 13, 13, 32, 32, 44, 44, 47, 47, 61, 61, 91, 91, 93, 93, 96, 96, 124, 124, 2, 0, 42, 42, 47, 47, 2, 0, 65, 65, 97, 97, 2, 0, 66, 66, 98, 98, 2, 0, 67, 67, 99, 99, 2, 0, 68, 68, 100, 100, 2, 0, 70, 70, 102, 102, 2, 0, 71, 71, 103, 103, 2, 0, 72, 72, 104, 104, 2, 0, 73, 73, 105, 105, 2, 0, 74, 74, 106, 106, 2, 0, 75, 75, 107, 107, 2, 0, 76, 76, 108, 108, 2, 0, 77, 77, 109, 109, 2, 0, 78, 78, 110, 110, 2, 0, 79, 79, 111, 111, 2, 0, 80, 80, 112, 112, 2, 0, 81, 81, 113, 113, 2, 0, 82, 82, 114, 114, 2, 0, 83, 83, 115, 115, 2, 0, 84, 84, 116, 116, 2, 0, 85, 85, 117, 117, 2, 0, 86, 86, 118, 118, 2, 0, 87, 87, 119, 119, 2, 0, 88, 88, 120, 120, 2, 0, 89, 89, 121, 121, 2, 0, 90, 90, 122, 122, 1711, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 1, 45, 1, 0, 0, 0, 1, 47, 1, 0, 0, 0, 1, 49, 1, 0, 0, 0, 1, 51, 1, 0, 0, 0, 1, 53, 1, 0, 0, 0, 2, 55, 1, 0, 0, 0, 2, 67, 1, 0, 0, 0, 2, 69, 1, 0, 0, 0, 2, 71, 1, 0, 0, 0, 2, 73, 1, 0, 0, 0, 2, 75, 1, 0, 0, 0, 2, 77, 1, 0, 0, 0, 2, 79, 1, 0, 0, 0, 2, 81, 1, 0, 0, 0, 2, 83, 1, 0, 0, 0, 2, 85, 1, 0, 0, 0, 2, 87, 1, 0, 0, 0, 2, 89, 1, 0, 0, 0, 2, 91, 1, 0, 0, 0, 2, 93, 1, 0, 0, 0, 2, 95, 1, 0, 0, 0, 2, 97, 1, 0, 0, 0, 2, 99, 1, 0, 0, 0, 2, 101, 1, 0, 0, 0, 2, 103, 1, 0, 0, 0, 2, 105, 1, 0, 0, 0, 2, 107, 1, 0, 0, 0, 2, 109, 1, 0, 0, 0, 2, 111, 1, 0, 0, 0, 2, 113, 1, 0, 0, 0, 2, 115, 1, 0, 0, 0, 2, 117, 1, 0, 0, 0, 2, 119, 1, 0, 0, 0, 2, 121, 1, 0, 0, 0, 2, 123, 1, 0, 0, 0, 2, 125, 1, 0, 0, 0, 2, 127, 1, 0, 0, 0, 2, 129, 1, 0, 0, 0, 2, 131, 1, 0, 0, 0, 2, 133, 1, 0, 0, 0, 2, 135, 1, 0, 0, 0, 2, 137, 1, 0, 0, 0, 2, 139, 1, 0, 0, 0, 2, 141, 1, 0, 0, 0, 2, 143, 1, 0, 0, 0, 2, 145, 1, 0, 0, 0, 2, 147, 1, 0, 0, 0, 2, 149, 1, 0, 0, 0, 2, 151, 1, 0, 0, 0, 3, 153, 1, 0, 0, 0, 3, 155, 1, 0, 0, 0, 3, 157, 1, 0, 0, 0, 3, 159, 1, 0, 0, 0, 3, 161, 1, 0, 0, 0, 3, 163, 1, 0, 0, 0, 3, 165, 1, 0, 0, 0, 3, 169, 1, 0, 0, 0, 3, 171, 1, 0, 0, 0, 3, 173, 1, 0, 0, 0, 3, 175, 1, 0, 0, 0, 4, 177, 1, 0, 0, 0, 4, 179, 1, 0, 0, 0, 4, 181, 1, 0, 0, 0, 4, 183, 1, 0, 0, 0, 4, 185, 1, 0, 0, 0, 4, 187, 1, 0, 0, 0, 4, 189, 1, 0, 0, 0, 4, 193, 1, 0, 0, 0, 4, 195, 1, 0, 0, 0, 4, 197, 1, 0, 0, 0, 4, 199, 1, 0, 0, 0, 5, 253, 1, 0, 0, 0, 7, 263, 1, 0, 0, 0, 9, 270, 1, 0, 0, 0, 11, 277, 1, 0, 0, 0, 13, 287, 1, 0, 0, 0, 15, 294, 1, 0, 0, 0, 17, 300, 1, 0, 0, 0, 19, 308, 1, 0, 0, 0, 21, 316, 1, 0, 0, 0, 23, 323, 1, 0, 0, 0, 25, 335, 1, 0, 0, 0, 27, 343, 1, 0, 0, 0, 29, 353, 1, 0, 0, 0, 31, 360, 1, 0, 0, 0, 33, 369, 1, 0, 0, 0, 35, 376, 1, 0, 0, 0, 37, 385, 1, 0, 0, 0, 39, 392, 1, 0, 0, 0, 41, 409, 1, 0, 0, 0, 43, 425, 1, 0, 0, 0, 45, 431, 1, 0, 0, 0, 47, 436, 1, 0, 0, 0, 49, 441, 1, 0, 0, 0, 51, 445, 1, 0, 0, 0, 53, 449, 1, 0, 0, 0, 55, 453, 1, 0, 0, 0, 57, 457, 1, 0, 0, 0, 59, 459, 1, 0, 0, 0, 61, 461, 1, 0, 0, 0, 63, 464, 1, 0, 0, 0, 65, 466, 1, 0, 0, 0, 67, 504, 1, 0, 0, 0, 69, 507, 1, 0, 0, 0, 71, 553, 1, 0, 0, 0, 73, 555, 1, 0, 0, 0, 75, 652, 1, 0, 0, 0, 77, 654, 1, 0, 0, 0, 79, 658, 1, 0, 0, 0, 81, 660, 1, 0, 0, 0, 83, 662, 1, 0, 0, 0, 85, 664, 1, 0, 0, 0, 87, 666, 1, 0, 0, 0, 89, 671, 1, 0, 0, 0, 91, 676, 1, 0, 0, 0, 93, 680, 1, 0, 0, 0, 95, 685, 1, 0, 0, 0, 97, 691, 1, 0, 0, 0, 99, 694, 1, 0, 0, 0, 101, 697, 1, 0, 0, 0, 103, 700, 1, 0, 0, 0, 105, 705, 1, 0, 0, 0, 107, 708, 1, 0, 0, 0, 109, 710, 1, 0, 0, 0, 111, 712, 1, 0, 0, 0, 113, 717, 1, 0, 0, 0, 115, 736, 1, 0, 0, 0, 117, 748, 1, 0, 0, 0, 119, 750, 1, 0, 0, 0, 121, 752, 1, 0, 0, 0, 123, 754, 1, 0, 0, 0, 125, 756, 1, 0, 0, 0, 127, 758, 1, 0, 0, 0, 129, 760, 1, 0, 0, 0, 131, 770, 1, 0, 0, 0, 133, 772, 1, 0, 0, 0, 135, 787, 1, 0, 0, 0, 137, 1231, 1, 0, 0, 0, 139, 1384, 1, 0, 0, 0, 141, 1386, 1, 0, 0, 0, 143, 1416, 1, 0, 0, 0, 145, 1418, 1, 0, 0, 0, 147, 1429, 1, 0, 0, 0, 149, 1433, 1, 0, 0, 0, 151, 1437, 1, 0, 0, 0, 153, 1441, 1, 0, 0, 0, 155, 1446, 1, 0, 0, 0, 157, 1452, 1, 0, 0, 0, 159, 1458, 1, 0, 0, 0, 161, 1462, 1, 0, 0, 0, 163, 1466, 1, 0, 0, 0, 165, 1476, 1, 0, 0, 0, 167, 1487, 1, 0, 0, 0, 169, 1489, 1, 0, 0, 0, 171, 1491, 1, 0, 0, 0, 173, 1495, 1, 0, 0, 0, 175, 1499, 1, 0, 0, 0, 177, 1503, 1, 0, 0, 0, 179, 1506, 1, 0, 0, 0, 181, 1511, 1, 0, 0, 0, 183, 1516, 1, 0, 0, 0, 185, 1522, 1, 0, 0, 0, 187, 1526, 1, 0, 0, 0, 189, 1531, 1, 0, 0, 0, 191, 1542, 1, 0, 0, 0, 193, 1544, 1, 0, 0, 0, 195, 1546, 1, 0, 0, 0, 197, 1550, 1, 0, 0, 0, 199, 1554, 1, 0, 0, 0, 201, 1558, 1, 0, 0, 0, 203, 1560, 1, 0, 0, 0, 205, 1562, 1, 0, 0, 0, 207, 1564, 1, 0, 0, 0, 209, 1566, 1, 0, 0, 0, 211, 1568, 1, 0, 0, 0, 213, 1570, 1, 0, 0, 0, 215, 1572, 1, 0, 0, 0, 217, 1574, 1, 0, 0, 0, 219, 1576, 1, 0, 0, 0, 221, 1578, 1, 0, 0, 0, 223, 1580, 1, 0, 0, 0, 225, 1582, 1, 0, 0, 0, 227, 1584, 1, 0, 0, 0, 229, 1586, 1, 0, 0, 0, 231, 1588, 1, 0, 0, 0, 233, 1590, 1, 0, 0, 0, 235, 1592, 1, 0, 0, 0, 237, 1594, 1, 0, 0, 0, 239, 1596, 1, 0, 0, 0, 241, 1598, 1, 0, 0, 0, 243, 1600, 1, 0, 0, 0, 245, 1602, 1, 0, 0, 0, 247, 1604, 1, 0, 0, 0, 249, 1606, 1, 0, 0, 0, 251, 1608, 1, 0, 0, 0, 253, 254, 3, 207, 101, 0, 254, 255, 3, 217, 106, 0, 255, 256, 3, 237, 116, 0, 256, 257, 3, 237, 116, 0, 257, 258, 3, 209, 102, 0, 258, 259, 3, 205, 100, 0, 259, 260, 3, 239, 117, 0, 260, 261, 1, 0, 0, 0, 261, 262, 6, 0, 0, 0, 262, 6, 1, 0, 0, 0, 263, 264, 3, 213, 104, 0, 264, 265, 3, 235, 115, 0, 265, 266, 3, 229, 112, 0, 266, 267, 3, 221, 108, 0, 267, 268, 1, 0, 0, 0, 268, 269, 6, 1, 0, 0, 269, 8, 1, 0, 0, 0, 270, 271, 3, 209, 102, 0, 271, 272, 3, 243, 119, 0, 272, 273, 3, 201, 98, 0, 273, 274, 3, 223, 109, 0, 274, 275, 1, 0, 0, 0, 275, 276, 6, 2, 0, 0, 276, 10, 1, 0, 0, 0, 277, 278, 3, 209, 102, 0, 278, 279, 3, 247, 121, 0, 279, 280, 3, 231, 113, 0, 280, 281, 3, 223, 109, 0, 281, 282, 3, 201, 98, 0, 282, 283, 3, 217, 106, 0, 283, 284, 3, 227, 111, 0, 284, 285, 1, 0, 0, 0, 285, 286, 6, 3, 1, 0, 286, 12, 1, 0, 0, 0, 287, 288, 3, 211, 103, 0, 288, 289, 3, 235, 115, 0, 289, 290, 3, 229, 112, 0, 290, 291, 3, 225, 110, 0, 291, 292, 1, 0, 0, 0, 292, 293, 6, 4, 2, 0, 293, 14, 1, 0, 0, 0, 294, 295, 3, 235, 115, 0, 295, 296, 3, 229, 112, 0, 296, 297, 3, 245, 120, 0, 297, 298, 1, 0, 0, 0, 298, 299, 6, 5, 0, 0, 299, 16, 1, 0, 0, 0, 300, 301, 3, 237, 116, 0, 301, 302, 3, 239, 117, 0, 302, 303, 3, 201, 98, 0, 303, 304, 3, 239, 117, 0, 304, 305, 3, 237, 116, 0, 305, 306, 1, 0, 0, 0, 306, 307, 6, 6, 0, 0, 307, 18, 1, 0, 0, 0, 308, 309, 3, 245, 120, 0, 309, 310, 3, 215, 105, 0, 310, 311, 3, 209, 102, 0, 311, 312, 3, 235, 115, 0, 312, 313, 3, 209, 102, 0, 313, 314, 1, 0, 0, 0, 314, 315, 6, 7, 0, 0, 315, 20, 1, 0, 0, 0, 316, 317, 3, 237, 116, 0, 317, 318, 3, 229, 112, 0, 318, 319, 3, 235, 115, 0, 319, 320, 3, 239, 117, 0, 320, 321, 1, 0, 0, 0, 321, 322, 6, 8, 0, 0, 322, 22, 1, 0, 0, 0, 323, 324, 3, 225, 110, 0, 324, 325, 3, 243, 119, 0, 325, 326, 3, 109, 52, 0, 326, 327, 3, 209, 102, 0, 327, 328, 3, 247, 121, 0, 328, 329, 3, 231, 113, 0, 329, 330, 3, 201, 98, 0, 330, 331, 3, 227, 111, 0, 331, 332, 3, 207, 101, 0, 332, 333, 1, 0, 0, 0, 333, 334, 6, 9, 0, 0, 334, 24, 1, 0, 0, 0, 335, 336, 3, 223, 109, 0, 336, 337, 3, 217, 106, 0, 337, 338, 3, 225, 110, 0, 338, 339, 3, 217, 106, 0, 339, 340, 3, 239, 117, 0, 340, 341, 1, 0, 0, 0, 341, 342, 6, 10, 0, 0, 342, 26, 1, 0, 0, 0, 343, 344, 3, 231, 113, 0, 344, 345, 3, 235, 115, 0, 345, 346, 3, 229, 112, 0, 346, 347, 3, 219, 107, 0, 347, 348, 3, 209, 102, 0, 348, 349, 3, 205, 100, 0, 349, 350, 3, 239, 117, 0, 350, 351, 1, 0, 0, 0, 351, 352, 6, 11, 0, 0, 352, 28, 1, 0, 0, 0, 353, 354, 3, 207, 101, 0, 354, 355, 3, 235, 115, 0, 355, 356, 3, 229, 112, 0, 356, 357, 3, 231, 113, 0, 357, 358, 1, 0, 0, 0, 358, 359, 6, 12, 0, 0, 359, 30, 1, 0, 0, 0, 360, 361, 3, 235, 115, 0, 361, 362, 3, 209, 102, 0, 362, 363, 3, 227, 111, 0, 363, 364, 3, 201, 98, 0, 364, 365, 3, 225, 110, 0, 365, 366, 3, 209, 102, 0, 366, 367, 1, 0, 0, 0, 367, 368, 6, 13, 0, 0, 368, 32, 1, 0, 0, 0, 369, 370, 3, 237, 116, 0, 370, 371, 3, 215, 105, 0, 371, 372, 3, 229, 112, 0, 372, 373, 3, 245, 120, 0, 373, 374, 1, 0, 0, 0, 374, 375, 6, 14, 0, 0, 375, 34, 1, 0, 0, 0, 376, 377, 3, 209, 102, 0, 377, 378, 3, 227, 111, 0, 378, 379, 3, 235, 115, 0, 379, 380, 3, 217, 106, 0, 380, 381, 3, 205, 100, 0, 381, 382, 3, 215, 105, 0, 382, 383, 1, 0, 0, 0, 383, 384, 6, 15, 3, 0, 384, 36, 1, 0, 0, 0, 385, 386, 3, 221, 108, 0, 386, 387, 3, 209, 102, 0, 387, 388, 3, 209, 102, 0, 388, 389, 3, 231, 113, 0, 389, 390, 1, 0, 0, 0, 390, 391, 6, 16, 0, 0, 391, 38, 1, 0, 0, 0, 392, 393, 5, 47, 0, 0, 393, 394, 5, 47, 0, 0, 394, 398, 1, 0, 0, 0, 395, 397, 8, 0, 0, 0, 396, 395, 1, 0, 0, 0, 397, 400, 1, 0, 0, 0, 398, 396, 1, 0, 0, 0, 398, 399, 1, 0, 0, 0, 399, 402, 1, 0, 0, 0, 400, 398, 1, 0, 0, 0, 401, 403, 5, 13, 0, 0, 402, 401, 1, 0, 0, 0, 402, 403, 1, 0, 0, 0, 403, 405, 1, 0, 0, 0, 404, 406, 5, 10, 0, 0, 405, 404, 1, 0, 0, 0, 405, 406, 1, 0, 0, 0, 406, 407, 1, 0, 0, 0, 407, 408, 6, 17, 4, 0, 408, 40, 1, 0, 0, 0, 409, 410, 5, 47, 0, 0, 410, 411, 5, 42, 0, 0, 411, 416, 1, 0, 0, 0, 412, 415, 3, 41, 18, 0, 413, 415, 9, 0, 0, 0, 414, 412, 1, 0, 0, 0, 414, 413, 1, 0, 0, 0, 415, 418, 1, 0, 0, 0, 416, 417, 1, 0, 0, 0, 416, 414, 1, 0, 0, 0, 417, 419, 1, 0, 0, 0, 418, 416, 1, 0, 0, 0, 419, 420, 5, 42, 0, 0, 420, 421, 5, 47, 0, 0, 421, 422, 1, 0, 0, 0, 422, 423, 6, 18, 4, 0, 423, 42, 1, 0, 0, 0, 424, 426, 7, 1, 0, 0, 425, 424, 1, 0, 0, 0, 426, 427, 1, 0, 0, 0, 427, 425, 1, 0, 0, 0, 427, 428, 1, 0, 0, 0, 428, 429, 1, 0, 0, 0, 429, 430, 6, 19, 4, 0, 430, 44, 1, 0, 0, 0, 431, 432, 5, 91, 0, 0, 432, 433, 1, 0, 0, 0, 433, 434, 6, 20, 5, 0, 434, 435, 6, 20, 6, 0, 435, 46, 1, 0, 0, 0, 436, 437, 5, 124, 0, 0, 437, 438, 1, 0, 0, 0, 438, 439, 6, 21, 7, 0, 439, 440, 6, 21, 8, 0, 440, 48, 1, 0, 0, 0, 441, 442, 3, 43, 19, 0, 442, 443, 1, 0, 0, 0, 443, 444, 6, 22, 4, 0, 444, 50, 1, 0, 0, 0, 445, 446, 3, 39, 17, 0, 446, 447, 1, 0, 0, 0, 447, 448, 6, 23, 4, 0, 448, 52, 1, 0, 0, 0, 449, 450, 3, 41, 18, 0, 450, 451, 1, 0, 0, 0, 451, 452, 6, 24, 4, 0, 452, 54, 1, 0, 0, 0, 453, 454, 5, 124, 0, 0, 454, 455, 1, 0, 0, 0, 455, 456, 6, 25, 8, 0, 456, 56, 1, 0, 0, 0, 457, 458, 7, 2, 0, 0, 458, 58, 1, 0, 0, 0, 459, 460, 7, 3, 0, 0, 460, 60, 1, 0, 0, 0, 461, 462, 5, 92, 0, 0, 462, 463, 7, 4, 0, 0, 463, 62, 1, 0, 0, 0, 464, 465, 8, 5, 0, 0, 465, 64, 1, 0, 0, 0, 466, 468, 7, 6, 0, 0, 467, 469, 7, 7, 0, 0, 468, 467, 1, 0, 0, 0, 468, 469, 1, 0, 0, 0, 469, 471, 1, 0, 0, 0, 470, 472, 3, 57, 26, 0, 471, 470, 1, 0, 0, 0, 472, 473, 1, 0, 0, 0, 473, 471, 1, 0, 0, 0, 473, 474, 1, 0, 0, 0, 474, 66, 1, 0, 0, 0, 475, 480, 5, 34, 0, 0, 476, 479, 3, 61, 28, 0, 477, 479, 3, 63, 29, 0, 478, 476, 1, 0, 0, 0, 478, 477, 1, 0, 0, 0, 479, 482, 1, 0, 0, 0, 480, 478, 1, 0, 0, 0, 480, 481, 1, 0, 0, 0, 481, 483, 1, 0, 0, 0, 482, 480, 1, 0, 0, 0, 483, 505, 5, 34, 0, 0, 484, 485, 5, 34, 0, 0, 485, 486, 5, 34, 0, 0, 486, 487, 5, 34, 0, 0, 487, 491, 1, 0, 0, 0, 488, 490, 8, 0, 0, 0, 489, 488, 1, 0, 0, 0, 490, 493, 1, 0, 0, 0, 491, 492, 1, 0, 0, 0, 491, 489, 1, 0, 0, 0, 492, 494, 1, 0, 0, 0, 493, 491, 1, 0, 0, 0, 494, 495, 5, 34, 0, 0, 495, 496, 5, 34, 0, 0, 496, 497, 5, 34, 0, 0, 497, 499, 1, 0, 0, 0, 498, 500, 5, 34, 0, 0, 499, 498, 1, 0, 0, 0, 499, 500, 1, 0, 0, 0, 500, 502, 1, 0, 0, 0, 501, 503, 5, 34, 0, 0, 502, 501, 1, 0, 0, 0, 502, 503, 1, 0, 0, 0, 503, 505, 1, 0, 0, 0, 504, 475, 1, 0, 0, 0, 504, 484, 1, 0, 0, 0, 505, 68, 1, 0, 0, 0, 506, 508, 3, 57, 26, 0, 507, 506, 1, 0, 0, 0, 508, 509, 1, 0, 0, 0, 509, 507, 1, 0, 0, 0, 509, 510, 1, 0, 0, 0, 510, 70, 1, 0, 0, 0, 511, 513, 3, 57, 26, 0, 512, 511, 1, 0, 0, 0, 513, 514, 1, 0, 0, 0, 514, 512, 1, 0, 0, 0, 514, 515, 1, 0, 0, 0, 515, 516, 1, 0, 0, 0, 516, 520, 3, 83, 39, 0, 517, 519, 3, 57, 26, 0, 518, 517, 1, 0, 0, 0, 519, 522, 1, 0, 0, 0, 520, 518, 1, 0, 0, 0, 520, 521, 1, 0, 0, 0, 521, 554, 1, 0, 0, 0, 522, 520, 1, 0, 0, 0, 523, 525, 3, 83, 39, 0, 524, 526, 3, 57, 26, 0, 525, 524, 1, 0, 0, 0, 526, 527, 1, 0, 0, 0, 527, 525, 1, 0, 0, 0, 527, 528, 1, 0, 0, 0, 528, 554, 1, 0, 0, 0, 529, 531, 3, 57, 26, 0, 530, 529, 1, 0, 0, 0, 531, 532, 1, 0, 0, 0, 532, 530, 1, 0, 0, 0, 532, 533, 1, 0, 0, 0, 533, 541, 1, 0, 0, 0, 534, 538, 3, 83, 39, 0, 535, 537, 3, 57, 26, 0, 536, 535, 1, 0, 0, 0, 537, 540, 1, 0, 0, 0, 538, 536, 1, 0, 0, 0, 538, 539, 1, 0, 0, 0, 539, 542, 1, 0, 0, 0, 540, 538, 1, 0, 0, 0, 541, 534, 1, 0, 0, 0, 541, 542, 1, 0, 0, 0, 542, 543, 1, 0, 0, 0, 543, 544, 3, 65, 30, 0, 544, 554, 1, 0, 0, 0, 545, 547, 3, 83, 39, 0, 546, 548, 3, 57, 26, 0, 547, 546, 1, 0, 0, 0, 548, 549, 1, 0, 0, 0, 549, 547, 1, 0, 0, 0, 549, 550, 1, 0, 0, 0, 550, 551, 1, 0, 0, 0, 551, 552, 3, 65, 30, 0, 552, 554, 1, 0, 0, 0, 553, 512, 1, 0, 0, 0, 553, 523, 1, 0, 0, 0, 553, 530, 1, 0, 0, 0, 553, 545, 1, 0, 0, 0, 554, 72, 1, 0, 0, 0, 555, 556, 5, 98, 0, 0, 556, 557, 5, 121, 0, 0, 557, 74, 1, 0, 0, 0, 558, 559, 5, 121, 0, 0, 559, 560, 5, 101, 0, 0, 560, 561, 5, 97, 0, 0, 561, 653, 5, 114, 0, 0, 562, 563, 5, 109, 0, 0, 563, 564, 5, 111, 0, 0, 564, 565, 5, 110, 0, 0, 565, 566, 5, 116, 0, 0, 566, 653, 5, 104, 0, 0, 567, 568, 5, 100, 0, 0, 568, 569, 5, 97, 0, 0, 569, 653, 5, 121, 0, 0, 570, 571, 5, 115, 0, 0, 571, 572, 5, 101, 0, 0, 572, 573, 5, 99, 0, 0, 573, 574, 5, 111, 0, 0, 574, 575, 5, 110, 0, 0, 575, 653, 5, 100, 0, 0, 576, 577, 5, 109, 0, 0, 577, 578, 5, 105, 0, 0, 578, 579, 5, 110, 0, 0, 579, 580, 5, 117, 0, 0, 580, 581, 5, 116, 0, 0, 581, 653, 5, 101, 0, 0, 582, 583, 5, 104, 0, 0, 583, 584, 5, 111, 0, 0, 584, 585, 5, 117, 0, 0, 585, 653, 5, 114, 0, 0, 586, 587, 5, 119, 0, 0, 587, 588, 5, 101, 0, 0, 588, 589, 5, 101, 0, 0, 589, 653, 5, 107, 0, 0, 590, 591, 5, 109, 0, 0, 591, 592, 5, 105, 0, 0, 592, 593, 5, 108, 0, 0, 593, 594, 5, 108, 0, 0, 594, 595, 5, 105, 0, 0, 595, 596, 5, 115, 0, 0, 596, 597, 5, 101, 0, 0, 597, 598, 5, 99, 0, 0, 598, 599, 5, 111, 0, 0, 599, 600, 5, 110, 0, 0, 600, 653, 5, 100, 0, 0, 601, 602, 5, 121, 0, 0, 602, 603, 5, 101, 0, 0, 603, 604, 5, 97, 0, 0, 604, 605, 5, 114, 0, 0, 605, 653, 5, 115, 0, 0, 606, 607, 5, 109, 0, 0, 607, 608, 5, 111, 0, 0, 608, 609, 5, 110, 0, 0, 609, 610, 5, 116, 0, 0, 610, 611, 5, 104, 0, 0, 611, 653, 5, 115, 0, 0, 612, 613, 5, 100, 0, 0, 613, 614, 5, 97, 0, 0, 614, 615, 5, 121, 0, 0, 615, 653, 5, 115, 0, 0, 616, 617, 5, 115, 0, 0, 617, 618, 5, 101, 0, 0, 618, 619, 5, 99, 0, 0, 619, 620, 5, 111, 0, 0, 620, 621, 5, 110, 0, 0, 621, 622, 5, 100, 0, 0, 622, 653, 5, 115, 0, 0, 623, 624, 5, 109, 0, 0, 624, 625, 5, 105, 0, 0, 625, 626, 5, 110, 0, 0, 626, 627, 5, 117, 0, 0, 627, 628, 5, 116, 0, 0, 628, 629, 5, 101, 0, 0, 629, 653, 5, 115, 0, 0, 630, 631, 5, 104, 0, 0, 631, 632, 5, 111, 0, 0, 632, 633, 5, 117, 0, 0, 633, 634, 5, 114, 0, 0, 634, 653, 5, 115, 0, 0, 635, 636, 5, 119, 0, 0, 636, 637, 5, 101, 0, 0, 637, 638, 5, 101, 0, 0, 638, 639, 5, 107, 0, 0, 639, 653, 5, 115, 0, 0, 640, 641, 5, 109, 0, 0, 641, 642, 5, 105, 0, 0, 642, 643, 5, 108, 0, 0, 643, 644, 5, 108, 0, 0, 644, 645, 5, 105, 0, 0, 645, 646, 5, 115, 0, 0, 646, 647, 5, 101, 0, 0, 647, 648, 5, 99, 0, 0, 648, 649, 5, 111, 0, 0, 649, 650, 5, 110, 0, 0, 650, 651, 5, 100, 0, 0, 651, 653, 5, 115, 0, 0, 652, 558, 1, 0, 0, 0, 652, 562, 1, 0, 0, 0, 652, 567, 1, 0, 0, 0, 652, 570, 1, 0, 0, 0, 652, 576, 1, 0, 0, 0, 652, 582, 1, 0, 0, 0, 652, 586, 1, 0, 0, 0, 652, 590, 1, 0, 0, 0, 652, 601, 1, 0, 0, 0, 652, 606, 1, 0, 0, 0, 652, 612, 1, 0, 0, 0, 652, 616, 1, 0, 0, 0, 652, 623, 1, 0, 0, 0, 652, 630, 1, 0, 0, 0, 652, 635, 1, 0, 0, 0, 652, 640, 1, 0, 0, 0, 653, 76, 1, 0, 0, 0, 654, 655, 5, 97, 0, 0, 655, 656, 5, 110, 0, 0, 656, 657, 5, 100, 0, 0, 657, 78, 1, 0, 0, 0, 658, 659, 5, 61, 0, 0, 659, 80, 1, 0, 0, 0, 660, 661, 5, 44, 0, 0, 661, 82, 1, 0, 0, 0, 662, 663, 5, 46, 0, 0, 663, 84, 1, 0, 0, 0, 664, 665, 5, 40, 0, 0, 665, 86, 1, 0, 0, 0, 666, 667, 5, 91, 0, 0, 667, 668, 1, 0, 0, 0, 668, 669, 6, 41, 0, 0, 669, 670, 6, 41, 0, 0, 670, 88, 1, 0, 0, 0, 671, 672, 5, 93, 0, 0, 672, 673, 1, 0, 0, 0, 673, 674, 6, 42, 8, 0, 674, 675, 6, 42, 8, 0, 675, 90, 1, 0, 0, 0, 676, 677, 3, 227, 111, 0, 677, 678, 3, 229, 112, 0, 678, 679, 3, 239, 117, 0, 679, 92, 1, 0, 0, 0, 680, 681, 3, 223, 109, 0, 681, 682, 3, 217, 106, 0, 682, 683, 3, 221, 108, 0, 683, 684, 3, 209, 102, 0, 684, 94, 1, 0, 0, 0, 685, 686, 3, 235, 115, 0, 686, 687, 3, 223, 109, 0, 687, 688, 3, 217, 106, 0, 688, 689, 3, 221, 108, 0, 689, 690, 3, 209, 102, 0, 690, 96, 1, 0, 0, 0, 691, 692, 3, 217, 106, 0, 692, 693, 3, 227, 111, 0, 693, 98, 1, 0, 0, 0, 694, 695, 3, 217, 106, 0, 695, 696, 3, 237, 116, 0, 696, 100, 1, 0, 0, 0, 697, 698, 3, 201, 98, 0, 698, 699, 3, 237, 116, 0, 699, 102, 1, 0, 0, 0, 700, 701, 3, 227, 111, 0, 701, 702, 3, 241, 118, 0, 702, 703, 3, 223, 109, 0, 703, 704, 3, 223, 109, 0, 704, 104, 1, 0, 0, 0, 705, 706, 5, 111, 0, 0, 706, 707, 5, 114, 0, 0, 707, 106, 1, 0, 0, 0, 708, 709, 5, 41, 0, 0, 709, 108, 1, 0, 0, 0, 710, 711, 5, 95, 0, 0, 711, 110, 1, 0, 0, 0, 712, 713, 5, 105, 0, 0, 713, 714, 5, 110, 0, 0, 714, 715, 5, 102, 0, 0, 715, 716, 5, 111, 0, 0, 716, 112, 1, 0, 0, 0, 717, 718, 5, 102, 0, 0, 718, 719, 5, 117, 0, 0, 719, 720, 5, 110, 0, 0, 720, 721, 5, 99, 0, 0, 721, 722, 5, 116, 0, 0, 722, 723, 5, 105, 0, 0, 723, 724, 5, 111, 0, 0, 724, 725, 5, 110, 0, 0, 725, 726, 5, 115, 0, 0, 726, 114, 1, 0, 0, 0, 727, 728, 5, 116, 0, 0, 728, 729, 5, 114, 0, 0, 729, 730, 5, 117, 0, 0, 730, 737, 5, 101, 0, 0, 731, 732, 5, 102, 0, 0, 732, 733, 5, 97, 0, 0, 733, 734, 5, 108, 0, 0, 734, 735, 5, 115, 0, 0, 735, 737, 5, 101, 0, 0, 736, 727, 1, 0, 0, 0, 736, 731, 1, 0, 0, 0, 737, 116, 1, 0, 0, 0, 738, 739, 5, 61, 0, 0, 739, 749, 5, 61, 0, 0, 740, 741, 5, 33, 0, 0, 741, 749, 5, 61, 0, 0, 742, 749, 5, 60, 0, 0, 743, 744, 5, 60, 0, 0, 744, 749, 5, 61, 0, 0, 745, 749, 5, 62, 0, 0, 746, 747, 5, 62, 0, 0, 747, 749, 5, 61, 0, 0, 748, 738, 1, 0, 0, 0, 748, 740, 1, 0, 0, 0, 748, 742, 1, 0, 0, 0, 748, 743, 1, 0, 0, 0, 748, 745, 1, 0, 0, 0, 748, 746, 1, 0, 0, 0, 749, 118, 1, 0, 0, 0, 750, 751, 5, 43, 0, 0, 751, 120, 1, 0, 0, 0, 752, 753, 5, 45, 0, 0, 753, 122, 1, 0, 0, 0, 754, 755, 5, 42, 0, 0, 755, 124, 1, 0, 0, 0, 756, 757, 5, 47, 0, 0, 757, 126, 1, 0, 0, 0, 758, 759, 5, 37, 0, 0, 759, 128, 1, 0, 0, 0, 760, 761, 5, 49, 0, 0, 761, 762, 5, 48, 0, 0, 762, 130, 1, 0, 0, 0, 763, 764, 5, 97, 0, 0, 764, 765, 5, 115, 0, 0, 765, 771, 5, 99, 0, 0, 766, 767, 5, 100, 0, 0, 767, 768, 5, 101, 0, 0, 768, 769, 5, 115, 0, 0, 769, 771, 5, 99, 0, 0, 770, 763, 1, 0, 0, 0, 770, 766, 1, 0, 0, 0, 771, 132, 1, 0, 0, 0, 772, 773, 5, 110, 0, 0, 773, 774, 5, 117, 0, 0, 774, 775, 5, 108, 0, 0, 775, 776, 5, 108, 0, 0, 776, 777, 5, 115, 0, 0, 777, 134, 1, 0, 0, 0, 778, 779, 5, 102, 0, 0, 779, 780, 5, 105, 0, 0, 780, 781, 5, 114, 0, 0, 781, 782, 5, 115, 0, 0, 782, 788, 5, 116, 0, 0, 783, 784, 5, 108, 0, 0, 784, 785, 5, 97, 0, 0, 785, 786, 5, 115, 0, 0, 786, 788, 5, 116, 0, 0, 787, 778, 1, 0, 0, 0, 787, 783, 1, 0, 0, 0, 788, 136, 1, 0, 0, 0, 789, 790, 3, 235, 115, 0, 790, 791, 3, 229, 112, 0, 791, 792, 3, 241, 118, 0, 792, 793, 3, 227, 111, 0, 793, 794, 3, 207, 101, 0, 794, 1232, 1, 0, 0, 0, 795, 796, 3, 201, 98, 0, 796, 797, 3, 203, 99, 0, 797, 798, 3, 237, 116, 0, 798, 1232, 1, 0, 0, 0, 799, 800, 3, 231, 113, 0, 800, 801, 3, 229, 112, 0, 801, 802, 3, 245, 120, 0, 802, 1232, 1, 0, 0, 0, 803, 804, 3, 223, 109, 0, 804, 805, 3, 229, 112, 0, 805, 806, 3, 213, 104, 0, 806, 807, 3, 129, 62, 0, 807, 1232, 1, 0, 0, 0, 808, 809, 3, 231, 113, 0, 809, 810, 3, 217, 106, 0, 810, 1232, 1, 0, 0, 0, 811, 812, 3, 239, 117, 0, 812, 813, 3, 201, 98, 0, 813, 814, 3, 241, 118, 0, 814, 1232, 1, 0, 0, 0, 815, 1232, 3, 209, 102, 0, 816, 817, 3, 237, 116, 0, 817, 818, 3, 241, 118, 0, 818, 819, 3, 203, 99, 0, 819, 820, 3, 237, 116, 0, 820, 821, 3, 239, 117, 0, 821, 822, 3, 235, 115, 0, 822, 823, 3, 217, 106, 0, 823, 824, 3, 227, 111, 0, 824, 825, 3, 213, 104, 0, 825, 1232, 1, 0, 0, 0, 826, 827, 3, 239, 117, 0, 827, 828, 3, 235, 115, 0, 828, 829, 3, 217, 106, 0, 829, 830, 3, 225, 110, 0, 830, 1232, 1, 0, 0, 0, 831, 832, 3, 205, 100, 0, 832, 833, 3, 229, 112, 0, 833, 834, 3, 227, 111, 0, 834, 835, 3, 205, 100, 0, 835, 836, 3, 201, 98, 0, 836, 837, 3, 239, 117, 0, 837, 1232, 1, 0, 0, 0, 838, 839, 3, 205, 100, 0, 839, 840, 3, 229, 112, 0, 840, 841, 3, 201, 98, 0, 841, 842, 3, 223, 109, 0, 842, 843, 3, 209, 102, 0, 843, 844, 3, 237, 116, 0, 844, 845, 3, 205, 100, 0, 845, 846, 3, 209, 102, 0, 846, 1232, 1, 0, 0, 0, 847, 848, 3, 213, 104, 0, 848, 849, 3, 235, 115, 0, 849, 850, 3, 209, 102, 0, 850, 851, 3, 201, 98, 0, 851, 852, 3, 239, 117, 0, 852, 853, 3, 209, 102, 0, 853, 854, 3, 237, 116, 0, 854, 855, 3, 239, 117, 0, 855, 1232, 1, 0, 0, 0, 856, 857, 3, 223, 109, 0, 857, 858, 3, 209, 102, 0, 858, 859, 3, 211, 103, 0, 859, 860, 3, 239, 117, 0, 860, 1232, 1, 0, 0, 0, 861, 862, 3, 227, 111, 0, 862, 863, 3, 229, 112, 0, 863, 864, 3, 245, 120, 0, 864, 1232, 1, 0, 0, 0, 865, 866, 3, 235, 115, 0, 866, 867, 3, 217, 106, 0, 867, 868, 3, 213, 104, 0, 868, 869, 3, 215, 105, 0, 869, 870, 3, 239, 117, 0, 870, 1232, 1, 0, 0, 0, 871, 872, 3, 237, 116, 0, 872, 873, 3, 239, 117, 0, 873, 874, 3, 201, 98, 0, 874, 875, 3, 235, 115, 0, 875, 876, 3, 239, 117, 0, 876, 877, 3, 237, 116, 0, 877, 878, 3, 109, 52, 0, 878, 879, 3, 245, 120, 0, 879, 880, 3, 217, 106, 0, 880, 881, 3, 239, 117, 0, 881, 882, 3, 215, 105, 0, 882, 1232, 1, 0, 0, 0, 883, 884, 3, 207, 101, 0, 884, 885, 3, 201, 98, 0, 885, 886, 3, 239, 117, 0, 886, 887, 3, 209, 102, 0, 887, 888, 3, 109, 52, 0, 888, 889, 3, 211, 103, 0, 889, 890, 3, 229, 112, 0, 890, 891, 3, 235, 115, 0, 891, 892, 3, 225, 110, 0, 892, 893, 3, 201, 98, 0, 893, 894, 3, 239, 117, 0, 894, 1232, 1, 0, 0, 0, 895, 896, 3, 207, 101, 0, 896, 897, 3, 201, 98, 0, 897, 898, 3, 239, 117, 0, 898, 899, 3, 209, 102, 0, 899, 900, 3, 109, 52, 0, 900, 901, 3, 239, 117, 0, 901, 902, 3, 235, 115, 0, 902, 903, 3, 241, 118, 0, 903, 904, 3, 227, 111, 0, 904, 905, 3, 205, 100, 0, 905, 1232, 1, 0, 0, 0, 906, 907, 3, 207, 101, 0, 907, 908, 3, 201, 98, 0, 908, 909, 3, 239, 117, 0, 909, 910, 3, 209, 102, 0, 910, 911, 3, 109, 52, 0, 911, 912, 3, 231, 113, 0, 912, 913, 3, 201, 98, 0, 913, 914, 3, 235, 115, 0, 914, 915, 3, 237, 116, 0, 915, 916, 3, 209, 102, 0, 916, 1232, 1, 0, 0, 0, 917, 918, 3, 201, 98, 0, 918, 919, 3, 241, 118, 0, 919, 920, 3, 239, 117, 0, 920, 921, 3, 229, 112, 0, 921, 922, 3, 109, 52, 0, 922, 923, 3, 203, 99, 0, 923, 924, 3, 241, 118, 0, 924, 925, 3, 205, 100, 0, 925, 926, 3, 221, 108, 0, 926, 927, 3, 209, 102, 0, 927, 928, 3, 239, 117, 0, 928, 1232, 1, 0, 0, 0, 929, 930, 3, 207, 101, 0, 930, 931, 3, 201, 98, 0, 931, 932, 3, 239, 117, 0, 932, 933, 3, 209, 102, 0, 933, 934, 3, 109, 52, 0, 934, 935, 3, 209, 102, 0, 935, 936, 3, 247, 121, 0, 936, 937, 3, 239, 117, 0, 937, 938, 3, 235, 115, 0, 938, 939, 3, 201, 98, 0, 939, 940, 3, 205, 100, 0, 940, 941, 3, 239, 117, 0, 941, 1232, 1, 0, 0, 0, 942, 943, 3, 217, 106, 0, 943, 944, 3, 237, 116, 0, 944, 945, 3, 109, 52, 0, 945, 946, 3, 211, 103, 0, 946, 947, 3, 217, 106, 0, 947, 948, 3, 227, 111, 0, 948, 949, 3, 217, 106, 0, 949, 950, 3, 239, 117, 0, 950, 951, 3, 209, 102, 0, 951, 1232, 1, 0, 0, 0, 952, 953, 3, 217, 106, 0, 953, 954, 3, 237, 116, 0, 954, 955, 3, 109, 52, 0, 955, 956, 3, 217, 106, 0, 956, 957, 3, 227, 111, 0, 957, 958, 3, 211, 103, 0, 958, 959, 3, 217, 106, 0, 959, 960, 3, 227, 111, 0, 960, 961, 3, 217, 106, 0, 961, 962, 3, 239, 117, 0, 962, 963, 3, 209, 102, 0, 963, 1232, 1, 0, 0, 0, 964, 965, 3, 205, 100, 0, 965, 966, 3, 201, 98, 0, 966, 967, 3, 237, 116, 0, 967, 968, 3, 209, 102, 0, 968, 1232, 1, 0, 0, 0, 969, 970, 3, 223, 109, 0, 970, 971, 3, 209, 102, 0, 971, 972, 3, 227, 111, 0, 972, 973, 3, 213, 104, 0, 973, 974, 3, 239, 117, 0, 974, 975, 3, 215, 105, 0, 975, 1232, 1, 0, 0, 0, 976, 977, 3, 225, 110, 0, 977, 978, 3, 243, 119, 0, 978, 979, 3, 109, 52, 0, 979, 980, 3, 225, 110, 0, 980, 981, 3, 201, 98, 0, 981, 982, 3, 247, 121, 0, 982, 1232, 1, 0, 0, 0, 983, 984, 3, 225, 110, 0, 984, 985, 3, 243, 119, 0, 985, 986, 3, 109, 52, 0, 986, 987, 3, 225, 110, 0, 987, 988, 3, 217, 106, 0, 988, 989, 3, 227, 111, 0, 989, 1232, 1, 0, 0, 0, 990, 991, 3, 225, 110, 0, 991, 992, 3, 243, 119, 0, 992, 993, 3, 109, 52, 0, 993, 994, 3, 201, 98, 0, 994, 995, 3, 243, 119, 0, 995, 996, 3, 213, 104, 0, 996, 1232, 1, 0, 0, 0, 997, 998, 3, 225, 110, 0, 998, 999, 3, 243, 119, 0, 999, 1000, 3, 109, 52, 0, 1000, 1001, 3, 237, 116, 0, 1001, 1002, 3, 241, 118, 0, 1002, 1003, 3, 225, 110, 0, 1003, 1232, 1, 0, 0, 0, 1004, 1005, 3, 225, 110, 0, 1005, 1006, 3, 243, 119, 0, 1006, 1007, 3, 109, 52, 0, 1007, 1008, 3, 205, 100, 0, 1008, 1009, 3, 229, 112, 0, 1009, 1010, 3, 241, 118, 0, 1010, 1011, 3, 227, 111, 0, 1011, 1012, 3, 239, 117, 0, 1012, 1232, 1, 0, 0, 0, 1013, 1014, 3, 225, 110, 0, 1014, 1015, 3, 243, 119, 0, 1015, 1016, 3, 109, 52, 0, 1016, 1017, 3, 205, 100, 0, 1017, 1018, 3, 229, 112, 0, 1018, 1019, 3, 227, 111, 0, 1019, 1020, 3, 205, 100, 0, 1020, 1021, 3, 201, 98, 0, 1021, 1022, 3, 239, 117, 0, 1022, 1232, 1, 0, 0, 0, 1023, 1024, 3, 225, 110, 0, 1024, 1025, 3, 243, 119, 0, 1025, 1026, 3, 109, 52, 0, 1026, 1027, 3, 219, 107, 0, 1027, 1028, 3, 229, 112, 0, 1028, 1029, 3, 217, 106, 0, 1029, 1030, 3, 227, 111, 0, 1030, 1232, 1, 0, 0, 0, 1031, 1032, 3, 225, 110, 0, 1032, 1033, 3, 243, 119, 0, 1033, 1034, 3, 109, 52, 0, 1034, 1035, 3, 225, 110, 0, 1035, 1036, 3, 209, 102, 0, 1036, 1037, 3, 207, 101, 0, 1037, 1038, 3, 217, 106, 0, 1038, 1039, 3, 201, 98, 0, 1039, 1040, 3, 227, 111, 0, 1040, 1232, 1, 0, 0, 0, 1041, 1042, 3, 225, 110, 0, 1042, 1043, 3, 243, 119, 0, 1043, 1044, 3, 109, 52, 0, 1044, 1045, 3, 207, 101, 0, 1045, 1046, 3, 209, 102, 0, 1046, 1047, 3, 207, 101, 0, 1047, 1048, 3, 241, 118, 0, 1048, 1049, 3, 231, 113, 0, 1049, 1050, 3, 209, 102, 0, 1050, 1232, 1, 0, 0, 0, 1051, 1052, 3, 225, 110, 0, 1052, 1053, 3, 209, 102, 0, 1053, 1054, 3, 239, 117, 0, 1054, 1055, 3, 201, 98, 0, 1055, 1056, 3, 207, 101, 0, 1056, 1057, 3, 201, 98, 0, 1057, 1058, 3, 239, 117, 0, 1058, 1059, 3, 201, 98, 0, 1059, 1232, 1, 0, 0, 0, 1060, 1061, 3, 237, 116, 0, 1061, 1062, 3, 231, 113, 0, 1062, 1063, 3, 223, 109, 0, 1063, 1064, 3, 217, 106, 0, 1064, 1065, 3, 239, 117, 0, 1065, 1232, 1, 0, 0, 0, 1066, 1067, 3, 239, 117, 0, 1067, 1068, 3, 229, 112, 0, 1068, 1069, 3, 109, 52, 0, 1069, 1070, 3, 237, 116, 0, 1070, 1071, 3, 239, 117, 0, 1071, 1072, 3, 235, 115, 0, 1072, 1073, 3, 217, 106, 0, 1073, 1074, 3, 227, 111, 0, 1074, 1075, 3, 213, 104, 0, 1075, 1232, 1, 0, 0, 0, 1076, 1077, 3, 239, 117, 0, 1077, 1078, 3, 229, 112, 0, 1078, 1079, 3, 109, 52, 0, 1079, 1080, 3, 237, 116, 0, 1080, 1081, 3, 239, 117, 0, 1081, 1082, 3, 235, 115, 0, 1082, 1232, 1, 0, 0, 0, 1083, 1084, 3, 239, 117, 0, 1084, 1085, 3, 229, 112, 0, 1085, 1086, 3, 109, 52, 0, 1086, 1087, 3, 203, 99, 0, 1087, 1088, 3, 229, 112, 0, 1088, 1089, 3, 229, 112, 0, 1089, 1090, 3, 223, 109, 0, 1090, 1232, 1, 0, 0, 0, 1091, 1092, 3, 239, 117, 0, 1092, 1093, 3, 229, 112, 0, 1093, 1094, 3, 109, 52, 0, 1094, 1095, 3, 203, 99, 0, 1095, 1096, 3, 229, 112, 0, 1096, 1097, 3, 229, 112, 0, 1097, 1098, 3, 223, 109, 0, 1098, 1099, 3, 209, 102, 0, 1099, 1100, 3, 201, 98, 0, 1100, 1101, 3, 227, 111, 0, 1101, 1232, 1, 0, 0, 0, 1102, 1103, 3, 239, 117, 0, 1103, 1104, 3, 229, 112, 0, 1104, 1105, 3, 109, 52, 0, 1105, 1106, 3, 207, 101, 0, 1106, 1107, 3, 201, 98, 0, 1107, 1108, 3, 239, 117, 0, 1108, 1109, 3, 209, 102, 0, 1109, 1110, 3, 239, 117, 0, 1110, 1111, 3, 217, 106, 0, 1111, 1112, 3, 225, 110, 0, 1112, 1113, 3, 209, 102, 0, 1113, 1232, 1, 0, 0, 0, 1114, 1115, 3, 239, 117, 0, 1115, 1116, 3, 229, 112, 0, 1116, 1117, 3, 109, 52, 0, 1117, 1118, 3, 207, 101, 0, 1118, 1119, 3, 239, 117, 0, 1119, 1232, 1, 0, 0, 0, 1120, 1121, 3, 239, 117, 0, 1121, 1122, 3, 229, 112, 0, 1122, 1123, 3, 109, 52, 0, 1123, 1124, 3, 207, 101, 0, 1124, 1125, 3, 203, 99, 0, 1125, 1126, 3, 223, 109, 0, 1126, 1232, 1, 0, 0, 0, 1127, 1128, 3, 239, 117, 0, 1128, 1129, 3, 229, 112, 0, 1129, 1130, 3, 109, 52, 0, 1130, 1131, 3, 207, 101, 0, 1131, 1132, 3, 229, 112, 0, 1132, 1133, 3, 241, 118, 0, 1133, 1134, 3, 203, 99, 0, 1134, 1135, 3, 223, 109, 0, 1135, 1136, 3, 209, 102, 0, 1136, 1232, 1, 0, 0, 0, 1137, 1138, 3, 239, 117, 0, 1138, 1139, 3, 229, 112, 0, 1139, 1140, 3, 109, 52, 0, 1140, 1141, 3, 207, 101, 0, 1141, 1142, 3, 209, 102, 0, 1142, 1143, 3, 213, 104, 0, 1143, 1144, 3, 235, 115, 0, 1144, 1145, 3, 209, 102, 0, 1145, 1146, 3, 209, 102, 0, 1146, 1147, 3, 237, 116, 0, 1147, 1232, 1, 0, 0, 0, 1148, 1149, 3, 239, 117, 0, 1149, 1150, 3, 229, 112, 0, 1150, 1151, 3, 109, 52, 0, 1151, 1152, 3, 217, 106, 0, 1152, 1153, 3, 227, 111, 0, 1153, 1154, 3, 239, 117, 0, 1154, 1232, 1, 0, 0, 0, 1155, 1156, 3, 239, 117, 0, 1156, 1157, 3, 229, 112, 0, 1157, 1158, 3, 109, 52, 0, 1158, 1159, 3, 217, 106, 0, 1159, 1160, 3, 227, 111, 0, 1160, 1161, 3, 239, 117, 0, 1161, 1162, 3, 209, 102, 0, 1162, 1163, 3, 213, 104, 0, 1163, 1164, 3, 209, 102, 0, 1164, 1165, 3, 235, 115, 0, 1165, 1232, 1, 0, 0, 0, 1166, 1167, 3, 239, 117, 0, 1167, 1168, 3, 229, 112, 0, 1168, 1169, 3, 109, 52, 0, 1169, 1170, 3, 217, 106, 0, 1170, 1171, 3, 231, 113, 0, 1171, 1232, 1, 0, 0, 0, 1172, 1173, 3, 239, 117, 0, 1173, 1174, 3, 229, 112, 0, 1174, 1175, 3, 109, 52, 0, 1175, 1176, 3, 223, 109, 0, 1176, 1177, 3, 229, 112, 0, 1177, 1178, 3, 227, 111, 0, 1178, 1179, 3, 213, 104, 0, 1179, 1232, 1, 0, 0, 0, 1180, 1181, 3, 239, 117, 0, 1181, 1182, 3, 229, 112, 0, 1182, 1183, 3, 109, 52, 0, 1183, 1184, 3, 235, 115, 0, 1184, 1185, 3, 201, 98, 0, 1185, 1186, 3, 207, 101, 0, 1186, 1187, 3, 217, 106, 0, 1187, 1188, 3, 201, 98, 0, 1188, 1189, 3, 227, 111, 0, 1189, 1190, 3, 237, 116, 0, 1190, 1232, 1, 0, 0, 0, 1191, 1192, 3, 239, 117, 0, 1192, 1193, 3, 229, 112, 0, 1193, 1194, 3, 109, 52, 0, 1194, 1195, 3, 243, 119, 0, 1195, 1196, 3, 209, 102, 0, 1196, 1197, 3, 235, 115, 0, 1197, 1198, 3, 237, 116, 0, 1198, 1199, 3, 217, 106, 0, 1199, 1200, 3, 229, 112, 0, 1200, 1201, 3, 227, 111, 0, 1201, 1232, 1, 0, 0, 0, 1202, 1203, 3, 239, 117, 0, 1203, 1204, 3, 229, 112, 0, 1204, 1205, 3, 109, 52, 0, 1205, 1206, 3, 241, 118, 0, 1206, 1207, 3, 227, 111, 0, 1207, 1208, 3, 237, 116, 0, 1208, 1209, 3, 217, 106, 0, 1209, 1210, 3, 213, 104, 0, 1210, 1211, 3, 227, 111, 0, 1211, 1212, 3, 209, 102, 0, 1212, 1213, 3, 207, 101, 0, 1213, 1214, 3, 109, 52, 0, 1214, 1215, 3, 223, 109, 0, 1215, 1216, 3, 229, 112, 0, 1216, 1217, 3, 227, 111, 0, 1217, 1218, 3, 213, 104, 0, 1218, 1232, 1, 0, 0, 0, 1219, 1220, 3, 239, 117, 0, 1220, 1221, 3, 229, 112, 0, 1221, 1222, 3, 109, 52, 0, 1222, 1223, 3, 213, 104, 0, 1223, 1224, 3, 209, 102, 0, 1224, 1225, 3, 229, 112, 0, 1225, 1226, 3, 231, 113, 0, 1226, 1227, 3, 229, 112, 0, 1227, 1228, 3, 217, 106, 0, 1228, 1229, 3, 227, 111, 0, 1229, 1230, 3, 239, 117, 0, 1230, 1232, 1, 0, 0, 0, 1231, 789, 1, 0, 0, 0, 1231, 795, 1, 0, 0, 0, 1231, 799, 1, 0, 0, 0, 1231, 803, 1, 0, 0, 0, 1231, 808, 1, 0, 0, 0, 1231, 811, 1, 0, 0, 0, 1231, 815, 1, 0, 0, 0, 1231, 816, 1, 0, 0, 0, 1231, 826, 1, 0, 0, 0, 1231, 831, 1, 0, 0, 0, 1231, 838, 1, 0, 0, 0, 1231, 847, 1, 0, 0, 0, 1231, 856, 1, 0, 0, 0, 1231, 861, 1, 0, 0, 0, 1231, 865, 1, 0, 0, 0, 1231, 871, 1, 0, 0, 0, 1231, 883, 1, 0, 0, 0, 1231, 895, 1, 0, 0, 0, 1231, 906, 1, 0, 0, 0, 1231, 917, 1, 0, 0, 0, 1231, 929, 1, 0, 0, 0, 1231, 942, 1, 0, 0, 0, 1231, 952, 1, 0, 0, 0, 1231, 964, 1, 0, 0, 0, 1231, 969, 1, 0, 0, 0, 1231, 976, 1, 0, 0, 0, 1231, 983, 1, 0, 0, 0, 1231, 990, 1, 0, 0, 0, 1231, 997, 1, 0, 0, 0, 1231, 1004, 1, 0, 0, 0, 1231, 1013, 1, 0, 0, 0, 1231, 1023, 1, 0, 0, 0, 1231, 1031, 1, 0, 0, 0, 1231, 1041, 1, 0, 0, 0, 1231, 1051, 1, 0, 0, 0, 1231, 1060, 1, 0, 0, 0, 1231, 1066, 1, 0, 0, 0, 1231, 1076, 1, 0, 0, 0, 1231, 1083, 1, 0, 0, 0, 1231, 1091, 1, 0, 0, 0, 1231, 1102, 1, 0, 0, 0, 1231, 1114, 1, 0, 0, 0, 1231, 1120, 1, 0, 0, 0, 1231, 1127, 1, 0, 0, 0, 1231, 1137, 1, 0, 0, 0, 1231, 1148, 1, 0, 0, 0, 1231, 1155, 1, 0, 0, 0, 1231, 1166, 1, 0, 0, 0, 1231, 1172, 1, 0, 0, 0, 1231, 1180, 1, 0, 0, 0, 1231, 1191, 1, 0, 0, 0, 1231, 1202, 1, 0, 0, 0, 1231, 1219, 1, 0, 0, 0, 1232, 138, 1, 0, 0, 0, 1233, 1234, 3, 201, 98, 0, 1234, 1235, 3, 243, 119, 0, 1235, 1236, 3, 213, 104, 0, 1236, 1385, 1, 0, 0, 0, 1237, 1238, 3, 225, 110, 0, 1238, 1239, 3, 217, 106, 0, 1239, 1240, 3, 227, 111, 0, 1240, 1385, 1, 0, 0, 0, 1241, 1242, 3, 225, 110, 0, 1242, 1243, 3, 201, 98, 0, 1243, 1244, 3, 247, 121, 0, 1244, 1385, 1, 0, 0, 0, 1245, 1246, 3, 237, 116, 0, 1246, 1247, 3, 241, 118, 0, 1247, 1248, 3, 225, 110, 0, 1248, 1385, 1, 0, 0, 0, 1249, 1250, 3, 205, 100, 0, 1250, 1251, 3, 229, 112, 0, 1251, 1252, 3, 241, 118, 0, 1252, 1253, 3, 227, 111, 0, 1253, 1254, 3, 239, 117, 0, 1254, 1385, 1, 0, 0, 0, 1255, 1256, 3, 205, 100, 0, 1256, 1257, 3, 229, 112, 0, 1257, 1258, 3, 241, 118, 0, 1258, 1259, 3, 227, 111, 0, 1259, 1260, 3, 239, 117, 0, 1260, 1261, 3, 109, 52, 0, 1261, 1262, 3, 207, 101, 0, 1262, 1263, 3, 217, 106, 0, 1263, 1264, 3, 237, 116, 0, 1264, 1265, 3, 239, 117, 0, 1265, 1266, 3, 217, 106, 0, 1266, 1267, 3, 227, 111, 0, 1267, 1268, 3, 205, 100, 0, 1268, 1269, 3, 239, 117, 0, 1269, 1385, 1, 0, 0, 0, 1270, 1271, 3, 231, 113, 0, 1271, 1272, 3, 209, 102, 0, 1272, 1273, 3, 235, 115, 0, 1273, 1274, 3, 205, 100, 0, 1274, 1275, 3, 209, 102, 0, 1275, 1276, 3, 227, 111, 0, 1276, 1277, 3, 239, 117, 0, 1277, 1278, 3, 217, 106, 0, 1278, 1279, 3, 223, 109, 0, 1279, 1280, 3, 209, 102, 0, 1280, 1385, 1, 0, 0, 0, 1281, 1282, 3, 225, 110, 0, 1282, 1283, 3, 209, 102, 0, 1283, 1284, 3, 207, 101, 0, 1284, 1285, 3, 217, 106, 0, 1285, 1286, 3, 201, 98, 0, 1286, 1287, 3, 227, 111, 0, 1287, 1385, 1, 0, 0, 0, 1288, 1289, 3, 225, 110, 0, 1289, 1290, 3, 209, 102, 0, 1290, 1291, 3, 207, 101, 0, 1291, 1292, 3, 217, 106, 0, 1292, 1293, 3, 201, 98, 0, 1293, 1294, 3, 227, 111, 0, 1294, 1295, 3, 109, 52, 0, 1295, 1296, 3, 201, 98, 0, 1296, 1297, 3, 203, 99, 0, 1297, 1298, 3, 237, 116, 0, 1298, 1299, 3, 229, 112, 0, 1299, 1300, 3, 223, 109, 0, 1300, 1301, 3, 241, 118, 0, 1301, 1302, 3, 239, 117, 0, 1302, 1303, 3, 209, 102, 0, 1303, 1304, 3, 109, 52, 0, 1304, 1305, 3, 207, 101, 0, 1305, 1306, 3, 209, 102, 0, 1306, 1307, 3, 243, 119, 0, 1307, 1308, 3, 217, 106, 0, 1308, 1309, 3, 201, 98, 0, 1309, 1310, 3, 239, 117, 0, 1310, 1311, 3, 217, 106, 0, 1311, 1312, 3, 229, 112, 0, 1312, 1313, 3, 227, 111, 0, 1313, 1385, 1, 0, 0, 0, 1314, 1315, 3, 201, 98, 0, 1315, 1316, 3, 205, 100, 0, 1316, 1317, 3, 229, 112, 0, 1317, 1318, 3, 237, 116, 0, 1318, 1385, 1, 0, 0, 0, 1319, 1320, 3, 201, 98, 0, 1320, 1321, 3, 237, 116, 0, 1321, 1322, 3, 217, 106, 0, 1322, 1323, 3, 227, 111, 0, 1323, 1385, 1, 0, 0, 0, 1324, 1325, 3, 201, 98, 0, 1325, 1326, 3, 239, 117, 0, 1326, 1327, 3, 201, 98, 0, 1327, 1328, 3, 227, 111, 0, 1328, 1385, 1, 0, 0, 0, 1329, 1330, 3, 201, 98, 0, 1330, 1331, 3, 239, 117, 0, 1331, 1332, 3, 201, 98, 0, 1332, 1333, 3, 227, 111, 0, 1333, 1334, 5, 50, 0, 0, 1334, 1385, 1, 0, 0, 0, 1335, 1336, 3, 205, 100, 0, 1336, 1337, 3, 209, 102, 0, 1337, 1338, 3, 217, 106, 0, 1338, 1339, 3, 223, 109, 0, 1339, 1385, 1, 0, 0, 0, 1340, 1341, 3, 205, 100, 0, 1341, 1342, 3, 229, 112, 0, 1342, 1343, 3, 237, 116, 0, 1343, 1385, 1, 0, 0, 0, 1344, 1345, 3, 205, 100, 0, 1345, 1346, 3, 229, 112, 0, 1346, 1347, 3, 237, 116, 0, 1347, 1348, 3, 215, 105, 0, 1348, 1385, 1, 0, 0, 0, 1349, 1350, 3, 211, 103, 0, 1350, 1351, 3, 223, 109, 0, 1351, 1352, 3, 229, 112, 0, 1352, 1353, 3, 229, 112, 0, 1353, 1354, 3, 235, 115, 0, 1354, 1385, 1, 0, 0, 0, 1355, 1356, 3, 223, 109, 0, 1356, 1357, 3, 239, 117, 0, 1357, 1358, 3, 235, 115, 0, 1358, 1359, 3, 217, 106, 0, 1359, 1360, 3, 225, 110, 0, 1360, 1385, 1, 0, 0, 0, 1361, 1362, 3, 237, 116, 0, 1362, 1363, 3, 217, 106, 0, 1363, 1364, 3, 227, 111, 0, 1364, 1385, 1, 0, 0, 0, 1365, 1366, 3, 237, 116, 0, 1366, 1367, 3, 217, 106, 0, 1367, 1368, 3, 227, 111, 0, 1368, 1369, 3, 215, 105, 0, 1369, 1385, 1, 0, 0, 0, 1370, 1371, 3, 237, 116, 0, 1371, 1372, 3, 233, 114, 0, 1372, 1373, 3, 235, 115, 0, 1373, 1374, 3, 239, 117, 0, 1374, 1385, 1, 0, 0, 0, 1375, 1376, 3, 239, 117, 0, 1376, 1377, 3, 201, 98, 0, 1377, 1378, 3, 227, 111, 0, 1378, 1385, 1, 0, 0, 0, 1379, 1380, 3, 239, 117, 0, 1380, 1381, 3, 201, 98, 0, 1381, 1382, 3, 227, 111, 0, 1382, 1383, 3, 215, 105, 0, 1383, 1385, 1, 0, 0, 0, 1384, 1233, 1, 0, 0, 0, 1384, 1237, 1, 0, 0, 0, 1384, 1241, 1, 0, 0, 0, 1384, 1245, 1, 0, 0, 0, 1384, 1249, 1, 0, 0, 0, 1384, 1255, 1, 0, 0, 0, 1384, 1270, 1, 0, 0, 0, 1384, 1281, 1, 0, 0, 0, 1384, 1288, 1, 0, 0, 0, 1384, 1314, 1, 0, 0, 0, 1384, 1319, 1, 0, 0, 0, 1384, 1324, 1, 0, 0, 0, 1384, 1329, 1, 0, 0, 0, 1384, 1335, 1, 0, 0, 0, 1384, 1340, 1, 0, 0, 0, 1384, 1344, 1, 0, 0, 0, 1384, 1349, 1, 0, 0, 0, 1384, 1355, 1, 0, 0, 0, 1384, 1361, 1, 0, 0, 0, 1384, 1365, 1, 0, 0, 0, 1384, 1370, 1, 0, 0, 0, 1384, 1375, 1, 0, 0, 0, 1384, 1379, 1, 0, 0, 0, 1385, 140, 1, 0, 0, 0, 1386, 1387, 3, 205, 100, 0, 1387, 1388, 3, 217, 106, 0, 1388, 1389, 3, 207, 101, 0, 1389, 1390, 3, 235, 115, 0, 1390, 1391, 3, 109, 52, 0, 1391, 1392, 3, 225, 110, 0, 1392, 1393, 3, 201, 98, 0, 1393, 1394, 3, 239, 117, 0, 1394, 1395, 3, 205, 100, 0, 1395, 1396, 3, 215, 105, 0, 1396, 142, 1, 0, 0, 0, 1397, 1404, 3, 59, 27, 0, 1398, 1403, 3, 59, 27, 0, 1399, 1403, 3, 57, 26, 0, 1400, 1403, 5, 95, 0, 0, 1401, 1403, 3, 123, 59, 0, 1402, 1398, 1, 0, 0, 0, 1402, 1399, 1, 0, 0, 0, 1402, 1400, 1, 0, 0, 0, 1402, 1401, 1, 0, 0, 0, 1403, 1406, 1, 0, 0, 0, 1404, 1402, 1, 0, 0, 0, 1404, 1405, 1, 0, 0, 0, 1405, 1417, 1, 0, 0, 0, 1406, 1404, 1, 0, 0, 0, 1407, 1412, 7, 8, 0, 0, 1408, 1413, 3, 59, 27, 0, 1409, 1413, 3, 57, 26, 0, 1410, 1413, 5, 95, 0, 0, 1411, 1413, 3, 123, 59, 0, 1412, 1408, 1, 0, 0, 0, 1412, 1409, 1, 0, 0, 0, 1412, 1410, 1, 0, 0, 0, 1412, 1411, 1, 0, 0, 0, 1413, 1414, 1, 0, 0, 0, 1414, 1412, 1, 0, 0, 0, 1414, 1415, 1, 0, 0, 0, 1415, 1417, 1, 0, 0, 0, 1416, 1397, 1, 0, 0, 0, 1416, 1407, 1, 0, 0, 0, 1417, 144, 1, 0, 0, 0, 1418, 1424, 5, 96, 0, 0, 1419, 1423, 8, 9, 0, 0, 1420, 1421, 5, 96, 0, 0, 1421, 1423, 5, 96, 0, 0, 1422, 1419, 1, 0, 0, 0, 1422, 1420, 1, 0, 0, 0, 1423, 1426, 1, 0, 0, 0, 1424, 1422, 1, 0, 0, 0, 1424, 1425, 1, 0, 0, 0, 1425, 1427, 1, 0, 0, 0, 1426, 1424, 1, 0, 0, 0, 1427, 1428, 5, 96, 0, 0, 1428, 146, 1, 0, 0, 0, 1429, 1430, 3, 39, 17, 0, 1430, 1431, 1, 0, 0, 0, 1431, 1432, 6, 71, 4, 0, 1432, 148, 1, 0, 0, 0, 1433, 1434, 3, 41, 18, 0, 1434, 1435, 1, 0, 0, 0, 1435, 1436, 6, 72, 4, 0, 1436, 150, 1, 0, 0, 0, 1437, 1438, 3, 43, 19, 0, 1438, 1439, 1, 0, 0, 0, 1439, 1440, 6, 73, 4, 0, 1440, 152, 1, 0, 0, 0, 1441, 1442, 5, 124, 0, 0, 1442, 1443, 1, 0, 0, 0, 1443, 1444, 6, 74, 7, 0, 1444, 1445, 6, 74, 8, 0, 1445, 154, 1, 0, 0, 0, 1446, 1447, 5, 91, 0, 0, 1447, 1448, 1, 0, 0, 0, 1448, 1449, 6, 75, 5, 0, 1449, 1450, 6, 75, 2, 0, 1450, 1451, 6, 75, 2, 0, 1451, 156, 1, 0, 0, 0, 1452, 1453, 5, 93, 0, 0, 1453, 1454, 1, 0, 0, 0, 1454, 1455, 6, 76, 8, 0, 1455, 1456, 6, 76, 8, 0, 1456, 1457, 6, 76, 9, 0, 1457, 158, 1, 0, 0, 0, 1458, 1459, 5, 44, 0, 0, 1459, 1460, 1, 0, 0, 0, 1460, 1461, 6, 77, 10, 0, 1461, 160, 1, 0, 0, 0, 1462, 1463, 5, 61, 0, 0, 1463, 1464, 1, 0, 0, 0, 1464, 1465, 6, 78, 11, 0, 1465, 162, 1, 0, 0, 0, 1466, 1467, 3, 225, 110, 0, 1467, 1468, 3, 209, 102, 0, 1468, 1469, 3, 239, 117, 0, 1469, 1470, 3, 201, 98, 0, 1470, 1471, 3, 207, 101, 0, 1471, 1472, 3, 201, 98, 0, 1472, 1473, 3, 239, 117, 0, 1473, 1474, 3, 201, 98, 0, 1474, 164, 1, 0, 0, 0, 1475, 1477, 3, 167, 81, 0, 1476, 1475, 1, 0, 0, 0, 1477, 1478, 1, 0, 0, 0, 1478, 1476, 1, 0, 0, 0, 1478, 1479, 1, 0, 0, 0, 1479, 166, 1, 0, 0, 0, 1480, 1482, 8, 10, 0, 0, 1481, 1480, 1, 0, 0, 0, 1482, 1483, 1, 0, 0, 0, 1483, 1481, 1, 0, 0, 0, 1483, 1484, 1, 0, 0, 0, 1484, 1488, 1, 0, 0, 0, 1485, 1486, 5, 47, 0, 0, 1486, 1488, 8, 11, 0, 0, 1487, 1481, 1, 0, 0, 0, 1487, 1485, 1, 0, 0, 0, 1488, 168, 1, 0, 0, 0, 1489, 1490, 3, 145, 70, 0, 1490, 170, 1, 0, 0, 0, 1491, 1492, 3, 39, 17, 0, 1492, 1493, 1, 0, 0, 0, 1493, 1494, 6, 83, 4, 0, 1494, 172, 1, 0, 0, 0, 1495, 1496, 3, 41, 18, 0, 1496, 1497, 1, 0, 0, 0, 1497, 1498, 6, 84, 4, 0, 1498, 174, 1, 0, 0, 0, 1499, 1500, 3, 43, 19, 0, 1500, 1501, 1, 0, 0, 0, 1501, 1502, 6, 85, 4, 0, 1502, 176, 1, 0, 0, 0, 1503, 1504, 3, 229, 112, 0, 1504, 1505, 3, 227, 111, 0, 1505, 178, 1, 0, 0, 0, 1506, 1507, 3, 245, 120, 0, 1507, 1508, 3, 217, 106, 0, 1508, 1509, 3, 239, 117, 0, 1509, 1510, 3, 215, 105, 0, 1510, 180, 1, 0, 0, 0, 1511, 1512, 5, 124, 0, 0, 1512, 1513, 1, 0, 0, 0, 1513, 1514, 6, 88, 7, 0, 1514, 1515, 6, 88, 8, 0, 1515, 182, 1, 0, 0, 0, 1516, 1517, 5, 93, 0, 0, 1517, 1518, 1, 0, 0, 0, 1518, 1519, 6, 89, 8, 0, 1519, 1520, 6, 89, 8, 0, 1520, 1521, 6, 89, 9, 0, 1521, 184, 1, 0, 0, 0, 1522, 1523, 5, 44, 0, 0, 1523, 1524, 1, 0, 0, 0, 1524, 1525, 6, 90, 10, 0, 1525, 186, 1, 0, 0, 0, 1526, 1527, 5, 61, 0, 0, 1527, 1528, 1, 0, 0, 0, 1528, 1529, 6, 91, 11, 0, 1529, 188, 1, 0, 0, 0, 1530, 1532, 3, 191, 93, 0, 1531, 1530, 1, 0, 0, 0, 1532, 1533, 1, 0, 0, 0, 1533, 1531, 1, 0, 0, 0, 1533, 1534, 1, 0, 0, 0, 1534, 190, 1, 0, 0, 0, 1535, 1537, 8, 10, 0, 0, 1536, 1535, 1, 0, 0, 0, 1537, 1538, 1, 0, 0, 0, 1538, 1536, 1, 0, 0, 0, 1538, 1539, 1, 0, 0, 0, 1539, 1543, 1, 0, 0, 0, 1540, 1541, 5, 47, 0, 0, 1541, 1543, 8, 11, 0, 0, 1542, 1536, 1, 0, 0, 0, 1542, 1540, 1, 0, 0, 0, 1543, 192, 1, 0, 0, 0, 1544, 1545, 3, 145, 70, 0, 1545, 194, 1, 0, 0, 0, 1546, 1547, 3, 39, 17, 0, 1547, 1548, 1, 0, 0, 0, 1548, 1549, 6, 95, 4, 0, 1549, 196, 1, 0, 0, 0, 1550, 1551, 3, 41, 18, 0, 1551, 1552, 1, 0, 0, 0, 1552, 1553, 6, 96, 4, 0, 1553, 198, 1, 0, 0, 0, 1554, 1555, 3, 43, 19, 0, 1555, 1556, 1, 0, 0, 0, 1556, 1557, 6, 97, 4, 0, 1557, 200, 1, 0, 0, 0, 1558, 1559, 7, 12, 0, 0, 1559, 202, 1, 0, 0, 0, 1560, 1561, 7, 13, 0, 0, 1561, 204, 1, 0, 0, 0, 1562, 1563, 7, 14, 0, 0, 1563, 206, 1, 0, 0, 0, 1564, 1565, 7, 15, 0, 0, 1565, 208, 1, 0, 0, 0, 1566, 1567, 7, 6, 0, 0, 1567, 210, 1, 0, 0, 0, 1568, 1569, 7, 16, 0, 0, 1569, 212, 1, 0, 0, 0, 1570, 1571, 7, 17, 0, 0, 1571, 214, 1, 0, 0, 0, 1572, 1573, 7, 18, 0, 0, 1573, 216, 1, 0, 0, 0, 1574, 1575, 7, 19, 0, 0, 1575, 218, 1, 0, 0, 0, 1576, 1577, 7, 20, 0, 0, 1577, 220, 1, 0, 0, 0, 1578, 1579, 7, 21, 0, 0, 1579, 222, 1, 0, 0, 0, 1580, 1581, 7, 22, 0, 0, 1581, 224, 1, 0, 0, 0, 1582, 1583, 7, 23, 0, 0, 1583, 226, 1, 0, 0, 0, 1584, 1585, 7, 24, 0, 0, 1585, 228, 1, 0, 0, 0, 1586, 1587, 7, 25, 0, 0, 1587, 230, 1, 0, 0, 0, 1588, 1589, 7, 26, 0, 0, 1589, 232, 1, 0, 0, 0, 1590, 1591, 7, 27, 0, 0, 1591, 234, 1, 0, 0, 0, 1592, 1593, 7, 28, 0, 0, 1593, 236, 1, 0, 0, 0, 1594, 1595, 7, 29, 0, 0, 1595, 238, 1, 0, 0, 0, 1596, 1597, 7, 30, 0, 0, 1597, 240, 1, 0, 0, 0, 1598, 1599, 7, 31, 0, 0, 1599, 242, 1, 0, 0, 0, 1600, 1601, 7, 32, 0, 0, 1601, 244, 1, 0, 0, 0, 1602, 1603, 7, 33, 0, 0, 1603, 246, 1, 0, 0, 0, 1604, 1605, 7, 34, 0, 0, 1605, 248, 1, 0, 0, 0, 1606, 1607, 7, 35, 0, 0, 1607, 250, 1, 0, 0, 0, 1608, 1609, 7, 36, 0, 0, 1609, 252, 1, 0, 0, 0, 48, 0, 1, 2, 3, 4, 398, 402, 405, 414, 416, 427, 468, 473, 478, 480, 491, 499, 502, 504, 509, 514, 520, 527, 532, 538, 541, 549, 553, 652, 736, 748, 770, 787, 1231, 1384, 1402, 1404, 1412, 1414, 1416, 1422, 1424, 1478, 1483, 1487, 1533, 1538, 1542, 12, 5, 2, 0, 5, 1, 0, 5, 3, 0, 5, 4, 0, 0, 1, 0, 7, 35, 0, 5, 0, 0, 7, 24, 0, 4, 0, 0, 7, 36, 0, 7, 32, 0, 7, 31, 0] \ No newline at end of file diff --git a/packages/kbn-esql/src/antlr/.antlr/esql_lexer.java b/packages/kbn-esql/src/antlr/.antlr/esql_lexer.java new file mode 100644 index 00000000000000..ac37718a22bcc3 --- /dev/null +++ b/packages/kbn-esql/src/antlr/.antlr/esql_lexer.java @@ -0,0 +1,1150 @@ +// Generated from /Users/marcoliberati/Work/kibana/packages/kbn-monaco/src/esql/antlr/esql_lexer.g4 by ANTLR 4.13.1 +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"}) +public class esql_lexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + DISSECT=1, GROK=2, EVAL=3, EXPLAIN=4, FROM=5, ROW=6, STATS=7, WHERE=8, + SORT=9, MV_EXPAND=10, LIMIT=11, PROJECT=12, DROP=13, RENAME=14, SHOW=15, + ENRICH=16, KEEP=17, LINE_COMMENT=18, MULTILINE_COMMENT=19, WS=20, EXPLAIN_WS=21, + EXPLAIN_LINE_COMMENT=22, EXPLAIN_MULTILINE_COMMENT=23, PIPE=24, STRING=25, + INTEGER_LITERAL=26, DECIMAL_LITERAL=27, BY=28, DATE_LITERAL=29, AND=30, + ASSIGN=31, COMMA=32, DOT=33, LP=34, OPENING_BRACKET=35, CLOSING_BRACKET=36, + NOT=37, LIKE=38, RLIKE=39, IN=40, IS=41, AS=42, NULL=43, OR=44, RP=45, + UNDERSCORE=46, INFO=47, FUNCTIONS=48, BOOLEAN_VALUE=49, COMPARISON_OPERATOR=50, + PLUS=51, MINUS=52, ASTERISK=53, SLASH=54, PERCENT=55, TEN=56, ORDERING=57, + NULLS_ORDERING=58, NULLS_ORDERING_DIRECTION=59, MATH_FUNCTION=60, UNARY_FUNCTION=61, + WHERE_FUNCTIONS=62, UNQUOTED_IDENTIFIER=63, QUOTED_IDENTIFIER=64, EXPR_LINE_COMMENT=65, + EXPR_MULTILINE_COMMENT=66, EXPR_WS=67, METADATA=68, SRC_UNQUOTED_IDENTIFIER=69, + SRC_QUOTED_IDENTIFIER=70, SRC_LINE_COMMENT=71, SRC_MULTILINE_COMMENT=72, + SRC_WS=73, ON=74, WITH=75, ENR_UNQUOTED_IDENTIFIER=76, ENR_QUOTED_IDENTIFIER=77, + ENR_LINE_COMMENT=78, ENR_MULTILINE_COMMENT=79, ENR_WS=80, EXPLAIN_PIPE=81; + public static final int + EXPLAIN_MODE=1, EXPRESSION=2, SOURCE_IDENTIFIERS=3, ENRICH_IDENTIFIERS=4; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE", "EXPLAIN_MODE", "EXPRESSION", "SOURCE_IDENTIFIERS", "ENRICH_IDENTIFIERS" + }; + + private static String[] makeRuleNames() { + return new String[] { + "DISSECT", "GROK", "EVAL", "EXPLAIN", "FROM", "ROW", "STATS", "WHERE", + "SORT", "MV_EXPAND", "LIMIT", "PROJECT", "DROP", "RENAME", "SHOW", "ENRICH", + "KEEP", "LINE_COMMENT", "MULTILINE_COMMENT", "WS", "EXPLAIN_OPENING_BRACKET", + "EXPLAIN_PIPE", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", "EXPLAIN_MULTILINE_COMMENT", + "PIPE", "DIGIT", "LETTER", "ESCAPE_SEQUENCE", "UNESCAPED_CHARS", "EXPONENT", + "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "DATE_LITERAL", + "AND", "ASSIGN", "COMMA", "DOT", "LP", "OPENING_BRACKET", "CLOSING_BRACKET", + "NOT", "LIKE", "RLIKE", "IN", "IS", "AS", "NULL", "OR", "RP", "UNDERSCORE", + "INFO", "FUNCTIONS", "BOOLEAN_VALUE", "COMPARISON_OPERATOR", "PLUS", + "MINUS", "ASTERISK", "SLASH", "PERCENT", "TEN", "ORDERING", "NULLS_ORDERING", + "NULLS_ORDERING_DIRECTION", "MATH_FUNCTION", "UNARY_FUNCTION", "WHERE_FUNCTIONS", + "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", + "EXPR_WS", "SRC_PIPE", "SRC_OPENING_BRACKET", "SRC_CLOSING_BRACKET", + "SRC_COMMA", "SRC_ASSIGN", "METADATA", "SRC_UNQUOTED_IDENTIFIER", "SRC_UNQUOTED_IDENTIFIER_PART", + "SRC_QUOTED_IDENTIFIER", "SRC_LINE_COMMENT", "SRC_MULTILINE_COMMENT", + "SRC_WS", "ON", "WITH", "ENR_PIPE", "ENR_CLOSING_BRACKET", "ENR_COMMA", + "ENR_ASSIGN", "ENR_UNQUOTED_IDENTIFIER", "ENR_UNQUOTED_IDENTIFIER_PART", + "ENR_QUOTED_IDENTIFIER", "ENR_LINE_COMMENT", "ENR_MULTILINE_COMMENT", + "ENR_WS", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", + "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, "'by'", null, "'and'", null, null, "'.'", "'('", + null, "']'", null, null, null, null, null, null, null, "'or'", "')'", + "'_'", "'info'", "'functions'", null, null, "'+'", "'-'", "'*'", "'/'", + "'%'", "'10'", null, "'nulls'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "DISSECT", "GROK", "EVAL", "EXPLAIN", "FROM", "ROW", "STATS", "WHERE", + "SORT", "MV_EXPAND", "LIMIT", "PROJECT", "DROP", "RENAME", "SHOW", "ENRICH", + "KEEP", "LINE_COMMENT", "MULTILINE_COMMENT", "WS", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", + "EXPLAIN_MULTILINE_COMMENT", "PIPE", "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", + "BY", "DATE_LITERAL", "AND", "ASSIGN", "COMMA", "DOT", "LP", "OPENING_BRACKET", + "CLOSING_BRACKET", "NOT", "LIKE", "RLIKE", "IN", "IS", "AS", "NULL", + "OR", "RP", "UNDERSCORE", "INFO", "FUNCTIONS", "BOOLEAN_VALUE", "COMPARISON_OPERATOR", + "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT", "TEN", "ORDERING", "NULLS_ORDERING", + "NULLS_ORDERING_DIRECTION", "MATH_FUNCTION", "UNARY_FUNCTION", "WHERE_FUNCTIONS", + "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", + "EXPR_WS", "METADATA", "SRC_UNQUOTED_IDENTIFIER", "SRC_QUOTED_IDENTIFIER", + "SRC_LINE_COMMENT", "SRC_MULTILINE_COMMENT", "SRC_WS", "ON", "WITH", + "ENR_UNQUOTED_IDENTIFIER", "ENR_QUOTED_IDENTIFIER", "ENR_LINE_COMMENT", + "ENR_MULTILINE_COMMENT", "ENR_WS", "EXPLAIN_PIPE" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public esql_lexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "esql_lexer.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + public static final String _serializedATN = + "\u0004\u0000Q\u064a\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff"+ + "\u0006\uffff\uffff\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002\u0001"+ + "\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004"+ + "\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007"+ + "\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b"+ + "\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0002"+ + "\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011\u0002"+ + "\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014\u0002"+ + "\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017\u0002"+ + "\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a\u0002"+ + "\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d\u0002"+ + "\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!\u0007"+ + "!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002&\u0007"+ + "&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002+\u0007"+ + "+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002/\u0007/\u00020\u0007"+ + "0\u00021\u00071\u00022\u00072\u00023\u00073\u00024\u00074\u00025\u0007"+ + "5\u00026\u00076\u00027\u00077\u00028\u00078\u00029\u00079\u0002:\u0007"+ + ":\u0002;\u0007;\u0002<\u0007<\u0002=\u0007=\u0002>\u0007>\u0002?\u0007"+ + "?\u0002@\u0007@\u0002A\u0007A\u0002B\u0007B\u0002C\u0007C\u0002D\u0007"+ + "D\u0002E\u0007E\u0002F\u0007F\u0002G\u0007G\u0002H\u0007H\u0002I\u0007"+ + "I\u0002J\u0007J\u0002K\u0007K\u0002L\u0007L\u0002M\u0007M\u0002N\u0007"+ + "N\u0002O\u0007O\u0002P\u0007P\u0002Q\u0007Q\u0002R\u0007R\u0002S\u0007"+ + "S\u0002T\u0007T\u0002U\u0007U\u0002V\u0007V\u0002W\u0007W\u0002X\u0007"+ + "X\u0002Y\u0007Y\u0002Z\u0007Z\u0002[\u0007[\u0002\\\u0007\\\u0002]\u0007"+ + "]\u0002^\u0007^\u0002_\u0007_\u0002`\u0007`\u0002a\u0007a\u0002b\u0007"+ + "b\u0002c\u0007c\u0002d\u0007d\u0002e\u0007e\u0002f\u0007f\u0002g\u0007"+ + "g\u0002h\u0007h\u0002i\u0007i\u0002j\u0007j\u0002k\u0007k\u0002l\u0007"+ + "l\u0002m\u0007m\u0002n\u0007n\u0002o\u0007o\u0002p\u0007p\u0002q\u0007"+ + "q\u0002r\u0007r\u0002s\u0007s\u0002t\u0007t\u0002u\u0007u\u0002v\u0007"+ + "v\u0002w\u0007w\u0002x\u0007x\u0002y\u0007y\u0002z\u0007z\u0002{\u0007"+ + "{\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000"+ + "\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002"+ + "\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002"+ + "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+ + "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004"+ + "\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0005"+ + "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0006"+ + "\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+ + "\u0001\u0006\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+ + "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\b\u0001\b\u0001\b\u0001\b\u0001"+ + "\b\u0001\b\u0001\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001"+ + "\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\n\u0001\n\u0001\n\u0001"+ + "\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b"+ + "\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+ + "\u0001\u000b\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001"+ + "\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001"+ + "\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001"+ + "\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001"+ + "\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0001"+ + "\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0011\u0001"+ + "\u0011\u0001\u0011\u0001\u0011\u0005\u0011\u018d\b\u0011\n\u0011\f\u0011"+ + "\u0190\t\u0011\u0001\u0011\u0003\u0011\u0193\b\u0011\u0001\u0011\u0003"+ + "\u0011\u0196\b\u0011\u0001\u0011\u0001\u0011\u0001\u0012\u0001\u0012\u0001"+ + "\u0012\u0001\u0012\u0001\u0012\u0005\u0012\u019f\b\u0012\n\u0012\f\u0012"+ + "\u01a2\t\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012"+ + "\u0001\u0013\u0004\u0013\u01aa\b\u0013\u000b\u0013\f\u0013\u01ab\u0001"+ + "\u0013\u0001\u0013\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001"+ + "\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001"+ + "\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0017\u0001\u0017\u0001"+ + "\u0017\u0001\u0017\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001"+ + "\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u001a\u0001\u001a\u0001"+ + "\u001b\u0001\u001b\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001d\u0001"+ + "\u001d\u0001\u001e\u0001\u001e\u0003\u001e\u01d5\b\u001e\u0001\u001e\u0004"+ + "\u001e\u01d8\b\u001e\u000b\u001e\f\u001e\u01d9\u0001\u001f\u0001\u001f"+ + "\u0001\u001f\u0005\u001f\u01df\b\u001f\n\u001f\f\u001f\u01e2\t\u001f\u0001"+ + "\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0005"+ + "\u001f\u01ea\b\u001f\n\u001f\f\u001f\u01ed\t\u001f\u0001\u001f\u0001\u001f"+ + "\u0001\u001f\u0001\u001f\u0001\u001f\u0003\u001f\u01f4\b\u001f\u0001\u001f"+ + "\u0003\u001f\u01f7\b\u001f\u0003\u001f\u01f9\b\u001f\u0001 \u0004 \u01fc"+ + "\b \u000b \f \u01fd\u0001!\u0004!\u0201\b!\u000b!\f!\u0202\u0001!\u0001"+ + "!\u0005!\u0207\b!\n!\f!\u020a\t!\u0001!\u0001!\u0004!\u020e\b!\u000b!"+ + "\f!\u020f\u0001!\u0004!\u0213\b!\u000b!\f!\u0214\u0001!\u0001!\u0005!"+ + "\u0219\b!\n!\f!\u021c\t!\u0003!\u021e\b!\u0001!\u0001!\u0001!\u0001!\u0004"+ + "!\u0224\b!\u000b!\f!\u0225\u0001!\u0001!\u0003!\u022a\b!\u0001\"\u0001"+ + "\"\u0001\"\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001"+ + "#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001"+ + "#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001"+ + "#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001"+ + "#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001"+ + "#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001"+ + "#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001"+ + "#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001"+ + "#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001#\u0001"+ + "#\u0001#\u0001#\u0001#\u0001#\u0001#\u0003#\u028d\b#\u0001$\u0001$\u0001"+ + "$\u0001$\u0001%\u0001%\u0001&\u0001&\u0001\'\u0001\'\u0001(\u0001(\u0001"+ + ")\u0001)\u0001)\u0001)\u0001)\u0001*\u0001*\u0001*\u0001*\u0001*\u0001"+ + "+\u0001+\u0001+\u0001+\u0001,\u0001,\u0001,\u0001,\u0001,\u0001-\u0001"+ + "-\u0001-\u0001-\u0001-\u0001-\u0001.\u0001.\u0001.\u0001/\u0001/\u0001"+ + "/\u00010\u00010\u00010\u00011\u00011\u00011\u00011\u00011\u00012\u0001"+ + "2\u00012\u00013\u00013\u00014\u00014\u00015\u00015\u00015\u00015\u0001"+ + "5\u00016\u00016\u00016\u00016\u00016\u00016\u00016\u00016\u00016\u0001"+ + "6\u00017\u00017\u00017\u00017\u00017\u00017\u00017\u00017\u00017\u0003"+ + "7\u02e1\b7\u00018\u00018\u00018\u00018\u00018\u00018\u00018\u00018\u0001"+ + "8\u00018\u00038\u02ed\b8\u00019\u00019\u0001:\u0001:\u0001;\u0001;\u0001"+ + "<\u0001<\u0001=\u0001=\u0001>\u0001>\u0001>\u0001?\u0001?\u0001?\u0001"+ + "?\u0001?\u0001?\u0001?\u0003?\u0303\b?\u0001@\u0001@\u0001@\u0001@\u0001"+ + "@\u0001@\u0001A\u0001A\u0001A\u0001A\u0001A\u0001A\u0001A\u0001A\u0001"+ + "A\u0003A\u0314\bA\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0001"+ + "B\u0001B\u0001B\u0001B\u0001B\u0003B\u04d0\bB\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0001C\u0003C\u0569\bC\u0001"+ + "D\u0001D\u0001D\u0001D\u0001D\u0001D\u0001D\u0001D\u0001D\u0001D\u0001"+ + "D\u0001E\u0001E\u0001E\u0001E\u0001E\u0005E\u057b\bE\nE\fE\u057e\tE\u0001"+ + "E\u0001E\u0001E\u0001E\u0001E\u0004E\u0585\bE\u000bE\fE\u0586\u0003E\u0589"+ + "\bE\u0001F\u0001F\u0001F\u0001F\u0005F\u058f\bF\nF\fF\u0592\tF\u0001F"+ + "\u0001F\u0001G\u0001G\u0001G\u0001G\u0001H\u0001H\u0001H\u0001H\u0001"+ + "I\u0001I\u0001I\u0001I\u0001J\u0001J\u0001J\u0001J\u0001J\u0001K\u0001"+ + "K\u0001K\u0001K\u0001K\u0001K\u0001L\u0001L\u0001L\u0001L\u0001L\u0001"+ + "L\u0001M\u0001M\u0001M\u0001M\u0001N\u0001N\u0001N\u0001N\u0001O\u0001"+ + "O\u0001O\u0001O\u0001O\u0001O\u0001O\u0001O\u0001O\u0001P\u0004P\u05c5"+ + "\bP\u000bP\fP\u05c6\u0001Q\u0004Q\u05ca\bQ\u000bQ\fQ\u05cb\u0001Q\u0001"+ + "Q\u0003Q\u05d0\bQ\u0001R\u0001R\u0001S\u0001S\u0001S\u0001S\u0001T\u0001"+ + "T\u0001T\u0001T\u0001U\u0001U\u0001U\u0001U\u0001V\u0001V\u0001V\u0001"+ + "W\u0001W\u0001W\u0001W\u0001W\u0001X\u0001X\u0001X\u0001X\u0001X\u0001"+ + "Y\u0001Y\u0001Y\u0001Y\u0001Y\u0001Y\u0001Z\u0001Z\u0001Z\u0001Z\u0001"+ + "[\u0001[\u0001[\u0001[\u0001\\\u0004\\\u05fc\b\\\u000b\\\f\\\u05fd\u0001"+ + "]\u0004]\u0601\b]\u000b]\f]\u0602\u0001]\u0001]\u0003]\u0607\b]\u0001"+ + "^\u0001^\u0001_\u0001_\u0001_\u0001_\u0001`\u0001`\u0001`\u0001`\u0001"+ + "a\u0001a\u0001a\u0001a\u0001b\u0001b\u0001c\u0001c\u0001d\u0001d\u0001"+ + "e\u0001e\u0001f\u0001f\u0001g\u0001g\u0001h\u0001h\u0001i\u0001i\u0001"+ + "j\u0001j\u0001k\u0001k\u0001l\u0001l\u0001m\u0001m\u0001n\u0001n\u0001"+ + "o\u0001o\u0001p\u0001p\u0001q\u0001q\u0001r\u0001r\u0001s\u0001s\u0001"+ + "t\u0001t\u0001u\u0001u\u0001v\u0001v\u0001w\u0001w\u0001x\u0001x\u0001"+ + "y\u0001y\u0001z\u0001z\u0001{\u0001{\u0002\u01a0\u01eb\u0000|\u0005\u0001"+ + "\u0007\u0002\t\u0003\u000b\u0004\r\u0005\u000f\u0006\u0011\u0007\u0013"+ + "\b\u0015\t\u0017\n\u0019\u000b\u001b\f\u001d\r\u001f\u000e!\u000f#\u0010"+ + "%\u0011\'\u0012)\u0013+\u0014-\u0000/Q1\u00153\u00165\u00177\u00189\u0000"+ + ";\u0000=\u0000?\u0000A\u0000C\u0019E\u001aG\u001bI\u001cK\u001dM\u001e"+ + "O\u001fQ S!U\"W#Y$[%]&_\'a(c)e*g+i,k-m.o/q0s1u2w3y4{5}6\u007f7\u00818"+ + "\u00839\u0085:\u0087;\u0089<\u008b=\u008d>\u008f?\u0091@\u0093A\u0095"+ + "B\u0097C\u0099\u0000\u009b\u0000\u009d\u0000\u009f\u0000\u00a1\u0000\u00a3"+ + "D\u00a5E\u00a7\u0000\u00a9F\u00abG\u00adH\u00afI\u00b1J\u00b3K\u00b5\u0000"+ + "\u00b7\u0000\u00b9\u0000\u00bb\u0000\u00bdL\u00bf\u0000\u00c1M\u00c3N"+ + "\u00c5O\u00c7P\u00c9\u0000\u00cb\u0000\u00cd\u0000\u00cf\u0000\u00d1\u0000"+ + "\u00d3\u0000\u00d5\u0000\u00d7\u0000\u00d9\u0000\u00db\u0000\u00dd\u0000"+ + "\u00df\u0000\u00e1\u0000\u00e3\u0000\u00e5\u0000\u00e7\u0000\u00e9\u0000"+ + "\u00eb\u0000\u00ed\u0000\u00ef\u0000\u00f1\u0000\u00f3\u0000\u00f5\u0000"+ + "\u00f7\u0000\u00f9\u0000\u00fb\u0000\u0005\u0000\u0001\u0002\u0003\u0004"+ + "%\u0002\u0000\n\n\r\r\u0003\u0000\t\n\r\r \u0001\u000009\u0002\u0000"+ + "AZaz\u0005\u0000\"\"\\\\nnrrtt\u0004\u0000\n\n\r\r\"\"\\\\\u0002\u0000"+ + "EEee\u0002\u0000++--\u0002\u0000@@__\u0001\u0000``\n\u0000\t\n\r\r ,"+ + ",//==[[]]``||\u0002\u0000**//\u0002\u0000AAaa\u0002\u0000BBbb\u0002\u0000"+ + "CCcc\u0002\u0000DDdd\u0002\u0000FFff\u0002\u0000GGgg\u0002\u0000HHhh\u0002"+ + "\u0000IIii\u0002\u0000JJjj\u0002\u0000KKkk\u0002\u0000LLll\u0002\u0000"+ + "MMmm\u0002\u0000NNnn\u0002\u0000OOoo\u0002\u0000PPpp\u0002\u0000QQqq\u0002"+ + "\u0000RRrr\u0002\u0000SSss\u0002\u0000TTtt\u0002\u0000UUuu\u0002\u0000"+ + "VVvv\u0002\u0000WWww\u0002\u0000XXxx\u0002\u0000YYyy\u0002\u0000ZZzz\u06af"+ + "\u0000\u0005\u0001\u0000\u0000\u0000\u0000\u0007\u0001\u0000\u0000\u0000"+ + "\u0000\t\u0001\u0000\u0000\u0000\u0000\u000b\u0001\u0000\u0000\u0000\u0000"+ + "\r\u0001\u0000\u0000\u0000\u0000\u000f\u0001\u0000\u0000\u0000\u0000\u0011"+ + "\u0001\u0000\u0000\u0000\u0000\u0013\u0001\u0000\u0000\u0000\u0000\u0015"+ + "\u0001\u0000\u0000\u0000\u0000\u0017\u0001\u0000\u0000\u0000\u0000\u0019"+ + "\u0001\u0000\u0000\u0000\u0000\u001b\u0001\u0000\u0000\u0000\u0000\u001d"+ + "\u0001\u0000\u0000\u0000\u0000\u001f\u0001\u0000\u0000\u0000\u0000!\u0001"+ + "\u0000\u0000\u0000\u0000#\u0001\u0000\u0000\u0000\u0000%\u0001\u0000\u0000"+ + "\u0000\u0000\'\u0001\u0000\u0000\u0000\u0000)\u0001\u0000\u0000\u0000"+ + "\u0000+\u0001\u0000\u0000\u0000\u0001-\u0001\u0000\u0000\u0000\u0001/"+ + "\u0001\u0000\u0000\u0000\u00011\u0001\u0000\u0000\u0000\u00013\u0001\u0000"+ + "\u0000\u0000\u00015\u0001\u0000\u0000\u0000\u00027\u0001\u0000\u0000\u0000"+ + "\u0002C\u0001\u0000\u0000\u0000\u0002E\u0001\u0000\u0000\u0000\u0002G"+ + "\u0001\u0000\u0000\u0000\u0002I\u0001\u0000\u0000\u0000\u0002K\u0001\u0000"+ + "\u0000\u0000\u0002M\u0001\u0000\u0000\u0000\u0002O\u0001\u0000\u0000\u0000"+ + "\u0002Q\u0001\u0000\u0000\u0000\u0002S\u0001\u0000\u0000\u0000\u0002U"+ + "\u0001\u0000\u0000\u0000\u0002W\u0001\u0000\u0000\u0000\u0002Y\u0001\u0000"+ + "\u0000\u0000\u0002[\u0001\u0000\u0000\u0000\u0002]\u0001\u0000\u0000\u0000"+ + "\u0002_\u0001\u0000\u0000\u0000\u0002a\u0001\u0000\u0000\u0000\u0002c"+ + "\u0001\u0000\u0000\u0000\u0002e\u0001\u0000\u0000\u0000\u0002g\u0001\u0000"+ + "\u0000\u0000\u0002i\u0001\u0000\u0000\u0000\u0002k\u0001\u0000\u0000\u0000"+ + "\u0002m\u0001\u0000\u0000\u0000\u0002o\u0001\u0000\u0000\u0000\u0002q"+ + "\u0001\u0000\u0000\u0000\u0002s\u0001\u0000\u0000\u0000\u0002u\u0001\u0000"+ + "\u0000\u0000\u0002w\u0001\u0000\u0000\u0000\u0002y\u0001\u0000\u0000\u0000"+ + "\u0002{\u0001\u0000\u0000\u0000\u0002}\u0001\u0000\u0000\u0000\u0002\u007f"+ + "\u0001\u0000\u0000\u0000\u0002\u0081\u0001\u0000\u0000\u0000\u0002\u0083"+ + "\u0001\u0000\u0000\u0000\u0002\u0085\u0001\u0000\u0000\u0000\u0002\u0087"+ + "\u0001\u0000\u0000\u0000\u0002\u0089\u0001\u0000\u0000\u0000\u0002\u008b"+ + "\u0001\u0000\u0000\u0000\u0002\u008d\u0001\u0000\u0000\u0000\u0002\u008f"+ + "\u0001\u0000\u0000\u0000\u0002\u0091\u0001\u0000\u0000\u0000\u0002\u0093"+ + "\u0001\u0000\u0000\u0000\u0002\u0095\u0001\u0000\u0000\u0000\u0002\u0097"+ + "\u0001\u0000\u0000\u0000\u0003\u0099\u0001\u0000\u0000\u0000\u0003\u009b"+ + "\u0001\u0000\u0000\u0000\u0003\u009d\u0001\u0000\u0000\u0000\u0003\u009f"+ + "\u0001\u0000\u0000\u0000\u0003\u00a1\u0001\u0000\u0000\u0000\u0003\u00a3"+ + "\u0001\u0000\u0000\u0000\u0003\u00a5\u0001\u0000\u0000\u0000\u0003\u00a9"+ + "\u0001\u0000\u0000\u0000\u0003\u00ab\u0001\u0000\u0000\u0000\u0003\u00ad"+ + "\u0001\u0000\u0000\u0000\u0003\u00af\u0001\u0000\u0000\u0000\u0004\u00b1"+ + "\u0001\u0000\u0000\u0000\u0004\u00b3\u0001\u0000\u0000\u0000\u0004\u00b5"+ + "\u0001\u0000\u0000\u0000\u0004\u00b7\u0001\u0000\u0000\u0000\u0004\u00b9"+ + "\u0001\u0000\u0000\u0000\u0004\u00bb\u0001\u0000\u0000\u0000\u0004\u00bd"+ + "\u0001\u0000\u0000\u0000\u0004\u00c1\u0001\u0000\u0000\u0000\u0004\u00c3"+ + "\u0001\u0000\u0000\u0000\u0004\u00c5\u0001\u0000\u0000\u0000\u0004\u00c7"+ + "\u0001\u0000\u0000\u0000\u0005\u00fd\u0001\u0000\u0000\u0000\u0007\u0107"+ + "\u0001\u0000\u0000\u0000\t\u010e\u0001\u0000\u0000\u0000\u000b\u0115\u0001"+ + "\u0000\u0000\u0000\r\u011f\u0001\u0000\u0000\u0000\u000f\u0126\u0001\u0000"+ + "\u0000\u0000\u0011\u012c\u0001\u0000\u0000\u0000\u0013\u0134\u0001\u0000"+ + "\u0000\u0000\u0015\u013c\u0001\u0000\u0000\u0000\u0017\u0143\u0001\u0000"+ + "\u0000\u0000\u0019\u014f\u0001\u0000\u0000\u0000\u001b\u0157\u0001\u0000"+ + "\u0000\u0000\u001d\u0161\u0001\u0000\u0000\u0000\u001f\u0168\u0001\u0000"+ + "\u0000\u0000!\u0171\u0001\u0000\u0000\u0000#\u0178\u0001\u0000\u0000\u0000"+ + "%\u0181\u0001\u0000\u0000\u0000\'\u0188\u0001\u0000\u0000\u0000)\u0199"+ + "\u0001\u0000\u0000\u0000+\u01a9\u0001\u0000\u0000\u0000-\u01af\u0001\u0000"+ + "\u0000\u0000/\u01b4\u0001\u0000\u0000\u00001\u01b9\u0001\u0000\u0000\u0000"+ + "3\u01bd\u0001\u0000\u0000\u00005\u01c1\u0001\u0000\u0000\u00007\u01c5"+ + "\u0001\u0000\u0000\u00009\u01c9\u0001\u0000\u0000\u0000;\u01cb\u0001\u0000"+ + "\u0000\u0000=\u01cd\u0001\u0000\u0000\u0000?\u01d0\u0001\u0000\u0000\u0000"+ + "A\u01d2\u0001\u0000\u0000\u0000C\u01f8\u0001\u0000\u0000\u0000E\u01fb"+ + "\u0001\u0000\u0000\u0000G\u0229\u0001\u0000\u0000\u0000I\u022b\u0001\u0000"+ + "\u0000\u0000K\u028c\u0001\u0000\u0000\u0000M\u028e\u0001\u0000\u0000\u0000"+ + "O\u0292\u0001\u0000\u0000\u0000Q\u0294\u0001\u0000\u0000\u0000S\u0296"+ + "\u0001\u0000\u0000\u0000U\u0298\u0001\u0000\u0000\u0000W\u029a\u0001\u0000"+ + "\u0000\u0000Y\u029f\u0001\u0000\u0000\u0000[\u02a4\u0001\u0000\u0000\u0000"+ + "]\u02a8\u0001\u0000\u0000\u0000_\u02ad\u0001\u0000\u0000\u0000a\u02b3"+ + "\u0001\u0000\u0000\u0000c\u02b6\u0001\u0000\u0000\u0000e\u02b9\u0001\u0000"+ + "\u0000\u0000g\u02bc\u0001\u0000\u0000\u0000i\u02c1\u0001\u0000\u0000\u0000"+ + "k\u02c4\u0001\u0000\u0000\u0000m\u02c6\u0001\u0000\u0000\u0000o\u02c8"+ + "\u0001\u0000\u0000\u0000q\u02cd\u0001\u0000\u0000\u0000s\u02e0\u0001\u0000"+ + "\u0000\u0000u\u02ec\u0001\u0000\u0000\u0000w\u02ee\u0001\u0000\u0000\u0000"+ + "y\u02f0\u0001\u0000\u0000\u0000{\u02f2\u0001\u0000\u0000\u0000}\u02f4"+ + "\u0001\u0000\u0000\u0000\u007f\u02f6\u0001\u0000\u0000\u0000\u0081\u02f8"+ + "\u0001\u0000\u0000\u0000\u0083\u0302\u0001\u0000\u0000\u0000\u0085\u0304"+ + "\u0001\u0000\u0000\u0000\u0087\u0313\u0001\u0000\u0000\u0000\u0089\u04cf"+ + "\u0001\u0000\u0000\u0000\u008b\u0568\u0001\u0000\u0000\u0000\u008d\u056a"+ + "\u0001\u0000\u0000\u0000\u008f\u0588\u0001\u0000\u0000\u0000\u0091\u058a"+ + "\u0001\u0000\u0000\u0000\u0093\u0595\u0001\u0000\u0000\u0000\u0095\u0599"+ + "\u0001\u0000\u0000\u0000\u0097\u059d\u0001\u0000\u0000\u0000\u0099\u05a1"+ + "\u0001\u0000\u0000\u0000\u009b\u05a6\u0001\u0000\u0000\u0000\u009d\u05ac"+ + "\u0001\u0000\u0000\u0000\u009f\u05b2\u0001\u0000\u0000\u0000\u00a1\u05b6"+ + "\u0001\u0000\u0000\u0000\u00a3\u05ba\u0001\u0000\u0000\u0000\u00a5\u05c4"+ + "\u0001\u0000\u0000\u0000\u00a7\u05cf\u0001\u0000\u0000\u0000\u00a9\u05d1"+ + "\u0001\u0000\u0000\u0000\u00ab\u05d3\u0001\u0000\u0000\u0000\u00ad\u05d7"+ + "\u0001\u0000\u0000\u0000\u00af\u05db\u0001\u0000\u0000\u0000\u00b1\u05df"+ + "\u0001\u0000\u0000\u0000\u00b3\u05e2\u0001\u0000\u0000\u0000\u00b5\u05e7"+ + "\u0001\u0000\u0000\u0000\u00b7\u05ec\u0001\u0000\u0000\u0000\u00b9\u05f2"+ + "\u0001\u0000\u0000\u0000\u00bb\u05f6\u0001\u0000\u0000\u0000\u00bd\u05fb"+ + "\u0001\u0000\u0000\u0000\u00bf\u0606\u0001\u0000\u0000\u0000\u00c1\u0608"+ + "\u0001\u0000\u0000\u0000\u00c3\u060a\u0001\u0000\u0000\u0000\u00c5\u060e"+ + "\u0001\u0000\u0000\u0000\u00c7\u0612\u0001\u0000\u0000\u0000\u00c9\u0616"+ + "\u0001\u0000\u0000\u0000\u00cb\u0618\u0001\u0000\u0000\u0000\u00cd\u061a"+ + "\u0001\u0000\u0000\u0000\u00cf\u061c\u0001\u0000\u0000\u0000\u00d1\u061e"+ + "\u0001\u0000\u0000\u0000\u00d3\u0620\u0001\u0000\u0000\u0000\u00d5\u0622"+ + "\u0001\u0000\u0000\u0000\u00d7\u0624\u0001\u0000\u0000\u0000\u00d9\u0626"+ + "\u0001\u0000\u0000\u0000\u00db\u0628\u0001\u0000\u0000\u0000\u00dd\u062a"+ + "\u0001\u0000\u0000\u0000\u00df\u062c\u0001\u0000\u0000\u0000\u00e1\u062e"+ + "\u0001\u0000\u0000\u0000\u00e3\u0630\u0001\u0000\u0000\u0000\u00e5\u0632"+ + "\u0001\u0000\u0000\u0000\u00e7\u0634\u0001\u0000\u0000\u0000\u00e9\u0636"+ + "\u0001\u0000\u0000\u0000\u00eb\u0638\u0001\u0000\u0000\u0000\u00ed\u063a"+ + "\u0001\u0000\u0000\u0000\u00ef\u063c\u0001\u0000\u0000\u0000\u00f1\u063e"+ + "\u0001\u0000\u0000\u0000\u00f3\u0640\u0001\u0000\u0000\u0000\u00f5\u0642"+ + "\u0001\u0000\u0000\u0000\u00f7\u0644\u0001\u0000\u0000\u0000\u00f9\u0646"+ + "\u0001\u0000\u0000\u0000\u00fb\u0648\u0001\u0000\u0000\u0000\u00fd\u00fe"+ + "\u0003\u00cfe\u0000\u00fe\u00ff\u0003\u00d9j\u0000\u00ff\u0100\u0003\u00ed"+ + "t\u0000\u0100\u0101\u0003\u00edt\u0000\u0101\u0102\u0003\u00d1f\u0000"+ + "\u0102\u0103\u0003\u00cdd\u0000\u0103\u0104\u0003\u00efu\u0000\u0104\u0105"+ + "\u0001\u0000\u0000\u0000\u0105\u0106\u0006\u0000\u0000\u0000\u0106\u0006"+ + "\u0001\u0000\u0000\u0000\u0107\u0108\u0003\u00d5h\u0000\u0108\u0109\u0003"+ + "\u00ebs\u0000\u0109\u010a\u0003\u00e5p\u0000\u010a\u010b\u0003\u00ddl"+ + "\u0000\u010b\u010c\u0001\u0000\u0000\u0000\u010c\u010d\u0006\u0001\u0000"+ + "\u0000\u010d\b\u0001\u0000\u0000\u0000\u010e\u010f\u0003\u00d1f\u0000"+ + "\u010f\u0110\u0003\u00f3w\u0000\u0110\u0111\u0003\u00c9b\u0000\u0111\u0112"+ + "\u0003\u00dfm\u0000\u0112\u0113\u0001\u0000\u0000\u0000\u0113\u0114\u0006"+ + "\u0002\u0000\u0000\u0114\n\u0001\u0000\u0000\u0000\u0115\u0116\u0003\u00d1"+ + "f\u0000\u0116\u0117\u0003\u00f7y\u0000\u0117\u0118\u0003\u00e7q\u0000"+ + "\u0118\u0119\u0003\u00dfm\u0000\u0119\u011a\u0003\u00c9b\u0000\u011a\u011b"+ + "\u0003\u00d9j\u0000\u011b\u011c\u0003\u00e3o\u0000\u011c\u011d\u0001\u0000"+ + "\u0000\u0000\u011d\u011e\u0006\u0003\u0001\u0000\u011e\f\u0001\u0000\u0000"+ + "\u0000\u011f\u0120\u0003\u00d3g\u0000\u0120\u0121\u0003\u00ebs\u0000\u0121"+ + "\u0122\u0003\u00e5p\u0000\u0122\u0123\u0003\u00e1n\u0000\u0123\u0124\u0001"+ + "\u0000\u0000\u0000\u0124\u0125\u0006\u0004\u0002\u0000\u0125\u000e\u0001"+ + "\u0000\u0000\u0000\u0126\u0127\u0003\u00ebs\u0000\u0127\u0128\u0003\u00e5"+ + "p\u0000\u0128\u0129\u0003\u00f5x\u0000\u0129\u012a\u0001\u0000\u0000\u0000"+ + "\u012a\u012b\u0006\u0005\u0000\u0000\u012b\u0010\u0001\u0000\u0000\u0000"+ + "\u012c\u012d\u0003\u00edt\u0000\u012d\u012e\u0003\u00efu\u0000\u012e\u012f"+ + "\u0003\u00c9b\u0000\u012f\u0130\u0003\u00efu\u0000\u0130\u0131\u0003\u00ed"+ + "t\u0000\u0131\u0132\u0001\u0000\u0000\u0000\u0132\u0133\u0006\u0006\u0000"+ + "\u0000\u0133\u0012\u0001\u0000\u0000\u0000\u0134\u0135\u0003\u00f5x\u0000"+ + "\u0135\u0136\u0003\u00d7i\u0000\u0136\u0137\u0003\u00d1f\u0000\u0137\u0138"+ + "\u0003\u00ebs\u0000\u0138\u0139\u0003\u00d1f\u0000\u0139\u013a\u0001\u0000"+ + "\u0000\u0000\u013a\u013b\u0006\u0007\u0000\u0000\u013b\u0014\u0001\u0000"+ + "\u0000\u0000\u013c\u013d\u0003\u00edt\u0000\u013d\u013e\u0003\u00e5p\u0000"+ + "\u013e\u013f\u0003\u00ebs\u0000\u013f\u0140\u0003\u00efu\u0000\u0140\u0141"+ + "\u0001\u0000\u0000\u0000\u0141\u0142\u0006\b\u0000\u0000\u0142\u0016\u0001"+ + "\u0000\u0000\u0000\u0143\u0144\u0003\u00e1n\u0000\u0144\u0145\u0003\u00f3"+ + "w\u0000\u0145\u0146\u0003m4\u0000\u0146\u0147\u0003\u00d1f\u0000\u0147"+ + "\u0148\u0003\u00f7y\u0000\u0148\u0149\u0003\u00e7q\u0000\u0149\u014a\u0003"+ + "\u00c9b\u0000\u014a\u014b\u0003\u00e3o\u0000\u014b\u014c\u0003\u00cfe"+ + "\u0000\u014c\u014d\u0001\u0000\u0000\u0000\u014d\u014e\u0006\t\u0000\u0000"+ + "\u014e\u0018\u0001\u0000\u0000\u0000\u014f\u0150\u0003\u00dfm\u0000\u0150"+ + "\u0151\u0003\u00d9j\u0000\u0151\u0152\u0003\u00e1n\u0000\u0152\u0153\u0003"+ + "\u00d9j\u0000\u0153\u0154\u0003\u00efu\u0000\u0154\u0155\u0001\u0000\u0000"+ + "\u0000\u0155\u0156\u0006\n\u0000\u0000\u0156\u001a\u0001\u0000\u0000\u0000"+ + "\u0157\u0158\u0003\u00e7q\u0000\u0158\u0159\u0003\u00ebs\u0000\u0159\u015a"+ + "\u0003\u00e5p\u0000\u015a\u015b\u0003\u00dbk\u0000\u015b\u015c\u0003\u00d1"+ + "f\u0000\u015c\u015d\u0003\u00cdd\u0000\u015d\u015e\u0003\u00efu\u0000"+ + "\u015e\u015f\u0001\u0000\u0000\u0000\u015f\u0160\u0006\u000b\u0000\u0000"+ + "\u0160\u001c\u0001\u0000\u0000\u0000\u0161\u0162\u0003\u00cfe\u0000\u0162"+ + "\u0163\u0003\u00ebs\u0000\u0163\u0164\u0003\u00e5p\u0000\u0164\u0165\u0003"+ + "\u00e7q\u0000\u0165\u0166\u0001\u0000\u0000\u0000\u0166\u0167\u0006\f"+ + "\u0000\u0000\u0167\u001e\u0001\u0000\u0000\u0000\u0168\u0169\u0003\u00eb"+ + "s\u0000\u0169\u016a\u0003\u00d1f\u0000\u016a\u016b\u0003\u00e3o\u0000"+ + "\u016b\u016c\u0003\u00c9b\u0000\u016c\u016d\u0003\u00e1n\u0000\u016d\u016e"+ + "\u0003\u00d1f\u0000\u016e\u016f\u0001\u0000\u0000\u0000\u016f\u0170\u0006"+ + "\r\u0000\u0000\u0170 \u0001\u0000\u0000\u0000\u0171\u0172\u0003\u00ed"+ + "t\u0000\u0172\u0173\u0003\u00d7i\u0000\u0173\u0174\u0003\u00e5p\u0000"+ + "\u0174\u0175\u0003\u00f5x\u0000\u0175\u0176\u0001\u0000\u0000\u0000\u0176"+ + "\u0177\u0006\u000e\u0000\u0000\u0177\"\u0001\u0000\u0000\u0000\u0178\u0179"+ + "\u0003\u00d1f\u0000\u0179\u017a\u0003\u00e3o\u0000\u017a\u017b\u0003\u00eb"+ + "s\u0000\u017b\u017c\u0003\u00d9j\u0000\u017c\u017d\u0003\u00cdd\u0000"+ + "\u017d\u017e\u0003\u00d7i\u0000\u017e\u017f\u0001\u0000\u0000\u0000\u017f"+ + "\u0180\u0006\u000f\u0003\u0000\u0180$\u0001\u0000\u0000\u0000\u0181\u0182"+ + "\u0003\u00ddl\u0000\u0182\u0183\u0003\u00d1f\u0000\u0183\u0184\u0003\u00d1"+ + "f\u0000\u0184\u0185\u0003\u00e7q\u0000\u0185\u0186\u0001\u0000\u0000\u0000"+ + "\u0186\u0187\u0006\u0010\u0000\u0000\u0187&\u0001\u0000\u0000\u0000\u0188"+ + "\u0189\u0005/\u0000\u0000\u0189\u018a\u0005/\u0000\u0000\u018a\u018e\u0001"+ + "\u0000\u0000\u0000\u018b\u018d\b\u0000\u0000\u0000\u018c\u018b\u0001\u0000"+ + "\u0000\u0000\u018d\u0190\u0001\u0000\u0000\u0000\u018e\u018c\u0001\u0000"+ + "\u0000\u0000\u018e\u018f\u0001\u0000\u0000\u0000\u018f\u0192\u0001\u0000"+ + "\u0000\u0000\u0190\u018e\u0001\u0000\u0000\u0000\u0191\u0193\u0005\r\u0000"+ + "\u0000\u0192\u0191\u0001\u0000\u0000\u0000\u0192\u0193\u0001\u0000\u0000"+ + "\u0000\u0193\u0195\u0001\u0000\u0000\u0000\u0194\u0196\u0005\n\u0000\u0000"+ + "\u0195\u0194\u0001\u0000\u0000\u0000\u0195\u0196\u0001\u0000\u0000\u0000"+ + "\u0196\u0197\u0001\u0000\u0000\u0000\u0197\u0198\u0006\u0011\u0004\u0000"+ + "\u0198(\u0001\u0000\u0000\u0000\u0199\u019a\u0005/\u0000\u0000\u019a\u019b"+ + "\u0005*\u0000\u0000\u019b\u01a0\u0001\u0000\u0000\u0000\u019c\u019f\u0003"+ + ")\u0012\u0000\u019d\u019f\t\u0000\u0000\u0000\u019e\u019c\u0001\u0000"+ + "\u0000\u0000\u019e\u019d\u0001\u0000\u0000\u0000\u019f\u01a2\u0001\u0000"+ + "\u0000\u0000\u01a0\u01a1\u0001\u0000\u0000\u0000\u01a0\u019e\u0001\u0000"+ + "\u0000\u0000\u01a1\u01a3\u0001\u0000\u0000\u0000\u01a2\u01a0\u0001\u0000"+ + "\u0000\u0000\u01a3\u01a4\u0005*\u0000\u0000\u01a4\u01a5\u0005/\u0000\u0000"+ + "\u01a5\u01a6\u0001\u0000\u0000\u0000\u01a6\u01a7\u0006\u0012\u0004\u0000"+ + "\u01a7*\u0001\u0000\u0000\u0000\u01a8\u01aa\u0007\u0001\u0000\u0000\u01a9"+ + "\u01a8\u0001\u0000\u0000\u0000\u01aa\u01ab\u0001\u0000\u0000\u0000\u01ab"+ + "\u01a9\u0001\u0000\u0000\u0000\u01ab\u01ac\u0001\u0000\u0000\u0000\u01ac"+ + "\u01ad\u0001\u0000\u0000\u0000\u01ad\u01ae\u0006\u0013\u0004\u0000\u01ae"+ + ",\u0001\u0000\u0000\u0000\u01af\u01b0\u0005[\u0000\u0000\u01b0\u01b1\u0001"+ + "\u0000\u0000\u0000\u01b1\u01b2\u0006\u0014\u0005\u0000\u01b2\u01b3\u0006"+ + "\u0014\u0006\u0000\u01b3.\u0001\u0000\u0000\u0000\u01b4\u01b5\u0005|\u0000"+ + "\u0000\u01b5\u01b6\u0001\u0000\u0000\u0000\u01b6\u01b7\u0006\u0015\u0007"+ + "\u0000\u01b7\u01b8\u0006\u0015\b\u0000\u01b80\u0001\u0000\u0000\u0000"+ + "\u01b9\u01ba\u0003+\u0013\u0000\u01ba\u01bb\u0001\u0000\u0000\u0000\u01bb"+ + "\u01bc\u0006\u0016\u0004\u0000\u01bc2\u0001\u0000\u0000\u0000\u01bd\u01be"+ + "\u0003\'\u0011\u0000\u01be\u01bf\u0001\u0000\u0000\u0000\u01bf\u01c0\u0006"+ + "\u0017\u0004\u0000\u01c04\u0001\u0000\u0000\u0000\u01c1\u01c2\u0003)\u0012"+ + "\u0000\u01c2\u01c3\u0001\u0000\u0000\u0000\u01c3\u01c4\u0006\u0018\u0004"+ + "\u0000\u01c46\u0001\u0000\u0000\u0000\u01c5\u01c6\u0005|\u0000\u0000\u01c6"+ + "\u01c7\u0001\u0000\u0000\u0000\u01c7\u01c8\u0006\u0019\b\u0000\u01c88"+ + "\u0001\u0000\u0000\u0000\u01c9\u01ca\u0007\u0002\u0000\u0000\u01ca:\u0001"+ + "\u0000\u0000\u0000\u01cb\u01cc\u0007\u0003\u0000\u0000\u01cc<\u0001\u0000"+ + "\u0000\u0000\u01cd\u01ce\u0005\\\u0000\u0000\u01ce\u01cf\u0007\u0004\u0000"+ + "\u0000\u01cf>\u0001\u0000\u0000\u0000\u01d0\u01d1\b\u0005\u0000\u0000"+ + "\u01d1@\u0001\u0000\u0000\u0000\u01d2\u01d4\u0007\u0006\u0000\u0000\u01d3"+ + "\u01d5\u0007\u0007\u0000\u0000\u01d4\u01d3\u0001\u0000\u0000\u0000\u01d4"+ + "\u01d5\u0001\u0000\u0000\u0000\u01d5\u01d7\u0001\u0000\u0000\u0000\u01d6"+ + "\u01d8\u00039\u001a\u0000\u01d7\u01d6\u0001\u0000\u0000\u0000\u01d8\u01d9"+ + "\u0001\u0000\u0000\u0000\u01d9\u01d7\u0001\u0000\u0000\u0000\u01d9\u01da"+ + "\u0001\u0000\u0000\u0000\u01daB\u0001\u0000\u0000\u0000\u01db\u01e0\u0005"+ + "\"\u0000\u0000\u01dc\u01df\u0003=\u001c\u0000\u01dd\u01df\u0003?\u001d"+ + "\u0000\u01de\u01dc\u0001\u0000\u0000\u0000\u01de\u01dd\u0001\u0000\u0000"+ + "\u0000\u01df\u01e2\u0001\u0000\u0000\u0000\u01e0\u01de\u0001\u0000\u0000"+ + "\u0000\u01e0\u01e1\u0001\u0000\u0000\u0000\u01e1\u01e3\u0001\u0000\u0000"+ + "\u0000\u01e2\u01e0\u0001\u0000\u0000\u0000\u01e3\u01f9\u0005\"\u0000\u0000"+ + "\u01e4\u01e5\u0005\"\u0000\u0000\u01e5\u01e6\u0005\"\u0000\u0000\u01e6"+ + "\u01e7\u0005\"\u0000\u0000\u01e7\u01eb\u0001\u0000\u0000\u0000\u01e8\u01ea"+ + "\b\u0000\u0000\u0000\u01e9\u01e8\u0001\u0000\u0000\u0000\u01ea\u01ed\u0001"+ + "\u0000\u0000\u0000\u01eb\u01ec\u0001\u0000\u0000\u0000\u01eb\u01e9\u0001"+ + "\u0000\u0000\u0000\u01ec\u01ee\u0001\u0000\u0000\u0000\u01ed\u01eb\u0001"+ + "\u0000\u0000\u0000\u01ee\u01ef\u0005\"\u0000\u0000\u01ef\u01f0\u0005\""+ + "\u0000\u0000\u01f0\u01f1\u0005\"\u0000\u0000\u01f1\u01f3\u0001\u0000\u0000"+ + "\u0000\u01f2\u01f4\u0005\"\u0000\u0000\u01f3\u01f2\u0001\u0000\u0000\u0000"+ + "\u01f3\u01f4\u0001\u0000\u0000\u0000\u01f4\u01f6\u0001\u0000\u0000\u0000"+ + "\u01f5\u01f7\u0005\"\u0000\u0000\u01f6\u01f5\u0001\u0000\u0000\u0000\u01f6"+ + "\u01f7\u0001\u0000\u0000\u0000\u01f7\u01f9\u0001\u0000\u0000\u0000\u01f8"+ + "\u01db\u0001\u0000\u0000\u0000\u01f8\u01e4\u0001\u0000\u0000\u0000\u01f9"+ + "D\u0001\u0000\u0000\u0000\u01fa\u01fc\u00039\u001a\u0000\u01fb\u01fa\u0001"+ + "\u0000\u0000\u0000\u01fc\u01fd\u0001\u0000\u0000\u0000\u01fd\u01fb\u0001"+ + "\u0000\u0000\u0000\u01fd\u01fe\u0001\u0000\u0000\u0000\u01feF\u0001\u0000"+ + "\u0000\u0000\u01ff\u0201\u00039\u001a\u0000\u0200\u01ff\u0001\u0000\u0000"+ + "\u0000\u0201\u0202\u0001\u0000\u0000\u0000\u0202\u0200\u0001\u0000\u0000"+ + "\u0000\u0202\u0203\u0001\u0000\u0000\u0000\u0203\u0204\u0001\u0000\u0000"+ + "\u0000\u0204\u0208\u0003S\'\u0000\u0205\u0207\u00039\u001a\u0000\u0206"+ + "\u0205\u0001\u0000\u0000\u0000\u0207\u020a\u0001\u0000\u0000\u0000\u0208"+ + "\u0206\u0001\u0000\u0000\u0000\u0208\u0209\u0001\u0000\u0000\u0000\u0209"+ + "\u022a\u0001\u0000\u0000\u0000\u020a\u0208\u0001\u0000\u0000\u0000\u020b"+ + "\u020d\u0003S\'\u0000\u020c\u020e\u00039\u001a\u0000\u020d\u020c\u0001"+ + "\u0000\u0000\u0000\u020e\u020f\u0001\u0000\u0000\u0000\u020f\u020d\u0001"+ + "\u0000\u0000\u0000\u020f\u0210\u0001\u0000\u0000\u0000\u0210\u022a\u0001"+ + "\u0000\u0000\u0000\u0211\u0213\u00039\u001a\u0000\u0212\u0211\u0001\u0000"+ + "\u0000\u0000\u0213\u0214\u0001\u0000\u0000\u0000\u0214\u0212\u0001\u0000"+ + "\u0000\u0000\u0214\u0215\u0001\u0000\u0000\u0000\u0215\u021d\u0001\u0000"+ + "\u0000\u0000\u0216\u021a\u0003S\'\u0000\u0217\u0219\u00039\u001a\u0000"+ + "\u0218\u0217\u0001\u0000\u0000\u0000\u0219\u021c\u0001\u0000\u0000\u0000"+ + "\u021a\u0218\u0001\u0000\u0000\u0000\u021a\u021b\u0001\u0000\u0000\u0000"+ + "\u021b\u021e\u0001\u0000\u0000\u0000\u021c\u021a\u0001\u0000\u0000\u0000"+ + "\u021d\u0216\u0001\u0000\u0000\u0000\u021d\u021e\u0001\u0000\u0000\u0000"+ + "\u021e\u021f\u0001\u0000\u0000\u0000\u021f\u0220\u0003A\u001e\u0000\u0220"+ + "\u022a\u0001\u0000\u0000\u0000\u0221\u0223\u0003S\'\u0000\u0222\u0224"+ + "\u00039\u001a\u0000\u0223\u0222\u0001\u0000\u0000\u0000\u0224\u0225\u0001"+ + "\u0000\u0000\u0000\u0225\u0223\u0001\u0000\u0000\u0000\u0225\u0226\u0001"+ + "\u0000\u0000\u0000\u0226\u0227\u0001\u0000\u0000\u0000\u0227\u0228\u0003"+ + "A\u001e\u0000\u0228\u022a\u0001\u0000\u0000\u0000\u0229\u0200\u0001\u0000"+ + "\u0000\u0000\u0229\u020b\u0001\u0000\u0000\u0000\u0229\u0212\u0001\u0000"+ + "\u0000\u0000\u0229\u0221\u0001\u0000\u0000\u0000\u022aH\u0001\u0000\u0000"+ + "\u0000\u022b\u022c\u0005b\u0000\u0000\u022c\u022d\u0005y\u0000\u0000\u022d"+ + "J\u0001\u0000\u0000\u0000\u022e\u022f\u0005y\u0000\u0000\u022f\u0230\u0005"+ + "e\u0000\u0000\u0230\u0231\u0005a\u0000\u0000\u0231\u028d\u0005r\u0000"+ + "\u0000\u0232\u0233\u0005m\u0000\u0000\u0233\u0234\u0005o\u0000\u0000\u0234"+ + "\u0235\u0005n\u0000\u0000\u0235\u0236\u0005t\u0000\u0000\u0236\u028d\u0005"+ + "h\u0000\u0000\u0237\u0238\u0005d\u0000\u0000\u0238\u0239\u0005a\u0000"+ + "\u0000\u0239\u028d\u0005y\u0000\u0000\u023a\u023b\u0005s\u0000\u0000\u023b"+ + "\u023c\u0005e\u0000\u0000\u023c\u023d\u0005c\u0000\u0000\u023d\u023e\u0005"+ + "o\u0000\u0000\u023e\u023f\u0005n\u0000\u0000\u023f\u028d\u0005d\u0000"+ + "\u0000\u0240\u0241\u0005m\u0000\u0000\u0241\u0242\u0005i\u0000\u0000\u0242"+ + "\u0243\u0005n\u0000\u0000\u0243\u0244\u0005u\u0000\u0000\u0244\u0245\u0005"+ + "t\u0000\u0000\u0245\u028d\u0005e\u0000\u0000\u0246\u0247\u0005h\u0000"+ + "\u0000\u0247\u0248\u0005o\u0000\u0000\u0248\u0249\u0005u\u0000\u0000\u0249"+ + "\u028d\u0005r\u0000\u0000\u024a\u024b\u0005w\u0000\u0000\u024b\u024c\u0005"+ + "e\u0000\u0000\u024c\u024d\u0005e\u0000\u0000\u024d\u028d\u0005k\u0000"+ + "\u0000\u024e\u024f\u0005m\u0000\u0000\u024f\u0250\u0005i\u0000\u0000\u0250"+ + "\u0251\u0005l\u0000\u0000\u0251\u0252\u0005l\u0000\u0000\u0252\u0253\u0005"+ + "i\u0000\u0000\u0253\u0254\u0005s\u0000\u0000\u0254\u0255\u0005e\u0000"+ + "\u0000\u0255\u0256\u0005c\u0000\u0000\u0256\u0257\u0005o\u0000\u0000\u0257"+ + "\u0258\u0005n\u0000\u0000\u0258\u028d\u0005d\u0000\u0000\u0259\u025a\u0005"+ + "y\u0000\u0000\u025a\u025b\u0005e\u0000\u0000\u025b\u025c\u0005a\u0000"+ + "\u0000\u025c\u025d\u0005r\u0000\u0000\u025d\u028d\u0005s\u0000\u0000\u025e"+ + "\u025f\u0005m\u0000\u0000\u025f\u0260\u0005o\u0000\u0000\u0260\u0261\u0005"+ + "n\u0000\u0000\u0261\u0262\u0005t\u0000\u0000\u0262\u0263\u0005h\u0000"+ + "\u0000\u0263\u028d\u0005s\u0000\u0000\u0264\u0265\u0005d\u0000\u0000\u0265"+ + "\u0266\u0005a\u0000\u0000\u0266\u0267\u0005y\u0000\u0000\u0267\u028d\u0005"+ + "s\u0000\u0000\u0268\u0269\u0005s\u0000\u0000\u0269\u026a\u0005e\u0000"+ + "\u0000\u026a\u026b\u0005c\u0000\u0000\u026b\u026c\u0005o\u0000\u0000\u026c"+ + "\u026d\u0005n\u0000\u0000\u026d\u026e\u0005d\u0000\u0000\u026e\u028d\u0005"+ + "s\u0000\u0000\u026f\u0270\u0005m\u0000\u0000\u0270\u0271\u0005i\u0000"+ + "\u0000\u0271\u0272\u0005n\u0000\u0000\u0272\u0273\u0005u\u0000\u0000\u0273"+ + "\u0274\u0005t\u0000\u0000\u0274\u0275\u0005e\u0000\u0000\u0275\u028d\u0005"+ + "s\u0000\u0000\u0276\u0277\u0005h\u0000\u0000\u0277\u0278\u0005o\u0000"+ + "\u0000\u0278\u0279\u0005u\u0000\u0000\u0279\u027a\u0005r\u0000\u0000\u027a"+ + "\u028d\u0005s\u0000\u0000\u027b\u027c\u0005w\u0000\u0000\u027c\u027d\u0005"+ + "e\u0000\u0000\u027d\u027e\u0005e\u0000\u0000\u027e\u027f\u0005k\u0000"+ + "\u0000\u027f\u028d\u0005s\u0000\u0000\u0280\u0281\u0005m\u0000\u0000\u0281"+ + "\u0282\u0005i\u0000\u0000\u0282\u0283\u0005l\u0000\u0000\u0283\u0284\u0005"+ + "l\u0000\u0000\u0284\u0285\u0005i\u0000\u0000\u0285\u0286\u0005s\u0000"+ + "\u0000\u0286\u0287\u0005e\u0000\u0000\u0287\u0288\u0005c\u0000\u0000\u0288"+ + "\u0289\u0005o\u0000\u0000\u0289\u028a\u0005n\u0000\u0000\u028a\u028b\u0005"+ + "d\u0000\u0000\u028b\u028d\u0005s\u0000\u0000\u028c\u022e\u0001\u0000\u0000"+ + "\u0000\u028c\u0232\u0001\u0000\u0000\u0000\u028c\u0237\u0001\u0000\u0000"+ + "\u0000\u028c\u023a\u0001\u0000\u0000\u0000\u028c\u0240\u0001\u0000\u0000"+ + "\u0000\u028c\u0246\u0001\u0000\u0000\u0000\u028c\u024a\u0001\u0000\u0000"+ + "\u0000\u028c\u024e\u0001\u0000\u0000\u0000\u028c\u0259\u0001\u0000\u0000"+ + "\u0000\u028c\u025e\u0001\u0000\u0000\u0000\u028c\u0264\u0001\u0000\u0000"+ + "\u0000\u028c\u0268\u0001\u0000\u0000\u0000\u028c\u026f\u0001\u0000\u0000"+ + "\u0000\u028c\u0276\u0001\u0000\u0000\u0000\u028c\u027b\u0001\u0000\u0000"+ + "\u0000\u028c\u0280\u0001\u0000\u0000\u0000\u028dL\u0001\u0000\u0000\u0000"+ + "\u028e\u028f\u0005a\u0000\u0000\u028f\u0290\u0005n\u0000\u0000\u0290\u0291"+ + "\u0005d\u0000\u0000\u0291N\u0001\u0000\u0000\u0000\u0292\u0293\u0005="+ + "\u0000\u0000\u0293P\u0001\u0000\u0000\u0000\u0294\u0295\u0005,\u0000\u0000"+ + "\u0295R\u0001\u0000\u0000\u0000\u0296\u0297\u0005.\u0000\u0000\u0297T"+ + "\u0001\u0000\u0000\u0000\u0298\u0299\u0005(\u0000\u0000\u0299V\u0001\u0000"+ + "\u0000\u0000\u029a\u029b\u0005[\u0000\u0000\u029b\u029c\u0001\u0000\u0000"+ + "\u0000\u029c\u029d\u0006)\u0000\u0000\u029d\u029e\u0006)\u0000\u0000\u029e"+ + "X\u0001\u0000\u0000\u0000\u029f\u02a0\u0005]\u0000\u0000\u02a0\u02a1\u0001"+ + "\u0000\u0000\u0000\u02a1\u02a2\u0006*\b\u0000\u02a2\u02a3\u0006*\b\u0000"+ + "\u02a3Z\u0001\u0000\u0000\u0000\u02a4\u02a5\u0003\u00e3o\u0000\u02a5\u02a6"+ + "\u0003\u00e5p\u0000\u02a6\u02a7\u0003\u00efu\u0000\u02a7\\\u0001\u0000"+ + "\u0000\u0000\u02a8\u02a9\u0003\u00dfm\u0000\u02a9\u02aa\u0003\u00d9j\u0000"+ + "\u02aa\u02ab\u0003\u00ddl\u0000\u02ab\u02ac\u0003\u00d1f\u0000\u02ac^"+ + "\u0001\u0000\u0000\u0000\u02ad\u02ae\u0003\u00ebs\u0000\u02ae\u02af\u0003"+ + "\u00dfm\u0000\u02af\u02b0\u0003\u00d9j\u0000\u02b0\u02b1\u0003\u00ddl"+ + "\u0000\u02b1\u02b2\u0003\u00d1f\u0000\u02b2`\u0001\u0000\u0000\u0000\u02b3"+ + "\u02b4\u0003\u00d9j\u0000\u02b4\u02b5\u0003\u00e3o\u0000\u02b5b\u0001"+ + "\u0000\u0000\u0000\u02b6\u02b7\u0003\u00d9j\u0000\u02b7\u02b8\u0003\u00ed"+ + "t\u0000\u02b8d\u0001\u0000\u0000\u0000\u02b9\u02ba\u0003\u00c9b\u0000"+ + "\u02ba\u02bb\u0003\u00edt\u0000\u02bbf\u0001\u0000\u0000\u0000\u02bc\u02bd"+ + "\u0003\u00e3o\u0000\u02bd\u02be\u0003\u00f1v\u0000\u02be\u02bf\u0003\u00df"+ + "m\u0000\u02bf\u02c0\u0003\u00dfm\u0000\u02c0h\u0001\u0000\u0000\u0000"+ + "\u02c1\u02c2\u0005o\u0000\u0000\u02c2\u02c3\u0005r\u0000\u0000\u02c3j"+ + "\u0001\u0000\u0000\u0000\u02c4\u02c5\u0005)\u0000\u0000\u02c5l\u0001\u0000"+ + "\u0000\u0000\u02c6\u02c7\u0005_\u0000\u0000\u02c7n\u0001\u0000\u0000\u0000"+ + "\u02c8\u02c9\u0005i\u0000\u0000\u02c9\u02ca\u0005n\u0000\u0000\u02ca\u02cb"+ + "\u0005f\u0000\u0000\u02cb\u02cc\u0005o\u0000\u0000\u02ccp\u0001\u0000"+ + "\u0000\u0000\u02cd\u02ce\u0005f\u0000\u0000\u02ce\u02cf\u0005u\u0000\u0000"+ + "\u02cf\u02d0\u0005n\u0000\u0000\u02d0\u02d1\u0005c\u0000\u0000\u02d1\u02d2"+ + "\u0005t\u0000\u0000\u02d2\u02d3\u0005i\u0000\u0000\u02d3\u02d4\u0005o"+ + "\u0000\u0000\u02d4\u02d5\u0005n\u0000\u0000\u02d5\u02d6\u0005s\u0000\u0000"+ + "\u02d6r\u0001\u0000\u0000\u0000\u02d7\u02d8\u0005t\u0000\u0000\u02d8\u02d9"+ + "\u0005r\u0000\u0000\u02d9\u02da\u0005u\u0000\u0000\u02da\u02e1\u0005e"+ + "\u0000\u0000\u02db\u02dc\u0005f\u0000\u0000\u02dc\u02dd\u0005a\u0000\u0000"+ + "\u02dd\u02de\u0005l\u0000\u0000\u02de\u02df\u0005s\u0000\u0000\u02df\u02e1"+ + "\u0005e\u0000\u0000\u02e0\u02d7\u0001\u0000\u0000\u0000\u02e0\u02db\u0001"+ + "\u0000\u0000\u0000\u02e1t\u0001\u0000\u0000\u0000\u02e2\u02e3\u0005=\u0000"+ + "\u0000\u02e3\u02ed\u0005=\u0000\u0000\u02e4\u02e5\u0005!\u0000\u0000\u02e5"+ + "\u02ed\u0005=\u0000\u0000\u02e6\u02ed\u0005<\u0000\u0000\u02e7\u02e8\u0005"+ + "<\u0000\u0000\u02e8\u02ed\u0005=\u0000\u0000\u02e9\u02ed\u0005>\u0000"+ + "\u0000\u02ea\u02eb\u0005>\u0000\u0000\u02eb\u02ed\u0005=\u0000\u0000\u02ec"+ + "\u02e2\u0001\u0000\u0000\u0000\u02ec\u02e4\u0001\u0000\u0000\u0000\u02ec"+ + "\u02e6\u0001\u0000\u0000\u0000\u02ec\u02e7\u0001\u0000\u0000\u0000\u02ec"+ + "\u02e9\u0001\u0000\u0000\u0000\u02ec\u02ea\u0001\u0000\u0000\u0000\u02ed"+ + "v\u0001\u0000\u0000\u0000\u02ee\u02ef\u0005+\u0000\u0000\u02efx\u0001"+ + "\u0000\u0000\u0000\u02f0\u02f1\u0005-\u0000\u0000\u02f1z\u0001\u0000\u0000"+ + "\u0000\u02f2\u02f3\u0005*\u0000\u0000\u02f3|\u0001\u0000\u0000\u0000\u02f4"+ + "\u02f5\u0005/\u0000\u0000\u02f5~\u0001\u0000\u0000\u0000\u02f6\u02f7\u0005"+ + "%\u0000\u0000\u02f7\u0080\u0001\u0000\u0000\u0000\u02f8\u02f9\u00051\u0000"+ + "\u0000\u02f9\u02fa\u00050\u0000\u0000\u02fa\u0082\u0001\u0000\u0000\u0000"+ + "\u02fb\u02fc\u0005a\u0000\u0000\u02fc\u02fd\u0005s\u0000\u0000\u02fd\u0303"+ + "\u0005c\u0000\u0000\u02fe\u02ff\u0005d\u0000\u0000\u02ff\u0300\u0005e"+ + "\u0000\u0000\u0300\u0301\u0005s\u0000\u0000\u0301\u0303\u0005c\u0000\u0000"+ + "\u0302\u02fb\u0001\u0000\u0000\u0000\u0302\u02fe\u0001\u0000\u0000\u0000"+ + "\u0303\u0084\u0001\u0000\u0000\u0000\u0304\u0305\u0005n\u0000\u0000\u0305"+ + "\u0306\u0005u\u0000\u0000\u0306\u0307\u0005l\u0000\u0000\u0307\u0308\u0005"+ + "l\u0000\u0000\u0308\u0309\u0005s\u0000\u0000\u0309\u0086\u0001\u0000\u0000"+ + "\u0000\u030a\u030b\u0005f\u0000\u0000\u030b\u030c\u0005i\u0000\u0000\u030c"+ + "\u030d\u0005r\u0000\u0000\u030d\u030e\u0005s\u0000\u0000\u030e\u0314\u0005"+ + "t\u0000\u0000\u030f\u0310\u0005l\u0000\u0000\u0310\u0311\u0005a\u0000"+ + "\u0000\u0311\u0312\u0005s\u0000\u0000\u0312\u0314\u0005t\u0000\u0000\u0313"+ + "\u030a\u0001\u0000\u0000\u0000\u0313\u030f\u0001\u0000\u0000\u0000\u0314"+ + "\u0088\u0001\u0000\u0000\u0000\u0315\u0316\u0003\u00ebs\u0000\u0316\u0317"+ + "\u0003\u00e5p\u0000\u0317\u0318\u0003\u00f1v\u0000\u0318\u0319\u0003\u00e3"+ + "o\u0000\u0319\u031a\u0003\u00cfe\u0000\u031a\u04d0\u0001\u0000\u0000\u0000"+ + "\u031b\u031c\u0003\u00c9b\u0000\u031c\u031d\u0003\u00cbc\u0000\u031d\u031e"+ + "\u0003\u00edt\u0000\u031e\u04d0\u0001\u0000\u0000\u0000\u031f\u0320\u0003"+ + "\u00e7q\u0000\u0320\u0321\u0003\u00e5p\u0000\u0321\u0322\u0003\u00f5x"+ + "\u0000\u0322\u04d0\u0001\u0000\u0000\u0000\u0323\u0324\u0003\u00dfm\u0000"+ + "\u0324\u0325\u0003\u00e5p\u0000\u0325\u0326\u0003\u00d5h\u0000\u0326\u0327"+ + "\u0003\u0081>\u0000\u0327\u04d0\u0001\u0000\u0000\u0000\u0328\u0329\u0003"+ + "\u00e7q\u0000\u0329\u032a\u0003\u00d9j\u0000\u032a\u04d0\u0001\u0000\u0000"+ + "\u0000\u032b\u032c\u0003\u00efu\u0000\u032c\u032d\u0003\u00c9b\u0000\u032d"+ + "\u032e\u0003\u00f1v\u0000\u032e\u04d0\u0001\u0000\u0000\u0000\u032f\u04d0"+ + "\u0003\u00d1f\u0000\u0330\u0331\u0003\u00edt\u0000\u0331\u0332\u0003\u00f1"+ + "v\u0000\u0332\u0333\u0003\u00cbc\u0000\u0333\u0334\u0003\u00edt\u0000"+ + "\u0334\u0335\u0003\u00efu\u0000\u0335\u0336\u0003\u00ebs\u0000\u0336\u0337"+ + "\u0003\u00d9j\u0000\u0337\u0338\u0003\u00e3o\u0000\u0338\u0339\u0003\u00d5"+ + "h\u0000\u0339\u04d0\u0001\u0000\u0000\u0000\u033a\u033b\u0003\u00efu\u0000"+ + "\u033b\u033c\u0003\u00ebs\u0000\u033c\u033d\u0003\u00d9j\u0000\u033d\u033e"+ + "\u0003\u00e1n\u0000\u033e\u04d0\u0001\u0000\u0000\u0000\u033f\u0340\u0003"+ + "\u00cdd\u0000\u0340\u0341\u0003\u00e5p\u0000\u0341\u0342\u0003\u00e3o"+ + "\u0000\u0342\u0343\u0003\u00cdd\u0000\u0343\u0344\u0003\u00c9b\u0000\u0344"+ + "\u0345\u0003\u00efu\u0000\u0345\u04d0\u0001\u0000\u0000\u0000\u0346\u0347"+ + "\u0003\u00cdd\u0000\u0347\u0348\u0003\u00e5p\u0000\u0348\u0349\u0003\u00c9"+ + "b\u0000\u0349\u034a\u0003\u00dfm\u0000\u034a\u034b\u0003\u00d1f\u0000"+ + "\u034b\u034c\u0003\u00edt\u0000\u034c\u034d\u0003\u00cdd\u0000\u034d\u034e"+ + "\u0003\u00d1f\u0000\u034e\u04d0\u0001\u0000\u0000\u0000\u034f\u0350\u0003"+ + "\u00d5h\u0000\u0350\u0351\u0003\u00ebs\u0000\u0351\u0352\u0003\u00d1f"+ + "\u0000\u0352\u0353\u0003\u00c9b\u0000\u0353\u0354\u0003\u00efu\u0000\u0354"+ + "\u0355\u0003\u00d1f\u0000\u0355\u0356\u0003\u00edt\u0000\u0356\u0357\u0003"+ + "\u00efu\u0000\u0357\u04d0\u0001\u0000\u0000\u0000\u0358\u0359\u0003\u00df"+ + "m\u0000\u0359\u035a\u0003\u00d1f\u0000\u035a\u035b\u0003\u00d3g\u0000"+ + "\u035b\u035c\u0003\u00efu\u0000\u035c\u04d0\u0001\u0000\u0000\u0000\u035d"+ + "\u035e\u0003\u00e3o\u0000\u035e\u035f\u0003\u00e5p\u0000\u035f\u0360\u0003"+ + "\u00f5x\u0000\u0360\u04d0\u0001\u0000\u0000\u0000\u0361\u0362\u0003\u00eb"+ + "s\u0000\u0362\u0363\u0003\u00d9j\u0000\u0363\u0364\u0003\u00d5h\u0000"+ + "\u0364\u0365\u0003\u00d7i\u0000\u0365\u0366\u0003\u00efu\u0000\u0366\u04d0"+ + "\u0001\u0000\u0000\u0000\u0367\u0368\u0003\u00edt\u0000\u0368\u0369\u0003"+ + "\u00efu\u0000\u0369\u036a\u0003\u00c9b\u0000\u036a\u036b\u0003\u00ebs"+ + "\u0000\u036b\u036c\u0003\u00efu\u0000\u036c\u036d\u0003\u00edt\u0000\u036d"+ + "\u036e\u0003m4\u0000\u036e\u036f\u0003\u00f5x\u0000\u036f\u0370\u0003"+ + "\u00d9j\u0000\u0370\u0371\u0003\u00efu\u0000\u0371\u0372\u0003\u00d7i"+ + "\u0000\u0372\u04d0\u0001\u0000\u0000\u0000\u0373\u0374\u0003\u00cfe\u0000"+ + "\u0374\u0375\u0003\u00c9b\u0000\u0375\u0376\u0003\u00efu\u0000\u0376\u0377"+ + "\u0003\u00d1f\u0000\u0377\u0378\u0003m4\u0000\u0378\u0379\u0003\u00d3"+ + "g\u0000\u0379\u037a\u0003\u00e5p\u0000\u037a\u037b\u0003\u00ebs\u0000"+ + "\u037b\u037c\u0003\u00e1n\u0000\u037c\u037d\u0003\u00c9b\u0000\u037d\u037e"+ + "\u0003\u00efu\u0000\u037e\u04d0\u0001\u0000\u0000\u0000\u037f\u0380\u0003"+ + "\u00cfe\u0000\u0380\u0381\u0003\u00c9b\u0000\u0381\u0382\u0003\u00efu"+ + "\u0000\u0382\u0383\u0003\u00d1f\u0000\u0383\u0384\u0003m4\u0000\u0384"+ + "\u0385\u0003\u00efu\u0000\u0385\u0386\u0003\u00ebs\u0000\u0386\u0387\u0003"+ + "\u00f1v\u0000\u0387\u0388\u0003\u00e3o\u0000\u0388\u0389\u0003\u00cdd"+ + "\u0000\u0389\u04d0\u0001\u0000\u0000\u0000\u038a\u038b\u0003\u00cfe\u0000"+ + "\u038b\u038c\u0003\u00c9b\u0000\u038c\u038d\u0003\u00efu\u0000\u038d\u038e"+ + "\u0003\u00d1f\u0000\u038e\u038f\u0003m4\u0000\u038f\u0390\u0003\u00e7"+ + "q\u0000\u0390\u0391\u0003\u00c9b\u0000\u0391\u0392\u0003\u00ebs\u0000"+ + "\u0392\u0393\u0003\u00edt\u0000\u0393\u0394\u0003\u00d1f\u0000\u0394\u04d0"+ + "\u0001\u0000\u0000\u0000\u0395\u0396\u0003\u00c9b\u0000\u0396\u0397\u0003"+ + "\u00f1v\u0000\u0397\u0398\u0003\u00efu\u0000\u0398\u0399\u0003\u00e5p"+ + "\u0000\u0399\u039a\u0003m4\u0000\u039a\u039b\u0003\u00cbc\u0000\u039b"+ + "\u039c\u0003\u00f1v\u0000\u039c\u039d\u0003\u00cdd\u0000\u039d\u039e\u0003"+ + "\u00ddl\u0000\u039e\u039f\u0003\u00d1f\u0000\u039f\u03a0\u0003\u00efu"+ + "\u0000\u03a0\u04d0\u0001\u0000\u0000\u0000\u03a1\u03a2\u0003\u00cfe\u0000"+ + "\u03a2\u03a3\u0003\u00c9b\u0000\u03a3\u03a4\u0003\u00efu\u0000\u03a4\u03a5"+ + "\u0003\u00d1f\u0000\u03a5\u03a6\u0003m4\u0000\u03a6\u03a7\u0003\u00d1"+ + "f\u0000\u03a7\u03a8\u0003\u00f7y\u0000\u03a8\u03a9\u0003\u00efu\u0000"+ + "\u03a9\u03aa\u0003\u00ebs\u0000\u03aa\u03ab\u0003\u00c9b\u0000\u03ab\u03ac"+ + "\u0003\u00cdd\u0000\u03ac\u03ad\u0003\u00efu\u0000\u03ad\u04d0\u0001\u0000"+ + "\u0000\u0000\u03ae\u03af\u0003\u00d9j\u0000\u03af\u03b0\u0003\u00edt\u0000"+ + "\u03b0\u03b1\u0003m4\u0000\u03b1\u03b2\u0003\u00d3g\u0000\u03b2\u03b3"+ + "\u0003\u00d9j\u0000\u03b3\u03b4\u0003\u00e3o\u0000\u03b4\u03b5\u0003\u00d9"+ + "j\u0000\u03b5\u03b6\u0003\u00efu\u0000\u03b6\u03b7\u0003\u00d1f\u0000"+ + "\u03b7\u04d0\u0001\u0000\u0000\u0000\u03b8\u03b9\u0003\u00d9j\u0000\u03b9"+ + "\u03ba\u0003\u00edt\u0000\u03ba\u03bb\u0003m4\u0000\u03bb\u03bc\u0003"+ + "\u00d9j\u0000\u03bc\u03bd\u0003\u00e3o\u0000\u03bd\u03be\u0003\u00d3g"+ + "\u0000\u03be\u03bf\u0003\u00d9j\u0000\u03bf\u03c0\u0003\u00e3o\u0000\u03c0"+ + "\u03c1\u0003\u00d9j\u0000\u03c1\u03c2\u0003\u00efu\u0000\u03c2\u03c3\u0003"+ + "\u00d1f\u0000\u03c3\u04d0\u0001\u0000\u0000\u0000\u03c4\u03c5\u0003\u00cd"+ + "d\u0000\u03c5\u03c6\u0003\u00c9b\u0000\u03c6\u03c7\u0003\u00edt\u0000"+ + "\u03c7\u03c8\u0003\u00d1f\u0000\u03c8\u04d0\u0001\u0000\u0000\u0000\u03c9"+ + "\u03ca\u0003\u00dfm\u0000\u03ca\u03cb\u0003\u00d1f\u0000\u03cb\u03cc\u0003"+ + "\u00e3o\u0000\u03cc\u03cd\u0003\u00d5h\u0000\u03cd\u03ce\u0003\u00efu"+ + "\u0000\u03ce\u03cf\u0003\u00d7i\u0000\u03cf\u04d0\u0001\u0000\u0000\u0000"+ + "\u03d0\u03d1\u0003\u00e1n\u0000\u03d1\u03d2\u0003\u00f3w\u0000\u03d2\u03d3"+ + "\u0003m4\u0000\u03d3\u03d4\u0003\u00e1n\u0000\u03d4\u03d5\u0003\u00c9"+ + "b\u0000\u03d5\u03d6\u0003\u00f7y\u0000\u03d6\u04d0\u0001\u0000\u0000\u0000"+ + "\u03d7\u03d8\u0003\u00e1n\u0000\u03d8\u03d9\u0003\u00f3w\u0000\u03d9\u03da"+ + "\u0003m4\u0000\u03da\u03db\u0003\u00e1n\u0000\u03db\u03dc\u0003\u00d9"+ + "j\u0000\u03dc\u03dd\u0003\u00e3o\u0000\u03dd\u04d0\u0001\u0000\u0000\u0000"+ + "\u03de\u03df\u0003\u00e1n\u0000\u03df\u03e0\u0003\u00f3w\u0000\u03e0\u03e1"+ + "\u0003m4\u0000\u03e1\u03e2\u0003\u00c9b\u0000\u03e2\u03e3\u0003\u00f3"+ + "w\u0000\u03e3\u03e4\u0003\u00d5h\u0000\u03e4\u04d0\u0001\u0000\u0000\u0000"+ + "\u03e5\u03e6\u0003\u00e1n\u0000\u03e6\u03e7\u0003\u00f3w\u0000\u03e7\u03e8"+ + "\u0003m4\u0000\u03e8\u03e9\u0003\u00edt\u0000\u03e9\u03ea\u0003\u00f1"+ + "v\u0000\u03ea\u03eb\u0003\u00e1n\u0000\u03eb\u04d0\u0001\u0000\u0000\u0000"+ + "\u03ec\u03ed\u0003\u00e1n\u0000\u03ed\u03ee\u0003\u00f3w\u0000\u03ee\u03ef"+ + "\u0003m4\u0000\u03ef\u03f0\u0003\u00cdd\u0000\u03f0\u03f1\u0003\u00e5"+ + "p\u0000\u03f1\u03f2\u0003\u00f1v\u0000\u03f2\u03f3\u0003\u00e3o\u0000"+ + "\u03f3\u03f4\u0003\u00efu\u0000\u03f4\u04d0\u0001\u0000\u0000\u0000\u03f5"+ + "\u03f6\u0003\u00e1n\u0000\u03f6\u03f7\u0003\u00f3w\u0000\u03f7\u03f8\u0003"+ + "m4\u0000\u03f8\u03f9\u0003\u00cdd\u0000\u03f9\u03fa\u0003\u00e5p\u0000"+ + "\u03fa\u03fb\u0003\u00e3o\u0000\u03fb\u03fc\u0003\u00cdd\u0000\u03fc\u03fd"+ + "\u0003\u00c9b\u0000\u03fd\u03fe\u0003\u00efu\u0000\u03fe\u04d0\u0001\u0000"+ + "\u0000\u0000\u03ff\u0400\u0003\u00e1n\u0000\u0400\u0401\u0003\u00f3w\u0000"+ + "\u0401\u0402\u0003m4\u0000\u0402\u0403\u0003\u00dbk\u0000\u0403\u0404"+ + "\u0003\u00e5p\u0000\u0404\u0405\u0003\u00d9j\u0000\u0405\u0406\u0003\u00e3"+ + "o\u0000\u0406\u04d0\u0001\u0000\u0000\u0000\u0407\u0408\u0003\u00e1n\u0000"+ + "\u0408\u0409\u0003\u00f3w\u0000\u0409\u040a\u0003m4\u0000\u040a\u040b"+ + "\u0003\u00e1n\u0000\u040b\u040c\u0003\u00d1f\u0000\u040c\u040d\u0003\u00cf"+ + "e\u0000\u040d\u040e\u0003\u00d9j\u0000\u040e\u040f\u0003\u00c9b\u0000"+ + "\u040f\u0410\u0003\u00e3o\u0000\u0410\u04d0\u0001\u0000\u0000\u0000\u0411"+ + "\u0412\u0003\u00e1n\u0000\u0412\u0413\u0003\u00f3w\u0000\u0413\u0414\u0003"+ + "m4\u0000\u0414\u0415\u0003\u00cfe\u0000\u0415\u0416\u0003\u00d1f\u0000"+ + "\u0416\u0417\u0003\u00cfe\u0000\u0417\u0418\u0003\u00f1v\u0000\u0418\u0419"+ + "\u0003\u00e7q\u0000\u0419\u041a\u0003\u00d1f\u0000\u041a\u04d0\u0001\u0000"+ + "\u0000\u0000\u041b\u041c\u0003\u00e1n\u0000\u041c\u041d\u0003\u00d1f\u0000"+ + "\u041d\u041e\u0003\u00efu\u0000\u041e\u041f\u0003\u00c9b\u0000\u041f\u0420"+ + "\u0003\u00cfe\u0000\u0420\u0421\u0003\u00c9b\u0000\u0421\u0422\u0003\u00ef"+ + "u\u0000\u0422\u0423\u0003\u00c9b\u0000\u0423\u04d0\u0001\u0000\u0000\u0000"+ + "\u0424\u0425\u0003\u00edt\u0000\u0425\u0426\u0003\u00e7q\u0000\u0426\u0427"+ + "\u0003\u00dfm\u0000\u0427\u0428\u0003\u00d9j\u0000\u0428\u0429\u0003\u00ef"+ + "u\u0000\u0429\u04d0\u0001\u0000\u0000\u0000\u042a\u042b\u0003\u00efu\u0000"+ + "\u042b\u042c\u0003\u00e5p\u0000\u042c\u042d\u0003m4\u0000\u042d\u042e"+ + "\u0003\u00edt\u0000\u042e\u042f\u0003\u00efu\u0000\u042f\u0430\u0003\u00eb"+ + "s\u0000\u0430\u0431\u0003\u00d9j\u0000\u0431\u0432\u0003\u00e3o\u0000"+ + "\u0432\u0433\u0003\u00d5h\u0000\u0433\u04d0\u0001\u0000\u0000\u0000\u0434"+ + "\u0435\u0003\u00efu\u0000\u0435\u0436\u0003\u00e5p\u0000\u0436\u0437\u0003"+ + "m4\u0000\u0437\u0438\u0003\u00edt\u0000\u0438\u0439\u0003\u00efu\u0000"+ + "\u0439\u043a\u0003\u00ebs\u0000\u043a\u04d0\u0001\u0000\u0000\u0000\u043b"+ + "\u043c\u0003\u00efu\u0000\u043c\u043d\u0003\u00e5p\u0000\u043d\u043e\u0003"+ + "m4\u0000\u043e\u043f\u0003\u00cbc\u0000\u043f\u0440\u0003\u00e5p\u0000"+ + "\u0440\u0441\u0003\u00e5p\u0000\u0441\u0442\u0003\u00dfm\u0000\u0442\u04d0"+ + "\u0001\u0000\u0000\u0000\u0443\u0444\u0003\u00efu\u0000\u0444\u0445\u0003"+ + "\u00e5p\u0000\u0445\u0446\u0003m4\u0000\u0446\u0447\u0003\u00cbc\u0000"+ + "\u0447\u0448\u0003\u00e5p\u0000\u0448\u0449\u0003\u00e5p\u0000\u0449\u044a"+ + "\u0003\u00dfm\u0000\u044a\u044b\u0003\u00d1f\u0000\u044b\u044c\u0003\u00c9"+ + "b\u0000\u044c\u044d\u0003\u00e3o\u0000\u044d\u04d0\u0001\u0000\u0000\u0000"+ + "\u044e\u044f\u0003\u00efu\u0000\u044f\u0450\u0003\u00e5p\u0000\u0450\u0451"+ + "\u0003m4\u0000\u0451\u0452\u0003\u00cfe\u0000\u0452\u0453\u0003\u00c9"+ + "b\u0000\u0453\u0454\u0003\u00efu\u0000\u0454\u0455\u0003\u00d1f\u0000"+ + "\u0455\u0456\u0003\u00efu\u0000\u0456\u0457\u0003\u00d9j\u0000\u0457\u0458"+ + "\u0003\u00e1n\u0000\u0458\u0459\u0003\u00d1f\u0000\u0459\u04d0\u0001\u0000"+ + "\u0000\u0000\u045a\u045b\u0003\u00efu\u0000\u045b\u045c\u0003\u00e5p\u0000"+ + "\u045c\u045d\u0003m4\u0000\u045d\u045e\u0003\u00cfe\u0000\u045e\u045f"+ + "\u0003\u00efu\u0000\u045f\u04d0\u0001\u0000\u0000\u0000\u0460\u0461\u0003"+ + "\u00efu\u0000\u0461\u0462\u0003\u00e5p\u0000\u0462\u0463\u0003m4\u0000"+ + "\u0463\u0464\u0003\u00cfe\u0000\u0464\u0465\u0003\u00cbc\u0000\u0465\u0466"+ + "\u0003\u00dfm\u0000\u0466\u04d0\u0001\u0000\u0000\u0000\u0467\u0468\u0003"+ + "\u00efu\u0000\u0468\u0469\u0003\u00e5p\u0000\u0469\u046a\u0003m4\u0000"+ + "\u046a\u046b\u0003\u00cfe\u0000\u046b\u046c\u0003\u00e5p\u0000\u046c\u046d"+ + "\u0003\u00f1v\u0000\u046d\u046e\u0003\u00cbc\u0000\u046e\u046f\u0003\u00df"+ + "m\u0000\u046f\u0470\u0003\u00d1f\u0000\u0470\u04d0\u0001\u0000\u0000\u0000"+ + "\u0471\u0472\u0003\u00efu\u0000\u0472\u0473\u0003\u00e5p\u0000\u0473\u0474"+ + "\u0003m4\u0000\u0474\u0475\u0003\u00cfe\u0000\u0475\u0476\u0003\u00d1"+ + "f\u0000\u0476\u0477\u0003\u00d5h\u0000\u0477\u0478\u0003\u00ebs\u0000"+ + "\u0478\u0479\u0003\u00d1f\u0000\u0479\u047a\u0003\u00d1f\u0000\u047a\u047b"+ + "\u0003\u00edt\u0000\u047b\u04d0\u0001\u0000\u0000\u0000\u047c\u047d\u0003"+ + "\u00efu\u0000\u047d\u047e\u0003\u00e5p\u0000\u047e\u047f\u0003m4\u0000"+ + "\u047f\u0480\u0003\u00d9j\u0000\u0480\u0481\u0003\u00e3o\u0000\u0481\u0482"+ + "\u0003\u00efu\u0000\u0482\u04d0\u0001\u0000\u0000\u0000\u0483\u0484\u0003"+ + "\u00efu\u0000\u0484\u0485\u0003\u00e5p\u0000\u0485\u0486\u0003m4\u0000"+ + "\u0486\u0487\u0003\u00d9j\u0000\u0487\u0488\u0003\u00e3o\u0000\u0488\u0489"+ + "\u0003\u00efu\u0000\u0489\u048a\u0003\u00d1f\u0000\u048a\u048b\u0003\u00d5"+ + "h\u0000\u048b\u048c\u0003\u00d1f\u0000\u048c\u048d\u0003\u00ebs\u0000"+ + "\u048d\u04d0\u0001\u0000\u0000\u0000\u048e\u048f\u0003\u00efu\u0000\u048f"+ + "\u0490\u0003\u00e5p\u0000\u0490\u0491\u0003m4\u0000\u0491\u0492\u0003"+ + "\u00d9j\u0000\u0492\u0493\u0003\u00e7q\u0000\u0493\u04d0\u0001\u0000\u0000"+ + "\u0000\u0494\u0495\u0003\u00efu\u0000\u0495\u0496\u0003\u00e5p\u0000\u0496"+ + "\u0497\u0003m4\u0000\u0497\u0498\u0003\u00dfm\u0000\u0498\u0499\u0003"+ + "\u00e5p\u0000\u0499\u049a\u0003\u00e3o\u0000\u049a\u049b\u0003\u00d5h"+ + "\u0000\u049b\u04d0\u0001\u0000\u0000\u0000\u049c\u049d\u0003\u00efu\u0000"+ + "\u049d\u049e\u0003\u00e5p\u0000\u049e\u049f\u0003m4\u0000\u049f\u04a0"+ + "\u0003\u00ebs\u0000\u04a0\u04a1\u0003\u00c9b\u0000\u04a1\u04a2\u0003\u00cf"+ + "e\u0000\u04a2\u04a3\u0003\u00d9j\u0000\u04a3\u04a4\u0003\u00c9b\u0000"+ + "\u04a4\u04a5\u0003\u00e3o\u0000\u04a5\u04a6\u0003\u00edt\u0000\u04a6\u04d0"+ + "\u0001\u0000\u0000\u0000\u04a7\u04a8\u0003\u00efu\u0000\u04a8\u04a9\u0003"+ + "\u00e5p\u0000\u04a9\u04aa\u0003m4\u0000\u04aa\u04ab\u0003\u00f3w\u0000"+ + "\u04ab\u04ac\u0003\u00d1f\u0000\u04ac\u04ad\u0003\u00ebs\u0000\u04ad\u04ae"+ + "\u0003\u00edt\u0000\u04ae\u04af\u0003\u00d9j\u0000\u04af\u04b0\u0003\u00e5"+ + "p\u0000\u04b0\u04b1\u0003\u00e3o\u0000\u04b1\u04d0\u0001\u0000\u0000\u0000"+ + "\u04b2\u04b3\u0003\u00efu\u0000\u04b3\u04b4\u0003\u00e5p\u0000\u04b4\u04b5"+ + "\u0003m4\u0000\u04b5\u04b6\u0003\u00f1v\u0000\u04b6\u04b7\u0003\u00e3"+ + "o\u0000\u04b7\u04b8\u0003\u00edt\u0000\u04b8\u04b9\u0003\u00d9j\u0000"+ + "\u04b9\u04ba\u0003\u00d5h\u0000\u04ba\u04bb\u0003\u00e3o\u0000\u04bb\u04bc"+ + "\u0003\u00d1f\u0000\u04bc\u04bd\u0003\u00cfe\u0000\u04bd\u04be\u0003m"+ + "4\u0000\u04be\u04bf\u0003\u00dfm\u0000\u04bf\u04c0\u0003\u00e5p\u0000"+ + "\u04c0\u04c1\u0003\u00e3o\u0000\u04c1\u04c2\u0003\u00d5h\u0000\u04c2\u04d0"+ + "\u0001\u0000\u0000\u0000\u04c3\u04c4\u0003\u00efu\u0000\u04c4\u04c5\u0003"+ + "\u00e5p\u0000\u04c5\u04c6\u0003m4\u0000\u04c6\u04c7\u0003\u00d5h\u0000"+ + "\u04c7\u04c8\u0003\u00d1f\u0000\u04c8\u04c9\u0003\u00e5p\u0000\u04c9\u04ca"+ + "\u0003\u00e7q\u0000\u04ca\u04cb\u0003\u00e5p\u0000\u04cb\u04cc\u0003\u00d9"+ + "j\u0000\u04cc\u04cd\u0003\u00e3o\u0000\u04cd\u04ce\u0003\u00efu\u0000"+ + "\u04ce\u04d0\u0001\u0000\u0000\u0000\u04cf\u0315\u0001\u0000\u0000\u0000"+ + "\u04cf\u031b\u0001\u0000\u0000\u0000\u04cf\u031f\u0001\u0000\u0000\u0000"+ + "\u04cf\u0323\u0001\u0000\u0000\u0000\u04cf\u0328\u0001\u0000\u0000\u0000"+ + "\u04cf\u032b\u0001\u0000\u0000\u0000\u04cf\u032f\u0001\u0000\u0000\u0000"+ + "\u04cf\u0330\u0001\u0000\u0000\u0000\u04cf\u033a\u0001\u0000\u0000\u0000"+ + "\u04cf\u033f\u0001\u0000\u0000\u0000\u04cf\u0346\u0001\u0000\u0000\u0000"+ + "\u04cf\u034f\u0001\u0000\u0000\u0000\u04cf\u0358\u0001\u0000\u0000\u0000"+ + "\u04cf\u035d\u0001\u0000\u0000\u0000\u04cf\u0361\u0001\u0000\u0000\u0000"+ + "\u04cf\u0367\u0001\u0000\u0000\u0000\u04cf\u0373\u0001\u0000\u0000\u0000"+ + "\u04cf\u037f\u0001\u0000\u0000\u0000\u04cf\u038a\u0001\u0000\u0000\u0000"+ + "\u04cf\u0395\u0001\u0000\u0000\u0000\u04cf\u03a1\u0001\u0000\u0000\u0000"+ + "\u04cf\u03ae\u0001\u0000\u0000\u0000\u04cf\u03b8\u0001\u0000\u0000\u0000"+ + "\u04cf\u03c4\u0001\u0000\u0000\u0000\u04cf\u03c9\u0001\u0000\u0000\u0000"+ + "\u04cf\u03d0\u0001\u0000\u0000\u0000\u04cf\u03d7\u0001\u0000\u0000\u0000"+ + "\u04cf\u03de\u0001\u0000\u0000\u0000\u04cf\u03e5\u0001\u0000\u0000\u0000"+ + "\u04cf\u03ec\u0001\u0000\u0000\u0000\u04cf\u03f5\u0001\u0000\u0000\u0000"+ + "\u04cf\u03ff\u0001\u0000\u0000\u0000\u04cf\u0407\u0001\u0000\u0000\u0000"+ + "\u04cf\u0411\u0001\u0000\u0000\u0000\u04cf\u041b\u0001\u0000\u0000\u0000"+ + "\u04cf\u0424\u0001\u0000\u0000\u0000\u04cf\u042a\u0001\u0000\u0000\u0000"+ + "\u04cf\u0434\u0001\u0000\u0000\u0000\u04cf\u043b\u0001\u0000\u0000\u0000"+ + "\u04cf\u0443\u0001\u0000\u0000\u0000\u04cf\u044e\u0001\u0000\u0000\u0000"+ + "\u04cf\u045a\u0001\u0000\u0000\u0000\u04cf\u0460\u0001\u0000\u0000\u0000"+ + "\u04cf\u0467\u0001\u0000\u0000\u0000\u04cf\u0471\u0001\u0000\u0000\u0000"+ + "\u04cf\u047c\u0001\u0000\u0000\u0000\u04cf\u0483\u0001\u0000\u0000\u0000"+ + "\u04cf\u048e\u0001\u0000\u0000\u0000\u04cf\u0494\u0001\u0000\u0000\u0000"+ + "\u04cf\u049c\u0001\u0000\u0000\u0000\u04cf\u04a7\u0001\u0000\u0000\u0000"+ + "\u04cf\u04b2\u0001\u0000\u0000\u0000\u04cf\u04c3\u0001\u0000\u0000\u0000"+ + "\u04d0\u008a\u0001\u0000\u0000\u0000\u04d1\u04d2\u0003\u00c9b\u0000\u04d2"+ + "\u04d3\u0003\u00f3w\u0000\u04d3\u04d4\u0003\u00d5h\u0000\u04d4\u0569\u0001"+ + "\u0000\u0000\u0000\u04d5\u04d6\u0003\u00e1n\u0000\u04d6\u04d7\u0003\u00d9"+ + "j\u0000\u04d7\u04d8\u0003\u00e3o\u0000\u04d8\u0569\u0001\u0000\u0000\u0000"+ + "\u04d9\u04da\u0003\u00e1n\u0000\u04da\u04db\u0003\u00c9b\u0000\u04db\u04dc"+ + "\u0003\u00f7y\u0000\u04dc\u0569\u0001\u0000\u0000\u0000\u04dd\u04de\u0003"+ + "\u00edt\u0000\u04de\u04df\u0003\u00f1v\u0000\u04df\u04e0\u0003\u00e1n"+ + "\u0000\u04e0\u0569\u0001\u0000\u0000\u0000\u04e1\u04e2\u0003\u00cdd\u0000"+ + "\u04e2\u04e3\u0003\u00e5p\u0000\u04e3\u04e4\u0003\u00f1v\u0000\u04e4\u04e5"+ + "\u0003\u00e3o\u0000\u04e5\u04e6\u0003\u00efu\u0000\u04e6\u0569\u0001\u0000"+ + "\u0000\u0000\u04e7\u04e8\u0003\u00cdd\u0000\u04e8\u04e9\u0003\u00e5p\u0000"+ + "\u04e9\u04ea\u0003\u00f1v\u0000\u04ea\u04eb\u0003\u00e3o\u0000\u04eb\u04ec"+ + "\u0003\u00efu\u0000\u04ec\u04ed\u0003m4\u0000\u04ed\u04ee\u0003\u00cf"+ + "e\u0000\u04ee\u04ef\u0003\u00d9j\u0000\u04ef\u04f0\u0003\u00edt\u0000"+ + "\u04f0\u04f1\u0003\u00efu\u0000\u04f1\u04f2\u0003\u00d9j\u0000\u04f2\u04f3"+ + "\u0003\u00e3o\u0000\u04f3\u04f4\u0003\u00cdd\u0000\u04f4\u04f5\u0003\u00ef"+ + "u\u0000\u04f5\u0569\u0001\u0000\u0000\u0000\u04f6\u04f7\u0003\u00e7q\u0000"+ + "\u04f7\u04f8\u0003\u00d1f\u0000\u04f8\u04f9\u0003\u00ebs\u0000\u04f9\u04fa"+ + "\u0003\u00cdd\u0000\u04fa\u04fb\u0003\u00d1f\u0000\u04fb\u04fc\u0003\u00e3"+ + "o\u0000\u04fc\u04fd\u0003\u00efu\u0000\u04fd\u04fe\u0003\u00d9j\u0000"+ + "\u04fe\u04ff\u0003\u00dfm\u0000\u04ff\u0500\u0003\u00d1f\u0000\u0500\u0569"+ + "\u0001\u0000\u0000\u0000\u0501\u0502\u0003\u00e1n\u0000\u0502\u0503\u0003"+ + "\u00d1f\u0000\u0503\u0504\u0003\u00cfe\u0000\u0504\u0505\u0003\u00d9j"+ + "\u0000\u0505\u0506\u0003\u00c9b\u0000\u0506\u0507\u0003\u00e3o\u0000\u0507"+ + "\u0569\u0001\u0000\u0000\u0000\u0508\u0509\u0003\u00e1n\u0000\u0509\u050a"+ + "\u0003\u00d1f\u0000\u050a\u050b\u0003\u00cfe\u0000\u050b\u050c\u0003\u00d9"+ + "j\u0000\u050c\u050d\u0003\u00c9b\u0000\u050d\u050e\u0003\u00e3o\u0000"+ + "\u050e\u050f\u0003m4\u0000\u050f\u0510\u0003\u00c9b\u0000\u0510\u0511"+ + "\u0003\u00cbc\u0000\u0511\u0512\u0003\u00edt\u0000\u0512\u0513\u0003\u00e5"+ + "p\u0000\u0513\u0514\u0003\u00dfm\u0000\u0514\u0515\u0003\u00f1v\u0000"+ + "\u0515\u0516\u0003\u00efu\u0000\u0516\u0517\u0003\u00d1f\u0000\u0517\u0518"+ + "\u0003m4\u0000\u0518\u0519\u0003\u00cfe\u0000\u0519\u051a\u0003\u00d1"+ + "f\u0000\u051a\u051b\u0003\u00f3w\u0000\u051b\u051c\u0003\u00d9j\u0000"+ + "\u051c\u051d\u0003\u00c9b\u0000\u051d\u051e\u0003\u00efu\u0000\u051e\u051f"+ + "\u0003\u00d9j\u0000\u051f\u0520\u0003\u00e5p\u0000\u0520\u0521\u0003\u00e3"+ + "o\u0000\u0521\u0569\u0001\u0000\u0000\u0000\u0522\u0523\u0003\u00c9b\u0000"+ + "\u0523\u0524\u0003\u00cdd\u0000\u0524\u0525\u0003\u00e5p\u0000\u0525\u0526"+ + "\u0003\u00edt\u0000\u0526\u0569\u0001\u0000\u0000\u0000\u0527\u0528\u0003"+ + "\u00c9b\u0000\u0528\u0529\u0003\u00edt\u0000\u0529\u052a\u0003\u00d9j"+ + "\u0000\u052a\u052b\u0003\u00e3o\u0000\u052b\u0569\u0001\u0000\u0000\u0000"+ + "\u052c\u052d\u0003\u00c9b\u0000\u052d\u052e\u0003\u00efu\u0000\u052e\u052f"+ + "\u0003\u00c9b\u0000\u052f\u0530\u0003\u00e3o\u0000\u0530\u0569\u0001\u0000"+ + "\u0000\u0000\u0531\u0532\u0003\u00c9b\u0000\u0532\u0533\u0003\u00efu\u0000"+ + "\u0533\u0534\u0003\u00c9b\u0000\u0534\u0535\u0003\u00e3o\u0000\u0535\u0536"+ + "\u00052\u0000\u0000\u0536\u0569\u0001\u0000\u0000\u0000\u0537\u0538\u0003"+ + "\u00cdd\u0000\u0538\u0539\u0003\u00d1f\u0000\u0539\u053a\u0003\u00d9j"+ + "\u0000\u053a\u053b\u0003\u00dfm\u0000\u053b\u0569\u0001\u0000\u0000\u0000"+ + "\u053c\u053d\u0003\u00cdd\u0000\u053d\u053e\u0003\u00e5p\u0000\u053e\u053f"+ + "\u0003\u00edt\u0000\u053f\u0569\u0001\u0000\u0000\u0000\u0540\u0541\u0003"+ + "\u00cdd\u0000\u0541\u0542\u0003\u00e5p\u0000\u0542\u0543\u0003\u00edt"+ + "\u0000\u0543\u0544\u0003\u00d7i\u0000\u0544\u0569\u0001\u0000\u0000\u0000"+ + "\u0545\u0546\u0003\u00d3g\u0000\u0546\u0547\u0003\u00dfm\u0000\u0547\u0548"+ + "\u0003\u00e5p\u0000\u0548\u0549\u0003\u00e5p\u0000\u0549\u054a\u0003\u00eb"+ + "s\u0000\u054a\u0569\u0001\u0000\u0000\u0000\u054b\u054c\u0003\u00dfm\u0000"+ + "\u054c\u054d\u0003\u00efu\u0000\u054d\u054e\u0003\u00ebs\u0000\u054e\u054f"+ + "\u0003\u00d9j\u0000\u054f\u0550\u0003\u00e1n\u0000\u0550\u0569\u0001\u0000"+ + "\u0000\u0000\u0551\u0552\u0003\u00edt\u0000\u0552\u0553\u0003\u00d9j\u0000"+ + "\u0553\u0554\u0003\u00e3o\u0000\u0554\u0569\u0001\u0000\u0000\u0000\u0555"+ + "\u0556\u0003\u00edt\u0000\u0556\u0557\u0003\u00d9j\u0000\u0557\u0558\u0003"+ + "\u00e3o\u0000\u0558\u0559\u0003\u00d7i\u0000\u0559\u0569\u0001\u0000\u0000"+ + "\u0000\u055a\u055b\u0003\u00edt\u0000\u055b\u055c\u0003\u00e9r\u0000\u055c"+ + "\u055d\u0003\u00ebs\u0000\u055d\u055e\u0003\u00efu\u0000\u055e\u0569\u0001"+ + "\u0000\u0000\u0000\u055f\u0560\u0003\u00efu\u0000\u0560\u0561\u0003\u00c9"+ + "b\u0000\u0561\u0562\u0003\u00e3o\u0000\u0562\u0569\u0001\u0000\u0000\u0000"+ + "\u0563\u0564\u0003\u00efu\u0000\u0564\u0565\u0003\u00c9b\u0000\u0565\u0566"+ + "\u0003\u00e3o\u0000\u0566\u0567\u0003\u00d7i\u0000\u0567\u0569\u0001\u0000"+ + "\u0000\u0000\u0568\u04d1\u0001\u0000\u0000\u0000\u0568\u04d5\u0001\u0000"+ + "\u0000\u0000\u0568\u04d9\u0001\u0000\u0000\u0000\u0568\u04dd\u0001\u0000"+ + "\u0000\u0000\u0568\u04e1\u0001\u0000\u0000\u0000\u0568\u04e7\u0001\u0000"+ + "\u0000\u0000\u0568\u04f6\u0001\u0000\u0000\u0000\u0568\u0501\u0001\u0000"+ + "\u0000\u0000\u0568\u0508\u0001\u0000\u0000\u0000\u0568\u0522\u0001\u0000"+ + "\u0000\u0000\u0568\u0527\u0001\u0000\u0000\u0000\u0568\u052c\u0001\u0000"+ + "\u0000\u0000\u0568\u0531\u0001\u0000\u0000\u0000\u0568\u0537\u0001\u0000"+ + "\u0000\u0000\u0568\u053c\u0001\u0000\u0000\u0000\u0568\u0540\u0001\u0000"+ + "\u0000\u0000\u0568\u0545\u0001\u0000\u0000\u0000\u0568\u054b\u0001\u0000"+ + "\u0000\u0000\u0568\u0551\u0001\u0000\u0000\u0000\u0568\u0555\u0001\u0000"+ + "\u0000\u0000\u0568\u055a\u0001\u0000\u0000\u0000\u0568\u055f\u0001\u0000"+ + "\u0000\u0000\u0568\u0563\u0001\u0000\u0000\u0000\u0569\u008c\u0001\u0000"+ + "\u0000\u0000\u056a\u056b\u0003\u00cdd\u0000\u056b\u056c\u0003\u00d9j\u0000"+ + "\u056c\u056d\u0003\u00cfe\u0000\u056d\u056e\u0003\u00ebs\u0000\u056e\u056f"+ + "\u0003m4\u0000\u056f\u0570\u0003\u00e1n\u0000\u0570\u0571\u0003\u00c9"+ + "b\u0000\u0571\u0572\u0003\u00efu\u0000\u0572\u0573\u0003\u00cdd\u0000"+ + "\u0573\u0574\u0003\u00d7i\u0000\u0574\u008e\u0001\u0000\u0000\u0000\u0575"+ + "\u057c\u0003;\u001b\u0000\u0576\u057b\u0003;\u001b\u0000\u0577\u057b\u0003"+ + "9\u001a\u0000\u0578\u057b\u0005_\u0000\u0000\u0579\u057b\u0003{;\u0000"+ + "\u057a\u0576\u0001\u0000\u0000\u0000\u057a\u0577\u0001\u0000\u0000\u0000"+ + "\u057a\u0578\u0001\u0000\u0000\u0000\u057a\u0579\u0001\u0000\u0000\u0000"+ + "\u057b\u057e\u0001\u0000\u0000\u0000\u057c\u057a\u0001\u0000\u0000\u0000"+ + "\u057c\u057d\u0001\u0000\u0000\u0000\u057d\u0589\u0001\u0000\u0000\u0000"+ + "\u057e\u057c\u0001\u0000\u0000\u0000\u057f\u0584\u0007\b\u0000\u0000\u0580"+ + "\u0585\u0003;\u001b\u0000\u0581\u0585\u00039\u001a\u0000\u0582\u0585\u0005"+ + "_\u0000\u0000\u0583\u0585\u0003{;\u0000\u0584\u0580\u0001\u0000\u0000"+ + "\u0000\u0584\u0581\u0001\u0000\u0000\u0000\u0584\u0582\u0001\u0000\u0000"+ + "\u0000\u0584\u0583\u0001\u0000\u0000\u0000\u0585\u0586\u0001\u0000\u0000"+ + "\u0000\u0586\u0584\u0001\u0000\u0000\u0000\u0586\u0587\u0001\u0000\u0000"+ + "\u0000\u0587\u0589\u0001\u0000\u0000\u0000\u0588\u0575\u0001\u0000\u0000"+ + "\u0000\u0588\u057f\u0001\u0000\u0000\u0000\u0589\u0090\u0001\u0000\u0000"+ + "\u0000\u058a\u0590\u0005`\u0000\u0000\u058b\u058f\b\t\u0000\u0000\u058c"+ + "\u058d\u0005`\u0000\u0000\u058d\u058f\u0005`\u0000\u0000\u058e\u058b\u0001"+ + "\u0000\u0000\u0000\u058e\u058c\u0001\u0000\u0000\u0000\u058f\u0592\u0001"+ + "\u0000\u0000\u0000\u0590\u058e\u0001\u0000\u0000\u0000\u0590\u0591\u0001"+ + "\u0000\u0000\u0000\u0591\u0593\u0001\u0000\u0000\u0000\u0592\u0590\u0001"+ + "\u0000\u0000\u0000\u0593\u0594\u0005`\u0000\u0000\u0594\u0092\u0001\u0000"+ + "\u0000\u0000\u0595\u0596\u0003\'\u0011\u0000\u0596\u0597\u0001\u0000\u0000"+ + "\u0000\u0597\u0598\u0006G\u0004\u0000\u0598\u0094\u0001\u0000\u0000\u0000"+ + "\u0599\u059a\u0003)\u0012\u0000\u059a\u059b\u0001\u0000\u0000\u0000\u059b"+ + "\u059c\u0006H\u0004\u0000\u059c\u0096\u0001\u0000\u0000\u0000\u059d\u059e"+ + "\u0003+\u0013\u0000\u059e\u059f\u0001\u0000\u0000\u0000\u059f\u05a0\u0006"+ + "I\u0004\u0000\u05a0\u0098\u0001\u0000\u0000\u0000\u05a1\u05a2\u0005|\u0000"+ + "\u0000\u05a2\u05a3\u0001\u0000\u0000\u0000\u05a3\u05a4\u0006J\u0007\u0000"+ + "\u05a4\u05a5\u0006J\b\u0000\u05a5\u009a\u0001\u0000\u0000\u0000\u05a6"+ + "\u05a7\u0005[\u0000\u0000\u05a7\u05a8\u0001\u0000\u0000\u0000\u05a8\u05a9"+ + "\u0006K\u0005\u0000\u05a9\u05aa\u0006K\u0002\u0000\u05aa\u05ab\u0006K"+ + "\u0002\u0000\u05ab\u009c\u0001\u0000\u0000\u0000\u05ac\u05ad\u0005]\u0000"+ + "\u0000\u05ad\u05ae\u0001\u0000\u0000\u0000\u05ae\u05af\u0006L\b\u0000"+ + "\u05af\u05b0\u0006L\b\u0000\u05b0\u05b1\u0006L\t\u0000\u05b1\u009e\u0001"+ + "\u0000\u0000\u0000\u05b2\u05b3\u0005,\u0000\u0000\u05b3\u05b4\u0001\u0000"+ + "\u0000\u0000\u05b4\u05b5\u0006M\n\u0000\u05b5\u00a0\u0001\u0000\u0000"+ + "\u0000\u05b6\u05b7\u0005=\u0000\u0000\u05b7\u05b8\u0001\u0000\u0000\u0000"+ + "\u05b8\u05b9\u0006N\u000b\u0000\u05b9\u00a2\u0001\u0000\u0000\u0000\u05ba"+ + "\u05bb\u0003\u00e1n\u0000\u05bb\u05bc\u0003\u00d1f\u0000\u05bc\u05bd\u0003"+ + "\u00efu\u0000\u05bd\u05be\u0003\u00c9b\u0000\u05be\u05bf\u0003\u00cfe"+ + "\u0000\u05bf\u05c0\u0003\u00c9b\u0000\u05c0\u05c1\u0003\u00efu\u0000\u05c1"+ + "\u05c2\u0003\u00c9b\u0000\u05c2\u00a4\u0001\u0000\u0000\u0000\u05c3\u05c5"+ + "\u0003\u00a7Q\u0000\u05c4\u05c3\u0001\u0000\u0000\u0000\u05c5\u05c6\u0001"+ + "\u0000\u0000\u0000\u05c6\u05c4\u0001\u0000\u0000\u0000\u05c6\u05c7\u0001"+ + "\u0000\u0000\u0000\u05c7\u00a6\u0001\u0000\u0000\u0000\u05c8\u05ca\b\n"+ + "\u0000\u0000\u05c9\u05c8\u0001\u0000\u0000\u0000\u05ca\u05cb\u0001\u0000"+ + "\u0000\u0000\u05cb\u05c9\u0001\u0000\u0000\u0000\u05cb\u05cc\u0001\u0000"+ + "\u0000\u0000\u05cc\u05d0\u0001\u0000\u0000\u0000\u05cd\u05ce\u0005/\u0000"+ + "\u0000\u05ce\u05d0\b\u000b\u0000\u0000\u05cf\u05c9\u0001\u0000\u0000\u0000"+ + "\u05cf\u05cd\u0001\u0000\u0000\u0000\u05d0\u00a8\u0001\u0000\u0000\u0000"+ + "\u05d1\u05d2\u0003\u0091F\u0000\u05d2\u00aa\u0001\u0000\u0000\u0000\u05d3"+ + "\u05d4\u0003\'\u0011\u0000\u05d4\u05d5\u0001\u0000\u0000\u0000\u05d5\u05d6"+ + "\u0006S\u0004\u0000\u05d6\u00ac\u0001\u0000\u0000\u0000\u05d7\u05d8\u0003"+ + ")\u0012\u0000\u05d8\u05d9\u0001\u0000\u0000\u0000\u05d9\u05da\u0006T\u0004"+ + "\u0000\u05da\u00ae\u0001\u0000\u0000\u0000\u05db\u05dc\u0003+\u0013\u0000"+ + "\u05dc\u05dd\u0001\u0000\u0000\u0000\u05dd\u05de\u0006U\u0004\u0000\u05de"+ + "\u00b0\u0001\u0000\u0000\u0000\u05df\u05e0\u0003\u00e5p\u0000\u05e0\u05e1"+ + "\u0003\u00e3o\u0000\u05e1\u00b2\u0001\u0000\u0000\u0000\u05e2\u05e3\u0003"+ + "\u00f5x\u0000\u05e3\u05e4\u0003\u00d9j\u0000\u05e4\u05e5\u0003\u00efu"+ + "\u0000\u05e5\u05e6\u0003\u00d7i\u0000\u05e6\u00b4\u0001\u0000\u0000\u0000"+ + "\u05e7\u05e8\u0005|\u0000\u0000\u05e8\u05e9\u0001\u0000\u0000\u0000\u05e9"+ + "\u05ea\u0006X\u0007\u0000\u05ea\u05eb\u0006X\b\u0000\u05eb\u00b6\u0001"+ + "\u0000\u0000\u0000\u05ec\u05ed\u0005]\u0000\u0000\u05ed\u05ee\u0001\u0000"+ + "\u0000\u0000\u05ee\u05ef\u0006Y\b\u0000\u05ef\u05f0\u0006Y\b\u0000\u05f0"+ + "\u05f1\u0006Y\t\u0000\u05f1\u00b8\u0001\u0000\u0000\u0000\u05f2\u05f3"+ + "\u0005,\u0000\u0000\u05f3\u05f4\u0001\u0000\u0000\u0000\u05f4\u05f5\u0006"+ + "Z\n\u0000\u05f5\u00ba\u0001\u0000\u0000\u0000\u05f6\u05f7\u0005=\u0000"+ + "\u0000\u05f7\u05f8\u0001\u0000\u0000\u0000\u05f8\u05f9\u0006[\u000b\u0000"+ + "\u05f9\u00bc\u0001\u0000\u0000\u0000\u05fa\u05fc\u0003\u00bf]\u0000\u05fb"+ + "\u05fa\u0001\u0000\u0000\u0000\u05fc\u05fd\u0001\u0000\u0000\u0000\u05fd"+ + "\u05fb\u0001\u0000\u0000\u0000\u05fd\u05fe\u0001\u0000\u0000\u0000\u05fe"+ + "\u00be\u0001\u0000\u0000\u0000\u05ff\u0601\b\n\u0000\u0000\u0600\u05ff"+ + "\u0001\u0000\u0000\u0000\u0601\u0602\u0001\u0000\u0000\u0000\u0602\u0600"+ + "\u0001\u0000\u0000\u0000\u0602\u0603\u0001\u0000\u0000\u0000\u0603\u0607"+ + "\u0001\u0000\u0000\u0000\u0604\u0605\u0005/\u0000\u0000\u0605\u0607\b"+ + "\u000b\u0000\u0000\u0606\u0600\u0001\u0000\u0000\u0000\u0606\u0604\u0001"+ + "\u0000\u0000\u0000\u0607\u00c0\u0001\u0000\u0000\u0000\u0608\u0609\u0003"+ + "\u0091F\u0000\u0609\u00c2\u0001\u0000\u0000\u0000\u060a\u060b\u0003\'"+ + "\u0011\u0000\u060b\u060c\u0001\u0000\u0000\u0000\u060c\u060d\u0006_\u0004"+ + "\u0000\u060d\u00c4\u0001\u0000\u0000\u0000\u060e\u060f\u0003)\u0012\u0000"+ + "\u060f\u0610\u0001\u0000\u0000\u0000\u0610\u0611\u0006`\u0004\u0000\u0611"+ + "\u00c6\u0001\u0000\u0000\u0000\u0612\u0613\u0003+\u0013\u0000\u0613\u0614"+ + "\u0001\u0000\u0000\u0000\u0614\u0615\u0006a\u0004\u0000\u0615\u00c8\u0001"+ + "\u0000\u0000\u0000\u0616\u0617\u0007\f\u0000\u0000\u0617\u00ca\u0001\u0000"+ + "\u0000\u0000\u0618\u0619\u0007\r\u0000\u0000\u0619\u00cc\u0001\u0000\u0000"+ + "\u0000\u061a\u061b\u0007\u000e\u0000\u0000\u061b\u00ce\u0001\u0000\u0000"+ + "\u0000\u061c\u061d\u0007\u000f\u0000\u0000\u061d\u00d0\u0001\u0000\u0000"+ + "\u0000\u061e\u061f\u0007\u0006\u0000\u0000\u061f\u00d2\u0001\u0000\u0000"+ + "\u0000\u0620\u0621\u0007\u0010\u0000\u0000\u0621\u00d4\u0001\u0000\u0000"+ + "\u0000\u0622\u0623\u0007\u0011\u0000\u0000\u0623\u00d6\u0001\u0000\u0000"+ + "\u0000\u0624\u0625\u0007\u0012\u0000\u0000\u0625\u00d8\u0001\u0000\u0000"+ + "\u0000\u0626\u0627\u0007\u0013\u0000\u0000\u0627\u00da\u0001\u0000\u0000"+ + "\u0000\u0628\u0629\u0007\u0014\u0000\u0000\u0629\u00dc\u0001\u0000\u0000"+ + "\u0000\u062a\u062b\u0007\u0015\u0000\u0000\u062b\u00de\u0001\u0000\u0000"+ + "\u0000\u062c\u062d\u0007\u0016\u0000\u0000\u062d\u00e0\u0001\u0000\u0000"+ + "\u0000\u062e\u062f\u0007\u0017\u0000\u0000\u062f\u00e2\u0001\u0000\u0000"+ + "\u0000\u0630\u0631\u0007\u0018\u0000\u0000\u0631\u00e4\u0001\u0000\u0000"+ + "\u0000\u0632\u0633\u0007\u0019\u0000\u0000\u0633\u00e6\u0001\u0000\u0000"+ + "\u0000\u0634\u0635\u0007\u001a\u0000\u0000\u0635\u00e8\u0001\u0000\u0000"+ + "\u0000\u0636\u0637\u0007\u001b\u0000\u0000\u0637\u00ea\u0001\u0000\u0000"+ + "\u0000\u0638\u0639\u0007\u001c\u0000\u0000\u0639\u00ec\u0001\u0000\u0000"+ + "\u0000\u063a\u063b\u0007\u001d\u0000\u0000\u063b\u00ee\u0001\u0000\u0000"+ + "\u0000\u063c\u063d\u0007\u001e\u0000\u0000\u063d\u00f0\u0001\u0000\u0000"+ + "\u0000\u063e\u063f\u0007\u001f\u0000\u0000\u063f\u00f2\u0001\u0000\u0000"+ + "\u0000\u0640\u0641\u0007 \u0000\u0000\u0641\u00f4\u0001\u0000\u0000\u0000"+ + "\u0642\u0643\u0007!\u0000\u0000\u0643\u00f6\u0001\u0000\u0000\u0000\u0644"+ + "\u0645\u0007\"\u0000\u0000\u0645\u00f8\u0001\u0000\u0000\u0000\u0646\u0647"+ + "\u0007#\u0000\u0000\u0647\u00fa\u0001\u0000\u0000\u0000\u0648\u0649\u0007"+ + "$\u0000\u0000\u0649\u00fc\u0001\u0000\u0000\u00000\u0000\u0001\u0002\u0003"+ + "\u0004\u018e\u0192\u0195\u019e\u01a0\u01ab\u01d4\u01d9\u01de\u01e0\u01eb"+ + "\u01f3\u01f6\u01f8\u01fd\u0202\u0208\u020f\u0214\u021a\u021d\u0225\u0229"+ + "\u028c\u02e0\u02ec\u0302\u0313\u04cf\u0568\u057a\u057c\u0584\u0586\u0588"+ + "\u058e\u0590\u05c6\u05cb\u05cf\u05fd\u0602\u0606\f\u0005\u0002\u0000\u0005"+ + "\u0001\u0000\u0005\u0003\u0000\u0005\u0004\u0000\u0000\u0001\u0000\u0007"+ + "#\u0000\u0005\u0000\u0000\u0007\u0018\u0000\u0004\u0000\u0000\u0007$\u0000"+ + "\u0007 \u0000\u0007\u001f\u0000"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/packages/kbn-esql/src/antlr/.antlr/esql_lexer.tokens b/packages/kbn-esql/src/antlr/.antlr/esql_lexer.tokens new file mode 100644 index 00000000000000..b72e97b9a2961b --- /dev/null +++ b/packages/kbn-esql/src/antlr/.antlr/esql_lexer.tokens @@ -0,0 +1,98 @@ +DISSECT=1 +GROK=2 +EVAL=3 +EXPLAIN=4 +FROM=5 +ROW=6 +STATS=7 +WHERE=8 +SORT=9 +MV_EXPAND=10 +LIMIT=11 +PROJECT=12 +DROP=13 +RENAME=14 +SHOW=15 +ENRICH=16 +KEEP=17 +LINE_COMMENT=18 +MULTILINE_COMMENT=19 +WS=20 +EXPLAIN_WS=21 +EXPLAIN_LINE_COMMENT=22 +EXPLAIN_MULTILINE_COMMENT=23 +PIPE=24 +STRING=25 +INTEGER_LITERAL=26 +DECIMAL_LITERAL=27 +BY=28 +DATE_LITERAL=29 +AND=30 +ASSIGN=31 +COMMA=32 +DOT=33 +LP=34 +OPENING_BRACKET=35 +CLOSING_BRACKET=36 +NOT=37 +LIKE=38 +RLIKE=39 +IN=40 +IS=41 +AS=42 +NULL=43 +OR=44 +RP=45 +UNDERSCORE=46 +INFO=47 +FUNCTIONS=48 +BOOLEAN_VALUE=49 +COMPARISON_OPERATOR=50 +PLUS=51 +MINUS=52 +ASTERISK=53 +SLASH=54 +PERCENT=55 +TEN=56 +ORDERING=57 +NULLS_ORDERING=58 +NULLS_ORDERING_DIRECTION=59 +MATH_FUNCTION=60 +UNARY_FUNCTION=61 +WHERE_FUNCTIONS=62 +UNQUOTED_IDENTIFIER=63 +QUOTED_IDENTIFIER=64 +EXPR_LINE_COMMENT=65 +EXPR_MULTILINE_COMMENT=66 +EXPR_WS=67 +METADATA=68 +SRC_UNQUOTED_IDENTIFIER=69 +SRC_QUOTED_IDENTIFIER=70 +SRC_LINE_COMMENT=71 +SRC_MULTILINE_COMMENT=72 +SRC_WS=73 +ON=74 +WITH=75 +ENR_UNQUOTED_IDENTIFIER=76 +ENR_QUOTED_IDENTIFIER=77 +ENR_LINE_COMMENT=78 +ENR_MULTILINE_COMMENT=79 +ENR_WS=80 +EXPLAIN_PIPE=81 +'by'=28 +'and'=30 +'.'=33 +'('=34 +']'=36 +'or'=44 +')'=45 +'_'=46 +'info'=47 +'functions'=48 +'+'=51 +'-'=52 +'*'=53 +'/'=54 +'%'=55 +'10'=56 +'nulls'=58 diff --git a/packages/kbn-esql/src/antlr/.antlr/esql_parser.interp b/packages/kbn-esql/src/antlr/.antlr/esql_parser.interp new file mode 100644 index 00000000000000..72a8d73c77d6df --- /dev/null +++ b/packages/kbn-esql/src/antlr/.antlr/esql_parser.interp @@ -0,0 +1,256 @@ +token literal names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +'|' +null +null +null +null +null +null +'=' +',' +null +'.' +null +null +null +'(' +null +null +null +null +null +null +null +'?' +null +')' +null +'==' +'!=' +'<' +'<=' +'>' +'>=' +'+' +'-' +'*' +'/' +'%' +null +']' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +DISSECT +DROP +ENRICH +EVAL +EXPLAIN +FROM +GROK +INLINESTATS +KEEP +LIMIT +MV_EXPAND +PROJECT +RENAME +ROW +SHOW +SORT +STATS +WHERE +UNKNOWN_CMD +LINE_COMMENT +MULTILINE_COMMENT +WS +EXPLAIN_WS +EXPLAIN_LINE_COMMENT +EXPLAIN_MULTILINE_COMMENT +PIPE +STRING +INTEGER_LITERAL +DECIMAL_LITERAL +BY +AND +ASC +ASSIGN +COMMA +DESC +DOT +FALSE +FIRST +LAST +LP +IN +IS +LIKE +NOT +NULL +NULLS +OR +PARAM +RLIKE +RP +TRUE +EQ +NEQ +LT +LTE +GT +GTE +PLUS +MINUS +ASTERISK +SLASH +PERCENT +OPENING_BRACKET +CLOSING_BRACKET +UNQUOTED_IDENTIFIER +QUOTED_IDENTIFIER +EXPR_LINE_COMMENT +EXPR_MULTILINE_COMMENT +EXPR_WS +METADATA +FROM_UNQUOTED_IDENTIFIER +FROM_LINE_COMMENT +FROM_MULTILINE_COMMENT +FROM_WS +PROJECT_UNQUOTED_IDENTIFIER +PROJECT_LINE_COMMENT +PROJECT_MULTILINE_COMMENT +PROJECT_WS +AS +RENAME_LINE_COMMENT +RENAME_MULTILINE_COMMENT +RENAME_WS +ON +WITH +ENRICH_LINE_COMMENT +ENRICH_MULTILINE_COMMENT +ENRICH_WS +ENRICH_FIELD_LINE_COMMENT +ENRICH_FIELD_MULTILINE_COMMENT +ENRICH_FIELD_WS +MVEXPAND_LINE_COMMENT +MVEXPAND_MULTILINE_COMMENT +MVEXPAND_WS +INFO +FUNCTIONS +SHOW_LINE_COMMENT +SHOW_MULTILINE_COMMENT +SHOW_WS + +rule names: +singleStatement +query +sourceCommand +processingCommand +whereCommand +booleanExpression +regexBooleanExpression +valueExpression +operatorExpression +primaryExpression +functionExpression +rowCommand +fields +field +fromCommand +metadata +evalCommand +statsCommand +inlinestatsCommand +grouping +fromIdentifier +qualifiedName +qualifiedNamePattern +identifier +identifierPattern +constant +limitCommand +sortCommand +orderExpression +keepCommand +dropCommand +renameCommand +renameClause +dissectCommand +grokCommand +mvExpandCommand +commandOptions +commandOption +booleanValue +numericValue +decimalValue +integerValue +string +comparisonOperator +explainCommand +subqueryExpression +showCommand +enrichCommand +enrichWithClause + + +atn: +[4, 1, 98, 519, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 108, 8, 1, 10, 1, 12, 1, 111, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 117, 8, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 132, 8, 3, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 144, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 151, 8, 5, 10, 5, 12, 5, 154, 9, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 161, 8, 5, 1, 5, 1, 5, 3, 5, 165, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 173, 8, 5, 10, 5, 12, 5, 176, 9, 5, 1, 6, 1, 6, 3, 6, 180, 8, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 187, 8, 6, 1, 6, 1, 6, 1, 6, 3, 6, 192, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 199, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 205, 8, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 5, 8, 213, 8, 8, 10, 8, 12, 8, 216, 9, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 225, 8, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 5, 10, 233, 8, 10, 10, 10, 12, 10, 236, 9, 10, 3, 10, 238, 8, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 5, 12, 248, 8, 12, 10, 12, 12, 12, 251, 9, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 258, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 5, 14, 264, 8, 14, 10, 14, 12, 14, 267, 9, 14, 1, 14, 3, 14, 270, 8, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 5, 15, 277, 8, 15, 10, 15, 12, 15, 280, 9, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 3, 17, 289, 8, 17, 1, 17, 1, 17, 3, 17, 293, 8, 17, 1, 18, 1, 18, 1, 18, 1, 18, 3, 18, 299, 8, 18, 1, 19, 1, 19, 1, 19, 5, 19, 304, 8, 19, 10, 19, 12, 19, 307, 9, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 5, 21, 314, 8, 21, 10, 21, 12, 21, 317, 9, 21, 1, 22, 1, 22, 1, 22, 5, 22, 322, 8, 22, 10, 22, 12, 22, 325, 9, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 5, 25, 344, 8, 25, 10, 25, 12, 25, 347, 9, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 5, 25, 355, 8, 25, 10, 25, 12, 25, 358, 9, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 5, 25, 366, 8, 25, 10, 25, 12, 25, 369, 9, 25, 1, 25, 1, 25, 3, 25, 373, 8, 25, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 5, 27, 382, 8, 27, 10, 27, 12, 27, 385, 9, 27, 1, 28, 1, 28, 3, 28, 389, 8, 28, 1, 28, 1, 28, 3, 28, 393, 8, 28, 1, 29, 1, 29, 1, 29, 1, 29, 5, 29, 399, 8, 29, 10, 29, 12, 29, 402, 9, 29, 1, 29, 1, 29, 1, 29, 1, 29, 5, 29, 408, 8, 29, 10, 29, 12, 29, 411, 9, 29, 3, 29, 413, 8, 29, 1, 30, 1, 30, 1, 30, 1, 30, 5, 30, 419, 8, 30, 10, 30, 12, 30, 422, 9, 30, 1, 31, 1, 31, 1, 31, 1, 31, 5, 31, 428, 8, 31, 10, 31, 12, 31, 431, 9, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 3, 33, 441, 8, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 5, 36, 453, 8, 36, 10, 36, 12, 36, 456, 9, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 39, 1, 39, 3, 39, 466, 8, 39, 1, 40, 3, 40, 469, 8, 40, 1, 40, 1, 40, 1, 41, 3, 41, 474, 8, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 493, 8, 46, 1, 47, 1, 47, 1, 47, 1, 47, 3, 47, 499, 8, 47, 1, 47, 1, 47, 1, 47, 1, 47, 5, 47, 505, 8, 47, 10, 47, 12, 47, 508, 9, 47, 3, 47, 510, 8, 47, 1, 48, 1, 48, 1, 48, 3, 48, 515, 8, 48, 1, 48, 1, 48, 1, 48, 0, 3, 2, 10, 16, 49, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 0, 9, 1, 0, 58, 59, 1, 0, 60, 62, 2, 0, 66, 66, 71, 71, 1, 0, 65, 66, 2, 0, 66, 66, 75, 75, 2, 0, 32, 32, 35, 35, 1, 0, 38, 39, 2, 0, 37, 37, 51, 51, 1, 0, 52, 57, 548, 0, 98, 1, 0, 0, 0, 2, 101, 1, 0, 0, 0, 4, 116, 1, 0, 0, 0, 6, 131, 1, 0, 0, 0, 8, 133, 1, 0, 0, 0, 10, 164, 1, 0, 0, 0, 12, 191, 1, 0, 0, 0, 14, 198, 1, 0, 0, 0, 16, 204, 1, 0, 0, 0, 18, 224, 1, 0, 0, 0, 20, 226, 1, 0, 0, 0, 22, 241, 1, 0, 0, 0, 24, 244, 1, 0, 0, 0, 26, 257, 1, 0, 0, 0, 28, 259, 1, 0, 0, 0, 30, 271, 1, 0, 0, 0, 32, 283, 1, 0, 0, 0, 34, 286, 1, 0, 0, 0, 36, 294, 1, 0, 0, 0, 38, 300, 1, 0, 0, 0, 40, 308, 1, 0, 0, 0, 42, 310, 1, 0, 0, 0, 44, 318, 1, 0, 0, 0, 46, 326, 1, 0, 0, 0, 48, 328, 1, 0, 0, 0, 50, 372, 1, 0, 0, 0, 52, 374, 1, 0, 0, 0, 54, 377, 1, 0, 0, 0, 56, 386, 1, 0, 0, 0, 58, 412, 1, 0, 0, 0, 60, 414, 1, 0, 0, 0, 62, 423, 1, 0, 0, 0, 64, 432, 1, 0, 0, 0, 66, 436, 1, 0, 0, 0, 68, 442, 1, 0, 0, 0, 70, 446, 1, 0, 0, 0, 72, 449, 1, 0, 0, 0, 74, 457, 1, 0, 0, 0, 76, 461, 1, 0, 0, 0, 78, 465, 1, 0, 0, 0, 80, 468, 1, 0, 0, 0, 82, 473, 1, 0, 0, 0, 84, 477, 1, 0, 0, 0, 86, 479, 1, 0, 0, 0, 88, 481, 1, 0, 0, 0, 90, 484, 1, 0, 0, 0, 92, 492, 1, 0, 0, 0, 94, 494, 1, 0, 0, 0, 96, 514, 1, 0, 0, 0, 98, 99, 3, 2, 1, 0, 99, 100, 5, 0, 0, 1, 100, 1, 1, 0, 0, 0, 101, 102, 6, 1, -1, 0, 102, 103, 3, 4, 2, 0, 103, 109, 1, 0, 0, 0, 104, 105, 10, 1, 0, 0, 105, 106, 5, 26, 0, 0, 106, 108, 3, 6, 3, 0, 107, 104, 1, 0, 0, 0, 108, 111, 1, 0, 0, 0, 109, 107, 1, 0, 0, 0, 109, 110, 1, 0, 0, 0, 110, 3, 1, 0, 0, 0, 111, 109, 1, 0, 0, 0, 112, 117, 3, 88, 44, 0, 113, 117, 3, 28, 14, 0, 114, 117, 3, 22, 11, 0, 115, 117, 3, 92, 46, 0, 116, 112, 1, 0, 0, 0, 116, 113, 1, 0, 0, 0, 116, 114, 1, 0, 0, 0, 116, 115, 1, 0, 0, 0, 117, 5, 1, 0, 0, 0, 118, 132, 3, 32, 16, 0, 119, 132, 3, 36, 18, 0, 120, 132, 3, 52, 26, 0, 121, 132, 3, 58, 29, 0, 122, 132, 3, 54, 27, 0, 123, 132, 3, 34, 17, 0, 124, 132, 3, 8, 4, 0, 125, 132, 3, 60, 30, 0, 126, 132, 3, 62, 31, 0, 127, 132, 3, 66, 33, 0, 128, 132, 3, 68, 34, 0, 129, 132, 3, 94, 47, 0, 130, 132, 3, 70, 35, 0, 131, 118, 1, 0, 0, 0, 131, 119, 1, 0, 0, 0, 131, 120, 1, 0, 0, 0, 131, 121, 1, 0, 0, 0, 131, 122, 1, 0, 0, 0, 131, 123, 1, 0, 0, 0, 131, 124, 1, 0, 0, 0, 131, 125, 1, 0, 0, 0, 131, 126, 1, 0, 0, 0, 131, 127, 1, 0, 0, 0, 131, 128, 1, 0, 0, 0, 131, 129, 1, 0, 0, 0, 131, 130, 1, 0, 0, 0, 132, 7, 1, 0, 0, 0, 133, 134, 5, 18, 0, 0, 134, 135, 3, 10, 5, 0, 135, 9, 1, 0, 0, 0, 136, 137, 6, 5, -1, 0, 137, 138, 5, 44, 0, 0, 138, 165, 3, 10, 5, 7, 139, 165, 3, 14, 7, 0, 140, 165, 3, 12, 6, 0, 141, 143, 3, 14, 7, 0, 142, 144, 5, 44, 0, 0, 143, 142, 1, 0, 0, 0, 143, 144, 1, 0, 0, 0, 144, 145, 1, 0, 0, 0, 145, 146, 5, 41, 0, 0, 146, 147, 5, 40, 0, 0, 147, 152, 3, 14, 7, 0, 148, 149, 5, 34, 0, 0, 149, 151, 3, 14, 7, 0, 150, 148, 1, 0, 0, 0, 151, 154, 1, 0, 0, 0, 152, 150, 1, 0, 0, 0, 152, 153, 1, 0, 0, 0, 153, 155, 1, 0, 0, 0, 154, 152, 1, 0, 0, 0, 155, 156, 5, 50, 0, 0, 156, 165, 1, 0, 0, 0, 157, 158, 3, 14, 7, 0, 158, 160, 5, 42, 0, 0, 159, 161, 5, 44, 0, 0, 160, 159, 1, 0, 0, 0, 160, 161, 1, 0, 0, 0, 161, 162, 1, 0, 0, 0, 162, 163, 5, 45, 0, 0, 163, 165, 1, 0, 0, 0, 164, 136, 1, 0, 0, 0, 164, 139, 1, 0, 0, 0, 164, 140, 1, 0, 0, 0, 164, 141, 1, 0, 0, 0, 164, 157, 1, 0, 0, 0, 165, 174, 1, 0, 0, 0, 166, 167, 10, 4, 0, 0, 167, 168, 5, 31, 0, 0, 168, 173, 3, 10, 5, 5, 169, 170, 10, 3, 0, 0, 170, 171, 5, 47, 0, 0, 171, 173, 3, 10, 5, 4, 172, 166, 1, 0, 0, 0, 172, 169, 1, 0, 0, 0, 173, 176, 1, 0, 0, 0, 174, 172, 1, 0, 0, 0, 174, 175, 1, 0, 0, 0, 175, 11, 1, 0, 0, 0, 176, 174, 1, 0, 0, 0, 177, 179, 3, 14, 7, 0, 178, 180, 5, 44, 0, 0, 179, 178, 1, 0, 0, 0, 179, 180, 1, 0, 0, 0, 180, 181, 1, 0, 0, 0, 181, 182, 5, 43, 0, 0, 182, 183, 3, 84, 42, 0, 183, 192, 1, 0, 0, 0, 184, 186, 3, 14, 7, 0, 185, 187, 5, 44, 0, 0, 186, 185, 1, 0, 0, 0, 186, 187, 1, 0, 0, 0, 187, 188, 1, 0, 0, 0, 188, 189, 5, 49, 0, 0, 189, 190, 3, 84, 42, 0, 190, 192, 1, 0, 0, 0, 191, 177, 1, 0, 0, 0, 191, 184, 1, 0, 0, 0, 192, 13, 1, 0, 0, 0, 193, 199, 3, 16, 8, 0, 194, 195, 3, 16, 8, 0, 195, 196, 3, 86, 43, 0, 196, 197, 3, 16, 8, 0, 197, 199, 1, 0, 0, 0, 198, 193, 1, 0, 0, 0, 198, 194, 1, 0, 0, 0, 199, 15, 1, 0, 0, 0, 200, 201, 6, 8, -1, 0, 201, 205, 3, 18, 9, 0, 202, 203, 7, 0, 0, 0, 203, 205, 3, 16, 8, 3, 204, 200, 1, 0, 0, 0, 204, 202, 1, 0, 0, 0, 205, 214, 1, 0, 0, 0, 206, 207, 10, 2, 0, 0, 207, 208, 7, 1, 0, 0, 208, 213, 3, 16, 8, 3, 209, 210, 10, 1, 0, 0, 210, 211, 7, 0, 0, 0, 211, 213, 3, 16, 8, 2, 212, 206, 1, 0, 0, 0, 212, 209, 1, 0, 0, 0, 213, 216, 1, 0, 0, 0, 214, 212, 1, 0, 0, 0, 214, 215, 1, 0, 0, 0, 215, 17, 1, 0, 0, 0, 216, 214, 1, 0, 0, 0, 217, 225, 3, 50, 25, 0, 218, 225, 3, 42, 21, 0, 219, 225, 3, 20, 10, 0, 220, 221, 5, 40, 0, 0, 221, 222, 3, 10, 5, 0, 222, 223, 5, 50, 0, 0, 223, 225, 1, 0, 0, 0, 224, 217, 1, 0, 0, 0, 224, 218, 1, 0, 0, 0, 224, 219, 1, 0, 0, 0, 224, 220, 1, 0, 0, 0, 225, 19, 1, 0, 0, 0, 226, 227, 3, 46, 23, 0, 227, 237, 5, 40, 0, 0, 228, 238, 5, 60, 0, 0, 229, 234, 3, 10, 5, 0, 230, 231, 5, 34, 0, 0, 231, 233, 3, 10, 5, 0, 232, 230, 1, 0, 0, 0, 233, 236, 1, 0, 0, 0, 234, 232, 1, 0, 0, 0, 234, 235, 1, 0, 0, 0, 235, 238, 1, 0, 0, 0, 236, 234, 1, 0, 0, 0, 237, 228, 1, 0, 0, 0, 237, 229, 1, 0, 0, 0, 237, 238, 1, 0, 0, 0, 238, 239, 1, 0, 0, 0, 239, 240, 5, 50, 0, 0, 240, 21, 1, 0, 0, 0, 241, 242, 5, 14, 0, 0, 242, 243, 3, 24, 12, 0, 243, 23, 1, 0, 0, 0, 244, 249, 3, 26, 13, 0, 245, 246, 5, 34, 0, 0, 246, 248, 3, 26, 13, 0, 247, 245, 1, 0, 0, 0, 248, 251, 1, 0, 0, 0, 249, 247, 1, 0, 0, 0, 249, 250, 1, 0, 0, 0, 250, 25, 1, 0, 0, 0, 251, 249, 1, 0, 0, 0, 252, 258, 3, 10, 5, 0, 253, 254, 3, 42, 21, 0, 254, 255, 5, 33, 0, 0, 255, 256, 3, 10, 5, 0, 256, 258, 1, 0, 0, 0, 257, 252, 1, 0, 0, 0, 257, 253, 1, 0, 0, 0, 258, 27, 1, 0, 0, 0, 259, 260, 5, 6, 0, 0, 260, 265, 3, 40, 20, 0, 261, 262, 5, 34, 0, 0, 262, 264, 3, 40, 20, 0, 263, 261, 1, 0, 0, 0, 264, 267, 1, 0, 0, 0, 265, 263, 1, 0, 0, 0, 265, 266, 1, 0, 0, 0, 266, 269, 1, 0, 0, 0, 267, 265, 1, 0, 0, 0, 268, 270, 3, 30, 15, 0, 269, 268, 1, 0, 0, 0, 269, 270, 1, 0, 0, 0, 270, 29, 1, 0, 0, 0, 271, 272, 5, 63, 0, 0, 272, 273, 5, 70, 0, 0, 273, 278, 3, 40, 20, 0, 274, 275, 5, 34, 0, 0, 275, 277, 3, 40, 20, 0, 276, 274, 1, 0, 0, 0, 277, 280, 1, 0, 0, 0, 278, 276, 1, 0, 0, 0, 278, 279, 1, 0, 0, 0, 279, 281, 1, 0, 0, 0, 280, 278, 1, 0, 0, 0, 281, 282, 5, 64, 0, 0, 282, 31, 1, 0, 0, 0, 283, 284, 5, 4, 0, 0, 284, 285, 3, 24, 12, 0, 285, 33, 1, 0, 0, 0, 286, 288, 5, 17, 0, 0, 287, 289, 3, 24, 12, 0, 288, 287, 1, 0, 0, 0, 288, 289, 1, 0, 0, 0, 289, 292, 1, 0, 0, 0, 290, 291, 5, 30, 0, 0, 291, 293, 3, 38, 19, 0, 292, 290, 1, 0, 0, 0, 292, 293, 1, 0, 0, 0, 293, 35, 1, 0, 0, 0, 294, 295, 5, 8, 0, 0, 295, 298, 3, 24, 12, 0, 296, 297, 5, 30, 0, 0, 297, 299, 3, 38, 19, 0, 298, 296, 1, 0, 0, 0, 298, 299, 1, 0, 0, 0, 299, 37, 1, 0, 0, 0, 300, 305, 3, 42, 21, 0, 301, 302, 5, 34, 0, 0, 302, 304, 3, 42, 21, 0, 303, 301, 1, 0, 0, 0, 304, 307, 1, 0, 0, 0, 305, 303, 1, 0, 0, 0, 305, 306, 1, 0, 0, 0, 306, 39, 1, 0, 0, 0, 307, 305, 1, 0, 0, 0, 308, 309, 7, 2, 0, 0, 309, 41, 1, 0, 0, 0, 310, 315, 3, 46, 23, 0, 311, 312, 5, 36, 0, 0, 312, 314, 3, 46, 23, 0, 313, 311, 1, 0, 0, 0, 314, 317, 1, 0, 0, 0, 315, 313, 1, 0, 0, 0, 315, 316, 1, 0, 0, 0, 316, 43, 1, 0, 0, 0, 317, 315, 1, 0, 0, 0, 318, 323, 3, 48, 24, 0, 319, 320, 5, 36, 0, 0, 320, 322, 3, 48, 24, 0, 321, 319, 1, 0, 0, 0, 322, 325, 1, 0, 0, 0, 323, 321, 1, 0, 0, 0, 323, 324, 1, 0, 0, 0, 324, 45, 1, 0, 0, 0, 325, 323, 1, 0, 0, 0, 326, 327, 7, 3, 0, 0, 327, 47, 1, 0, 0, 0, 328, 329, 7, 4, 0, 0, 329, 49, 1, 0, 0, 0, 330, 373, 5, 45, 0, 0, 331, 332, 3, 82, 41, 0, 332, 333, 5, 65, 0, 0, 333, 373, 1, 0, 0, 0, 334, 373, 3, 80, 40, 0, 335, 373, 3, 82, 41, 0, 336, 373, 3, 76, 38, 0, 337, 373, 5, 48, 0, 0, 338, 373, 3, 84, 42, 0, 339, 340, 5, 63, 0, 0, 340, 345, 3, 78, 39, 0, 341, 342, 5, 34, 0, 0, 342, 344, 3, 78, 39, 0, 343, 341, 1, 0, 0, 0, 344, 347, 1, 0, 0, 0, 345, 343, 1, 0, 0, 0, 345, 346, 1, 0, 0, 0, 346, 348, 1, 0, 0, 0, 347, 345, 1, 0, 0, 0, 348, 349, 5, 64, 0, 0, 349, 373, 1, 0, 0, 0, 350, 351, 5, 63, 0, 0, 351, 356, 3, 76, 38, 0, 352, 353, 5, 34, 0, 0, 353, 355, 3, 76, 38, 0, 354, 352, 1, 0, 0, 0, 355, 358, 1, 0, 0, 0, 356, 354, 1, 0, 0, 0, 356, 357, 1, 0, 0, 0, 357, 359, 1, 0, 0, 0, 358, 356, 1, 0, 0, 0, 359, 360, 5, 64, 0, 0, 360, 373, 1, 0, 0, 0, 361, 362, 5, 63, 0, 0, 362, 367, 3, 84, 42, 0, 363, 364, 5, 34, 0, 0, 364, 366, 3, 84, 42, 0, 365, 363, 1, 0, 0, 0, 366, 369, 1, 0, 0, 0, 367, 365, 1, 0, 0, 0, 367, 368, 1, 0, 0, 0, 368, 370, 1, 0, 0, 0, 369, 367, 1, 0, 0, 0, 370, 371, 5, 64, 0, 0, 371, 373, 1, 0, 0, 0, 372, 330, 1, 0, 0, 0, 372, 331, 1, 0, 0, 0, 372, 334, 1, 0, 0, 0, 372, 335, 1, 0, 0, 0, 372, 336, 1, 0, 0, 0, 372, 337, 1, 0, 0, 0, 372, 338, 1, 0, 0, 0, 372, 339, 1, 0, 0, 0, 372, 350, 1, 0, 0, 0, 372, 361, 1, 0, 0, 0, 373, 51, 1, 0, 0, 0, 374, 375, 5, 10, 0, 0, 375, 376, 5, 28, 0, 0, 376, 53, 1, 0, 0, 0, 377, 378, 5, 16, 0, 0, 378, 383, 3, 56, 28, 0, 379, 380, 5, 34, 0, 0, 380, 382, 3, 56, 28, 0, 381, 379, 1, 0, 0, 0, 382, 385, 1, 0, 0, 0, 383, 381, 1, 0, 0, 0, 383, 384, 1, 0, 0, 0, 384, 55, 1, 0, 0, 0, 385, 383, 1, 0, 0, 0, 386, 388, 3, 10, 5, 0, 387, 389, 7, 5, 0, 0, 388, 387, 1, 0, 0, 0, 388, 389, 1, 0, 0, 0, 389, 392, 1, 0, 0, 0, 390, 391, 5, 46, 0, 0, 391, 393, 7, 6, 0, 0, 392, 390, 1, 0, 0, 0, 392, 393, 1, 0, 0, 0, 393, 57, 1, 0, 0, 0, 394, 395, 5, 9, 0, 0, 395, 400, 3, 44, 22, 0, 396, 397, 5, 34, 0, 0, 397, 399, 3, 44, 22, 0, 398, 396, 1, 0, 0, 0, 399, 402, 1, 0, 0, 0, 400, 398, 1, 0, 0, 0, 400, 401, 1, 0, 0, 0, 401, 413, 1, 0, 0, 0, 402, 400, 1, 0, 0, 0, 403, 404, 5, 12, 0, 0, 404, 409, 3, 44, 22, 0, 405, 406, 5, 34, 0, 0, 406, 408, 3, 44, 22, 0, 407, 405, 1, 0, 0, 0, 408, 411, 1, 0, 0, 0, 409, 407, 1, 0, 0, 0, 409, 410, 1, 0, 0, 0, 410, 413, 1, 0, 0, 0, 411, 409, 1, 0, 0, 0, 412, 394, 1, 0, 0, 0, 412, 403, 1, 0, 0, 0, 413, 59, 1, 0, 0, 0, 414, 415, 5, 2, 0, 0, 415, 420, 3, 44, 22, 0, 416, 417, 5, 34, 0, 0, 417, 419, 3, 44, 22, 0, 418, 416, 1, 0, 0, 0, 419, 422, 1, 0, 0, 0, 420, 418, 1, 0, 0, 0, 420, 421, 1, 0, 0, 0, 421, 61, 1, 0, 0, 0, 422, 420, 1, 0, 0, 0, 423, 424, 5, 13, 0, 0, 424, 429, 3, 64, 32, 0, 425, 426, 5, 34, 0, 0, 426, 428, 3, 64, 32, 0, 427, 425, 1, 0, 0, 0, 428, 431, 1, 0, 0, 0, 429, 427, 1, 0, 0, 0, 429, 430, 1, 0, 0, 0, 430, 63, 1, 0, 0, 0, 431, 429, 1, 0, 0, 0, 432, 433, 3, 44, 22, 0, 433, 434, 5, 79, 0, 0, 434, 435, 3, 44, 22, 0, 435, 65, 1, 0, 0, 0, 436, 437, 5, 1, 0, 0, 437, 438, 3, 18, 9, 0, 438, 440, 3, 84, 42, 0, 439, 441, 3, 72, 36, 0, 440, 439, 1, 0, 0, 0, 440, 441, 1, 0, 0, 0, 441, 67, 1, 0, 0, 0, 442, 443, 5, 7, 0, 0, 443, 444, 3, 18, 9, 0, 444, 445, 3, 84, 42, 0, 445, 69, 1, 0, 0, 0, 446, 447, 5, 11, 0, 0, 447, 448, 3, 42, 21, 0, 448, 71, 1, 0, 0, 0, 449, 454, 3, 74, 37, 0, 450, 451, 5, 34, 0, 0, 451, 453, 3, 74, 37, 0, 452, 450, 1, 0, 0, 0, 453, 456, 1, 0, 0, 0, 454, 452, 1, 0, 0, 0, 454, 455, 1, 0, 0, 0, 455, 73, 1, 0, 0, 0, 456, 454, 1, 0, 0, 0, 457, 458, 3, 46, 23, 0, 458, 459, 5, 33, 0, 0, 459, 460, 3, 50, 25, 0, 460, 75, 1, 0, 0, 0, 461, 462, 7, 7, 0, 0, 462, 77, 1, 0, 0, 0, 463, 466, 3, 80, 40, 0, 464, 466, 3, 82, 41, 0, 465, 463, 1, 0, 0, 0, 465, 464, 1, 0, 0, 0, 466, 79, 1, 0, 0, 0, 467, 469, 7, 0, 0, 0, 468, 467, 1, 0, 0, 0, 468, 469, 1, 0, 0, 0, 469, 470, 1, 0, 0, 0, 470, 471, 5, 29, 0, 0, 471, 81, 1, 0, 0, 0, 472, 474, 7, 0, 0, 0, 473, 472, 1, 0, 0, 0, 473, 474, 1, 0, 0, 0, 474, 475, 1, 0, 0, 0, 475, 476, 5, 28, 0, 0, 476, 83, 1, 0, 0, 0, 477, 478, 5, 27, 0, 0, 478, 85, 1, 0, 0, 0, 479, 480, 7, 8, 0, 0, 480, 87, 1, 0, 0, 0, 481, 482, 5, 5, 0, 0, 482, 483, 3, 90, 45, 0, 483, 89, 1, 0, 0, 0, 484, 485, 5, 63, 0, 0, 485, 486, 3, 2, 1, 0, 486, 487, 5, 64, 0, 0, 487, 91, 1, 0, 0, 0, 488, 489, 5, 15, 0, 0, 489, 493, 5, 94, 0, 0, 490, 491, 5, 15, 0, 0, 491, 493, 5, 95, 0, 0, 492, 488, 1, 0, 0, 0, 492, 490, 1, 0, 0, 0, 493, 93, 1, 0, 0, 0, 494, 495, 5, 3, 0, 0, 495, 498, 3, 40, 20, 0, 496, 497, 5, 83, 0, 0, 497, 499, 3, 44, 22, 0, 498, 496, 1, 0, 0, 0, 498, 499, 1, 0, 0, 0, 499, 509, 1, 0, 0, 0, 500, 501, 5, 84, 0, 0, 501, 506, 3, 96, 48, 0, 502, 503, 5, 34, 0, 0, 503, 505, 3, 96, 48, 0, 504, 502, 1, 0, 0, 0, 505, 508, 1, 0, 0, 0, 506, 504, 1, 0, 0, 0, 506, 507, 1, 0, 0, 0, 507, 510, 1, 0, 0, 0, 508, 506, 1, 0, 0, 0, 509, 500, 1, 0, 0, 0, 509, 510, 1, 0, 0, 0, 510, 95, 1, 0, 0, 0, 511, 512, 3, 44, 22, 0, 512, 513, 5, 33, 0, 0, 513, 515, 1, 0, 0, 0, 514, 511, 1, 0, 0, 0, 514, 515, 1, 0, 0, 0, 515, 516, 1, 0, 0, 0, 516, 517, 3, 44, 22, 0, 517, 97, 1, 0, 0, 0, 52, 109, 116, 131, 143, 152, 160, 164, 172, 174, 179, 186, 191, 198, 204, 212, 214, 224, 234, 237, 249, 257, 265, 269, 278, 288, 292, 298, 305, 315, 323, 345, 356, 367, 372, 383, 388, 392, 400, 409, 412, 420, 429, 440, 454, 465, 468, 473, 492, 498, 506, 509, 514] \ No newline at end of file diff --git a/packages/kbn-esql/src/antlr/.antlr/esql_parser.java b/packages/kbn-esql/src/antlr/.antlr/esql_parser.java new file mode 100644 index 00000000000000..c784cc891d6a08 --- /dev/null +++ b/packages/kbn-esql/src/antlr/.antlr/esql_parser.java @@ -0,0 +1,3914 @@ +// Generated from /Users/marcoliberati/Work/kibana/packages/kbn-monaco/src/esql/antlr/esql_parser.g4 by ANTLR 4.13.1 +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.misc.*; +import org.antlr.v4.runtime.tree.*; +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"}) +public class esql_parser extends Parser { + static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + DISSECT=1, DROP=2, ENRICH=3, EVAL=4, EXPLAIN=5, FROM=6, GROK=7, INLINESTATS=8, + KEEP=9, LIMIT=10, MV_EXPAND=11, PROJECT=12, RENAME=13, ROW=14, SHOW=15, + SORT=16, STATS=17, WHERE=18, UNKNOWN_CMD=19, LINE_COMMENT=20, MULTILINE_COMMENT=21, + WS=22, EXPLAIN_WS=23, EXPLAIN_LINE_COMMENT=24, EXPLAIN_MULTILINE_COMMENT=25, + PIPE=26, STRING=27, INTEGER_LITERAL=28, DECIMAL_LITERAL=29, BY=30, AND=31, + ASC=32, ASSIGN=33, COMMA=34, DESC=35, DOT=36, FALSE=37, FIRST=38, LAST=39, + LP=40, IN=41, IS=42, LIKE=43, NOT=44, NULL=45, NULLS=46, OR=47, PARAM=48, + RLIKE=49, RP=50, TRUE=51, EQ=52, NEQ=53, LT=54, LTE=55, GT=56, GTE=57, + PLUS=58, MINUS=59, ASTERISK=60, SLASH=61, PERCENT=62, OPENING_BRACKET=63, + CLOSING_BRACKET=64, UNQUOTED_IDENTIFIER=65, QUOTED_IDENTIFIER=66, EXPR_LINE_COMMENT=67, + EXPR_MULTILINE_COMMENT=68, EXPR_WS=69, METADATA=70, FROM_UNQUOTED_IDENTIFIER=71, + FROM_LINE_COMMENT=72, FROM_MULTILINE_COMMENT=73, FROM_WS=74, PROJECT_UNQUOTED_IDENTIFIER=75, + PROJECT_LINE_COMMENT=76, PROJECT_MULTILINE_COMMENT=77, PROJECT_WS=78, + AS=79, RENAME_LINE_COMMENT=80, RENAME_MULTILINE_COMMENT=81, RENAME_WS=82, + ON=83, WITH=84, ENRICH_LINE_COMMENT=85, ENRICH_MULTILINE_COMMENT=86, ENRICH_WS=87, + ENRICH_FIELD_LINE_COMMENT=88, ENRICH_FIELD_MULTILINE_COMMENT=89, ENRICH_FIELD_WS=90, + MVEXPAND_LINE_COMMENT=91, MVEXPAND_MULTILINE_COMMENT=92, MVEXPAND_WS=93, + INFO=94, FUNCTIONS=95, SHOW_LINE_COMMENT=96, SHOW_MULTILINE_COMMENT=97, + SHOW_WS=98; + public static final int + RULE_singleStatement = 0, RULE_query = 1, RULE_sourceCommand = 2, RULE_processingCommand = 3, + RULE_whereCommand = 4, RULE_booleanExpression = 5, RULE_regexBooleanExpression = 6, + RULE_valueExpression = 7, RULE_operatorExpression = 8, RULE_primaryExpression = 9, + RULE_functionExpression = 10, RULE_rowCommand = 11, RULE_fields = 12, + RULE_field = 13, RULE_fromCommand = 14, RULE_metadata = 15, RULE_evalCommand = 16, + RULE_statsCommand = 17, RULE_inlinestatsCommand = 18, RULE_grouping = 19, + RULE_fromIdentifier = 20, RULE_qualifiedName = 21, RULE_qualifiedNamePattern = 22, + RULE_identifier = 23, RULE_identifierPattern = 24, RULE_constant = 25, + RULE_limitCommand = 26, RULE_sortCommand = 27, RULE_orderExpression = 28, + RULE_keepCommand = 29, RULE_dropCommand = 30, RULE_renameCommand = 31, + RULE_renameClause = 32, RULE_dissectCommand = 33, RULE_grokCommand = 34, + RULE_mvExpandCommand = 35, RULE_commandOptions = 36, RULE_commandOption = 37, + RULE_booleanValue = 38, RULE_numericValue = 39, RULE_decimalValue = 40, + RULE_integerValue = 41, RULE_string = 42, RULE_comparisonOperator = 43, + RULE_explainCommand = 44, RULE_subqueryExpression = 45, RULE_showCommand = 46, + RULE_enrichCommand = 47, RULE_enrichWithClause = 48; + private static String[] makeRuleNames() { + return new String[] { + "singleStatement", "query", "sourceCommand", "processingCommand", "whereCommand", + "booleanExpression", "regexBooleanExpression", "valueExpression", "operatorExpression", + "primaryExpression", "functionExpression", "rowCommand", "fields", "field", + "fromCommand", "metadata", "evalCommand", "statsCommand", "inlinestatsCommand", + "grouping", "fromIdentifier", "qualifiedName", "qualifiedNamePattern", + "identifier", "identifierPattern", "constant", "limitCommand", "sortCommand", + "orderExpression", "keepCommand", "dropCommand", "renameCommand", "renameClause", + "dissectCommand", "grokCommand", "mvExpandCommand", "commandOptions", + "commandOption", "booleanValue", "numericValue", "decimalValue", "integerValue", + "string", "comparisonOperator", "explainCommand", "subqueryExpression", + "showCommand", "enrichCommand", "enrichWithClause" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, "'|'", null, null, null, null, null, null, "'='", "','", + null, "'.'", null, null, null, "'('", null, null, null, null, null, null, + null, "'?'", null, "')'", null, "'=='", "'!='", "'<'", "'<='", "'>'", + "'>='", "'+'", "'-'", "'*'", "'/'", "'%'", null, "']'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK", + "INLINESTATS", "KEEP", "LIMIT", "MV_EXPAND", "PROJECT", "RENAME", "ROW", + "SHOW", "SORT", "STATS", "WHERE", "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", + "WS", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", "EXPLAIN_MULTILINE_COMMENT", + "PIPE", "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", + "ASC", "ASSIGN", "COMMA", "DESC", "DOT", "FALSE", "FIRST", "LAST", "LP", + "IN", "IS", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", + "TRUE", "EQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", + "SLASH", "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", + "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", "EXPR_WS", + "METADATA", "FROM_UNQUOTED_IDENTIFIER", "FROM_LINE_COMMENT", "FROM_MULTILINE_COMMENT", + "FROM_WS", "PROJECT_UNQUOTED_IDENTIFIER", "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT", + "PROJECT_WS", "AS", "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", + "RENAME_WS", "ON", "WITH", "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT", + "ENRICH_WS", "ENRICH_FIELD_LINE_COMMENT", "ENRICH_FIELD_MULTILINE_COMMENT", + "ENRICH_FIELD_WS", "MVEXPAND_LINE_COMMENT", "MVEXPAND_MULTILINE_COMMENT", + "MVEXPAND_WS", "INFO", "FUNCTIONS", "SHOW_LINE_COMMENT", "SHOW_MULTILINE_COMMENT", + "SHOW_WS" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "esql_parser.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public esql_parser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @SuppressWarnings("CheckReturnValue") + public static class SingleStatementContext extends ParserRuleContext { + public QueryContext query() { + return getRuleContext(QueryContext.class,0); + } + public TerminalNode EOF() { return getToken(esql_parser.EOF, 0); } + public SingleStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_singleStatement; } + } + + public final SingleStatementContext singleStatement() throws RecognitionException { + SingleStatementContext _localctx = new SingleStatementContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_singleStatement); + try { + enterOuterAlt(_localctx, 1); + { + setState(98); + query(0); + setState(99); + match(EOF); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class QueryContext extends ParserRuleContext { + public QueryContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_query; } + + public QueryContext() { } + public void copyFrom(QueryContext ctx) { + super.copyFrom(ctx); + } + } + @SuppressWarnings("CheckReturnValue") + public static class CompositeQueryContext extends QueryContext { + public QueryContext query() { + return getRuleContext(QueryContext.class,0); + } + public TerminalNode PIPE() { return getToken(esql_parser.PIPE, 0); } + public ProcessingCommandContext processingCommand() { + return getRuleContext(ProcessingCommandContext.class,0); + } + public CompositeQueryContext(QueryContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class SingleCommandQueryContext extends QueryContext { + public SourceCommandContext sourceCommand() { + return getRuleContext(SourceCommandContext.class,0); + } + public SingleCommandQueryContext(QueryContext ctx) { copyFrom(ctx); } + } + + public final QueryContext query() throws RecognitionException { + return query(0); + } + + private QueryContext query(int _p) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + QueryContext _localctx = new QueryContext(_ctx, _parentState); + QueryContext _prevctx = _localctx; + int _startState = 2; + enterRecursionRule(_localctx, 2, RULE_query, _p); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + { + _localctx = new SingleCommandQueryContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + + setState(102); + sourceCommand(); + } + _ctx.stop = _input.LT(-1); + setState(109); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,0,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + if ( _parseListeners!=null ) triggerExitRuleEvent(); + _prevctx = _localctx; + { + { + _localctx = new CompositeQueryContext(new QueryContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_query); + setState(104); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(105); + match(PIPE); + setState(106); + processingCommand(); + } + } + } + setState(111); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,0,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + unrollRecursionContexts(_parentctx); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class SourceCommandContext extends ParserRuleContext { + public ExplainCommandContext explainCommand() { + return getRuleContext(ExplainCommandContext.class,0); + } + public FromCommandContext fromCommand() { + return getRuleContext(FromCommandContext.class,0); + } + public RowCommandContext rowCommand() { + return getRuleContext(RowCommandContext.class,0); + } + public ShowCommandContext showCommand() { + return getRuleContext(ShowCommandContext.class,0); + } + public SourceCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_sourceCommand; } + } + + public final SourceCommandContext sourceCommand() throws RecognitionException { + SourceCommandContext _localctx = new SourceCommandContext(_ctx, getState()); + enterRule(_localctx, 4, RULE_sourceCommand); + try { + setState(116); + _errHandler.sync(this); + switch (_input.LA(1)) { + case EXPLAIN: + enterOuterAlt(_localctx, 1); + { + setState(112); + explainCommand(); + } + break; + case FROM: + enterOuterAlt(_localctx, 2); + { + setState(113); + fromCommand(); + } + break; + case ROW: + enterOuterAlt(_localctx, 3); + { + setState(114); + rowCommand(); + } + break; + case SHOW: + enterOuterAlt(_localctx, 4); + { + setState(115); + showCommand(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class ProcessingCommandContext extends ParserRuleContext { + public EvalCommandContext evalCommand() { + return getRuleContext(EvalCommandContext.class,0); + } + public InlinestatsCommandContext inlinestatsCommand() { + return getRuleContext(InlinestatsCommandContext.class,0); + } + public LimitCommandContext limitCommand() { + return getRuleContext(LimitCommandContext.class,0); + } + public KeepCommandContext keepCommand() { + return getRuleContext(KeepCommandContext.class,0); + } + public SortCommandContext sortCommand() { + return getRuleContext(SortCommandContext.class,0); + } + public StatsCommandContext statsCommand() { + return getRuleContext(StatsCommandContext.class,0); + } + public WhereCommandContext whereCommand() { + return getRuleContext(WhereCommandContext.class,0); + } + public DropCommandContext dropCommand() { + return getRuleContext(DropCommandContext.class,0); + } + public RenameCommandContext renameCommand() { + return getRuleContext(RenameCommandContext.class,0); + } + public DissectCommandContext dissectCommand() { + return getRuleContext(DissectCommandContext.class,0); + } + public GrokCommandContext grokCommand() { + return getRuleContext(GrokCommandContext.class,0); + } + public EnrichCommandContext enrichCommand() { + return getRuleContext(EnrichCommandContext.class,0); + } + public MvExpandCommandContext mvExpandCommand() { + return getRuleContext(MvExpandCommandContext.class,0); + } + public ProcessingCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_processingCommand; } + } + + public final ProcessingCommandContext processingCommand() throws RecognitionException { + ProcessingCommandContext _localctx = new ProcessingCommandContext(_ctx, getState()); + enterRule(_localctx, 6, RULE_processingCommand); + try { + setState(131); + _errHandler.sync(this); + switch (_input.LA(1)) { + case EVAL: + enterOuterAlt(_localctx, 1); + { + setState(118); + evalCommand(); + } + break; + case INLINESTATS: + enterOuterAlt(_localctx, 2); + { + setState(119); + inlinestatsCommand(); + } + break; + case LIMIT: + enterOuterAlt(_localctx, 3); + { + setState(120); + limitCommand(); + } + break; + case KEEP: + case PROJECT: + enterOuterAlt(_localctx, 4); + { + setState(121); + keepCommand(); + } + break; + case SORT: + enterOuterAlt(_localctx, 5); + { + setState(122); + sortCommand(); + } + break; + case STATS: + enterOuterAlt(_localctx, 6); + { + setState(123); + statsCommand(); + } + break; + case WHERE: + enterOuterAlt(_localctx, 7); + { + setState(124); + whereCommand(); + } + break; + case DROP: + enterOuterAlt(_localctx, 8); + { + setState(125); + dropCommand(); + } + break; + case RENAME: + enterOuterAlt(_localctx, 9); + { + setState(126); + renameCommand(); + } + break; + case DISSECT: + enterOuterAlt(_localctx, 10); + { + setState(127); + dissectCommand(); + } + break; + case GROK: + enterOuterAlt(_localctx, 11); + { + setState(128); + grokCommand(); + } + break; + case ENRICH: + enterOuterAlt(_localctx, 12); + { + setState(129); + enrichCommand(); + } + break; + case MV_EXPAND: + enterOuterAlt(_localctx, 13); + { + setState(130); + mvExpandCommand(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class WhereCommandContext extends ParserRuleContext { + public TerminalNode WHERE() { return getToken(esql_parser.WHERE, 0); } + public BooleanExpressionContext booleanExpression() { + return getRuleContext(BooleanExpressionContext.class,0); + } + public WhereCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_whereCommand; } + } + + public final WhereCommandContext whereCommand() throws RecognitionException { + WhereCommandContext _localctx = new WhereCommandContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_whereCommand); + try { + enterOuterAlt(_localctx, 1); + { + setState(133); + match(WHERE); + setState(134); + booleanExpression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class BooleanExpressionContext extends ParserRuleContext { + public BooleanExpressionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_booleanExpression; } + + public BooleanExpressionContext() { } + public void copyFrom(BooleanExpressionContext ctx) { + super.copyFrom(ctx); + } + } + @SuppressWarnings("CheckReturnValue") + public static class LogicalNotContext extends BooleanExpressionContext { + public TerminalNode NOT() { return getToken(esql_parser.NOT, 0); } + public BooleanExpressionContext booleanExpression() { + return getRuleContext(BooleanExpressionContext.class,0); + } + public LogicalNotContext(BooleanExpressionContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class BooleanDefaultContext extends BooleanExpressionContext { + public ValueExpressionContext valueExpression() { + return getRuleContext(ValueExpressionContext.class,0); + } + public BooleanDefaultContext(BooleanExpressionContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class IsNullContext extends BooleanExpressionContext { + public ValueExpressionContext valueExpression() { + return getRuleContext(ValueExpressionContext.class,0); + } + public TerminalNode IS() { return getToken(esql_parser.IS, 0); } + public TerminalNode NULL() { return getToken(esql_parser.NULL, 0); } + public TerminalNode NOT() { return getToken(esql_parser.NOT, 0); } + public IsNullContext(BooleanExpressionContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class RegexExpressionContext extends BooleanExpressionContext { + public RegexBooleanExpressionContext regexBooleanExpression() { + return getRuleContext(RegexBooleanExpressionContext.class,0); + } + public RegexExpressionContext(BooleanExpressionContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class LogicalInContext extends BooleanExpressionContext { + public List valueExpression() { + return getRuleContexts(ValueExpressionContext.class); + } + public ValueExpressionContext valueExpression(int i) { + return getRuleContext(ValueExpressionContext.class,i); + } + public TerminalNode IN() { return getToken(esql_parser.IN, 0); } + public TerminalNode LP() { return getToken(esql_parser.LP, 0); } + public TerminalNode RP() { return getToken(esql_parser.RP, 0); } + public TerminalNode NOT() { return getToken(esql_parser.NOT, 0); } + public List COMMA() { return getTokens(esql_parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(esql_parser.COMMA, i); + } + public LogicalInContext(BooleanExpressionContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class LogicalBinaryContext extends BooleanExpressionContext { + public BooleanExpressionContext left; + public Token operator; + public BooleanExpressionContext right; + public List booleanExpression() { + return getRuleContexts(BooleanExpressionContext.class); + } + public BooleanExpressionContext booleanExpression(int i) { + return getRuleContext(BooleanExpressionContext.class,i); + } + public TerminalNode AND() { return getToken(esql_parser.AND, 0); } + public TerminalNode OR() { return getToken(esql_parser.OR, 0); } + public LogicalBinaryContext(BooleanExpressionContext ctx) { copyFrom(ctx); } + } + + public final BooleanExpressionContext booleanExpression() throws RecognitionException { + return booleanExpression(0); + } + + private BooleanExpressionContext booleanExpression(int _p) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + BooleanExpressionContext _localctx = new BooleanExpressionContext(_ctx, _parentState); + BooleanExpressionContext _prevctx = _localctx; + int _startState = 10; + enterRecursionRule(_localctx, 10, RULE_booleanExpression, _p); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(164); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) { + case 1: + { + _localctx = new LogicalNotContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + + setState(137); + match(NOT); + setState(138); + booleanExpression(7); + } + break; + case 2: + { + _localctx = new BooleanDefaultContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(139); + valueExpression(); + } + break; + case 3: + { + _localctx = new RegexExpressionContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(140); + regexBooleanExpression(); + } + break; + case 4: + { + _localctx = new LogicalInContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(141); + valueExpression(); + setState(143); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==NOT) { + { + setState(142); + match(NOT); + } + } + + setState(145); + match(IN); + setState(146); + match(LP); + setState(147); + valueExpression(); + setState(152); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(148); + match(COMMA); + setState(149); + valueExpression(); + } + } + setState(154); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(155); + match(RP); + } + break; + case 5: + { + _localctx = new IsNullContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(157); + valueExpression(); + setState(158); + match(IS); + setState(160); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==NOT) { + { + setState(159); + match(NOT); + } + } + + setState(162); + match(NULL); + } + break; + } + _ctx.stop = _input.LT(-1); + setState(174); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,8,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + if ( _parseListeners!=null ) triggerExitRuleEvent(); + _prevctx = _localctx; + { + setState(172); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) { + case 1: + { + _localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState)); + ((LogicalBinaryContext)_localctx).left = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_booleanExpression); + setState(166); + if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); + setState(167); + ((LogicalBinaryContext)_localctx).operator = match(AND); + setState(168); + ((LogicalBinaryContext)_localctx).right = booleanExpression(5); + } + break; + case 2: + { + _localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState)); + ((LogicalBinaryContext)_localctx).left = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_booleanExpression); + setState(169); + if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); + setState(170); + ((LogicalBinaryContext)_localctx).operator = match(OR); + setState(171); + ((LogicalBinaryContext)_localctx).right = booleanExpression(4); + } + break; + } + } + } + setState(176); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,8,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + unrollRecursionContexts(_parentctx); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class RegexBooleanExpressionContext extends ParserRuleContext { + public Token kind; + public StringContext pattern; + public ValueExpressionContext valueExpression() { + return getRuleContext(ValueExpressionContext.class,0); + } + public TerminalNode LIKE() { return getToken(esql_parser.LIKE, 0); } + public StringContext string() { + return getRuleContext(StringContext.class,0); + } + public TerminalNode NOT() { return getToken(esql_parser.NOT, 0); } + public TerminalNode RLIKE() { return getToken(esql_parser.RLIKE, 0); } + public RegexBooleanExpressionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_regexBooleanExpression; } + } + + public final RegexBooleanExpressionContext regexBooleanExpression() throws RecognitionException { + RegexBooleanExpressionContext _localctx = new RegexBooleanExpressionContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_regexBooleanExpression); + int _la; + try { + setState(191); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(177); + valueExpression(); + setState(179); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==NOT) { + { + setState(178); + match(NOT); + } + } + + setState(181); + ((RegexBooleanExpressionContext)_localctx).kind = match(LIKE); + setState(182); + ((RegexBooleanExpressionContext)_localctx).pattern = string(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(184); + valueExpression(); + setState(186); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==NOT) { + { + setState(185); + match(NOT); + } + } + + setState(188); + ((RegexBooleanExpressionContext)_localctx).kind = match(RLIKE); + setState(189); + ((RegexBooleanExpressionContext)_localctx).pattern = string(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class ValueExpressionContext extends ParserRuleContext { + public ValueExpressionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_valueExpression; } + + public ValueExpressionContext() { } + public void copyFrom(ValueExpressionContext ctx) { + super.copyFrom(ctx); + } + } + @SuppressWarnings("CheckReturnValue") + public static class ValueExpressionDefaultContext extends ValueExpressionContext { + public OperatorExpressionContext operatorExpression() { + return getRuleContext(OperatorExpressionContext.class,0); + } + public ValueExpressionDefaultContext(ValueExpressionContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class ComparisonContext extends ValueExpressionContext { + public OperatorExpressionContext left; + public OperatorExpressionContext right; + public ComparisonOperatorContext comparisonOperator() { + return getRuleContext(ComparisonOperatorContext.class,0); + } + public List operatorExpression() { + return getRuleContexts(OperatorExpressionContext.class); + } + public OperatorExpressionContext operatorExpression(int i) { + return getRuleContext(OperatorExpressionContext.class,i); + } + public ComparisonContext(ValueExpressionContext ctx) { copyFrom(ctx); } + } + + public final ValueExpressionContext valueExpression() throws RecognitionException { + ValueExpressionContext _localctx = new ValueExpressionContext(_ctx, getState()); + enterRule(_localctx, 14, RULE_valueExpression); + try { + setState(198); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) { + case 1: + _localctx = new ValueExpressionDefaultContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(193); + operatorExpression(0); + } + break; + case 2: + _localctx = new ComparisonContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(194); + ((ComparisonContext)_localctx).left = operatorExpression(0); + setState(195); + comparisonOperator(); + setState(196); + ((ComparisonContext)_localctx).right = operatorExpression(0); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class OperatorExpressionContext extends ParserRuleContext { + public OperatorExpressionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_operatorExpression; } + + public OperatorExpressionContext() { } + public void copyFrom(OperatorExpressionContext ctx) { + super.copyFrom(ctx); + } + } + @SuppressWarnings("CheckReturnValue") + public static class OperatorExpressionDefaultContext extends OperatorExpressionContext { + public PrimaryExpressionContext primaryExpression() { + return getRuleContext(PrimaryExpressionContext.class,0); + } + public OperatorExpressionDefaultContext(OperatorExpressionContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class ArithmeticBinaryContext extends OperatorExpressionContext { + public OperatorExpressionContext left; + public Token operator; + public OperatorExpressionContext right; + public List operatorExpression() { + return getRuleContexts(OperatorExpressionContext.class); + } + public OperatorExpressionContext operatorExpression(int i) { + return getRuleContext(OperatorExpressionContext.class,i); + } + public TerminalNode ASTERISK() { return getToken(esql_parser.ASTERISK, 0); } + public TerminalNode SLASH() { return getToken(esql_parser.SLASH, 0); } + public TerminalNode PERCENT() { return getToken(esql_parser.PERCENT, 0); } + public TerminalNode PLUS() { return getToken(esql_parser.PLUS, 0); } + public TerminalNode MINUS() { return getToken(esql_parser.MINUS, 0); } + public ArithmeticBinaryContext(OperatorExpressionContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class ArithmeticUnaryContext extends OperatorExpressionContext { + public Token operator; + public OperatorExpressionContext operatorExpression() { + return getRuleContext(OperatorExpressionContext.class,0); + } + public TerminalNode MINUS() { return getToken(esql_parser.MINUS, 0); } + public TerminalNode PLUS() { return getToken(esql_parser.PLUS, 0); } + public ArithmeticUnaryContext(OperatorExpressionContext ctx) { copyFrom(ctx); } + } + + public final OperatorExpressionContext operatorExpression() throws RecognitionException { + return operatorExpression(0); + } + + private OperatorExpressionContext operatorExpression(int _p) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + OperatorExpressionContext _localctx = new OperatorExpressionContext(_ctx, _parentState); + OperatorExpressionContext _prevctx = _localctx; + int _startState = 16; + enterRecursionRule(_localctx, 16, RULE_operatorExpression, _p); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(204); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) { + case 1: + { + _localctx = new OperatorExpressionDefaultContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + + setState(201); + primaryExpression(); + } + break; + case 2: + { + _localctx = new ArithmeticUnaryContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(202); + ((ArithmeticUnaryContext)_localctx).operator = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==PLUS || _la==MINUS) ) { + ((ArithmeticUnaryContext)_localctx).operator = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(203); + operatorExpression(3); + } + break; + } + _ctx.stop = _input.LT(-1); + setState(214); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,15,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + if ( _parseListeners!=null ) triggerExitRuleEvent(); + _prevctx = _localctx; + { + setState(212); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) { + case 1: + { + _localctx = new ArithmeticBinaryContext(new OperatorExpressionContext(_parentctx, _parentState)); + ((ArithmeticBinaryContext)_localctx).left = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_operatorExpression); + setState(206); + if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); + setState(207); + ((ArithmeticBinaryContext)_localctx).operator = _input.LT(1); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 8070450532247928832L) != 0)) ) { + ((ArithmeticBinaryContext)_localctx).operator = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(208); + ((ArithmeticBinaryContext)_localctx).right = operatorExpression(3); + } + break; + case 2: + { + _localctx = new ArithmeticBinaryContext(new OperatorExpressionContext(_parentctx, _parentState)); + ((ArithmeticBinaryContext)_localctx).left = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_operatorExpression); + setState(209); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(210); + ((ArithmeticBinaryContext)_localctx).operator = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==PLUS || _la==MINUS) ) { + ((ArithmeticBinaryContext)_localctx).operator = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(211); + ((ArithmeticBinaryContext)_localctx).right = operatorExpression(2); + } + break; + } + } + } + setState(216); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,15,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + unrollRecursionContexts(_parentctx); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class PrimaryExpressionContext extends ParserRuleContext { + public PrimaryExpressionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_primaryExpression; } + + public PrimaryExpressionContext() { } + public void copyFrom(PrimaryExpressionContext ctx) { + super.copyFrom(ctx); + } + } + @SuppressWarnings("CheckReturnValue") + public static class DereferenceContext extends PrimaryExpressionContext { + public QualifiedNameContext qualifiedName() { + return getRuleContext(QualifiedNameContext.class,0); + } + public DereferenceContext(PrimaryExpressionContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class ConstantDefaultContext extends PrimaryExpressionContext { + public ConstantContext constant() { + return getRuleContext(ConstantContext.class,0); + } + public ConstantDefaultContext(PrimaryExpressionContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class ParenthesizedExpressionContext extends PrimaryExpressionContext { + public TerminalNode LP() { return getToken(esql_parser.LP, 0); } + public BooleanExpressionContext booleanExpression() { + return getRuleContext(BooleanExpressionContext.class,0); + } + public TerminalNode RP() { return getToken(esql_parser.RP, 0); } + public ParenthesizedExpressionContext(PrimaryExpressionContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class FunctionContext extends PrimaryExpressionContext { + public FunctionExpressionContext functionExpression() { + return getRuleContext(FunctionExpressionContext.class,0); + } + public FunctionContext(PrimaryExpressionContext ctx) { copyFrom(ctx); } + } + + public final PrimaryExpressionContext primaryExpression() throws RecognitionException { + PrimaryExpressionContext _localctx = new PrimaryExpressionContext(_ctx, getState()); + enterRule(_localctx, 18, RULE_primaryExpression); + try { + setState(224); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,16,_ctx) ) { + case 1: + _localctx = new ConstantDefaultContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(217); + constant(); + } + break; + case 2: + _localctx = new DereferenceContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(218); + qualifiedName(); + } + break; + case 3: + _localctx = new FunctionContext(_localctx); + enterOuterAlt(_localctx, 3); + { + setState(219); + functionExpression(); + } + break; + case 4: + _localctx = new ParenthesizedExpressionContext(_localctx); + enterOuterAlt(_localctx, 4); + { + setState(220); + match(LP); + setState(221); + booleanExpression(0); + setState(222); + match(RP); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class FunctionExpressionContext extends ParserRuleContext { + public IdentifierContext identifier() { + return getRuleContext(IdentifierContext.class,0); + } + public TerminalNode LP() { return getToken(esql_parser.LP, 0); } + public TerminalNode RP() { return getToken(esql_parser.RP, 0); } + public TerminalNode ASTERISK() { return getToken(esql_parser.ASTERISK, 0); } + public List booleanExpression() { + return getRuleContexts(BooleanExpressionContext.class); + } + public BooleanExpressionContext booleanExpression(int i) { + return getRuleContext(BooleanExpressionContext.class,i); + } + public List COMMA() { return getTokens(esql_parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(esql_parser.COMMA, i); + } + public FunctionExpressionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_functionExpression; } + } + + public final FunctionExpressionContext functionExpression() throws RecognitionException { + FunctionExpressionContext _localctx = new FunctionExpressionContext(_ctx, getState()); + enterRule(_localctx, 20, RULE_functionExpression); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(226); + identifier(); + setState(227); + match(LP); + setState(237); + _errHandler.sync(this); + switch (_input.LA(1)) { + case ASTERISK: + { + setState(228); + match(ASTERISK); + } + break; + case STRING: + case INTEGER_LITERAL: + case DECIMAL_LITERAL: + case FALSE: + case LP: + case NOT: + case NULL: + case PARAM: + case TRUE: + case PLUS: + case MINUS: + case OPENING_BRACKET: + case UNQUOTED_IDENTIFIER: + case QUOTED_IDENTIFIER: + { + { + setState(229); + booleanExpression(0); + setState(234); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(230); + match(COMMA); + setState(231); + booleanExpression(0); + } + } + setState(236); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + break; + case RP: + break; + default: + break; + } + setState(239); + match(RP); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class RowCommandContext extends ParserRuleContext { + public TerminalNode ROW() { return getToken(esql_parser.ROW, 0); } + public FieldsContext fields() { + return getRuleContext(FieldsContext.class,0); + } + public RowCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_rowCommand; } + } + + public final RowCommandContext rowCommand() throws RecognitionException { + RowCommandContext _localctx = new RowCommandContext(_ctx, getState()); + enterRule(_localctx, 22, RULE_rowCommand); + try { + enterOuterAlt(_localctx, 1); + { + setState(241); + match(ROW); + setState(242); + fields(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class FieldsContext extends ParserRuleContext { + public List field() { + return getRuleContexts(FieldContext.class); + } + public FieldContext field(int i) { + return getRuleContext(FieldContext.class,i); + } + public List COMMA() { return getTokens(esql_parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(esql_parser.COMMA, i); + } + public FieldsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fields; } + } + + public final FieldsContext fields() throws RecognitionException { + FieldsContext _localctx = new FieldsContext(_ctx, getState()); + enterRule(_localctx, 24, RULE_fields); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(244); + field(); + setState(249); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,19,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(245); + match(COMMA); + setState(246); + field(); + } + } + } + setState(251); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,19,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class FieldContext extends ParserRuleContext { + public BooleanExpressionContext booleanExpression() { + return getRuleContext(BooleanExpressionContext.class,0); + } + public QualifiedNameContext qualifiedName() { + return getRuleContext(QualifiedNameContext.class,0); + } + public TerminalNode ASSIGN() { return getToken(esql_parser.ASSIGN, 0); } + public FieldContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_field; } + } + + public final FieldContext field() throws RecognitionException { + FieldContext _localctx = new FieldContext(_ctx, getState()); + enterRule(_localctx, 26, RULE_field); + try { + setState(257); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,20,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(252); + booleanExpression(0); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(253); + qualifiedName(); + setState(254); + match(ASSIGN); + setState(255); + booleanExpression(0); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class FromCommandContext extends ParserRuleContext { + public TerminalNode FROM() { return getToken(esql_parser.FROM, 0); } + public List fromIdentifier() { + return getRuleContexts(FromIdentifierContext.class); + } + public FromIdentifierContext fromIdentifier(int i) { + return getRuleContext(FromIdentifierContext.class,i); + } + public List COMMA() { return getTokens(esql_parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(esql_parser.COMMA, i); + } + public MetadataContext metadata() { + return getRuleContext(MetadataContext.class,0); + } + public FromCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fromCommand; } + } + + public final FromCommandContext fromCommand() throws RecognitionException { + FromCommandContext _localctx = new FromCommandContext(_ctx, getState()); + enterRule(_localctx, 28, RULE_fromCommand); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(259); + match(FROM); + setState(260); + fromIdentifier(); + setState(265); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,21,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(261); + match(COMMA); + setState(262); + fromIdentifier(); + } + } + } + setState(267); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,21,_ctx); + } + setState(269); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,22,_ctx) ) { + case 1: + { + setState(268); + metadata(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class MetadataContext extends ParserRuleContext { + public TerminalNode OPENING_BRACKET() { return getToken(esql_parser.OPENING_BRACKET, 0); } + public TerminalNode METADATA() { return getToken(esql_parser.METADATA, 0); } + public List fromIdentifier() { + return getRuleContexts(FromIdentifierContext.class); + } + public FromIdentifierContext fromIdentifier(int i) { + return getRuleContext(FromIdentifierContext.class,i); + } + public TerminalNode CLOSING_BRACKET() { return getToken(esql_parser.CLOSING_BRACKET, 0); } + public List COMMA() { return getTokens(esql_parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(esql_parser.COMMA, i); + } + public MetadataContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_metadata; } + } + + public final MetadataContext metadata() throws RecognitionException { + MetadataContext _localctx = new MetadataContext(_ctx, getState()); + enterRule(_localctx, 30, RULE_metadata); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(271); + match(OPENING_BRACKET); + setState(272); + match(METADATA); + setState(273); + fromIdentifier(); + setState(278); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(274); + match(COMMA); + setState(275); + fromIdentifier(); + } + } + setState(280); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(281); + match(CLOSING_BRACKET); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class EvalCommandContext extends ParserRuleContext { + public TerminalNode EVAL() { return getToken(esql_parser.EVAL, 0); } + public FieldsContext fields() { + return getRuleContext(FieldsContext.class,0); + } + public EvalCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_evalCommand; } + } + + public final EvalCommandContext evalCommand() throws RecognitionException { + EvalCommandContext _localctx = new EvalCommandContext(_ctx, getState()); + enterRule(_localctx, 32, RULE_evalCommand); + try { + enterOuterAlt(_localctx, 1); + { + setState(283); + match(EVAL); + setState(284); + fields(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class StatsCommandContext extends ParserRuleContext { + public TerminalNode STATS() { return getToken(esql_parser.STATS, 0); } + public FieldsContext fields() { + return getRuleContext(FieldsContext.class,0); + } + public TerminalNode BY() { return getToken(esql_parser.BY, 0); } + public GroupingContext grouping() { + return getRuleContext(GroupingContext.class,0); + } + public StatsCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_statsCommand; } + } + + public final StatsCommandContext statsCommand() throws RecognitionException { + StatsCommandContext _localctx = new StatsCommandContext(_ctx, getState()); + enterRule(_localctx, 34, RULE_statsCommand); + try { + enterOuterAlt(_localctx, 1); + { + setState(286); + match(STATS); + setState(288); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,24,_ctx) ) { + case 1: + { + setState(287); + fields(); + } + break; + } + setState(292); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,25,_ctx) ) { + case 1: + { + setState(290); + match(BY); + setState(291); + grouping(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class InlinestatsCommandContext extends ParserRuleContext { + public TerminalNode INLINESTATS() { return getToken(esql_parser.INLINESTATS, 0); } + public FieldsContext fields() { + return getRuleContext(FieldsContext.class,0); + } + public TerminalNode BY() { return getToken(esql_parser.BY, 0); } + public GroupingContext grouping() { + return getRuleContext(GroupingContext.class,0); + } + public InlinestatsCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_inlinestatsCommand; } + } + + public final InlinestatsCommandContext inlinestatsCommand() throws RecognitionException { + InlinestatsCommandContext _localctx = new InlinestatsCommandContext(_ctx, getState()); + enterRule(_localctx, 36, RULE_inlinestatsCommand); + try { + enterOuterAlt(_localctx, 1); + { + setState(294); + match(INLINESTATS); + setState(295); + fields(); + setState(298); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,26,_ctx) ) { + case 1: + { + setState(296); + match(BY); + setState(297); + grouping(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class GroupingContext extends ParserRuleContext { + public List qualifiedName() { + return getRuleContexts(QualifiedNameContext.class); + } + public QualifiedNameContext qualifiedName(int i) { + return getRuleContext(QualifiedNameContext.class,i); + } + public List COMMA() { return getTokens(esql_parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(esql_parser.COMMA, i); + } + public GroupingContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_grouping; } + } + + public final GroupingContext grouping() throws RecognitionException { + GroupingContext _localctx = new GroupingContext(_ctx, getState()); + enterRule(_localctx, 38, RULE_grouping); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(300); + qualifiedName(); + setState(305); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,27,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(301); + match(COMMA); + setState(302); + qualifiedName(); + } + } + } + setState(307); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,27,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class FromIdentifierContext extends ParserRuleContext { + public TerminalNode FROM_UNQUOTED_IDENTIFIER() { return getToken(esql_parser.FROM_UNQUOTED_IDENTIFIER, 0); } + public TerminalNode QUOTED_IDENTIFIER() { return getToken(esql_parser.QUOTED_IDENTIFIER, 0); } + public FromIdentifierContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fromIdentifier; } + } + + public final FromIdentifierContext fromIdentifier() throws RecognitionException { + FromIdentifierContext _localctx = new FromIdentifierContext(_ctx, getState()); + enterRule(_localctx, 40, RULE_fromIdentifier); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(308); + _la = _input.LA(1); + if ( !(_la==QUOTED_IDENTIFIER || _la==FROM_UNQUOTED_IDENTIFIER) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class QualifiedNameContext extends ParserRuleContext { + public List identifier() { + return getRuleContexts(IdentifierContext.class); + } + public IdentifierContext identifier(int i) { + return getRuleContext(IdentifierContext.class,i); + } + public List DOT() { return getTokens(esql_parser.DOT); } + public TerminalNode DOT(int i) { + return getToken(esql_parser.DOT, i); + } + public QualifiedNameContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_qualifiedName; } + } + + public final QualifiedNameContext qualifiedName() throws RecognitionException { + QualifiedNameContext _localctx = new QualifiedNameContext(_ctx, getState()); + enterRule(_localctx, 42, RULE_qualifiedName); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(310); + identifier(); + setState(315); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,28,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(311); + match(DOT); + setState(312); + identifier(); + } + } + } + setState(317); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,28,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class QualifiedNamePatternContext extends ParserRuleContext { + public List identifierPattern() { + return getRuleContexts(IdentifierPatternContext.class); + } + public IdentifierPatternContext identifierPattern(int i) { + return getRuleContext(IdentifierPatternContext.class,i); + } + public List DOT() { return getTokens(esql_parser.DOT); } + public TerminalNode DOT(int i) { + return getToken(esql_parser.DOT, i); + } + public QualifiedNamePatternContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_qualifiedNamePattern; } + } + + public final QualifiedNamePatternContext qualifiedNamePattern() throws RecognitionException { + QualifiedNamePatternContext _localctx = new QualifiedNamePatternContext(_ctx, getState()); + enterRule(_localctx, 44, RULE_qualifiedNamePattern); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(318); + identifierPattern(); + setState(323); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,29,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(319); + match(DOT); + setState(320); + identifierPattern(); + } + } + } + setState(325); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,29,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class IdentifierContext extends ParserRuleContext { + public TerminalNode UNQUOTED_IDENTIFIER() { return getToken(esql_parser.UNQUOTED_IDENTIFIER, 0); } + public TerminalNode QUOTED_IDENTIFIER() { return getToken(esql_parser.QUOTED_IDENTIFIER, 0); } + public IdentifierContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_identifier; } + } + + public final IdentifierContext identifier() throws RecognitionException { + IdentifierContext _localctx = new IdentifierContext(_ctx, getState()); + enterRule(_localctx, 46, RULE_identifier); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(326); + _la = _input.LA(1); + if ( !(_la==UNQUOTED_IDENTIFIER || _la==QUOTED_IDENTIFIER) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class IdentifierPatternContext extends ParserRuleContext { + public TerminalNode PROJECT_UNQUOTED_IDENTIFIER() { return getToken(esql_parser.PROJECT_UNQUOTED_IDENTIFIER, 0); } + public TerminalNode QUOTED_IDENTIFIER() { return getToken(esql_parser.QUOTED_IDENTIFIER, 0); } + public IdentifierPatternContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_identifierPattern; } + } + + public final IdentifierPatternContext identifierPattern() throws RecognitionException { + IdentifierPatternContext _localctx = new IdentifierPatternContext(_ctx, getState()); + enterRule(_localctx, 48, RULE_identifierPattern); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(328); + _la = _input.LA(1); + if ( !(_la==QUOTED_IDENTIFIER || _la==PROJECT_UNQUOTED_IDENTIFIER) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class ConstantContext extends ParserRuleContext { + public ConstantContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_constant; } + + public ConstantContext() { } + public void copyFrom(ConstantContext ctx) { + super.copyFrom(ctx); + } + } + @SuppressWarnings("CheckReturnValue") + public static class BooleanArrayLiteralContext extends ConstantContext { + public TerminalNode OPENING_BRACKET() { return getToken(esql_parser.OPENING_BRACKET, 0); } + public List booleanValue() { + return getRuleContexts(BooleanValueContext.class); + } + public BooleanValueContext booleanValue(int i) { + return getRuleContext(BooleanValueContext.class,i); + } + public TerminalNode CLOSING_BRACKET() { return getToken(esql_parser.CLOSING_BRACKET, 0); } + public List COMMA() { return getTokens(esql_parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(esql_parser.COMMA, i); + } + public BooleanArrayLiteralContext(ConstantContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class DecimalLiteralContext extends ConstantContext { + public DecimalValueContext decimalValue() { + return getRuleContext(DecimalValueContext.class,0); + } + public DecimalLiteralContext(ConstantContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class NullLiteralContext extends ConstantContext { + public TerminalNode NULL() { return getToken(esql_parser.NULL, 0); } + public NullLiteralContext(ConstantContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class QualifiedIntegerLiteralContext extends ConstantContext { + public IntegerValueContext integerValue() { + return getRuleContext(IntegerValueContext.class,0); + } + public TerminalNode UNQUOTED_IDENTIFIER() { return getToken(esql_parser.UNQUOTED_IDENTIFIER, 0); } + public QualifiedIntegerLiteralContext(ConstantContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class StringArrayLiteralContext extends ConstantContext { + public TerminalNode OPENING_BRACKET() { return getToken(esql_parser.OPENING_BRACKET, 0); } + public List string() { + return getRuleContexts(StringContext.class); + } + public StringContext string(int i) { + return getRuleContext(StringContext.class,i); + } + public TerminalNode CLOSING_BRACKET() { return getToken(esql_parser.CLOSING_BRACKET, 0); } + public List COMMA() { return getTokens(esql_parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(esql_parser.COMMA, i); + } + public StringArrayLiteralContext(ConstantContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class StringLiteralContext extends ConstantContext { + public StringContext string() { + return getRuleContext(StringContext.class,0); + } + public StringLiteralContext(ConstantContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class NumericArrayLiteralContext extends ConstantContext { + public TerminalNode OPENING_BRACKET() { return getToken(esql_parser.OPENING_BRACKET, 0); } + public List numericValue() { + return getRuleContexts(NumericValueContext.class); + } + public NumericValueContext numericValue(int i) { + return getRuleContext(NumericValueContext.class,i); + } + public TerminalNode CLOSING_BRACKET() { return getToken(esql_parser.CLOSING_BRACKET, 0); } + public List COMMA() { return getTokens(esql_parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(esql_parser.COMMA, i); + } + public NumericArrayLiteralContext(ConstantContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class InputParamContext extends ConstantContext { + public TerminalNode PARAM() { return getToken(esql_parser.PARAM, 0); } + public InputParamContext(ConstantContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class IntegerLiteralContext extends ConstantContext { + public IntegerValueContext integerValue() { + return getRuleContext(IntegerValueContext.class,0); + } + public IntegerLiteralContext(ConstantContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class BooleanLiteralContext extends ConstantContext { + public BooleanValueContext booleanValue() { + return getRuleContext(BooleanValueContext.class,0); + } + public BooleanLiteralContext(ConstantContext ctx) { copyFrom(ctx); } + } + + public final ConstantContext constant() throws RecognitionException { + ConstantContext _localctx = new ConstantContext(_ctx, getState()); + enterRule(_localctx, 50, RULE_constant); + int _la; + try { + setState(372); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,33,_ctx) ) { + case 1: + _localctx = new NullLiteralContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(330); + match(NULL); + } + break; + case 2: + _localctx = new QualifiedIntegerLiteralContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(331); + integerValue(); + setState(332); + match(UNQUOTED_IDENTIFIER); + } + break; + case 3: + _localctx = new DecimalLiteralContext(_localctx); + enterOuterAlt(_localctx, 3); + { + setState(334); + decimalValue(); + } + break; + case 4: + _localctx = new IntegerLiteralContext(_localctx); + enterOuterAlt(_localctx, 4); + { + setState(335); + integerValue(); + } + break; + case 5: + _localctx = new BooleanLiteralContext(_localctx); + enterOuterAlt(_localctx, 5); + { + setState(336); + booleanValue(); + } + break; + case 6: + _localctx = new InputParamContext(_localctx); + enterOuterAlt(_localctx, 6); + { + setState(337); + match(PARAM); + } + break; + case 7: + _localctx = new StringLiteralContext(_localctx); + enterOuterAlt(_localctx, 7); + { + setState(338); + string(); + } + break; + case 8: + _localctx = new NumericArrayLiteralContext(_localctx); + enterOuterAlt(_localctx, 8); + { + setState(339); + match(OPENING_BRACKET); + setState(340); + numericValue(); + setState(345); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(341); + match(COMMA); + setState(342); + numericValue(); + } + } + setState(347); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(348); + match(CLOSING_BRACKET); + } + break; + case 9: + _localctx = new BooleanArrayLiteralContext(_localctx); + enterOuterAlt(_localctx, 9); + { + setState(350); + match(OPENING_BRACKET); + setState(351); + booleanValue(); + setState(356); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(352); + match(COMMA); + setState(353); + booleanValue(); + } + } + setState(358); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(359); + match(CLOSING_BRACKET); + } + break; + case 10: + _localctx = new StringArrayLiteralContext(_localctx); + enterOuterAlt(_localctx, 10); + { + setState(361); + match(OPENING_BRACKET); + setState(362); + string(); + setState(367); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(363); + match(COMMA); + setState(364); + string(); + } + } + setState(369); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(370); + match(CLOSING_BRACKET); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class LimitCommandContext extends ParserRuleContext { + public TerminalNode LIMIT() { return getToken(esql_parser.LIMIT, 0); } + public TerminalNode INTEGER_LITERAL() { return getToken(esql_parser.INTEGER_LITERAL, 0); } + public LimitCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_limitCommand; } + } + + public final LimitCommandContext limitCommand() throws RecognitionException { + LimitCommandContext _localctx = new LimitCommandContext(_ctx, getState()); + enterRule(_localctx, 52, RULE_limitCommand); + try { + enterOuterAlt(_localctx, 1); + { + setState(374); + match(LIMIT); + setState(375); + match(INTEGER_LITERAL); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class SortCommandContext extends ParserRuleContext { + public TerminalNode SORT() { return getToken(esql_parser.SORT, 0); } + public List orderExpression() { + return getRuleContexts(OrderExpressionContext.class); + } + public OrderExpressionContext orderExpression(int i) { + return getRuleContext(OrderExpressionContext.class,i); + } + public List COMMA() { return getTokens(esql_parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(esql_parser.COMMA, i); + } + public SortCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_sortCommand; } + } + + public final SortCommandContext sortCommand() throws RecognitionException { + SortCommandContext _localctx = new SortCommandContext(_ctx, getState()); + enterRule(_localctx, 54, RULE_sortCommand); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(377); + match(SORT); + setState(378); + orderExpression(); + setState(383); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,34,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(379); + match(COMMA); + setState(380); + orderExpression(); + } + } + } + setState(385); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,34,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class OrderExpressionContext extends ParserRuleContext { + public Token ordering; + public Token nullOrdering; + public BooleanExpressionContext booleanExpression() { + return getRuleContext(BooleanExpressionContext.class,0); + } + public TerminalNode NULLS() { return getToken(esql_parser.NULLS, 0); } + public TerminalNode ASC() { return getToken(esql_parser.ASC, 0); } + public TerminalNode DESC() { return getToken(esql_parser.DESC, 0); } + public TerminalNode FIRST() { return getToken(esql_parser.FIRST, 0); } + public TerminalNode LAST() { return getToken(esql_parser.LAST, 0); } + public OrderExpressionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_orderExpression; } + } + + public final OrderExpressionContext orderExpression() throws RecognitionException { + OrderExpressionContext _localctx = new OrderExpressionContext(_ctx, getState()); + enterRule(_localctx, 56, RULE_orderExpression); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(386); + booleanExpression(0); + setState(388); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,35,_ctx) ) { + case 1: + { + setState(387); + ((OrderExpressionContext)_localctx).ordering = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==ASC || _la==DESC) ) { + ((OrderExpressionContext)_localctx).ordering = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + break; + } + setState(392); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,36,_ctx) ) { + case 1: + { + setState(390); + match(NULLS); + setState(391); + ((OrderExpressionContext)_localctx).nullOrdering = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==FIRST || _la==LAST) ) { + ((OrderExpressionContext)_localctx).nullOrdering = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class KeepCommandContext extends ParserRuleContext { + public TerminalNode KEEP() { return getToken(esql_parser.KEEP, 0); } + public List qualifiedNamePattern() { + return getRuleContexts(QualifiedNamePatternContext.class); + } + public QualifiedNamePatternContext qualifiedNamePattern(int i) { + return getRuleContext(QualifiedNamePatternContext.class,i); + } + public List COMMA() { return getTokens(esql_parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(esql_parser.COMMA, i); + } + public TerminalNode PROJECT() { return getToken(esql_parser.PROJECT, 0); } + public KeepCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_keepCommand; } + } + + public final KeepCommandContext keepCommand() throws RecognitionException { + KeepCommandContext _localctx = new KeepCommandContext(_ctx, getState()); + enterRule(_localctx, 58, RULE_keepCommand); + try { + int _alt; + setState(412); + _errHandler.sync(this); + switch (_input.LA(1)) { + case KEEP: + enterOuterAlt(_localctx, 1); + { + setState(394); + match(KEEP); + setState(395); + qualifiedNamePattern(); + setState(400); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,37,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(396); + match(COMMA); + setState(397); + qualifiedNamePattern(); + } + } + } + setState(402); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,37,_ctx); + } + } + break; + case PROJECT: + enterOuterAlt(_localctx, 2); + { + setState(403); + match(PROJECT); + setState(404); + qualifiedNamePattern(); + setState(409); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,38,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(405); + match(COMMA); + setState(406); + qualifiedNamePattern(); + } + } + } + setState(411); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,38,_ctx); + } + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class DropCommandContext extends ParserRuleContext { + public TerminalNode DROP() { return getToken(esql_parser.DROP, 0); } + public List qualifiedNamePattern() { + return getRuleContexts(QualifiedNamePatternContext.class); + } + public QualifiedNamePatternContext qualifiedNamePattern(int i) { + return getRuleContext(QualifiedNamePatternContext.class,i); + } + public List COMMA() { return getTokens(esql_parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(esql_parser.COMMA, i); + } + public DropCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_dropCommand; } + } + + public final DropCommandContext dropCommand() throws RecognitionException { + DropCommandContext _localctx = new DropCommandContext(_ctx, getState()); + enterRule(_localctx, 60, RULE_dropCommand); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(414); + match(DROP); + setState(415); + qualifiedNamePattern(); + setState(420); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,40,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(416); + match(COMMA); + setState(417); + qualifiedNamePattern(); + } + } + } + setState(422); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,40,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class RenameCommandContext extends ParserRuleContext { + public TerminalNode RENAME() { return getToken(esql_parser.RENAME, 0); } + public List renameClause() { + return getRuleContexts(RenameClauseContext.class); + } + public RenameClauseContext renameClause(int i) { + return getRuleContext(RenameClauseContext.class,i); + } + public List COMMA() { return getTokens(esql_parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(esql_parser.COMMA, i); + } + public RenameCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_renameCommand; } + } + + public final RenameCommandContext renameCommand() throws RecognitionException { + RenameCommandContext _localctx = new RenameCommandContext(_ctx, getState()); + enterRule(_localctx, 62, RULE_renameCommand); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(423); + match(RENAME); + setState(424); + renameClause(); + setState(429); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,41,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(425); + match(COMMA); + setState(426); + renameClause(); + } + } + } + setState(431); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,41,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class RenameClauseContext extends ParserRuleContext { + public QualifiedNamePatternContext oldName; + public QualifiedNamePatternContext newName; + public TerminalNode AS() { return getToken(esql_parser.AS, 0); } + public List qualifiedNamePattern() { + return getRuleContexts(QualifiedNamePatternContext.class); + } + public QualifiedNamePatternContext qualifiedNamePattern(int i) { + return getRuleContext(QualifiedNamePatternContext.class,i); + } + public RenameClauseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_renameClause; } + } + + public final RenameClauseContext renameClause() throws RecognitionException { + RenameClauseContext _localctx = new RenameClauseContext(_ctx, getState()); + enterRule(_localctx, 64, RULE_renameClause); + try { + enterOuterAlt(_localctx, 1); + { + setState(432); + ((RenameClauseContext)_localctx).oldName = qualifiedNamePattern(); + setState(433); + match(AS); + setState(434); + ((RenameClauseContext)_localctx).newName = qualifiedNamePattern(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class DissectCommandContext extends ParserRuleContext { + public TerminalNode DISSECT() { return getToken(esql_parser.DISSECT, 0); } + public PrimaryExpressionContext primaryExpression() { + return getRuleContext(PrimaryExpressionContext.class,0); + } + public StringContext string() { + return getRuleContext(StringContext.class,0); + } + public CommandOptionsContext commandOptions() { + return getRuleContext(CommandOptionsContext.class,0); + } + public DissectCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_dissectCommand; } + } + + public final DissectCommandContext dissectCommand() throws RecognitionException { + DissectCommandContext _localctx = new DissectCommandContext(_ctx, getState()); + enterRule(_localctx, 66, RULE_dissectCommand); + try { + enterOuterAlt(_localctx, 1); + { + setState(436); + match(DISSECT); + setState(437); + primaryExpression(); + setState(438); + string(); + setState(440); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,42,_ctx) ) { + case 1: + { + setState(439); + commandOptions(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class GrokCommandContext extends ParserRuleContext { + public TerminalNode GROK() { return getToken(esql_parser.GROK, 0); } + public PrimaryExpressionContext primaryExpression() { + return getRuleContext(PrimaryExpressionContext.class,0); + } + public StringContext string() { + return getRuleContext(StringContext.class,0); + } + public GrokCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_grokCommand; } + } + + public final GrokCommandContext grokCommand() throws RecognitionException { + GrokCommandContext _localctx = new GrokCommandContext(_ctx, getState()); + enterRule(_localctx, 68, RULE_grokCommand); + try { + enterOuterAlt(_localctx, 1); + { + setState(442); + match(GROK); + setState(443); + primaryExpression(); + setState(444); + string(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class MvExpandCommandContext extends ParserRuleContext { + public TerminalNode MV_EXPAND() { return getToken(esql_parser.MV_EXPAND, 0); } + public QualifiedNameContext qualifiedName() { + return getRuleContext(QualifiedNameContext.class,0); + } + public MvExpandCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_mvExpandCommand; } + } + + public final MvExpandCommandContext mvExpandCommand() throws RecognitionException { + MvExpandCommandContext _localctx = new MvExpandCommandContext(_ctx, getState()); + enterRule(_localctx, 70, RULE_mvExpandCommand); + try { + enterOuterAlt(_localctx, 1); + { + setState(446); + match(MV_EXPAND); + setState(447); + qualifiedName(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class CommandOptionsContext extends ParserRuleContext { + public List commandOption() { + return getRuleContexts(CommandOptionContext.class); + } + public CommandOptionContext commandOption(int i) { + return getRuleContext(CommandOptionContext.class,i); + } + public List COMMA() { return getTokens(esql_parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(esql_parser.COMMA, i); + } + public CommandOptionsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_commandOptions; } + } + + public final CommandOptionsContext commandOptions() throws RecognitionException { + CommandOptionsContext _localctx = new CommandOptionsContext(_ctx, getState()); + enterRule(_localctx, 72, RULE_commandOptions); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(449); + commandOption(); + setState(454); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,43,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(450); + match(COMMA); + setState(451); + commandOption(); + } + } + } + setState(456); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,43,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class CommandOptionContext extends ParserRuleContext { + public IdentifierContext identifier() { + return getRuleContext(IdentifierContext.class,0); + } + public TerminalNode ASSIGN() { return getToken(esql_parser.ASSIGN, 0); } + public ConstantContext constant() { + return getRuleContext(ConstantContext.class,0); + } + public CommandOptionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_commandOption; } + } + + public final CommandOptionContext commandOption() throws RecognitionException { + CommandOptionContext _localctx = new CommandOptionContext(_ctx, getState()); + enterRule(_localctx, 74, RULE_commandOption); + try { + enterOuterAlt(_localctx, 1); + { + setState(457); + identifier(); + setState(458); + match(ASSIGN); + setState(459); + constant(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class BooleanValueContext extends ParserRuleContext { + public TerminalNode TRUE() { return getToken(esql_parser.TRUE, 0); } + public TerminalNode FALSE() { return getToken(esql_parser.FALSE, 0); } + public BooleanValueContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_booleanValue; } + } + + public final BooleanValueContext booleanValue() throws RecognitionException { + BooleanValueContext _localctx = new BooleanValueContext(_ctx, getState()); + enterRule(_localctx, 76, RULE_booleanValue); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(461); + _la = _input.LA(1); + if ( !(_la==FALSE || _la==TRUE) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class NumericValueContext extends ParserRuleContext { + public DecimalValueContext decimalValue() { + return getRuleContext(DecimalValueContext.class,0); + } + public IntegerValueContext integerValue() { + return getRuleContext(IntegerValueContext.class,0); + } + public NumericValueContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_numericValue; } + } + + public final NumericValueContext numericValue() throws RecognitionException { + NumericValueContext _localctx = new NumericValueContext(_ctx, getState()); + enterRule(_localctx, 78, RULE_numericValue); + try { + setState(465); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,44,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(463); + decimalValue(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(464); + integerValue(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class DecimalValueContext extends ParserRuleContext { + public TerminalNode DECIMAL_LITERAL() { return getToken(esql_parser.DECIMAL_LITERAL, 0); } + public TerminalNode PLUS() { return getToken(esql_parser.PLUS, 0); } + public TerminalNode MINUS() { return getToken(esql_parser.MINUS, 0); } + public DecimalValueContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_decimalValue; } + } + + public final DecimalValueContext decimalValue() throws RecognitionException { + DecimalValueContext _localctx = new DecimalValueContext(_ctx, getState()); + enterRule(_localctx, 80, RULE_decimalValue); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(468); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==PLUS || _la==MINUS) { + { + setState(467); + _la = _input.LA(1); + if ( !(_la==PLUS || _la==MINUS) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + + setState(470); + match(DECIMAL_LITERAL); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class IntegerValueContext extends ParserRuleContext { + public TerminalNode INTEGER_LITERAL() { return getToken(esql_parser.INTEGER_LITERAL, 0); } + public TerminalNode PLUS() { return getToken(esql_parser.PLUS, 0); } + public TerminalNode MINUS() { return getToken(esql_parser.MINUS, 0); } + public IntegerValueContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_integerValue; } + } + + public final IntegerValueContext integerValue() throws RecognitionException { + IntegerValueContext _localctx = new IntegerValueContext(_ctx, getState()); + enterRule(_localctx, 82, RULE_integerValue); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(473); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==PLUS || _la==MINUS) { + { + setState(472); + _la = _input.LA(1); + if ( !(_la==PLUS || _la==MINUS) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + + setState(475); + match(INTEGER_LITERAL); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class StringContext extends ParserRuleContext { + public TerminalNode STRING() { return getToken(esql_parser.STRING, 0); } + public StringContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_string; } + } + + public final StringContext string() throws RecognitionException { + StringContext _localctx = new StringContext(_ctx, getState()); + enterRule(_localctx, 84, RULE_string); + try { + enterOuterAlt(_localctx, 1); + { + setState(477); + match(STRING); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class ComparisonOperatorContext extends ParserRuleContext { + public TerminalNode EQ() { return getToken(esql_parser.EQ, 0); } + public TerminalNode NEQ() { return getToken(esql_parser.NEQ, 0); } + public TerminalNode LT() { return getToken(esql_parser.LT, 0); } + public TerminalNode LTE() { return getToken(esql_parser.LTE, 0); } + public TerminalNode GT() { return getToken(esql_parser.GT, 0); } + public TerminalNode GTE() { return getToken(esql_parser.GTE, 0); } + public ComparisonOperatorContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_comparisonOperator; } + } + + public final ComparisonOperatorContext comparisonOperator() throws RecognitionException { + ComparisonOperatorContext _localctx = new ComparisonOperatorContext(_ctx, getState()); + enterRule(_localctx, 86, RULE_comparisonOperator); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(479); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 283726776524341248L) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class ExplainCommandContext extends ParserRuleContext { + public TerminalNode EXPLAIN() { return getToken(esql_parser.EXPLAIN, 0); } + public SubqueryExpressionContext subqueryExpression() { + return getRuleContext(SubqueryExpressionContext.class,0); + } + public ExplainCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_explainCommand; } + } + + public final ExplainCommandContext explainCommand() throws RecognitionException { + ExplainCommandContext _localctx = new ExplainCommandContext(_ctx, getState()); + enterRule(_localctx, 88, RULE_explainCommand); + try { + enterOuterAlt(_localctx, 1); + { + setState(481); + match(EXPLAIN); + setState(482); + subqueryExpression(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class SubqueryExpressionContext extends ParserRuleContext { + public TerminalNode OPENING_BRACKET() { return getToken(esql_parser.OPENING_BRACKET, 0); } + public QueryContext query() { + return getRuleContext(QueryContext.class,0); + } + public TerminalNode CLOSING_BRACKET() { return getToken(esql_parser.CLOSING_BRACKET, 0); } + public SubqueryExpressionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_subqueryExpression; } + } + + public final SubqueryExpressionContext subqueryExpression() throws RecognitionException { + SubqueryExpressionContext _localctx = new SubqueryExpressionContext(_ctx, getState()); + enterRule(_localctx, 90, RULE_subqueryExpression); + try { + enterOuterAlt(_localctx, 1); + { + setState(484); + match(OPENING_BRACKET); + setState(485); + query(0); + setState(486); + match(CLOSING_BRACKET); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class ShowCommandContext extends ParserRuleContext { + public ShowCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_showCommand; } + + public ShowCommandContext() { } + public void copyFrom(ShowCommandContext ctx) { + super.copyFrom(ctx); + } + } + @SuppressWarnings("CheckReturnValue") + public static class ShowInfoContext extends ShowCommandContext { + public TerminalNode SHOW() { return getToken(esql_parser.SHOW, 0); } + public TerminalNode INFO() { return getToken(esql_parser.INFO, 0); } + public ShowInfoContext(ShowCommandContext ctx) { copyFrom(ctx); } + } + @SuppressWarnings("CheckReturnValue") + public static class ShowFunctionsContext extends ShowCommandContext { + public TerminalNode SHOW() { return getToken(esql_parser.SHOW, 0); } + public TerminalNode FUNCTIONS() { return getToken(esql_parser.FUNCTIONS, 0); } + public ShowFunctionsContext(ShowCommandContext ctx) { copyFrom(ctx); } + } + + public final ShowCommandContext showCommand() throws RecognitionException { + ShowCommandContext _localctx = new ShowCommandContext(_ctx, getState()); + enterRule(_localctx, 92, RULE_showCommand); + try { + setState(492); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,47,_ctx) ) { + case 1: + _localctx = new ShowInfoContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(488); + match(SHOW); + setState(489); + match(INFO); + } + break; + case 2: + _localctx = new ShowFunctionsContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(490); + match(SHOW); + setState(491); + match(FUNCTIONS); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class EnrichCommandContext extends ParserRuleContext { + public FromIdentifierContext policyName; + public QualifiedNamePatternContext matchField; + public TerminalNode ENRICH() { return getToken(esql_parser.ENRICH, 0); } + public FromIdentifierContext fromIdentifier() { + return getRuleContext(FromIdentifierContext.class,0); + } + public TerminalNode ON() { return getToken(esql_parser.ON, 0); } + public TerminalNode WITH() { return getToken(esql_parser.WITH, 0); } + public List enrichWithClause() { + return getRuleContexts(EnrichWithClauseContext.class); + } + public EnrichWithClauseContext enrichWithClause(int i) { + return getRuleContext(EnrichWithClauseContext.class,i); + } + public QualifiedNamePatternContext qualifiedNamePattern() { + return getRuleContext(QualifiedNamePatternContext.class,0); + } + public List COMMA() { return getTokens(esql_parser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(esql_parser.COMMA, i); + } + public EnrichCommandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_enrichCommand; } + } + + public final EnrichCommandContext enrichCommand() throws RecognitionException { + EnrichCommandContext _localctx = new EnrichCommandContext(_ctx, getState()); + enterRule(_localctx, 94, RULE_enrichCommand); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(494); + match(ENRICH); + setState(495); + ((EnrichCommandContext)_localctx).policyName = fromIdentifier(); + setState(498); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,48,_ctx) ) { + case 1: + { + setState(496); + match(ON); + setState(497); + ((EnrichCommandContext)_localctx).matchField = qualifiedNamePattern(); + } + break; + } + setState(509); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,50,_ctx) ) { + case 1: + { + setState(500); + match(WITH); + setState(501); + enrichWithClause(); + setState(506); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,49,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(502); + match(COMMA); + setState(503); + enrichWithClause(); + } + } + } + setState(508); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,49,_ctx); + } + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class EnrichWithClauseContext extends ParserRuleContext { + public QualifiedNamePatternContext newName; + public QualifiedNamePatternContext enrichField; + public List qualifiedNamePattern() { + return getRuleContexts(QualifiedNamePatternContext.class); + } + public QualifiedNamePatternContext qualifiedNamePattern(int i) { + return getRuleContext(QualifiedNamePatternContext.class,i); + } + public TerminalNode ASSIGN() { return getToken(esql_parser.ASSIGN, 0); } + public EnrichWithClauseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_enrichWithClause; } + } + + public final EnrichWithClauseContext enrichWithClause() throws RecognitionException { + EnrichWithClauseContext _localctx = new EnrichWithClauseContext(_ctx, getState()); + enterRule(_localctx, 96, RULE_enrichWithClause); + try { + enterOuterAlt(_localctx, 1); + { + setState(514); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,51,_ctx) ) { + case 1: + { + setState(511); + ((EnrichWithClauseContext)_localctx).newName = qualifiedNamePattern(); + setState(512); + match(ASSIGN); + } + break; + } + setState(516); + ((EnrichWithClauseContext)_localctx).enrichField = qualifiedNamePattern(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + case 1: + return query_sempred((QueryContext)_localctx, predIndex); + case 5: + return booleanExpression_sempred((BooleanExpressionContext)_localctx, predIndex); + case 8: + return operatorExpression_sempred((OperatorExpressionContext)_localctx, predIndex); + } + return true; + } + private boolean query_sempred(QueryContext _localctx, int predIndex) { + switch (predIndex) { + case 0: + return precpred(_ctx, 1); + } + return true; + } + private boolean booleanExpression_sempred(BooleanExpressionContext _localctx, int predIndex) { + switch (predIndex) { + case 1: + return precpred(_ctx, 4); + case 2: + return precpred(_ctx, 3); + } + return true; + } + private boolean operatorExpression_sempred(OperatorExpressionContext _localctx, int predIndex) { + switch (predIndex) { + case 3: + return precpred(_ctx, 2); + case 4: + return precpred(_ctx, 1); + } + return true; + } + + public static final String _serializedATN = + "\u0004\u0001b\u0207\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+ + "\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002"+ + "\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007\u0007\u0007\u0002"+ + "\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b\u0007\u000b\u0002"+ + "\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0002\u000f\u0007\u000f"+ + "\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011\u0002\u0012\u0007\u0012"+ + "\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014\u0002\u0015\u0007\u0015"+ + "\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017\u0002\u0018\u0007\u0018"+ + "\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a\u0002\u001b\u0007\u001b"+ + "\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d\u0002\u001e\u0007\u001e"+ + "\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!\u0007!\u0002\"\u0007\"\u0002"+ + "#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002&\u0007&\u0002\'\u0007\'\u0002"+ + "(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002+\u0007+\u0002,\u0007,\u0002"+ + "-\u0007-\u0002.\u0007.\u0002/\u0007/\u00020\u00070\u0001\u0000\u0001\u0000"+ + "\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0005\u0001l\b\u0001\n\u0001\f\u0001o\t\u0001\u0001\u0002"+ + "\u0001\u0002\u0001\u0002\u0001\u0002\u0003\u0002u\b\u0002\u0001\u0003"+ + "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+ + "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+ + "\u0003\u0003\u0084\b\u0003\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0005"+ + "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+ + "\u0003\u0005\u0090\b\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+ + "\u0001\u0005\u0005\u0005\u0097\b\u0005\n\u0005\f\u0005\u009a\t\u0005\u0001"+ + "\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0003\u0005\u00a1"+ + "\b\u0005\u0001\u0005\u0001\u0005\u0003\u0005\u00a5\b\u0005\u0001\u0005"+ + "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0005\u0005"+ + "\u00ad\b\u0005\n\u0005\f\u0005\u00b0\t\u0005\u0001\u0006\u0001\u0006\u0003"+ + "\u0006\u00b4\b\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001"+ + "\u0006\u0003\u0006\u00bb\b\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0003"+ + "\u0006\u00c0\b\u0006\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001"+ + "\u0007\u0003\u0007\u00c7\b\u0007\u0001\b\u0001\b\u0001\b\u0001\b\u0003"+ + "\b\u00cd\b\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0005\b\u00d5"+ + "\b\b\n\b\f\b\u00d8\t\b\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t"+ + "\u0001\t\u0003\t\u00e1\b\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001"+ + "\n\u0005\n\u00e9\b\n\n\n\f\n\u00ec\t\n\u0003\n\u00ee\b\n\u0001\n\u0001"+ + "\n\u0001\u000b\u0001\u000b\u0001\u000b\u0001\f\u0001\f\u0001\f\u0005\f"+ + "\u00f8\b\f\n\f\f\f\u00fb\t\f\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0003"+ + "\r\u0102\b\r\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0005\u000e"+ + "\u0108\b\u000e\n\u000e\f\u000e\u010b\t\u000e\u0001\u000e\u0003\u000e\u010e"+ + "\b\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0005"+ + "\u000f\u0115\b\u000f\n\u000f\f\u000f\u0118\t\u000f\u0001\u000f\u0001\u000f"+ + "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0003\u0011"+ + "\u0121\b\u0011\u0001\u0011\u0001\u0011\u0003\u0011\u0125\b\u0011\u0001"+ + "\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0003\u0012\u012b\b\u0012\u0001"+ + "\u0013\u0001\u0013\u0001\u0013\u0005\u0013\u0130\b\u0013\n\u0013\f\u0013"+ + "\u0133\t\u0013\u0001\u0014\u0001\u0014\u0001\u0015\u0001\u0015\u0001\u0015"+ + "\u0005\u0015\u013a\b\u0015\n\u0015\f\u0015\u013d\t\u0015\u0001\u0016\u0001"+ + "\u0016\u0001\u0016\u0005\u0016\u0142\b\u0016\n\u0016\f\u0016\u0145\t\u0016"+ + "\u0001\u0017\u0001\u0017\u0001\u0018\u0001\u0018\u0001\u0019\u0001\u0019"+ + "\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019"+ + "\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0005\u0019"+ + "\u0158\b\u0019\n\u0019\f\u0019\u015b\t\u0019\u0001\u0019\u0001\u0019\u0001"+ + "\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0005\u0019\u0163\b\u0019\n"+ + "\u0019\f\u0019\u0166\t\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001"+ + "\u0019\u0001\u0019\u0001\u0019\u0005\u0019\u016e\b\u0019\n\u0019\f\u0019"+ + "\u0171\t\u0019\u0001\u0019\u0001\u0019\u0003\u0019\u0175\b\u0019\u0001"+ + "\u001a\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001"+ + "\u001b\u0005\u001b\u017e\b\u001b\n\u001b\f\u001b\u0181\t\u001b\u0001\u001c"+ + "\u0001\u001c\u0003\u001c\u0185\b\u001c\u0001\u001c\u0001\u001c\u0003\u001c"+ + "\u0189\b\u001c\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0005\u001d"+ + "\u018f\b\u001d\n\u001d\f\u001d\u0192\t\u001d\u0001\u001d\u0001\u001d\u0001"+ + "\u001d\u0001\u001d\u0005\u001d\u0198\b\u001d\n\u001d\f\u001d\u019b\t\u001d"+ + "\u0003\u001d\u019d\b\u001d\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001e"+ + "\u0005\u001e\u01a3\b\u001e\n\u001e\f\u001e\u01a6\t\u001e\u0001\u001f\u0001"+ + "\u001f\u0001\u001f\u0001\u001f\u0005\u001f\u01ac\b\u001f\n\u001f\f\u001f"+ + "\u01af\t\u001f\u0001 \u0001 \u0001 \u0001 \u0001!\u0001!\u0001!\u0001"+ + "!\u0003!\u01b9\b!\u0001\"\u0001\"\u0001\"\u0001\"\u0001#\u0001#\u0001"+ + "#\u0001$\u0001$\u0001$\u0005$\u01c5\b$\n$\f$\u01c8\t$\u0001%\u0001%\u0001"+ + "%\u0001%\u0001&\u0001&\u0001\'\u0001\'\u0003\'\u01d2\b\'\u0001(\u0003"+ + "(\u01d5\b(\u0001(\u0001(\u0001)\u0003)\u01da\b)\u0001)\u0001)\u0001*\u0001"+ + "*\u0001+\u0001+\u0001,\u0001,\u0001,\u0001-\u0001-\u0001-\u0001-\u0001"+ + ".\u0001.\u0001.\u0001.\u0003.\u01ed\b.\u0001/\u0001/\u0001/\u0001/\u0003"+ + "/\u01f3\b/\u0001/\u0001/\u0001/\u0001/\u0005/\u01f9\b/\n/\f/\u01fc\t/"+ + "\u0003/\u01fe\b/\u00010\u00010\u00010\u00030\u0203\b0\u00010\u00010\u0001"+ + "0\u0000\u0003\u0002\n\u00101\u0000\u0002\u0004\u0006\b\n\f\u000e\u0010"+ + "\u0012\u0014\u0016\u0018\u001a\u001c\u001e \"$&(*,.02468:<>@BDFHJLNPR"+ + "TVXZ\\^`\u0000\t\u0001\u0000:;\u0001\u0000<>\u0002\u0000BBGG\u0001\u0000"+ + "AB\u0002\u0000BBKK\u0002\u0000 ##\u0001\u0000&\'\u0002\u0000%%33\u0001"+ + "\u000049\u0224\u0000b\u0001\u0000\u0000\u0000\u0002e\u0001\u0000\u0000"+ + "\u0000\u0004t\u0001\u0000\u0000\u0000\u0006\u0083\u0001\u0000\u0000\u0000"+ + "\b\u0085\u0001\u0000\u0000\u0000\n\u00a4\u0001\u0000\u0000\u0000\f\u00bf"+ + "\u0001\u0000\u0000\u0000\u000e\u00c6\u0001\u0000\u0000\u0000\u0010\u00cc"+ + "\u0001\u0000\u0000\u0000\u0012\u00e0\u0001\u0000\u0000\u0000\u0014\u00e2"+ + "\u0001\u0000\u0000\u0000\u0016\u00f1\u0001\u0000\u0000\u0000\u0018\u00f4"+ + "\u0001\u0000\u0000\u0000\u001a\u0101\u0001\u0000\u0000\u0000\u001c\u0103"+ + "\u0001\u0000\u0000\u0000\u001e\u010f\u0001\u0000\u0000\u0000 \u011b\u0001"+ + "\u0000\u0000\u0000\"\u011e\u0001\u0000\u0000\u0000$\u0126\u0001\u0000"+ + "\u0000\u0000&\u012c\u0001\u0000\u0000\u0000(\u0134\u0001\u0000\u0000\u0000"+ + "*\u0136\u0001\u0000\u0000\u0000,\u013e\u0001\u0000\u0000\u0000.\u0146"+ + "\u0001\u0000\u0000\u00000\u0148\u0001\u0000\u0000\u00002\u0174\u0001\u0000"+ + "\u0000\u00004\u0176\u0001\u0000\u0000\u00006\u0179\u0001\u0000\u0000\u0000"+ + "8\u0182\u0001\u0000\u0000\u0000:\u019c\u0001\u0000\u0000\u0000<\u019e"+ + "\u0001\u0000\u0000\u0000>\u01a7\u0001\u0000\u0000\u0000@\u01b0\u0001\u0000"+ + "\u0000\u0000B\u01b4\u0001\u0000\u0000\u0000D\u01ba\u0001\u0000\u0000\u0000"+ + "F\u01be\u0001\u0000\u0000\u0000H\u01c1\u0001\u0000\u0000\u0000J\u01c9"+ + "\u0001\u0000\u0000\u0000L\u01cd\u0001\u0000\u0000\u0000N\u01d1\u0001\u0000"+ + "\u0000\u0000P\u01d4\u0001\u0000\u0000\u0000R\u01d9\u0001\u0000\u0000\u0000"+ + "T\u01dd\u0001\u0000\u0000\u0000V\u01df\u0001\u0000\u0000\u0000X\u01e1"+ + "\u0001\u0000\u0000\u0000Z\u01e4\u0001\u0000\u0000\u0000\\\u01ec\u0001"+ + "\u0000\u0000\u0000^\u01ee\u0001\u0000\u0000\u0000`\u0202\u0001\u0000\u0000"+ + "\u0000bc\u0003\u0002\u0001\u0000cd\u0005\u0000\u0000\u0001d\u0001\u0001"+ + "\u0000\u0000\u0000ef\u0006\u0001\uffff\uffff\u0000fg\u0003\u0004\u0002"+ + "\u0000gm\u0001\u0000\u0000\u0000hi\n\u0001\u0000\u0000ij\u0005\u001a\u0000"+ + "\u0000jl\u0003\u0006\u0003\u0000kh\u0001\u0000\u0000\u0000lo\u0001\u0000"+ + "\u0000\u0000mk\u0001\u0000\u0000\u0000mn\u0001\u0000\u0000\u0000n\u0003"+ + "\u0001\u0000\u0000\u0000om\u0001\u0000\u0000\u0000pu\u0003X,\u0000qu\u0003"+ + "\u001c\u000e\u0000ru\u0003\u0016\u000b\u0000su\u0003\\.\u0000tp\u0001"+ + "\u0000\u0000\u0000tq\u0001\u0000\u0000\u0000tr\u0001\u0000\u0000\u0000"+ + "ts\u0001\u0000\u0000\u0000u\u0005\u0001\u0000\u0000\u0000v\u0084\u0003"+ + " \u0010\u0000w\u0084\u0003$\u0012\u0000x\u0084\u00034\u001a\u0000y\u0084"+ + "\u0003:\u001d\u0000z\u0084\u00036\u001b\u0000{\u0084\u0003\"\u0011\u0000"+ + "|\u0084\u0003\b\u0004\u0000}\u0084\u0003<\u001e\u0000~\u0084\u0003>\u001f"+ + "\u0000\u007f\u0084\u0003B!\u0000\u0080\u0084\u0003D\"\u0000\u0081\u0084"+ + "\u0003^/\u0000\u0082\u0084\u0003F#\u0000\u0083v\u0001\u0000\u0000\u0000"+ + "\u0083w\u0001\u0000\u0000\u0000\u0083x\u0001\u0000\u0000\u0000\u0083y"+ + "\u0001\u0000\u0000\u0000\u0083z\u0001\u0000\u0000\u0000\u0083{\u0001\u0000"+ + "\u0000\u0000\u0083|\u0001\u0000\u0000\u0000\u0083}\u0001\u0000\u0000\u0000"+ + "\u0083~\u0001\u0000\u0000\u0000\u0083\u007f\u0001\u0000\u0000\u0000\u0083"+ + "\u0080\u0001\u0000\u0000\u0000\u0083\u0081\u0001\u0000\u0000\u0000\u0083"+ + "\u0082\u0001\u0000\u0000\u0000\u0084\u0007\u0001\u0000\u0000\u0000\u0085"+ + "\u0086\u0005\u0012\u0000\u0000\u0086\u0087\u0003\n\u0005\u0000\u0087\t"+ + "\u0001\u0000\u0000\u0000\u0088\u0089\u0006\u0005\uffff\uffff\u0000\u0089"+ + "\u008a\u0005,\u0000\u0000\u008a\u00a5\u0003\n\u0005\u0007\u008b\u00a5"+ + "\u0003\u000e\u0007\u0000\u008c\u00a5\u0003\f\u0006\u0000\u008d\u008f\u0003"+ + "\u000e\u0007\u0000\u008e\u0090\u0005,\u0000\u0000\u008f\u008e\u0001\u0000"+ + "\u0000\u0000\u008f\u0090\u0001\u0000\u0000\u0000\u0090\u0091\u0001\u0000"+ + "\u0000\u0000\u0091\u0092\u0005)\u0000\u0000\u0092\u0093\u0005(\u0000\u0000"+ + "\u0093\u0098\u0003\u000e\u0007\u0000\u0094\u0095\u0005\"\u0000\u0000\u0095"+ + "\u0097\u0003\u000e\u0007\u0000\u0096\u0094\u0001\u0000\u0000\u0000\u0097"+ + "\u009a\u0001\u0000\u0000\u0000\u0098\u0096\u0001\u0000\u0000\u0000\u0098"+ + "\u0099\u0001\u0000\u0000\u0000\u0099\u009b\u0001\u0000\u0000\u0000\u009a"+ + "\u0098\u0001\u0000\u0000\u0000\u009b\u009c\u00052\u0000\u0000\u009c\u00a5"+ + "\u0001\u0000\u0000\u0000\u009d\u009e\u0003\u000e\u0007\u0000\u009e\u00a0"+ + "\u0005*\u0000\u0000\u009f\u00a1\u0005,\u0000\u0000\u00a0\u009f\u0001\u0000"+ + "\u0000\u0000\u00a0\u00a1\u0001\u0000\u0000\u0000\u00a1\u00a2\u0001\u0000"+ + "\u0000\u0000\u00a2\u00a3\u0005-\u0000\u0000\u00a3\u00a5\u0001\u0000\u0000"+ + "\u0000\u00a4\u0088\u0001\u0000\u0000\u0000\u00a4\u008b\u0001\u0000\u0000"+ + "\u0000\u00a4\u008c\u0001\u0000\u0000\u0000\u00a4\u008d\u0001\u0000\u0000"+ + "\u0000\u00a4\u009d\u0001\u0000\u0000\u0000\u00a5\u00ae\u0001\u0000\u0000"+ + "\u0000\u00a6\u00a7\n\u0004\u0000\u0000\u00a7\u00a8\u0005\u001f\u0000\u0000"+ + "\u00a8\u00ad\u0003\n\u0005\u0005\u00a9\u00aa\n\u0003\u0000\u0000\u00aa"+ + "\u00ab\u0005/\u0000\u0000\u00ab\u00ad\u0003\n\u0005\u0004\u00ac\u00a6"+ + "\u0001\u0000\u0000\u0000\u00ac\u00a9\u0001\u0000\u0000\u0000\u00ad\u00b0"+ + "\u0001\u0000\u0000\u0000\u00ae\u00ac\u0001\u0000\u0000\u0000\u00ae\u00af"+ + "\u0001\u0000\u0000\u0000\u00af\u000b\u0001\u0000\u0000\u0000\u00b0\u00ae"+ + "\u0001\u0000\u0000\u0000\u00b1\u00b3\u0003\u000e\u0007\u0000\u00b2\u00b4"+ + "\u0005,\u0000\u0000\u00b3\u00b2\u0001\u0000\u0000\u0000\u00b3\u00b4\u0001"+ + "\u0000\u0000\u0000\u00b4\u00b5\u0001\u0000\u0000\u0000\u00b5\u00b6\u0005"+ + "+\u0000\u0000\u00b6\u00b7\u0003T*\u0000\u00b7\u00c0\u0001\u0000\u0000"+ + "\u0000\u00b8\u00ba\u0003\u000e\u0007\u0000\u00b9\u00bb\u0005,\u0000\u0000"+ + "\u00ba\u00b9\u0001\u0000\u0000\u0000\u00ba\u00bb\u0001\u0000\u0000\u0000"+ + "\u00bb\u00bc\u0001\u0000\u0000\u0000\u00bc\u00bd\u00051\u0000\u0000\u00bd"+ + "\u00be\u0003T*\u0000\u00be\u00c0\u0001\u0000\u0000\u0000\u00bf\u00b1\u0001"+ + "\u0000\u0000\u0000\u00bf\u00b8\u0001\u0000\u0000\u0000\u00c0\r\u0001\u0000"+ + "\u0000\u0000\u00c1\u00c7\u0003\u0010\b\u0000\u00c2\u00c3\u0003\u0010\b"+ + "\u0000\u00c3\u00c4\u0003V+\u0000\u00c4\u00c5\u0003\u0010\b\u0000\u00c5"+ + "\u00c7\u0001\u0000\u0000\u0000\u00c6\u00c1\u0001\u0000\u0000\u0000\u00c6"+ + "\u00c2\u0001\u0000\u0000\u0000\u00c7\u000f\u0001\u0000\u0000\u0000\u00c8"+ + "\u00c9\u0006\b\uffff\uffff\u0000\u00c9\u00cd\u0003\u0012\t\u0000\u00ca"+ + "\u00cb\u0007\u0000\u0000\u0000\u00cb\u00cd\u0003\u0010\b\u0003\u00cc\u00c8"+ + "\u0001\u0000\u0000\u0000\u00cc\u00ca\u0001\u0000\u0000\u0000\u00cd\u00d6"+ + "\u0001\u0000\u0000\u0000\u00ce\u00cf\n\u0002\u0000\u0000\u00cf\u00d0\u0007"+ + "\u0001\u0000\u0000\u00d0\u00d5\u0003\u0010\b\u0003\u00d1\u00d2\n\u0001"+ + "\u0000\u0000\u00d2\u00d3\u0007\u0000\u0000\u0000\u00d3\u00d5\u0003\u0010"+ + "\b\u0002\u00d4\u00ce\u0001\u0000\u0000\u0000\u00d4\u00d1\u0001\u0000\u0000"+ + "\u0000\u00d5\u00d8\u0001\u0000\u0000\u0000\u00d6\u00d4\u0001\u0000\u0000"+ + "\u0000\u00d6\u00d7\u0001\u0000\u0000\u0000\u00d7\u0011\u0001\u0000\u0000"+ + "\u0000\u00d8\u00d6\u0001\u0000\u0000\u0000\u00d9\u00e1\u00032\u0019\u0000"+ + "\u00da\u00e1\u0003*\u0015\u0000\u00db\u00e1\u0003\u0014\n\u0000\u00dc"+ + "\u00dd\u0005(\u0000\u0000\u00dd\u00de\u0003\n\u0005\u0000\u00de\u00df"+ + "\u00052\u0000\u0000\u00df\u00e1\u0001\u0000\u0000\u0000\u00e0\u00d9\u0001"+ + "\u0000\u0000\u0000\u00e0\u00da\u0001\u0000\u0000\u0000\u00e0\u00db\u0001"+ + "\u0000\u0000\u0000\u00e0\u00dc\u0001\u0000\u0000\u0000\u00e1\u0013\u0001"+ + "\u0000\u0000\u0000\u00e2\u00e3\u0003.\u0017\u0000\u00e3\u00ed\u0005(\u0000"+ + "\u0000\u00e4\u00ee\u0005<\u0000\u0000\u00e5\u00ea\u0003\n\u0005\u0000"+ + "\u00e6\u00e7\u0005\"\u0000\u0000\u00e7\u00e9\u0003\n\u0005\u0000\u00e8"+ + "\u00e6\u0001\u0000\u0000\u0000\u00e9\u00ec\u0001\u0000\u0000\u0000\u00ea"+ + "\u00e8\u0001\u0000\u0000\u0000\u00ea\u00eb\u0001\u0000\u0000\u0000\u00eb"+ + "\u00ee\u0001\u0000\u0000\u0000\u00ec\u00ea\u0001\u0000\u0000\u0000\u00ed"+ + "\u00e4\u0001\u0000\u0000\u0000\u00ed\u00e5\u0001\u0000\u0000\u0000\u00ed"+ + "\u00ee\u0001\u0000\u0000\u0000\u00ee\u00ef\u0001\u0000\u0000\u0000\u00ef"+ + "\u00f0\u00052\u0000\u0000\u00f0\u0015\u0001\u0000\u0000\u0000\u00f1\u00f2"+ + "\u0005\u000e\u0000\u0000\u00f2\u00f3\u0003\u0018\f\u0000\u00f3\u0017\u0001"+ + "\u0000\u0000\u0000\u00f4\u00f9\u0003\u001a\r\u0000\u00f5\u00f6\u0005\""+ + "\u0000\u0000\u00f6\u00f8\u0003\u001a\r\u0000\u00f7\u00f5\u0001\u0000\u0000"+ + "\u0000\u00f8\u00fb\u0001\u0000\u0000\u0000\u00f9\u00f7\u0001\u0000\u0000"+ + "\u0000\u00f9\u00fa\u0001\u0000\u0000\u0000\u00fa\u0019\u0001\u0000\u0000"+ + "\u0000\u00fb\u00f9\u0001\u0000\u0000\u0000\u00fc\u0102\u0003\n\u0005\u0000"+ + "\u00fd\u00fe\u0003*\u0015\u0000\u00fe\u00ff\u0005!\u0000\u0000\u00ff\u0100"+ + "\u0003\n\u0005\u0000\u0100\u0102\u0001\u0000\u0000\u0000\u0101\u00fc\u0001"+ + "\u0000\u0000\u0000\u0101\u00fd\u0001\u0000\u0000\u0000\u0102\u001b\u0001"+ + "\u0000\u0000\u0000\u0103\u0104\u0005\u0006\u0000\u0000\u0104\u0109\u0003"+ + "(\u0014\u0000\u0105\u0106\u0005\"\u0000\u0000\u0106\u0108\u0003(\u0014"+ + "\u0000\u0107\u0105\u0001\u0000\u0000\u0000\u0108\u010b\u0001\u0000\u0000"+ + "\u0000\u0109\u0107\u0001\u0000\u0000\u0000\u0109\u010a\u0001\u0000\u0000"+ + "\u0000\u010a\u010d\u0001\u0000\u0000\u0000\u010b\u0109\u0001\u0000\u0000"+ + "\u0000\u010c\u010e\u0003\u001e\u000f\u0000\u010d\u010c\u0001\u0000\u0000"+ + "\u0000\u010d\u010e\u0001\u0000\u0000\u0000\u010e\u001d\u0001\u0000\u0000"+ + "\u0000\u010f\u0110\u0005?\u0000\u0000\u0110\u0111\u0005F\u0000\u0000\u0111"+ + "\u0116\u0003(\u0014\u0000\u0112\u0113\u0005\"\u0000\u0000\u0113\u0115"+ + "\u0003(\u0014\u0000\u0114\u0112\u0001\u0000\u0000\u0000\u0115\u0118\u0001"+ + "\u0000\u0000\u0000\u0116\u0114\u0001\u0000\u0000\u0000\u0116\u0117\u0001"+ + "\u0000\u0000\u0000\u0117\u0119\u0001\u0000\u0000\u0000\u0118\u0116\u0001"+ + "\u0000\u0000\u0000\u0119\u011a\u0005@\u0000\u0000\u011a\u001f\u0001\u0000"+ + "\u0000\u0000\u011b\u011c\u0005\u0004\u0000\u0000\u011c\u011d\u0003\u0018"+ + "\f\u0000\u011d!\u0001\u0000\u0000\u0000\u011e\u0120\u0005\u0011\u0000"+ + "\u0000\u011f\u0121\u0003\u0018\f\u0000\u0120\u011f\u0001\u0000\u0000\u0000"+ + "\u0120\u0121\u0001\u0000\u0000\u0000\u0121\u0124\u0001\u0000\u0000\u0000"+ + "\u0122\u0123\u0005\u001e\u0000\u0000\u0123\u0125\u0003&\u0013\u0000\u0124"+ + "\u0122\u0001\u0000\u0000\u0000\u0124\u0125\u0001\u0000\u0000\u0000\u0125"+ + "#\u0001\u0000\u0000\u0000\u0126\u0127\u0005\b\u0000\u0000\u0127\u012a"+ + "\u0003\u0018\f\u0000\u0128\u0129\u0005\u001e\u0000\u0000\u0129\u012b\u0003"+ + "&\u0013\u0000\u012a\u0128\u0001\u0000\u0000\u0000\u012a\u012b\u0001\u0000"+ + "\u0000\u0000\u012b%\u0001\u0000\u0000\u0000\u012c\u0131\u0003*\u0015\u0000"+ + "\u012d\u012e\u0005\"\u0000\u0000\u012e\u0130\u0003*\u0015\u0000\u012f"+ + "\u012d\u0001\u0000\u0000\u0000\u0130\u0133\u0001\u0000\u0000\u0000\u0131"+ + "\u012f\u0001\u0000\u0000\u0000\u0131\u0132\u0001\u0000\u0000\u0000\u0132"+ + "\'\u0001\u0000\u0000\u0000\u0133\u0131\u0001\u0000\u0000\u0000\u0134\u0135"+ + "\u0007\u0002\u0000\u0000\u0135)\u0001\u0000\u0000\u0000\u0136\u013b\u0003"+ + ".\u0017\u0000\u0137\u0138\u0005$\u0000\u0000\u0138\u013a\u0003.\u0017"+ + "\u0000\u0139\u0137\u0001\u0000\u0000\u0000\u013a\u013d\u0001\u0000\u0000"+ + "\u0000\u013b\u0139\u0001\u0000\u0000\u0000\u013b\u013c\u0001\u0000\u0000"+ + "\u0000\u013c+\u0001\u0000\u0000\u0000\u013d\u013b\u0001\u0000\u0000\u0000"+ + "\u013e\u0143\u00030\u0018\u0000\u013f\u0140\u0005$\u0000\u0000\u0140\u0142"+ + "\u00030\u0018\u0000\u0141\u013f\u0001\u0000\u0000\u0000\u0142\u0145\u0001"+ + "\u0000\u0000\u0000\u0143\u0141\u0001\u0000\u0000\u0000\u0143\u0144\u0001"+ + "\u0000\u0000\u0000\u0144-\u0001\u0000\u0000\u0000\u0145\u0143\u0001\u0000"+ + "\u0000\u0000\u0146\u0147\u0007\u0003\u0000\u0000\u0147/\u0001\u0000\u0000"+ + "\u0000\u0148\u0149\u0007\u0004\u0000\u0000\u01491\u0001\u0000\u0000\u0000"+ + "\u014a\u0175\u0005-\u0000\u0000\u014b\u014c\u0003R)\u0000\u014c\u014d"+ + "\u0005A\u0000\u0000\u014d\u0175\u0001\u0000\u0000\u0000\u014e\u0175\u0003"+ + "P(\u0000\u014f\u0175\u0003R)\u0000\u0150\u0175\u0003L&\u0000\u0151\u0175"+ + "\u00050\u0000\u0000\u0152\u0175\u0003T*\u0000\u0153\u0154\u0005?\u0000"+ + "\u0000\u0154\u0159\u0003N\'\u0000\u0155\u0156\u0005\"\u0000\u0000\u0156"+ + "\u0158\u0003N\'\u0000\u0157\u0155\u0001\u0000\u0000\u0000\u0158\u015b"+ + "\u0001\u0000\u0000\u0000\u0159\u0157\u0001\u0000\u0000\u0000\u0159\u015a"+ + "\u0001\u0000\u0000\u0000\u015a\u015c\u0001\u0000\u0000\u0000\u015b\u0159"+ + "\u0001\u0000\u0000\u0000\u015c\u015d\u0005@\u0000\u0000\u015d\u0175\u0001"+ + "\u0000\u0000\u0000\u015e\u015f\u0005?\u0000\u0000\u015f\u0164\u0003L&"+ + "\u0000\u0160\u0161\u0005\"\u0000\u0000\u0161\u0163\u0003L&\u0000\u0162"+ + "\u0160\u0001\u0000\u0000\u0000\u0163\u0166\u0001\u0000\u0000\u0000\u0164"+ + "\u0162\u0001\u0000\u0000\u0000\u0164\u0165\u0001\u0000\u0000\u0000\u0165"+ + "\u0167\u0001\u0000\u0000\u0000\u0166\u0164\u0001\u0000\u0000\u0000\u0167"+ + "\u0168\u0005@\u0000\u0000\u0168\u0175\u0001\u0000\u0000\u0000\u0169\u016a"+ + "\u0005?\u0000\u0000\u016a\u016f\u0003T*\u0000\u016b\u016c\u0005\"\u0000"+ + "\u0000\u016c\u016e\u0003T*\u0000\u016d\u016b\u0001\u0000\u0000\u0000\u016e"+ + "\u0171\u0001\u0000\u0000\u0000\u016f\u016d\u0001\u0000\u0000\u0000\u016f"+ + "\u0170\u0001\u0000\u0000\u0000\u0170\u0172\u0001\u0000\u0000\u0000\u0171"+ + "\u016f\u0001\u0000\u0000\u0000\u0172\u0173\u0005@\u0000\u0000\u0173\u0175"+ + "\u0001\u0000\u0000\u0000\u0174\u014a\u0001\u0000\u0000\u0000\u0174\u014b"+ + "\u0001\u0000\u0000\u0000\u0174\u014e\u0001\u0000\u0000\u0000\u0174\u014f"+ + "\u0001\u0000\u0000\u0000\u0174\u0150\u0001\u0000\u0000\u0000\u0174\u0151"+ + "\u0001\u0000\u0000\u0000\u0174\u0152\u0001\u0000\u0000\u0000\u0174\u0153"+ + "\u0001\u0000\u0000\u0000\u0174\u015e\u0001\u0000\u0000\u0000\u0174\u0169"+ + "\u0001\u0000\u0000\u0000\u01753\u0001\u0000\u0000\u0000\u0176\u0177\u0005"+ + "\n\u0000\u0000\u0177\u0178\u0005\u001c\u0000\u0000\u01785\u0001\u0000"+ + "\u0000\u0000\u0179\u017a\u0005\u0010\u0000\u0000\u017a\u017f\u00038\u001c"+ + "\u0000\u017b\u017c\u0005\"\u0000\u0000\u017c\u017e\u00038\u001c\u0000"+ + "\u017d\u017b\u0001\u0000\u0000\u0000\u017e\u0181\u0001\u0000\u0000\u0000"+ + "\u017f\u017d\u0001\u0000\u0000\u0000\u017f\u0180\u0001\u0000\u0000\u0000"+ + "\u01807\u0001\u0000\u0000\u0000\u0181\u017f\u0001\u0000\u0000\u0000\u0182"+ + "\u0184\u0003\n\u0005\u0000\u0183\u0185\u0007\u0005\u0000\u0000\u0184\u0183"+ + "\u0001\u0000\u0000\u0000\u0184\u0185\u0001\u0000\u0000\u0000\u0185\u0188"+ + "\u0001\u0000\u0000\u0000\u0186\u0187\u0005.\u0000\u0000\u0187\u0189\u0007"+ + "\u0006\u0000\u0000\u0188\u0186\u0001\u0000\u0000\u0000\u0188\u0189\u0001"+ + "\u0000\u0000\u0000\u01899\u0001\u0000\u0000\u0000\u018a\u018b\u0005\t"+ + "\u0000\u0000\u018b\u0190\u0003,\u0016\u0000\u018c\u018d\u0005\"\u0000"+ + "\u0000\u018d\u018f\u0003,\u0016\u0000\u018e\u018c\u0001\u0000\u0000\u0000"+ + "\u018f\u0192\u0001\u0000\u0000\u0000\u0190\u018e\u0001\u0000\u0000\u0000"+ + "\u0190\u0191\u0001\u0000\u0000\u0000\u0191\u019d\u0001\u0000\u0000\u0000"+ + "\u0192\u0190\u0001\u0000\u0000\u0000\u0193\u0194\u0005\f\u0000\u0000\u0194"+ + "\u0199\u0003,\u0016\u0000\u0195\u0196\u0005\"\u0000\u0000\u0196\u0198"+ + "\u0003,\u0016\u0000\u0197\u0195\u0001\u0000\u0000\u0000\u0198\u019b\u0001"+ + "\u0000\u0000\u0000\u0199\u0197\u0001\u0000\u0000\u0000\u0199\u019a\u0001"+ + "\u0000\u0000\u0000\u019a\u019d\u0001\u0000\u0000\u0000\u019b\u0199\u0001"+ + "\u0000\u0000\u0000\u019c\u018a\u0001\u0000\u0000\u0000\u019c\u0193\u0001"+ + "\u0000\u0000\u0000\u019d;\u0001\u0000\u0000\u0000\u019e\u019f\u0005\u0002"+ + "\u0000\u0000\u019f\u01a4\u0003,\u0016\u0000\u01a0\u01a1\u0005\"\u0000"+ + "\u0000\u01a1\u01a3\u0003,\u0016\u0000\u01a2\u01a0\u0001\u0000\u0000\u0000"+ + "\u01a3\u01a6\u0001\u0000\u0000\u0000\u01a4\u01a2\u0001\u0000\u0000\u0000"+ + "\u01a4\u01a5\u0001\u0000\u0000\u0000\u01a5=\u0001\u0000\u0000\u0000\u01a6"+ + "\u01a4\u0001\u0000\u0000\u0000\u01a7\u01a8\u0005\r\u0000\u0000\u01a8\u01ad"+ + "\u0003@ \u0000\u01a9\u01aa\u0005\"\u0000\u0000\u01aa\u01ac\u0003@ \u0000"+ + "\u01ab\u01a9\u0001\u0000\u0000\u0000\u01ac\u01af\u0001\u0000\u0000\u0000"+ + "\u01ad\u01ab\u0001\u0000\u0000\u0000\u01ad\u01ae\u0001\u0000\u0000\u0000"+ + "\u01ae?\u0001\u0000\u0000\u0000\u01af\u01ad\u0001\u0000\u0000\u0000\u01b0"+ + "\u01b1\u0003,\u0016\u0000\u01b1\u01b2\u0005O\u0000\u0000\u01b2\u01b3\u0003"+ + ",\u0016\u0000\u01b3A\u0001\u0000\u0000\u0000\u01b4\u01b5\u0005\u0001\u0000"+ + "\u0000\u01b5\u01b6\u0003\u0012\t\u0000\u01b6\u01b8\u0003T*\u0000\u01b7"+ + "\u01b9\u0003H$\u0000\u01b8\u01b7\u0001\u0000\u0000\u0000\u01b8\u01b9\u0001"+ + "\u0000\u0000\u0000\u01b9C\u0001\u0000\u0000\u0000\u01ba\u01bb\u0005\u0007"+ + "\u0000\u0000\u01bb\u01bc\u0003\u0012\t\u0000\u01bc\u01bd\u0003T*\u0000"+ + "\u01bdE\u0001\u0000\u0000\u0000\u01be\u01bf\u0005\u000b\u0000\u0000\u01bf"+ + "\u01c0\u0003*\u0015\u0000\u01c0G\u0001\u0000\u0000\u0000\u01c1\u01c6\u0003"+ + "J%\u0000\u01c2\u01c3\u0005\"\u0000\u0000\u01c3\u01c5\u0003J%\u0000\u01c4"+ + "\u01c2\u0001\u0000\u0000\u0000\u01c5\u01c8\u0001\u0000\u0000\u0000\u01c6"+ + "\u01c4\u0001\u0000\u0000\u0000\u01c6\u01c7\u0001\u0000\u0000\u0000\u01c7"+ + "I\u0001\u0000\u0000\u0000\u01c8\u01c6\u0001\u0000\u0000\u0000\u01c9\u01ca"+ + "\u0003.\u0017\u0000\u01ca\u01cb\u0005!\u0000\u0000\u01cb\u01cc\u00032"+ + "\u0019\u0000\u01ccK\u0001\u0000\u0000\u0000\u01cd\u01ce\u0007\u0007\u0000"+ + "\u0000\u01ceM\u0001\u0000\u0000\u0000\u01cf\u01d2\u0003P(\u0000\u01d0"+ + "\u01d2\u0003R)\u0000\u01d1\u01cf\u0001\u0000\u0000\u0000\u01d1\u01d0\u0001"+ + "\u0000\u0000\u0000\u01d2O\u0001\u0000\u0000\u0000\u01d3\u01d5\u0007\u0000"+ + "\u0000\u0000\u01d4\u01d3\u0001\u0000\u0000\u0000\u01d4\u01d5\u0001\u0000"+ + "\u0000\u0000\u01d5\u01d6\u0001\u0000\u0000\u0000\u01d6\u01d7\u0005\u001d"+ + "\u0000\u0000\u01d7Q\u0001\u0000\u0000\u0000\u01d8\u01da\u0007\u0000\u0000"+ + "\u0000\u01d9\u01d8\u0001\u0000\u0000\u0000\u01d9\u01da\u0001\u0000\u0000"+ + "\u0000\u01da\u01db\u0001\u0000\u0000\u0000\u01db\u01dc\u0005\u001c\u0000"+ + "\u0000\u01dcS\u0001\u0000\u0000\u0000\u01dd\u01de\u0005\u001b\u0000\u0000"+ + "\u01deU\u0001\u0000\u0000\u0000\u01df\u01e0\u0007\b\u0000\u0000\u01e0"+ + "W\u0001\u0000\u0000\u0000\u01e1\u01e2\u0005\u0005\u0000\u0000\u01e2\u01e3"+ + "\u0003Z-\u0000\u01e3Y\u0001\u0000\u0000\u0000\u01e4\u01e5\u0005?\u0000"+ + "\u0000\u01e5\u01e6\u0003\u0002\u0001\u0000\u01e6\u01e7\u0005@\u0000\u0000"+ + "\u01e7[\u0001\u0000\u0000\u0000\u01e8\u01e9\u0005\u000f\u0000\u0000\u01e9"+ + "\u01ed\u0005^\u0000\u0000\u01ea\u01eb\u0005\u000f\u0000\u0000\u01eb\u01ed"+ + "\u0005_\u0000\u0000\u01ec\u01e8\u0001\u0000\u0000\u0000\u01ec\u01ea\u0001"+ + "\u0000\u0000\u0000\u01ed]\u0001\u0000\u0000\u0000\u01ee\u01ef\u0005\u0003"+ + "\u0000\u0000\u01ef\u01f2\u0003(\u0014\u0000\u01f0\u01f1\u0005S\u0000\u0000"+ + "\u01f1\u01f3\u0003,\u0016\u0000\u01f2\u01f0\u0001\u0000\u0000\u0000\u01f2"+ + "\u01f3\u0001\u0000\u0000\u0000\u01f3\u01fd\u0001\u0000\u0000\u0000\u01f4"+ + "\u01f5\u0005T\u0000\u0000\u01f5\u01fa\u0003`0\u0000\u01f6\u01f7\u0005"+ + "\"\u0000\u0000\u01f7\u01f9\u0003`0\u0000\u01f8\u01f6\u0001\u0000\u0000"+ + "\u0000\u01f9\u01fc\u0001\u0000\u0000\u0000\u01fa\u01f8\u0001\u0000\u0000"+ + "\u0000\u01fa\u01fb\u0001\u0000\u0000\u0000\u01fb\u01fe\u0001\u0000\u0000"+ + "\u0000\u01fc\u01fa\u0001\u0000\u0000\u0000\u01fd\u01f4\u0001\u0000\u0000"+ + "\u0000\u01fd\u01fe\u0001\u0000\u0000\u0000\u01fe_\u0001\u0000\u0000\u0000"+ + "\u01ff\u0200\u0003,\u0016\u0000\u0200\u0201\u0005!\u0000\u0000\u0201\u0203"+ + "\u0001\u0000\u0000\u0000\u0202\u01ff\u0001\u0000\u0000\u0000\u0202\u0203"+ + "\u0001\u0000\u0000\u0000\u0203\u0204\u0001\u0000\u0000\u0000\u0204\u0205"+ + "\u0003,\u0016\u0000\u0205a\u0001\u0000\u0000\u00004mt\u0083\u008f\u0098"+ + "\u00a0\u00a4\u00ac\u00ae\u00b3\u00ba\u00bf\u00c6\u00cc\u00d4\u00d6\u00e0"+ + "\u00ea\u00ed\u00f9\u0101\u0109\u010d\u0116\u0120\u0124\u012a\u0131\u013b"+ + "\u0143\u0159\u0164\u016f\u0174\u017f\u0184\u0188\u0190\u0199\u019c\u01a4"+ + "\u01ad\u01b8\u01c6\u01d1\u01d4\u01d9\u01ec\u01f2\u01fa\u01fd\u0202"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/packages/kbn-esql/src/antlr/.antlr/esql_parser.tokens b/packages/kbn-esql/src/antlr/.antlr/esql_parser.tokens new file mode 100644 index 00000000000000..85a98c3a6d2688 --- /dev/null +++ b/packages/kbn-esql/src/antlr/.antlr/esql_parser.tokens @@ -0,0 +1,117 @@ +DISSECT=1 +DROP=2 +ENRICH=3 +EVAL=4 +EXPLAIN=5 +FROM=6 +GROK=7 +INLINESTATS=8 +KEEP=9 +LIMIT=10 +MV_EXPAND=11 +PROJECT=12 +RENAME=13 +ROW=14 +SHOW=15 +SORT=16 +STATS=17 +WHERE=18 +UNKNOWN_CMD=19 +LINE_COMMENT=20 +MULTILINE_COMMENT=21 +WS=22 +EXPLAIN_WS=23 +EXPLAIN_LINE_COMMENT=24 +EXPLAIN_MULTILINE_COMMENT=25 +PIPE=26 +STRING=27 +INTEGER_LITERAL=28 +DECIMAL_LITERAL=29 +BY=30 +AND=31 +ASC=32 +ASSIGN=33 +COMMA=34 +DESC=35 +DOT=36 +FALSE=37 +FIRST=38 +LAST=39 +LP=40 +IN=41 +IS=42 +LIKE=43 +NOT=44 +NULL=45 +NULLS=46 +OR=47 +PARAM=48 +RLIKE=49 +RP=50 +TRUE=51 +EQ=52 +NEQ=53 +LT=54 +LTE=55 +GT=56 +GTE=57 +PLUS=58 +MINUS=59 +ASTERISK=60 +SLASH=61 +PERCENT=62 +OPENING_BRACKET=63 +CLOSING_BRACKET=64 +UNQUOTED_IDENTIFIER=65 +QUOTED_IDENTIFIER=66 +EXPR_LINE_COMMENT=67 +EXPR_MULTILINE_COMMENT=68 +EXPR_WS=69 +METADATA=70 +FROM_UNQUOTED_IDENTIFIER=71 +FROM_LINE_COMMENT=72 +FROM_MULTILINE_COMMENT=73 +FROM_WS=74 +PROJECT_UNQUOTED_IDENTIFIER=75 +PROJECT_LINE_COMMENT=76 +PROJECT_MULTILINE_COMMENT=77 +PROJECT_WS=78 +AS=79 +RENAME_LINE_COMMENT=80 +RENAME_MULTILINE_COMMENT=81 +RENAME_WS=82 +ON=83 +WITH=84 +ENRICH_LINE_COMMENT=85 +ENRICH_MULTILINE_COMMENT=86 +ENRICH_WS=87 +ENRICH_FIELD_LINE_COMMENT=88 +ENRICH_FIELD_MULTILINE_COMMENT=89 +ENRICH_FIELD_WS=90 +MVEXPAND_LINE_COMMENT=91 +MVEXPAND_MULTILINE_COMMENT=92 +MVEXPAND_WS=93 +INFO=94 +FUNCTIONS=95 +SHOW_LINE_COMMENT=96 +SHOW_MULTILINE_COMMENT=97 +SHOW_WS=98 +'|'=26 +'='=33 +','=34 +'.'=36 +'('=40 +'?'=48 +')'=50 +'=='=52 +'!='=53 +'<'=54 +'<='=55 +'>'=56 +'>='=57 +'+'=58 +'-'=59 +'*'=60 +'/'=61 +'%'=62 +']'=64 diff --git a/packages/kbn-monaco/src/esql/antlr/esql_lexer.g4 b/packages/kbn-monaco/src/esql/antlr/esql_lexer.g4 index 90a892d8d1dd62..d22db2818d4e78 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_lexer.g4 +++ b/packages/kbn-monaco/src/esql/antlr/esql_lexer.g4 @@ -8,23 +8,25 @@ lexer grammar esql_lexer; options { } -DISSECT : D I S S E C T -> pushMode(EXPRESSION); -DROP : D R O P -> pushMode(SOURCE_IDENTIFIERS); -ENRICH : E N R I C H -> pushMode(SOURCE_IDENTIFIERS); -EVAL : E V A L -> pushMode(EXPRESSION); -FROM : F R O M -> pushMode(SOURCE_IDENTIFIERS); -GROK : G R O K -> pushMode(EXPRESSION); -KEEP : K E E P -> pushMode(SOURCE_IDENTIFIERS); -LIMIT : L I M I T -> pushMode(EXPRESSION); -MV_EXPAND : M V UNDERSCORE E X P A N D -> pushMode(SOURCE_IDENTIFIERS); -PROJECT : P R O J E C T -> pushMode(SOURCE_IDENTIFIERS); -RENAME : R E N A M E -> pushMode(SOURCE_IDENTIFIERS); -ROW : R O W -> pushMode(EXPRESSION); -SHOW : S H O W -> pushMode(EXPRESSION); -SORT : S O R T -> pushMode(EXPRESSION); -STATS : S T A T S -> pushMode(EXPRESSION); -WHERE : W H E R E -> pushMode(EXPRESSION); -UNKNOWN_CMD : ~[ \r\n\t[\]/]+ -> pushMode(EXPRESSION); +DISSECT : D I S S E C T -> pushMode(EXPRESSION_MODE); +DROP : D R O P -> pushMode(PROJECT_MODE); +ENRICH : E N R I C H -> pushMode(ENRICH_MODE); +EVAL : E V A L -> pushMode(EXPRESSION_MODE); +EXPLAIN : E X P L A I N -> pushMode(EXPLAIN_MODE); +FROM : F R O M -> pushMode(FROM_MODE); +GROK : G R O K -> pushMode(EXPRESSION_MODE); +INLINESTATS : I N L I N E S T A T S -> pushMode(EXPRESSION_MODE); +KEEP : K E E P -> pushMode(PROJECT_MODE); +LIMIT : L I M I T -> pushMode(EXPRESSION_MODE); +MV_EXPAND : M V UNDERSCORE E X P A N D -> pushMode(MVEXPAND_MODE); +PROJECT : P R O J E C T -> pushMode(PROJECT_MODE); +RENAME : R E N A M E -> pushMode(RENAME_MODE); +ROW : R O W -> pushMode(EXPRESSION_MODE); +SHOW : S H O W -> pushMode(SHOW_MODE); +SORT : S O R T -> pushMode(EXPRESSION_MODE); +STATS : S T A T S -> pushMode(EXPRESSION_MODE); +WHERE : W H E R E -> pushMode(EXPRESSION_MODE); +UNKNOWN_CMD : ~[ \r\n\t[\]/]+ -> pushMode(EXPRESSION_MODE); LINE_COMMENT : '//' ~[\r\n]* '\r'? '\n'? -> channel(HIDDEN) @@ -37,8 +39,20 @@ MULTILINE_COMMENT WS : [ \r\n\t]+ -> channel(HIDDEN) ; - -mode EXPRESSION; +// +// Explain +// +mode EXPLAIN_MODE; +EXPLAIN_OPENING_BRACKET : OPENING_BRACKET -> type(OPENING_BRACKET), pushMode(DEFAULT_MODE); +EXPLAIN_PIPE : PIPE -> type(PIPE), popMode; +EXPLAIN_WS : WS -> channel(HIDDEN); +EXPLAIN_LINE_COMMENT : LINE_COMMENT -> channel(HIDDEN); +EXPLAIN_MULTILINE_COMMENT : MULTILINE_COMMENT -> channel(HIDDEN); + +// +// Expression - used by most command +// +mode EXPRESSION_MODE; PIPE : '|' -> popMode; @@ -62,6 +76,27 @@ fragment EXPONENT : [Ee] [+-]? DIGIT+ ; +fragment ASPERAND + : '@' + ; + +fragment BACKQUOTE + : '`' + ; + +fragment BACKQUOTE_BLOCK + : ~'`' + | '``' + ; + +fragment UNDERSCORE + : '_' + ; + +fragment UNQUOTED_ID_BODY + : (LETTER | DIGIT | UNDERSCORE) + ; + STRING : '"' (ESCAPE_SEQUENCE | UNESCAPED_CHARS)* '"' | '"""' (~[\r\n])*? '"""' '"'? '"'? @@ -101,9 +136,6 @@ PARAM: '?'; RLIKE: R L I K E; RP : ')'; TRUE : T R U E; -INFO : I N F O; -FUNCTIONS : F U N C T I O N S; -UNDERSCORE: '_'; EQ : '=='; NEQ : '!='; @@ -123,19 +155,18 @@ PERCENT : '%'; // mode. Thus, the two popModes on CLOSING_BRACKET. The other way could as // the start of a multivalued field constant. To line up with the double pop // the explain mode needs, we double push when we see that. -OPENING_BRACKET : '[' -> pushMode(EXPRESSION), pushMode(EXPRESSION); +OPENING_BRACKET : '[' -> pushMode(EXPRESSION_MODE), pushMode(EXPRESSION_MODE); CLOSING_BRACKET : ']' -> popMode, popMode; - UNQUOTED_IDENTIFIER - : LETTER (LETTER | DIGIT | '_')* + : LETTER UNQUOTED_ID_BODY* // only allow @ at beginning of identifier to keep the option to allow @ as infix operator in the future // also, single `_` and `@` characters are not valid identifiers - | ('_' | '@') (LETTER | DIGIT | '_')+ + | (UNDERSCORE | ASPERAND) UNQUOTED_ID_BODY+ ; QUOTED_IDENTIFIER - : '`' ( ~'`' | '``' )* '`' + : BACKQUOTE BACKQUOTE_BLOCK+ BACKQUOTE ; EXPR_LINE_COMMENT @@ -149,43 +180,206 @@ EXPR_MULTILINE_COMMENT EXPR_WS : WS -> channel(HIDDEN) ; +// +// FROM command +// +mode FROM_MODE; +FROM_PIPE : PIPE -> type(PIPE), popMode; +FROM_OPENING_BRACKET : OPENING_BRACKET -> type(OPENING_BRACKET), pushMode(FROM_MODE), pushMode(FROM_MODE); +FROM_CLOSING_BRACKET : CLOSING_BRACKET -> type(CLOSING_BRACKET), popMode, popMode; +FROM_COMMA : COMMA -> type(COMMA); +FROM_ASSIGN : ASSIGN -> type(ASSIGN); +METADATA: M E T A D A T A; +fragment FROM_UNQUOTED_IDENTIFIER_PART + : ~[=`|,[\]/ \t\r\n] + | '/' ~[*/] // allow single / but not followed by another / or * which would start a comment + ; -mode SOURCE_IDENTIFIERS; +FROM_UNQUOTED_IDENTIFIER + : FROM_UNQUOTED_IDENTIFIER_PART+ + ; + +FROM_QUOTED_IDENTIFIER + : QUOTED_IDENTIFIER -> type(QUOTED_IDENTIFIER) + ; + +FROM_LINE_COMMENT + : LINE_COMMENT -> channel(HIDDEN) + ; + +FROM_MULTILINE_COMMENT + : MULTILINE_COMMENT -> channel(HIDDEN) + ; + +FROM_WS + : WS -> channel(HIDDEN) + ; +// +// DROP, KEEP, PROJECT +// +mode PROJECT_MODE; +PROJECT_PIPE : PIPE -> type(PIPE), popMode; +PROJECT_DOT: DOT -> type(DOT); +PROJECT_COMMA : COMMA -> type(COMMA); + +fragment UNQUOTED_ID_BODY_WITH_PATTERN + : (LETTER | DIGIT | UNDERSCORE | ASTERISK) + ; + +PROJECT_UNQUOTED_IDENTIFIER + : (LETTER | ASTERISK) UNQUOTED_ID_BODY_WITH_PATTERN* + | (UNDERSCORE | ASPERAND) UNQUOTED_ID_BODY_WITH_PATTERN+ + ; + +PROJECT_QUOTED_IDENTIFIER + : QUOTED_IDENTIFIER -> type(QUOTED_IDENTIFIER) + ; + +PROJECT_LINE_COMMENT + : LINE_COMMENT -> channel(HIDDEN) + ; + +PROJECT_MULTILINE_COMMENT + : MULTILINE_COMMENT -> channel(HIDDEN) + ; + +PROJECT_WS + : WS -> channel(HIDDEN) + ; +// +// | RENAME a.b AS x, c AS y +// +mode RENAME_MODE; +RENAME_PIPE : PIPE -> type(PIPE), popMode; +RENAME_ASSIGN : ASSIGN -> type(ASSIGN); +RENAME_COMMA : COMMA -> type(COMMA); +RENAME_DOT: DOT -> type(DOT); -SRC_PIPE : '|' -> type(PIPE), popMode; -SRC_OPENING_BRACKET : '[' -> type(OPENING_BRACKET), pushMode(SOURCE_IDENTIFIERS), pushMode(SOURCE_IDENTIFIERS); -SRC_CLOSING_BRACKET : ']' -> popMode, popMode, type(CLOSING_BRACKET); -SRC_COMMA : ',' -> type(COMMA); -SRC_ASSIGN : '=' -> type(ASSIGN); AS : A S; -METADATA: M E T A D A T A; -ON : O N; -WITH : W I T H; -SRC_UNQUOTED_IDENTIFIER - : SRC_UNQUOTED_IDENTIFIER_PART+ +RENAME_QUOTED_IDENTIFIER + : QUOTED_IDENTIFIER -> type(QUOTED_IDENTIFIER) ; -fragment SRC_UNQUOTED_IDENTIFIER_PART - : ~[=`|,[\]/ \t\r\n]+ - | '/' ~[*/] // allow single / but not followed by another / or * which would start a comment +// use the unquoted pattern to let the parser invalidate fields with * +RENAME_UNQUOTED_IDENTIFIER + : PROJECT_UNQUOTED_IDENTIFIER -> type(PROJECT_UNQUOTED_IDENTIFIER) ; -SRC_QUOTED_IDENTIFIER - : QUOTED_IDENTIFIER +RENAME_LINE_COMMENT + : LINE_COMMENT -> channel(HIDDEN) + ; + +RENAME_MULTILINE_COMMENT + : MULTILINE_COMMENT -> channel(HIDDEN) ; -SRC_LINE_COMMENT +RENAME_WS + : WS -> channel(HIDDEN) + ; + +// | ENRICH ON key WITH fields +mode ENRICH_MODE; +ENRICH_PIPE : PIPE -> type(PIPE), popMode; + +ON : O N -> pushMode(ENRICH_FIELD_MODE); +WITH : W I T H -> pushMode(ENRICH_FIELD_MODE); + +// use the unquoted pattern to let the parser invalidate fields with * +ENRICH_POLICY_UNQUOTED_IDENTIFIER + : FROM_UNQUOTED_IDENTIFIER -> type(FROM_UNQUOTED_IDENTIFIER) + ; + +ENRICH_QUOTED_IDENTIFIER + : QUOTED_IDENTIFIER -> type(QUOTED_IDENTIFIER) + ; + +ENRICH_LINE_COMMENT + : LINE_COMMENT -> channel(HIDDEN) + ; + +ENRICH_MULTILINE_COMMENT + : MULTILINE_COMMENT -> channel(HIDDEN) + ; + +ENRICH_WS + : WS -> channel(HIDDEN) + ; + +// submode for Enrich to allow different lexing between policy identifier (loose) and field identifiers +mode ENRICH_FIELD_MODE; +ENRICH_FIELD_PIPE : PIPE -> type(PIPE), popMode, popMode; +ENRICH_FIELD_ASSIGN : ASSIGN -> type(ASSIGN); +ENRICH_FIELD_COMMA : COMMA -> type(COMMA); +ENRICH_FIELD_DOT: DOT -> type(DOT); + +ENRICH_FIELD_WITH : WITH -> type(WITH) ; + +ENRICH_FIELD_UNQUOTED_IDENTIFIER + : PROJECT_UNQUOTED_IDENTIFIER -> type(PROJECT_UNQUOTED_IDENTIFIER) + ; + +ENRICH_FIELD_QUOTED_IDENTIFIER + : QUOTED_IDENTIFIER -> type(QUOTED_IDENTIFIER) + ; + +ENRICH_FIELD_LINE_COMMENT + : LINE_COMMENT -> channel(HIDDEN) + ; + +ENRICH_FIELD_MULTILINE_COMMENT + : MULTILINE_COMMENT -> channel(HIDDEN) + ; + +ENRICH_FIELD_WS + : WS -> channel(HIDDEN) + ; + +mode MVEXPAND_MODE; +MVEXPAND_PIPE : PIPE -> type(PIPE), popMode; +MVEXPAND_DOT: DOT -> type(DOT); + +MVEXPAND_QUOTED_IDENTIFIER + : QUOTED_IDENTIFIER -> type(QUOTED_IDENTIFIER) + ; + +MVEXPAND_UNQUOTED_IDENTIFIER + : UNQUOTED_IDENTIFIER -> type(UNQUOTED_IDENTIFIER) + ; + + +MVEXPAND_LINE_COMMENT + : LINE_COMMENT -> channel(HIDDEN) + ; + +MVEXPAND_MULTILINE_COMMENT + : MULTILINE_COMMENT -> channel(HIDDEN) + ; + +MVEXPAND_WS + : WS -> channel(HIDDEN) + ; + +// +// SHOW INFO +// +mode SHOW_MODE; +SHOW_PIPE : PIPE -> type(PIPE), popMode; + +INFO : I N F O; +FUNCTIONS : F U N C T I O N S; + +SHOW_LINE_COMMENT : LINE_COMMENT -> channel(HIDDEN) ; -SRC_MULTILINE_COMMENT +SHOW_MULTILINE_COMMENT : MULTILINE_COMMENT -> channel(HIDDEN) ; -SRC_WS +SHOW_WS : WS -> channel(HIDDEN) ; diff --git a/packages/kbn-monaco/src/esql/antlr/esql_lexer.interp b/packages/kbn-monaco/src/esql/antlr/esql_lexer.interp index 0ff1f62c47445c..d2516b469b29d0 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_lexer.interp +++ b/packages/kbn-monaco/src/esql/antlr/esql_lexer.interp @@ -25,11 +25,16 @@ null null null null +'|' null null null null null +null +'=' +',' +null '.' null null @@ -46,9 +51,6 @@ null null ')' null -null -null -'_' '==' '!=' '<' @@ -76,6 +78,26 @@ null null null null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null token symbolic names: null @@ -83,8 +105,10 @@ DISSECT DROP ENRICH EVAL +EXPLAIN FROM GROK +INLINESTATS KEEP LIMIT MV_EXPAND @@ -99,6 +123,9 @@ UNKNOWN_CMD LINE_COMMENT MULTILINE_COMMENT WS +EXPLAIN_WS +EXPLAIN_LINE_COMMENT +EXPLAIN_MULTILINE_COMMENT PIPE STRING INTEGER_LITERAL @@ -125,9 +152,6 @@ PARAM RLIKE RP TRUE -INFO -FUNCTIONS -UNDERSCORE EQ NEQ LT @@ -146,23 +170,45 @@ QUOTED_IDENTIFIER EXPR_LINE_COMMENT EXPR_MULTILINE_COMMENT EXPR_WS -AS METADATA +FROM_UNQUOTED_IDENTIFIER +FROM_LINE_COMMENT +FROM_MULTILINE_COMMENT +FROM_WS +PROJECT_UNQUOTED_IDENTIFIER +PROJECT_LINE_COMMENT +PROJECT_MULTILINE_COMMENT +PROJECT_WS +AS +RENAME_LINE_COMMENT +RENAME_MULTILINE_COMMENT +RENAME_WS ON WITH -SRC_UNQUOTED_IDENTIFIER -SRC_QUOTED_IDENTIFIER -SRC_LINE_COMMENT -SRC_MULTILINE_COMMENT -SRC_WS +ENRICH_LINE_COMMENT +ENRICH_MULTILINE_COMMENT +ENRICH_WS +ENRICH_FIELD_LINE_COMMENT +ENRICH_FIELD_MULTILINE_COMMENT +ENRICH_FIELD_WS +MVEXPAND_LINE_COMMENT +MVEXPAND_MULTILINE_COMMENT +MVEXPAND_WS +INFO +FUNCTIONS +SHOW_LINE_COMMENT +SHOW_MULTILINE_COMMENT +SHOW_WS rule names: DISSECT DROP ENRICH EVAL +EXPLAIN FROM GROK +INLINESTATS KEEP LIMIT MV_EXPAND @@ -177,12 +223,22 @@ UNKNOWN_CMD LINE_COMMENT MULTILINE_COMMENT WS +EXPLAIN_OPENING_BRACKET +EXPLAIN_PIPE +EXPLAIN_WS +EXPLAIN_LINE_COMMENT +EXPLAIN_MULTILINE_COMMENT PIPE DIGIT LETTER ESCAPE_SEQUENCE UNESCAPED_CHARS EXPONENT +ASPERAND +BACKQUOTE +BACKQUOTE_BLOCK +UNDERSCORE +UNQUOTED_ID_BODY STRING INTEGER_LITERAL DECIMAL_LITERAL @@ -208,9 +264,6 @@ PARAM RLIKE RP TRUE -INFO -FUNCTIONS -UNDERSCORE EQ NEQ LT @@ -229,21 +282,68 @@ QUOTED_IDENTIFIER EXPR_LINE_COMMENT EXPR_MULTILINE_COMMENT EXPR_WS -SRC_PIPE -SRC_OPENING_BRACKET -SRC_CLOSING_BRACKET -SRC_COMMA -SRC_ASSIGN -AS +FROM_PIPE +FROM_OPENING_BRACKET +FROM_CLOSING_BRACKET +FROM_COMMA +FROM_ASSIGN METADATA +FROM_UNQUOTED_IDENTIFIER_PART +FROM_UNQUOTED_IDENTIFIER +FROM_QUOTED_IDENTIFIER +FROM_LINE_COMMENT +FROM_MULTILINE_COMMENT +FROM_WS +PROJECT_PIPE +PROJECT_DOT +PROJECT_COMMA +UNQUOTED_ID_BODY_WITH_PATTERN +PROJECT_UNQUOTED_IDENTIFIER +PROJECT_QUOTED_IDENTIFIER +PROJECT_LINE_COMMENT +PROJECT_MULTILINE_COMMENT +PROJECT_WS +RENAME_PIPE +RENAME_ASSIGN +RENAME_COMMA +RENAME_DOT +AS +RENAME_QUOTED_IDENTIFIER +RENAME_UNQUOTED_IDENTIFIER +RENAME_LINE_COMMENT +RENAME_MULTILINE_COMMENT +RENAME_WS +ENRICH_PIPE ON WITH -SRC_UNQUOTED_IDENTIFIER -SRC_UNQUOTED_IDENTIFIER_PART -SRC_QUOTED_IDENTIFIER -SRC_LINE_COMMENT -SRC_MULTILINE_COMMENT -SRC_WS +ENRICH_POLICY_UNQUOTED_IDENTIFIER +ENRICH_QUOTED_IDENTIFIER +ENRICH_LINE_COMMENT +ENRICH_MULTILINE_COMMENT +ENRICH_WS +ENRICH_FIELD_PIPE +ENRICH_FIELD_ASSIGN +ENRICH_FIELD_COMMA +ENRICH_FIELD_DOT +ENRICH_FIELD_WITH +ENRICH_FIELD_UNQUOTED_IDENTIFIER +ENRICH_FIELD_QUOTED_IDENTIFIER +ENRICH_FIELD_LINE_COMMENT +ENRICH_FIELD_MULTILINE_COMMENT +ENRICH_FIELD_WS +MVEXPAND_PIPE +MVEXPAND_DOT +MVEXPAND_QUOTED_IDENTIFIER +MVEXPAND_UNQUOTED_IDENTIFIER +MVEXPAND_LINE_COMMENT +MVEXPAND_MULTILINE_COMMENT +MVEXPAND_WS +SHOW_PIPE +INFO +FUNCTIONS +SHOW_LINE_COMMENT +SHOW_MULTILINE_COMMENT +SHOW_WS A B C @@ -277,8 +377,15 @@ HIDDEN mode names: DEFAULT_MODE -EXPRESSION -SOURCE_IDENTIFIERS +EXPLAIN_MODE +EXPRESSION_MODE +FROM_MODE +PROJECT_MODE +RENAME_MODE +ENRICH_MODE +ENRICH_FIELD_MODE +MVEXPAND_MODE +SHOW_MODE atn: -[3, 51485, 51898, 1421, 44986, 20307, 1543, 60043, 49729, 2, 78, 813, 8, 1, 8, 1, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 6, 18, 362, 10, 18, 13, 18, 14, 18, 363, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 19, 7, 19, 372, 10, 19, 12, 19, 14, 19, 375, 11, 19, 3, 19, 5, 19, 378, 10, 19, 3, 19, 5, 19, 381, 10, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 7, 20, 390, 10, 20, 12, 20, 14, 20, 393, 11, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 21, 6, 21, 401, 10, 21, 13, 21, 14, 21, 402, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 5, 27, 422, 10, 27, 3, 27, 6, 27, 425, 10, 27, 13, 27, 14, 27, 426, 3, 28, 3, 28, 3, 28, 7, 28, 432, 10, 28, 12, 28, 14, 28, 435, 11, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 7, 28, 443, 10, 28, 12, 28, 14, 28, 446, 11, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 5, 28, 453, 10, 28, 3, 28, 5, 28, 456, 10, 28, 5, 28, 458, 10, 28, 3, 29, 6, 29, 461, 10, 29, 13, 29, 14, 29, 462, 3, 30, 6, 30, 466, 10, 30, 13, 30, 14, 30, 467, 3, 30, 3, 30, 7, 30, 472, 10, 30, 12, 30, 14, 30, 475, 11, 30, 3, 30, 3, 30, 6, 30, 479, 10, 30, 13, 30, 14, 30, 480, 3, 30, 6, 30, 484, 10, 30, 13, 30, 14, 30, 485, 3, 30, 3, 30, 7, 30, 490, 10, 30, 12, 30, 14, 30, 493, 11, 30, 5, 30, 495, 10, 30, 3, 30, 3, 30, 3, 30, 3, 30, 6, 30, 501, 10, 30, 13, 30, 14, 30, 502, 3, 30, 3, 30, 5, 30, 507, 10, 30, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 63, 3, 63, 3, 64, 3, 64, 3, 65, 3, 65, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 7, 69, 651, 10, 69, 12, 69, 14, 69, 654, 11, 69, 3, 69, 3, 69, 3, 69, 3, 69, 6, 69, 660, 10, 69, 13, 69, 14, 69, 661, 5, 69, 664, 10, 69, 3, 70, 3, 70, 3, 70, 3, 70, 7, 70, 670, 10, 70, 12, 70, 14, 70, 673, 11, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 82, 3, 82, 3, 83, 6, 83, 735, 10, 83, 13, 83, 14, 83, 736, 3, 84, 6, 84, 740, 10, 84, 13, 84, 14, 84, 741, 3, 84, 3, 84, 5, 84, 746, 10, 84, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 90, 3, 90, 3, 91, 3, 91, 3, 92, 3, 92, 3, 93, 3, 93, 3, 94, 3, 94, 3, 95, 3, 95, 3, 96, 3, 96, 3, 97, 3, 97, 3, 98, 3, 98, 3, 99, 3, 99, 3, 100, 3, 100, 3, 101, 3, 101, 3, 102, 3, 102, 3, 103, 3, 103, 3, 104, 3, 104, 3, 105, 3, 105, 3, 106, 3, 106, 3, 107, 3, 107, 3, 108, 3, 108, 3, 109, 3, 109, 3, 110, 3, 110, 3, 111, 3, 111, 3, 112, 3, 112, 3, 113, 3, 113, 3, 114, 3, 114, 4, 391, 444, 2, 2, 115, 5, 2, 3, 7, 2, 4, 9, 2, 5, 11, 2, 6, 13, 2, 7, 15, 2, 8, 17, 2, 9, 19, 2, 10, 21, 2, 11, 23, 2, 12, 25, 2, 13, 27, 2, 14, 29, 2, 15, 31, 2, 16, 33, 2, 17, 35, 2, 18, 37, 2, 19, 39, 2, 20, 41, 2, 21, 43, 2, 22, 45, 2, 23, 47, 2, 2, 49, 2, 2, 51, 2, 2, 53, 2, 2, 55, 2, 2, 57, 2, 24, 59, 2, 25, 61, 2, 26, 63, 2, 27, 65, 2, 28, 67, 2, 29, 69, 2, 30, 71, 2, 31, 73, 2, 32, 75, 2, 33, 77, 2, 34, 79, 2, 35, 81, 2, 36, 83, 2, 37, 85, 2, 38, 87, 2, 39, 89, 2, 40, 91, 2, 41, 93, 2, 42, 95, 2, 43, 97, 2, 44, 99, 2, 45, 101, 2, 46, 103, 2, 47, 105, 2, 48, 107, 2, 49, 109, 2, 50, 111, 2, 51, 113, 2, 52, 115, 2, 53, 117, 2, 54, 119, 2, 55, 121, 2, 56, 123, 2, 57, 125, 2, 58, 127, 2, 59, 129, 2, 60, 131, 2, 61, 133, 2, 62, 135, 2, 63, 137, 2, 64, 139, 2, 65, 141, 2, 66, 143, 2, 67, 145, 2, 68, 147, 2, 69, 149, 2, 2, 151, 2, 2, 153, 2, 2, 155, 2, 2, 157, 2, 2, 159, 2, 70, 161, 2, 71, 163, 2, 72, 165, 2, 73, 167, 2, 74, 169, 2, 2, 171, 2, 75, 173, 2, 76, 175, 2, 77, 177, 2, 78, 179, 2, 2, 181, 2, 2, 183, 2, 2, 185, 2, 2, 187, 2, 2, 189, 2, 2, 191, 2, 2, 193, 2, 2, 195, 2, 2, 197, 2, 2, 199, 2, 2, 201, 2, 2, 203, 2, 2, 205, 2, 2, 207, 2, 2, 209, 2, 2, 211, 2, 2, 213, 2, 2, 215, 2, 2, 217, 2, 2, 219, 2, 2, 221, 2, 2, 223, 2, 2, 225, 2, 2, 227, 2, 2, 229, 2, 2, 5, 2, 3, 4, 40, 8, 2, 11, 12, 15, 15, 34, 34, 49, 49, 93, 93, 95, 95, 4, 2, 12, 12, 15, 15, 5, 2, 11, 12, 15, 15, 34, 34, 3, 2, 50, 59, 4, 2, 67, 92, 99, 124, 7, 2, 36, 36, 94, 94, 112, 112, 116, 116, 118, 118, 6, 2, 12, 12, 15, 15, 36, 36, 94, 94, 4, 2, 71, 71, 103, 103, 4, 2, 45, 45, 47, 47, 4, 2, 66, 66, 97, 97, 3, 2, 98, 98, 12, 2, 11, 12, 15, 15, 34, 34, 46, 46, 49, 49, 63, 63, 93, 93, 95, 95, 98, 98, 126, 126, 4, 2, 44, 44, 49, 49, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 77, 77, 109, 109, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, 2, 92, 92, 124, 124, 2, 816, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 3, 45, 3, 2, 2, 2, 3, 57, 3, 2, 2, 2, 3, 59, 3, 2, 2, 2, 3, 61, 3, 2, 2, 2, 3, 63, 3, 2, 2, 2, 3, 65, 3, 2, 2, 2, 3, 67, 3, 2, 2, 2, 3, 69, 3, 2, 2, 2, 3, 71, 3, 2, 2, 2, 3, 73, 3, 2, 2, 2, 3, 75, 3, 2, 2, 2, 3, 77, 3, 2, 2, 2, 3, 79, 3, 2, 2, 2, 3, 81, 3, 2, 2, 2, 3, 83, 3, 2, 2, 2, 3, 85, 3, 2, 2, 2, 3, 87, 3, 2, 2, 2, 3, 89, 3, 2, 2, 2, 3, 91, 3, 2, 2, 2, 3, 93, 3, 2, 2, 2, 3, 95, 3, 2, 2, 2, 3, 97, 3, 2, 2, 2, 3, 99, 3, 2, 2, 2, 3, 101, 3, 2, 2, 2, 3, 103, 3, 2, 2, 2, 3, 105, 3, 2, 2, 2, 3, 107, 3, 2, 2, 2, 3, 109, 3, 2, 2, 2, 3, 111, 3, 2, 2, 2, 3, 113, 3, 2, 2, 2, 3, 115, 3, 2, 2, 2, 3, 117, 3, 2, 2, 2, 3, 119, 3, 2, 2, 2, 3, 121, 3, 2, 2, 2, 3, 123, 3, 2, 2, 2, 3, 125, 3, 2, 2, 2, 3, 127, 3, 2, 2, 2, 3, 129, 3, 2, 2, 2, 3, 131, 3, 2, 2, 2, 3, 133, 3, 2, 2, 2, 3, 135, 3, 2, 2, 2, 3, 137, 3, 2, 2, 2, 3, 139, 3, 2, 2, 2, 3, 141, 3, 2, 2, 2, 3, 143, 3, 2, 2, 2, 3, 145, 3, 2, 2, 2, 3, 147, 3, 2, 2, 2, 4, 149, 3, 2, 2, 2, 4, 151, 3, 2, 2, 2, 4, 153, 3, 2, 2, 2, 4, 155, 3, 2, 2, 2, 4, 157, 3, 2, 2, 2, 4, 159, 3, 2, 2, 2, 4, 161, 3, 2, 2, 2, 4, 163, 3, 2, 2, 2, 4, 165, 3, 2, 2, 2, 4, 167, 3, 2, 2, 2, 4, 171, 3, 2, 2, 2, 4, 173, 3, 2, 2, 2, 4, 175, 3, 2, 2, 2, 4, 177, 3, 2, 2, 2, 5, 231, 3, 2, 2, 2, 7, 241, 3, 2, 2, 2, 9, 248, 3, 2, 2, 2, 11, 257, 3, 2, 2, 2, 13, 264, 3, 2, 2, 2, 15, 271, 3, 2, 2, 2, 17, 278, 3, 2, 2, 2, 19, 285, 3, 2, 2, 2, 21, 293, 3, 2, 2, 2, 23, 305, 3, 2, 2, 2, 25, 315, 3, 2, 2, 2, 27, 324, 3, 2, 2, 2, 29, 330, 3, 2, 2, 2, 31, 337, 3, 2, 2, 2, 33, 344, 3, 2, 2, 2, 35, 352, 3, 2, 2, 2, 37, 361, 3, 2, 2, 2, 39, 367, 3, 2, 2, 2, 41, 384, 3, 2, 2, 2, 43, 400, 3, 2, 2, 2, 45, 406, 3, 2, 2, 2, 47, 410, 3, 2, 2, 2, 49, 412, 3, 2, 2, 2, 51, 414, 3, 2, 2, 2, 53, 417, 3, 2, 2, 2, 55, 419, 3, 2, 2, 2, 57, 457, 3, 2, 2, 2, 59, 460, 3, 2, 2, 2, 61, 506, 3, 2, 2, 2, 63, 508, 3, 2, 2, 2, 65, 511, 3, 2, 2, 2, 67, 515, 3, 2, 2, 2, 69, 519, 3, 2, 2, 2, 71, 521, 3, 2, 2, 2, 73, 523, 3, 2, 2, 2, 75, 528, 3, 2, 2, 2, 77, 530, 3, 2, 2, 2, 79, 536, 3, 2, 2, 2, 81, 542, 3, 2, 2, 2, 83, 547, 3, 2, 2, 2, 85, 549, 3, 2, 2, 2, 87, 552, 3, 2, 2, 2, 89, 555, 3, 2, 2, 2, 91, 560, 3, 2, 2, 2, 93, 564, 3, 2, 2, 2, 95, 569, 3, 2, 2, 2, 97, 575, 3, 2, 2, 2, 99, 578, 3, 2, 2, 2, 101, 580, 3, 2, 2, 2, 103, 586, 3, 2, 2, 2, 105, 588, 3, 2, 2, 2, 107, 593, 3, 2, 2, 2, 109, 598, 3, 2, 2, 2, 111, 608, 3, 2, 2, 2, 113, 610, 3, 2, 2, 2, 115, 613, 3, 2, 2, 2, 117, 616, 3, 2, 2, 2, 119, 618, 3, 2, 2, 2, 121, 621, 3, 2, 2, 2, 123, 623, 3, 2, 2, 2, 125, 626, 3, 2, 2, 2, 127, 628, 3, 2, 2, 2, 129, 630, 3, 2, 2, 2, 131, 632, 3, 2, 2, 2, 133, 634, 3, 2, 2, 2, 135, 636, 3, 2, 2, 2, 137, 641, 3, 2, 2, 2, 139, 663, 3, 2, 2, 2, 141, 665, 3, 2, 2, 2, 143, 676, 3, 2, 2, 2, 145, 680, 3, 2, 2, 2, 147, 684, 3, 2, 2, 2, 149, 688, 3, 2, 2, 2, 151, 693, 3, 2, 2, 2, 153, 699, 3, 2, 2, 2, 155, 705, 3, 2, 2, 2, 157, 709, 3, 2, 2, 2, 159, 713, 3, 2, 2, 2, 161, 716, 3, 2, 2, 2, 163, 725, 3, 2, 2, 2, 165, 728, 3, 2, 2, 2, 167, 734, 3, 2, 2, 2, 169, 745, 3, 2, 2, 2, 171, 747, 3, 2, 2, 2, 173, 749, 3, 2, 2, 2, 175, 753, 3, 2, 2, 2, 177, 757, 3, 2, 2, 2, 179, 761, 3, 2, 2, 2, 181, 763, 3, 2, 2, 2, 183, 765, 3, 2, 2, 2, 185, 767, 3, 2, 2, 2, 187, 769, 3, 2, 2, 2, 189, 771, 3, 2, 2, 2, 191, 773, 3, 2, 2, 2, 193, 775, 3, 2, 2, 2, 195, 777, 3, 2, 2, 2, 197, 779, 3, 2, 2, 2, 199, 781, 3, 2, 2, 2, 201, 783, 3, 2, 2, 2, 203, 785, 3, 2, 2, 2, 205, 787, 3, 2, 2, 2, 207, 789, 3, 2, 2, 2, 209, 791, 3, 2, 2, 2, 211, 793, 3, 2, 2, 2, 213, 795, 3, 2, 2, 2, 215, 797, 3, 2, 2, 2, 217, 799, 3, 2, 2, 2, 219, 801, 3, 2, 2, 2, 221, 803, 3, 2, 2, 2, 223, 805, 3, 2, 2, 2, 225, 807, 3, 2, 2, 2, 227, 809, 3, 2, 2, 2, 229, 811, 3, 2, 2, 2, 231, 232, 5, 185, 92, 2, 232, 233, 5, 195, 97, 2, 233, 234, 5, 215, 107, 2, 234, 235, 5, 215, 107, 2, 235, 236, 5, 187, 93, 2, 236, 237, 5, 183, 91, 2, 237, 238, 5, 217, 108, 2, 238, 239, 3, 2, 2, 2, 239, 240, 8, 2, 2, 2, 240, 6, 3, 2, 2, 2, 241, 242, 5, 185, 92, 2, 242, 243, 5, 213, 106, 2, 243, 244, 5, 207, 103, 2, 244, 245, 5, 209, 104, 2, 245, 246, 3, 2, 2, 2, 246, 247, 8, 3, 3, 2, 247, 8, 3, 2, 2, 2, 248, 249, 5, 187, 93, 2, 249, 250, 5, 205, 102, 2, 250, 251, 5, 213, 106, 2, 251, 252, 5, 195, 97, 2, 252, 253, 5, 183, 91, 2, 253, 254, 5, 193, 96, 2, 254, 255, 3, 2, 2, 2, 255, 256, 8, 4, 3, 2, 256, 10, 3, 2, 2, 2, 257, 258, 5, 187, 93, 2, 258, 259, 5, 221, 110, 2, 259, 260, 5, 179, 89, 2, 260, 261, 5, 201, 100, 2, 261, 262, 3, 2, 2, 2, 262, 263, 8, 5, 2, 2, 263, 12, 3, 2, 2, 2, 264, 265, 5, 189, 94, 2, 265, 266, 5, 213, 106, 2, 266, 267, 5, 207, 103, 2, 267, 268, 5, 203, 101, 2, 268, 269, 3, 2, 2, 2, 269, 270, 8, 6, 3, 2, 270, 14, 3, 2, 2, 2, 271, 272, 5, 191, 95, 2, 272, 273, 5, 213, 106, 2, 273, 274, 5, 207, 103, 2, 274, 275, 5, 199, 99, 2, 275, 276, 3, 2, 2, 2, 276, 277, 8, 7, 2, 2, 277, 16, 3, 2, 2, 2, 278, 279, 5, 199, 99, 2, 279, 280, 5, 187, 93, 2, 280, 281, 5, 187, 93, 2, 281, 282, 5, 209, 104, 2, 282, 283, 3, 2, 2, 2, 283, 284, 8, 8, 3, 2, 284, 18, 3, 2, 2, 2, 285, 286, 5, 201, 100, 2, 286, 287, 5, 195, 97, 2, 287, 288, 5, 203, 101, 2, 288, 289, 5, 195, 97, 2, 289, 290, 5, 217, 108, 2, 290, 291, 3, 2, 2, 2, 291, 292, 8, 9, 2, 2, 292, 20, 3, 2, 2, 2, 293, 294, 5, 203, 101, 2, 294, 295, 5, 221, 110, 2, 295, 296, 5, 111, 55, 2, 296, 297, 5, 187, 93, 2, 297, 298, 5, 225, 112, 2, 298, 299, 5, 209, 104, 2, 299, 300, 5, 179, 89, 2, 300, 301, 5, 205, 102, 2, 301, 302, 5, 185, 92, 2, 302, 303, 3, 2, 2, 2, 303, 304, 8, 10, 3, 2, 304, 22, 3, 2, 2, 2, 305, 306, 5, 209, 104, 2, 306, 307, 5, 213, 106, 2, 307, 308, 5, 207, 103, 2, 308, 309, 5, 197, 98, 2, 309, 310, 5, 187, 93, 2, 310, 311, 5, 183, 91, 2, 311, 312, 5, 217, 108, 2, 312, 313, 3, 2, 2, 2, 313, 314, 8, 11, 3, 2, 314, 24, 3, 2, 2, 2, 315, 316, 5, 213, 106, 2, 316, 317, 5, 187, 93, 2, 317, 318, 5, 205, 102, 2, 318, 319, 5, 179, 89, 2, 319, 320, 5, 203, 101, 2, 320, 321, 5, 187, 93, 2, 321, 322, 3, 2, 2, 2, 322, 323, 8, 12, 3, 2, 323, 26, 3, 2, 2, 2, 324, 325, 5, 213, 106, 2, 325, 326, 5, 207, 103, 2, 326, 327, 5, 223, 111, 2, 327, 328, 3, 2, 2, 2, 328, 329, 8, 13, 2, 2, 329, 28, 3, 2, 2, 2, 330, 331, 5, 215, 107, 2, 331, 332, 5, 193, 96, 2, 332, 333, 5, 207, 103, 2, 333, 334, 5, 223, 111, 2, 334, 335, 3, 2, 2, 2, 335, 336, 8, 14, 2, 2, 336, 30, 3, 2, 2, 2, 337, 338, 5, 215, 107, 2, 338, 339, 5, 207, 103, 2, 339, 340, 5, 213, 106, 2, 340, 341, 5, 217, 108, 2, 341, 342, 3, 2, 2, 2, 342, 343, 8, 15, 2, 2, 343, 32, 3, 2, 2, 2, 344, 345, 5, 215, 107, 2, 345, 346, 5, 217, 108, 2, 346, 347, 5, 179, 89, 2, 347, 348, 5, 217, 108, 2, 348, 349, 5, 215, 107, 2, 349, 350, 3, 2, 2, 2, 350, 351, 8, 16, 2, 2, 351, 34, 3, 2, 2, 2, 352, 353, 5, 223, 111, 2, 353, 354, 5, 193, 96, 2, 354, 355, 5, 187, 93, 2, 355, 356, 5, 213, 106, 2, 356, 357, 5, 187, 93, 2, 357, 358, 3, 2, 2, 2, 358, 359, 8, 17, 2, 2, 359, 36, 3, 2, 2, 2, 360, 362, 10, 2, 2, 2, 361, 360, 3, 2, 2, 2, 362, 363, 3, 2, 2, 2, 363, 361, 3, 2, 2, 2, 363, 364, 3, 2, 2, 2, 364, 365, 3, 2, 2, 2, 365, 366, 8, 18, 2, 2, 366, 38, 3, 2, 2, 2, 367, 368, 7, 49, 2, 2, 368, 369, 7, 49, 2, 2, 369, 373, 3, 2, 2, 2, 370, 372, 10, 3, 2, 2, 371, 370, 3, 2, 2, 2, 372, 375, 3, 2, 2, 2, 373, 371, 3, 2, 2, 2, 373, 374, 3, 2, 2, 2, 374, 377, 3, 2, 2, 2, 375, 373, 3, 2, 2, 2, 376, 378, 7, 15, 2, 2, 377, 376, 3, 2, 2, 2, 377, 378, 3, 2, 2, 2, 378, 380, 3, 2, 2, 2, 379, 381, 7, 12, 2, 2, 380, 379, 3, 2, 2, 2, 380, 381, 3, 2, 2, 2, 381, 382, 3, 2, 2, 2, 382, 383, 8, 19, 4, 2, 383, 40, 3, 2, 2, 2, 384, 385, 7, 49, 2, 2, 385, 386, 7, 44, 2, 2, 386, 391, 3, 2, 2, 2, 387, 390, 5, 41, 20, 2, 388, 390, 11, 2, 2, 2, 389, 387, 3, 2, 2, 2, 389, 388, 3, 2, 2, 2, 390, 393, 3, 2, 2, 2, 391, 392, 3, 2, 2, 2, 391, 389, 3, 2, 2, 2, 392, 394, 3, 2, 2, 2, 393, 391, 3, 2, 2, 2, 394, 395, 7, 44, 2, 2, 395, 396, 7, 49, 2, 2, 396, 397, 3, 2, 2, 2, 397, 398, 8, 20, 4, 2, 398, 42, 3, 2, 2, 2, 399, 401, 9, 4, 2, 2, 400, 399, 3, 2, 2, 2, 401, 402, 3, 2, 2, 2, 402, 400, 3, 2, 2, 2, 402, 403, 3, 2, 2, 2, 403, 404, 3, 2, 2, 2, 404, 405, 8, 21, 4, 2, 405, 44, 3, 2, 2, 2, 406, 407, 7, 126, 2, 2, 407, 408, 3, 2, 2, 2, 408, 409, 8, 22, 5, 2, 409, 46, 3, 2, 2, 2, 410, 411, 9, 5, 2, 2, 411, 48, 3, 2, 2, 2, 412, 413, 9, 6, 2, 2, 413, 50, 3, 2, 2, 2, 414, 415, 7, 94, 2, 2, 415, 416, 9, 7, 2, 2, 416, 52, 3, 2, 2, 2, 417, 418, 10, 8, 2, 2, 418, 54, 3, 2, 2, 2, 419, 421, 9, 9, 2, 2, 420, 422, 9, 10, 2, 2, 421, 420, 3, 2, 2, 2, 421, 422, 3, 2, 2, 2, 422, 424, 3, 2, 2, 2, 423, 425, 5, 47, 23, 2, 424, 423, 3, 2, 2, 2, 425, 426, 3, 2, 2, 2, 426, 424, 3, 2, 2, 2, 426, 427, 3, 2, 2, 2, 427, 56, 3, 2, 2, 2, 428, 433, 7, 36, 2, 2, 429, 432, 5, 51, 25, 2, 430, 432, 5, 53, 26, 2, 431, 429, 3, 2, 2, 2, 431, 430, 3, 2, 2, 2, 432, 435, 3, 2, 2, 2, 433, 431, 3, 2, 2, 2, 433, 434, 3, 2, 2, 2, 434, 436, 3, 2, 2, 2, 435, 433, 3, 2, 2, 2, 436, 458, 7, 36, 2, 2, 437, 438, 7, 36, 2, 2, 438, 439, 7, 36, 2, 2, 439, 440, 7, 36, 2, 2, 440, 444, 3, 2, 2, 2, 441, 443, 10, 3, 2, 2, 442, 441, 3, 2, 2, 2, 443, 446, 3, 2, 2, 2, 444, 445, 3, 2, 2, 2, 444, 442, 3, 2, 2, 2, 445, 447, 3, 2, 2, 2, 446, 444, 3, 2, 2, 2, 447, 448, 7, 36, 2, 2, 448, 449, 7, 36, 2, 2, 449, 450, 7, 36, 2, 2, 450, 452, 3, 2, 2, 2, 451, 453, 7, 36, 2, 2, 452, 451, 3, 2, 2, 2, 452, 453, 3, 2, 2, 2, 453, 455, 3, 2, 2, 2, 454, 456, 7, 36, 2, 2, 455, 454, 3, 2, 2, 2, 455, 456, 3, 2, 2, 2, 456, 458, 3, 2, 2, 2, 457, 428, 3, 2, 2, 2, 457, 437, 3, 2, 2, 2, 458, 58, 3, 2, 2, 2, 459, 461, 5, 47, 23, 2, 460, 459, 3, 2, 2, 2, 461, 462, 3, 2, 2, 2, 462, 460, 3, 2, 2, 2, 462, 463, 3, 2, 2, 2, 463, 60, 3, 2, 2, 2, 464, 466, 5, 47, 23, 2, 465, 464, 3, 2, 2, 2, 466, 467, 3, 2, 2, 2, 467, 465, 3, 2, 2, 2, 467, 468, 3, 2, 2, 2, 468, 469, 3, 2, 2, 2, 469, 473, 5, 75, 37, 2, 470, 472, 5, 47, 23, 2, 471, 470, 3, 2, 2, 2, 472, 475, 3, 2, 2, 2, 473, 471, 3, 2, 2, 2, 473, 474, 3, 2, 2, 2, 474, 507, 3, 2, 2, 2, 475, 473, 3, 2, 2, 2, 476, 478, 5, 75, 37, 2, 477, 479, 5, 47, 23, 2, 478, 477, 3, 2, 2, 2, 479, 480, 3, 2, 2, 2, 480, 478, 3, 2, 2, 2, 480, 481, 3, 2, 2, 2, 481, 507, 3, 2, 2, 2, 482, 484, 5, 47, 23, 2, 483, 482, 3, 2, 2, 2, 484, 485, 3, 2, 2, 2, 485, 483, 3, 2, 2, 2, 485, 486, 3, 2, 2, 2, 486, 494, 3, 2, 2, 2, 487, 491, 5, 75, 37, 2, 488, 490, 5, 47, 23, 2, 489, 488, 3, 2, 2, 2, 490, 493, 3, 2, 2, 2, 491, 489, 3, 2, 2, 2, 491, 492, 3, 2, 2, 2, 492, 495, 3, 2, 2, 2, 493, 491, 3, 2, 2, 2, 494, 487, 3, 2, 2, 2, 494, 495, 3, 2, 2, 2, 495, 496, 3, 2, 2, 2, 496, 497, 5, 55, 27, 2, 497, 507, 3, 2, 2, 2, 498, 500, 5, 75, 37, 2, 499, 501, 5, 47, 23, 2, 500, 499, 3, 2, 2, 2, 501, 502, 3, 2, 2, 2, 502, 500, 3, 2, 2, 2, 502, 503, 3, 2, 2, 2, 503, 504, 3, 2, 2, 2, 504, 505, 5, 55, 27, 2, 505, 507, 3, 2, 2, 2, 506, 465, 3, 2, 2, 2, 506, 476, 3, 2, 2, 2, 506, 483, 3, 2, 2, 2, 506, 498, 3, 2, 2, 2, 507, 62, 3, 2, 2, 2, 508, 509, 5, 181, 90, 2, 509, 510, 5, 227, 113, 2, 510, 64, 3, 2, 2, 2, 511, 512, 5, 179, 89, 2, 512, 513, 5, 205, 102, 2, 513, 514, 5, 185, 92, 2, 514, 66, 3, 2, 2, 2, 515, 516, 5, 179, 89, 2, 516, 517, 5, 215, 107, 2, 517, 518, 5, 183, 91, 2, 518, 68, 3, 2, 2, 2, 519, 520, 7, 63, 2, 2, 520, 70, 3, 2, 2, 2, 521, 522, 7, 46, 2, 2, 522, 72, 3, 2, 2, 2, 523, 524, 5, 185, 92, 2, 524, 525, 5, 187, 93, 2, 525, 526, 5, 215, 107, 2, 526, 527, 5, 183, 91, 2, 527, 74, 3, 2, 2, 2, 528, 529, 7, 48, 2, 2, 529, 76, 3, 2, 2, 2, 530, 531, 5, 189, 94, 2, 531, 532, 5, 179, 89, 2, 532, 533, 5, 201, 100, 2, 533, 534, 5, 215, 107, 2, 534, 535, 5, 187, 93, 2, 535, 78, 3, 2, 2, 2, 536, 537, 5, 189, 94, 2, 537, 538, 5, 195, 97, 2, 538, 539, 5, 213, 106, 2, 539, 540, 5, 215, 107, 2, 540, 541, 5, 217, 108, 2, 541, 80, 3, 2, 2, 2, 542, 543, 5, 201, 100, 2, 543, 544, 5, 179, 89, 2, 544, 545, 5, 215, 107, 2, 545, 546, 5, 217, 108, 2, 546, 82, 3, 2, 2, 2, 547, 548, 7, 42, 2, 2, 548, 84, 3, 2, 2, 2, 549, 550, 5, 195, 97, 2, 550, 551, 5, 205, 102, 2, 551, 86, 3, 2, 2, 2, 552, 553, 5, 195, 97, 2, 553, 554, 5, 215, 107, 2, 554, 88, 3, 2, 2, 2, 555, 556, 5, 201, 100, 2, 556, 557, 5, 195, 97, 2, 557, 558, 5, 199, 99, 2, 558, 559, 5, 187, 93, 2, 559, 90, 3, 2, 2, 2, 560, 561, 5, 205, 102, 2, 561, 562, 5, 207, 103, 2, 562, 563, 5, 217, 108, 2, 563, 92, 3, 2, 2, 2, 564, 565, 5, 205, 102, 2, 565, 566, 5, 219, 109, 2, 566, 567, 5, 201, 100, 2, 567, 568, 5, 201, 100, 2, 568, 94, 3, 2, 2, 2, 569, 570, 5, 205, 102, 2, 570, 571, 5, 219, 109, 2, 571, 572, 5, 201, 100, 2, 572, 573, 5, 201, 100, 2, 573, 574, 5, 215, 107, 2, 574, 96, 3, 2, 2, 2, 575, 576, 5, 207, 103, 2, 576, 577, 5, 213, 106, 2, 577, 98, 3, 2, 2, 2, 578, 579, 7, 65, 2, 2, 579, 100, 3, 2, 2, 2, 580, 581, 5, 213, 106, 2, 581, 582, 5, 201, 100, 2, 582, 583, 5, 195, 97, 2, 583, 584, 5, 199, 99, 2, 584, 585, 5, 187, 93, 2, 585, 102, 3, 2, 2, 2, 586, 587, 7, 43, 2, 2, 587, 104, 3, 2, 2, 2, 588, 589, 5, 217, 108, 2, 589, 590, 5, 213, 106, 2, 590, 591, 5, 219, 109, 2, 591, 592, 5, 187, 93, 2, 592, 106, 3, 2, 2, 2, 593, 594, 5, 195, 97, 2, 594, 595, 5, 205, 102, 2, 595, 596, 5, 189, 94, 2, 596, 597, 5, 207, 103, 2, 597, 108, 3, 2, 2, 2, 598, 599, 5, 189, 94, 2, 599, 600, 5, 219, 109, 2, 600, 601, 5, 205, 102, 2, 601, 602, 5, 183, 91, 2, 602, 603, 5, 217, 108, 2, 603, 604, 5, 195, 97, 2, 604, 605, 5, 207, 103, 2, 605, 606, 5, 205, 102, 2, 606, 607, 5, 215, 107, 2, 607, 110, 3, 2, 2, 2, 608, 609, 7, 97, 2, 2, 609, 112, 3, 2, 2, 2, 610, 611, 7, 63, 2, 2, 611, 612, 7, 63, 2, 2, 612, 114, 3, 2, 2, 2, 613, 614, 7, 35, 2, 2, 614, 615, 7, 63, 2, 2, 615, 116, 3, 2, 2, 2, 616, 617, 7, 62, 2, 2, 617, 118, 3, 2, 2, 2, 618, 619, 7, 62, 2, 2, 619, 620, 7, 63, 2, 2, 620, 120, 3, 2, 2, 2, 621, 622, 7, 64, 2, 2, 622, 122, 3, 2, 2, 2, 623, 624, 7, 64, 2, 2, 624, 625, 7, 63, 2, 2, 625, 124, 3, 2, 2, 2, 626, 627, 7, 45, 2, 2, 627, 126, 3, 2, 2, 2, 628, 629, 7, 47, 2, 2, 629, 128, 3, 2, 2, 2, 630, 631, 7, 44, 2, 2, 631, 130, 3, 2, 2, 2, 632, 633, 7, 49, 2, 2, 633, 132, 3, 2, 2, 2, 634, 635, 7, 39, 2, 2, 635, 134, 3, 2, 2, 2, 636, 637, 7, 93, 2, 2, 637, 638, 3, 2, 2, 2, 638, 639, 8, 67, 2, 2, 639, 640, 8, 67, 2, 2, 640, 136, 3, 2, 2, 2, 641, 642, 7, 95, 2, 2, 642, 643, 3, 2, 2, 2, 643, 644, 8, 68, 5, 2, 644, 645, 8, 68, 5, 2, 645, 138, 3, 2, 2, 2, 646, 652, 5, 49, 24, 2, 647, 651, 5, 49, 24, 2, 648, 651, 5, 47, 23, 2, 649, 651, 7, 97, 2, 2, 650, 647, 3, 2, 2, 2, 650, 648, 3, 2, 2, 2, 650, 649, 3, 2, 2, 2, 651, 654, 3, 2, 2, 2, 652, 650, 3, 2, 2, 2, 652, 653, 3, 2, 2, 2, 653, 664, 3, 2, 2, 2, 654, 652, 3, 2, 2, 2, 655, 659, 9, 11, 2, 2, 656, 660, 5, 49, 24, 2, 657, 660, 5, 47, 23, 2, 658, 660, 7, 97, 2, 2, 659, 656, 3, 2, 2, 2, 659, 657, 3, 2, 2, 2, 659, 658, 3, 2, 2, 2, 660, 661, 3, 2, 2, 2, 661, 659, 3, 2, 2, 2, 661, 662, 3, 2, 2, 2, 662, 664, 3, 2, 2, 2, 663, 646, 3, 2, 2, 2, 663, 655, 3, 2, 2, 2, 664, 140, 3, 2, 2, 2, 665, 671, 7, 98, 2, 2, 666, 670, 10, 12, 2, 2, 667, 668, 7, 98, 2, 2, 668, 670, 7, 98, 2, 2, 669, 666, 3, 2, 2, 2, 669, 667, 3, 2, 2, 2, 670, 673, 3, 2, 2, 2, 671, 669, 3, 2, 2, 2, 671, 672, 3, 2, 2, 2, 672, 674, 3, 2, 2, 2, 673, 671, 3, 2, 2, 2, 674, 675, 7, 98, 2, 2, 675, 142, 3, 2, 2, 2, 676, 677, 5, 39, 19, 2, 677, 678, 3, 2, 2, 2, 678, 679, 8, 71, 4, 2, 679, 144, 3, 2, 2, 2, 680, 681, 5, 41, 20, 2, 681, 682, 3, 2, 2, 2, 682, 683, 8, 72, 4, 2, 683, 146, 3, 2, 2, 2, 684, 685, 5, 43, 21, 2, 685, 686, 3, 2, 2, 2, 686, 687, 8, 73, 4, 2, 687, 148, 3, 2, 2, 2, 688, 689, 7, 126, 2, 2, 689, 690, 3, 2, 2, 2, 690, 691, 8, 74, 6, 2, 691, 692, 8, 74, 5, 2, 692, 150, 3, 2, 2, 2, 693, 694, 7, 93, 2, 2, 694, 695, 3, 2, 2, 2, 695, 696, 8, 75, 7, 2, 696, 697, 8, 75, 3, 2, 697, 698, 8, 75, 3, 2, 698, 152, 3, 2, 2, 2, 699, 700, 7, 95, 2, 2, 700, 701, 3, 2, 2, 2, 701, 702, 8, 76, 5, 2, 702, 703, 8, 76, 5, 2, 703, 704, 8, 76, 8, 2, 704, 154, 3, 2, 2, 2, 705, 706, 7, 46, 2, 2, 706, 707, 3, 2, 2, 2, 707, 708, 8, 77, 9, 2, 708, 156, 3, 2, 2, 2, 709, 710, 7, 63, 2, 2, 710, 711, 3, 2, 2, 2, 711, 712, 8, 78, 10, 2, 712, 158, 3, 2, 2, 2, 713, 714, 5, 179, 89, 2, 714, 715, 5, 215, 107, 2, 715, 160, 3, 2, 2, 2, 716, 717, 5, 203, 101, 2, 717, 718, 5, 187, 93, 2, 718, 719, 5, 217, 108, 2, 719, 720, 5, 179, 89, 2, 720, 721, 5, 185, 92, 2, 721, 722, 5, 179, 89, 2, 722, 723, 5, 217, 108, 2, 723, 724, 5, 179, 89, 2, 724, 162, 3, 2, 2, 2, 725, 726, 5, 207, 103, 2, 726, 727, 5, 205, 102, 2, 727, 164, 3, 2, 2, 2, 728, 729, 5, 223, 111, 2, 729, 730, 5, 195, 97, 2, 730, 731, 5, 217, 108, 2, 731, 732, 5, 193, 96, 2, 732, 166, 3, 2, 2, 2, 733, 735, 5, 169, 84, 2, 734, 733, 3, 2, 2, 2, 735, 736, 3, 2, 2, 2, 736, 734, 3, 2, 2, 2, 736, 737, 3, 2, 2, 2, 737, 168, 3, 2, 2, 2, 738, 740, 10, 13, 2, 2, 739, 738, 3, 2, 2, 2, 740, 741, 3, 2, 2, 2, 741, 739, 3, 2, 2, 2, 741, 742, 3, 2, 2, 2, 742, 746, 3, 2, 2, 2, 743, 744, 7, 49, 2, 2, 744, 746, 10, 14, 2, 2, 745, 739, 3, 2, 2, 2, 745, 743, 3, 2, 2, 2, 746, 170, 3, 2, 2, 2, 747, 748, 5, 141, 70, 2, 748, 172, 3, 2, 2, 2, 749, 750, 5, 39, 19, 2, 750, 751, 3, 2, 2, 2, 751, 752, 8, 86, 4, 2, 752, 174, 3, 2, 2, 2, 753, 754, 5, 41, 20, 2, 754, 755, 3, 2, 2, 2, 755, 756, 8, 87, 4, 2, 756, 176, 3, 2, 2, 2, 757, 758, 5, 43, 21, 2, 758, 759, 3, 2, 2, 2, 759, 760, 8, 88, 4, 2, 760, 178, 3, 2, 2, 2, 761, 762, 9, 15, 2, 2, 762, 180, 3, 2, 2, 2, 763, 764, 9, 16, 2, 2, 764, 182, 3, 2, 2, 2, 765, 766, 9, 17, 2, 2, 766, 184, 3, 2, 2, 2, 767, 768, 9, 18, 2, 2, 768, 186, 3, 2, 2, 2, 769, 770, 9, 9, 2, 2, 770, 188, 3, 2, 2, 2, 771, 772, 9, 19, 2, 2, 772, 190, 3, 2, 2, 2, 773, 774, 9, 20, 2, 2, 774, 192, 3, 2, 2, 2, 775, 776, 9, 21, 2, 2, 776, 194, 3, 2, 2, 2, 777, 778, 9, 22, 2, 2, 778, 196, 3, 2, 2, 2, 779, 780, 9, 23, 2, 2, 780, 198, 3, 2, 2, 2, 781, 782, 9, 24, 2, 2, 782, 200, 3, 2, 2, 2, 783, 784, 9, 25, 2, 2, 784, 202, 3, 2, 2, 2, 785, 786, 9, 26, 2, 2, 786, 204, 3, 2, 2, 2, 787, 788, 9, 27, 2, 2, 788, 206, 3, 2, 2, 2, 789, 790, 9, 28, 2, 2, 790, 208, 3, 2, 2, 2, 791, 792, 9, 29, 2, 2, 792, 210, 3, 2, 2, 2, 793, 794, 9, 30, 2, 2, 794, 212, 3, 2, 2, 2, 795, 796, 9, 31, 2, 2, 796, 214, 3, 2, 2, 2, 797, 798, 9, 32, 2, 2, 798, 216, 3, 2, 2, 2, 799, 800, 9, 33, 2, 2, 800, 218, 3, 2, 2, 2, 801, 802, 9, 34, 2, 2, 802, 220, 3, 2, 2, 2, 803, 804, 9, 35, 2, 2, 804, 222, 3, 2, 2, 2, 805, 806, 9, 36, 2, 2, 806, 224, 3, 2, 2, 2, 807, 808, 9, 37, 2, 2, 808, 226, 3, 2, 2, 2, 809, 810, 9, 38, 2, 2, 810, 228, 3, 2, 2, 2, 811, 812, 9, 39, 2, 2, 812, 230, 3, 2, 2, 2, 39, 2, 3, 4, 363, 373, 377, 380, 389, 391, 402, 421, 426, 431, 433, 444, 452, 455, 457, 462, 467, 473, 480, 485, 491, 494, 502, 506, 650, 652, 659, 661, 663, 669, 671, 736, 741, 745, 11, 7, 3, 2, 7, 4, 2, 2, 3, 2, 6, 2, 2, 9, 23, 2, 9, 63, 2, 9, 64, 2, 9, 31, 2, 9, 30, 2] \ No newline at end of file +[3, 51485, 51898, 1421, 44986, 20307, 1543, 60043, 49729, 2, 100, 1196, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 4, 149, 9, 149, 4, 150, 9, 150, 4, 151, 9, 151, 4, 152, 9, 152, 4, 153, 9, 153, 4, 154, 9, 154, 4, 155, 9, 155, 4, 156, 9, 156, 4, 157, 9, 157, 4, 158, 9, 158, 4, 159, 9, 159, 4, 160, 9, 160, 4, 161, 9, 161, 4, 162, 9, 162, 4, 163, 9, 163, 4, 164, 9, 164, 4, 165, 9, 165, 4, 166, 9, 166, 4, 167, 9, 167, 4, 168, 9, 168, 4, 169, 9, 169, 4, 170, 9, 170, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 20, 6, 20, 505, 10, 20, 13, 20, 14, 20, 506, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 21, 7, 21, 515, 10, 21, 12, 21, 14, 21, 518, 11, 21, 3, 21, 5, 21, 521, 10, 21, 3, 21, 5, 21, 524, 10, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 7, 22, 533, 10, 22, 12, 22, 14, 22, 536, 11, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 6, 23, 544, 10, 23, 13, 23, 14, 23, 545, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 34, 3, 34, 5, 34, 587, 10, 34, 3, 34, 6, 34, 590, 10, 34, 13, 34, 14, 34, 591, 3, 35, 3, 35, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 5, 37, 601, 10, 37, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 5, 39, 608, 10, 39, 3, 40, 3, 40, 3, 40, 7, 40, 613, 10, 40, 12, 40, 14, 40, 616, 11, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 7, 40, 624, 10, 40, 12, 40, 14, 40, 627, 11, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 5, 40, 634, 10, 40, 3, 40, 5, 40, 637, 10, 40, 5, 40, 639, 10, 40, 3, 41, 6, 41, 642, 10, 41, 13, 41, 14, 41, 643, 3, 42, 6, 42, 647, 10, 42, 13, 42, 14, 42, 648, 3, 42, 3, 42, 7, 42, 653, 10, 42, 12, 42, 14, 42, 656, 11, 42, 3, 42, 3, 42, 6, 42, 660, 10, 42, 13, 42, 14, 42, 661, 3, 42, 6, 42, 665, 10, 42, 13, 42, 14, 42, 666, 3, 42, 3, 42, 7, 42, 671, 10, 42, 12, 42, 14, 42, 674, 11, 42, 5, 42, 676, 10, 42, 3, 42, 3, 42, 3, 42, 3, 42, 6, 42, 682, 10, 42, 13, 42, 14, 42, 683, 3, 42, 3, 42, 5, 42, 688, 10, 42, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 72, 3, 72, 3, 73, 3, 73, 3, 74, 3, 74, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 7, 78, 813, 10, 78, 12, 78, 14, 78, 816, 11, 78, 3, 78, 3, 78, 5, 78, 820, 10, 78, 3, 78, 6, 78, 823, 10, 78, 13, 78, 14, 78, 824, 5, 78, 827, 10, 78, 3, 79, 3, 79, 6, 79, 831, 10, 79, 13, 79, 14, 79, 832, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 88, 3, 88, 3, 88, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 5, 89, 886, 10, 89, 3, 90, 6, 90, 889, 10, 90, 13, 90, 14, 90, 890, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 98, 3, 98, 5, 98, 926, 10, 98, 3, 99, 3, 99, 5, 99, 930, 10, 99, 3, 99, 7, 99, 933, 10, 99, 12, 99, 14, 99, 936, 11, 99, 3, 99, 3, 99, 5, 99, 940, 10, 99, 3, 99, 6, 99, 943, 10, 99, 13, 99, 14, 99, 944, 5, 99, 947, 10, 99, 3, 100, 3, 100, 3, 100, 3, 100, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 104, 3, 104, 3, 105, 3, 105, 3, 105, 3, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 116, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 118, 3, 118, 3, 119, 3, 119, 3, 119, 3, 119, 3, 120, 3, 120, 3, 120, 3, 120, 3, 121, 3, 121, 3, 121, 3, 121, 3, 122, 3, 122, 3, 122, 3, 122, 3, 122, 3, 122, 3, 123, 3, 123, 3, 123, 3, 123, 3, 124, 3, 124, 3, 124, 3, 124, 3, 125, 3, 125, 3, 125, 3, 125, 3, 126, 3, 126, 3, 126, 3, 126, 3, 127, 3, 127, 3, 127, 3, 127, 3, 128, 3, 128, 3, 128, 3, 128, 3, 129, 3, 129, 3, 129, 3, 129, 3, 130, 3, 130, 3, 130, 3, 130, 3, 131, 3, 131, 3, 131, 3, 131, 3, 132, 3, 132, 3, 132, 3, 132, 3, 132, 3, 133, 3, 133, 3, 133, 3, 133, 3, 134, 3, 134, 3, 134, 3, 134, 3, 135, 3, 135, 3, 135, 3, 135, 3, 136, 3, 136, 3, 136, 3, 136, 3, 137, 3, 137, 3, 137, 3, 137, 3, 138, 3, 138, 3, 138, 3, 138, 3, 139, 3, 139, 3, 139, 3, 139, 3, 139, 3, 140, 3, 140, 3, 140, 3, 140, 3, 140, 3, 141, 3, 141, 3, 141, 3, 141, 3, 141, 3, 141, 3, 141, 3, 141, 3, 141, 3, 141, 3, 142, 3, 142, 3, 142, 3, 142, 3, 143, 3, 143, 3, 143, 3, 143, 3, 144, 3, 144, 3, 144, 3, 144, 3, 145, 3, 145, 3, 146, 3, 146, 3, 147, 3, 147, 3, 148, 3, 148, 3, 149, 3, 149, 3, 150, 3, 150, 3, 151, 3, 151, 3, 152, 3, 152, 3, 153, 3, 153, 3, 154, 3, 154, 3, 155, 3, 155, 3, 156, 3, 156, 3, 157, 3, 157, 3, 158, 3, 158, 3, 159, 3, 159, 3, 160, 3, 160, 3, 161, 3, 161, 3, 162, 3, 162, 3, 163, 3, 163, 3, 164, 3, 164, 3, 165, 3, 165, 3, 166, 3, 166, 3, 167, 3, 167, 3, 168, 3, 168, 3, 169, 3, 169, 3, 170, 3, 170, 4, 534, 625, 2, 2, 171, 12, 2, 3, 14, 2, 4, 16, 2, 5, 18, 2, 6, 20, 2, 7, 22, 2, 8, 24, 2, 9, 26, 2, 10, 28, 2, 11, 30, 2, 12, 32, 2, 13, 34, 2, 14, 36, 2, 15, 38, 2, 16, 40, 2, 17, 42, 2, 18, 44, 2, 19, 46, 2, 20, 48, 2, 21, 50, 2, 22, 52, 2, 23, 54, 2, 24, 56, 2, 2, 58, 2, 2, 60, 2, 25, 62, 2, 26, 64, 2, 27, 66, 2, 28, 68, 2, 2, 70, 2, 2, 72, 2, 2, 74, 2, 2, 76, 2, 2, 78, 2, 2, 80, 2, 2, 82, 2, 2, 84, 2, 2, 86, 2, 2, 88, 2, 29, 90, 2, 30, 92, 2, 31, 94, 2, 32, 96, 2, 33, 98, 2, 34, 100, 2, 35, 102, 2, 36, 104, 2, 37, 106, 2, 38, 108, 2, 39, 110, 2, 40, 112, 2, 41, 114, 2, 42, 116, 2, 43, 118, 2, 44, 120, 2, 45, 122, 2, 46, 124, 2, 47, 126, 2, 48, 128, 2, 49, 130, 2, 50, 132, 2, 51, 134, 2, 52, 136, 2, 53, 138, 2, 54, 140, 2, 55, 142, 2, 56, 144, 2, 57, 146, 2, 58, 148, 2, 59, 150, 2, 60, 152, 2, 61, 154, 2, 62, 156, 2, 63, 158, 2, 64, 160, 2, 65, 162, 2, 66, 164, 2, 67, 166, 2, 68, 168, 2, 69, 170, 2, 70, 172, 2, 71, 174, 2, 2, 176, 2, 2, 178, 2, 2, 180, 2, 2, 182, 2, 2, 184, 2, 72, 186, 2, 2, 188, 2, 73, 190, 2, 2, 192, 2, 74, 194, 2, 75, 196, 2, 76, 198, 2, 2, 200, 2, 2, 202, 2, 2, 204, 2, 2, 206, 2, 77, 208, 2, 2, 210, 2, 78, 212, 2, 79, 214, 2, 80, 216, 2, 2, 218, 2, 2, 220, 2, 2, 222, 2, 2, 224, 2, 81, 226, 2, 2, 228, 2, 2, 230, 2, 82, 232, 2, 83, 234, 2, 84, 236, 2, 2, 238, 2, 85, 240, 2, 86, 242, 2, 2, 244, 2, 2, 246, 2, 87, 248, 2, 88, 250, 2, 89, 252, 2, 2, 254, 2, 2, 256, 2, 2, 258, 2, 2, 260, 2, 2, 262, 2, 2, 264, 2, 2, 266, 2, 90, 268, 2, 91, 270, 2, 92, 272, 2, 2, 274, 2, 2, 276, 2, 2, 278, 2, 2, 280, 2, 93, 282, 2, 94, 284, 2, 95, 286, 2, 2, 288, 2, 96, 290, 2, 97, 292, 2, 98, 294, 2, 99, 296, 2, 100, 298, 2, 2, 300, 2, 2, 302, 2, 2, 304, 2, 2, 306, 2, 2, 308, 2, 2, 310, 2, 2, 312, 2, 2, 314, 2, 2, 316, 2, 2, 318, 2, 2, 320, 2, 2, 322, 2, 2, 324, 2, 2, 326, 2, 2, 328, 2, 2, 330, 2, 2, 332, 2, 2, 334, 2, 2, 336, 2, 2, 338, 2, 2, 340, 2, 2, 342, 2, 2, 344, 2, 2, 346, 2, 2, 348, 2, 2, 12, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 39, 8, 2, 11, 12, 15, 15, 34, 34, 49, 49, 93, 93, 95, 95, 4, 2, 12, 12, 15, 15, 5, 2, 11, 12, 15, 15, 34, 34, 3, 2, 50, 59, 4, 2, 67, 92, 99, 124, 7, 2, 36, 36, 94, 94, 112, 112, 116, 116, 118, 118, 6, 2, 12, 12, 15, 15, 36, 36, 94, 94, 4, 2, 71, 71, 103, 103, 4, 2, 45, 45, 47, 47, 3, 2, 98, 98, 12, 2, 11, 12, 15, 15, 34, 34, 46, 46, 49, 49, 63, 63, 93, 93, 95, 95, 98, 98, 126, 126, 4, 2, 44, 44, 49, 49, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 77, 77, 109, 109, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, 2, 92, 92, 124, 124, 2, 1192, 2, 12, 3, 2, 2, 2, 2, 14, 3, 2, 2, 2, 2, 16, 3, 2, 2, 2, 2, 18, 3, 2, 2, 2, 2, 20, 3, 2, 2, 2, 2, 22, 3, 2, 2, 2, 2, 24, 3, 2, 2, 2, 2, 26, 3, 2, 2, 2, 2, 28, 3, 2, 2, 2, 2, 30, 3, 2, 2, 2, 2, 32, 3, 2, 2, 2, 2, 34, 3, 2, 2, 2, 2, 36, 3, 2, 2, 2, 2, 38, 3, 2, 2, 2, 2, 40, 3, 2, 2, 2, 2, 42, 3, 2, 2, 2, 2, 44, 3, 2, 2, 2, 2, 46, 3, 2, 2, 2, 2, 48, 3, 2, 2, 2, 2, 50, 3, 2, 2, 2, 2, 52, 3, 2, 2, 2, 2, 54, 3, 2, 2, 2, 3, 56, 3, 2, 2, 2, 3, 58, 3, 2, 2, 2, 3, 60, 3, 2, 2, 2, 3, 62, 3, 2, 2, 2, 3, 64, 3, 2, 2, 2, 4, 66, 3, 2, 2, 2, 4, 88, 3, 2, 2, 2, 4, 90, 3, 2, 2, 2, 4, 92, 3, 2, 2, 2, 4, 94, 3, 2, 2, 2, 4, 96, 3, 2, 2, 2, 4, 98, 3, 2, 2, 2, 4, 100, 3, 2, 2, 2, 4, 102, 3, 2, 2, 2, 4, 104, 3, 2, 2, 2, 4, 106, 3, 2, 2, 2, 4, 108, 3, 2, 2, 2, 4, 110, 3, 2, 2, 2, 4, 112, 3, 2, 2, 2, 4, 114, 3, 2, 2, 2, 4, 116, 3, 2, 2, 2, 4, 118, 3, 2, 2, 2, 4, 120, 3, 2, 2, 2, 4, 122, 3, 2, 2, 2, 4, 124, 3, 2, 2, 2, 4, 126, 3, 2, 2, 2, 4, 128, 3, 2, 2, 2, 4, 130, 3, 2, 2, 2, 4, 132, 3, 2, 2, 2, 4, 134, 3, 2, 2, 2, 4, 136, 3, 2, 2, 2, 4, 138, 3, 2, 2, 2, 4, 140, 3, 2, 2, 2, 4, 142, 3, 2, 2, 2, 4, 144, 3, 2, 2, 2, 4, 146, 3, 2, 2, 2, 4, 148, 3, 2, 2, 2, 4, 150, 3, 2, 2, 2, 4, 152, 3, 2, 2, 2, 4, 154, 3, 2, 2, 2, 4, 156, 3, 2, 2, 2, 4, 158, 3, 2, 2, 2, 4, 160, 3, 2, 2, 2, 4, 162, 3, 2, 2, 2, 4, 164, 3, 2, 2, 2, 4, 166, 3, 2, 2, 2, 4, 168, 3, 2, 2, 2, 4, 170, 3, 2, 2, 2, 4, 172, 3, 2, 2, 2, 5, 174, 3, 2, 2, 2, 5, 176, 3, 2, 2, 2, 5, 178, 3, 2, 2, 2, 5, 180, 3, 2, 2, 2, 5, 182, 3, 2, 2, 2, 5, 184, 3, 2, 2, 2, 5, 188, 3, 2, 2, 2, 5, 190, 3, 2, 2, 2, 5, 192, 3, 2, 2, 2, 5, 194, 3, 2, 2, 2, 5, 196, 3, 2, 2, 2, 6, 198, 3, 2, 2, 2, 6, 200, 3, 2, 2, 2, 6, 202, 3, 2, 2, 2, 6, 206, 3, 2, 2, 2, 6, 208, 3, 2, 2, 2, 6, 210, 3, 2, 2, 2, 6, 212, 3, 2, 2, 2, 6, 214, 3, 2, 2, 2, 7, 216, 3, 2, 2, 2, 7, 218, 3, 2, 2, 2, 7, 220, 3, 2, 2, 2, 7, 222, 3, 2, 2, 2, 7, 224, 3, 2, 2, 2, 7, 226, 3, 2, 2, 2, 7, 228, 3, 2, 2, 2, 7, 230, 3, 2, 2, 2, 7, 232, 3, 2, 2, 2, 7, 234, 3, 2, 2, 2, 8, 236, 3, 2, 2, 2, 8, 238, 3, 2, 2, 2, 8, 240, 3, 2, 2, 2, 8, 242, 3, 2, 2, 2, 8, 244, 3, 2, 2, 2, 8, 246, 3, 2, 2, 2, 8, 248, 3, 2, 2, 2, 8, 250, 3, 2, 2, 2, 9, 252, 3, 2, 2, 2, 9, 254, 3, 2, 2, 2, 9, 256, 3, 2, 2, 2, 9, 258, 3, 2, 2, 2, 9, 260, 3, 2, 2, 2, 9, 262, 3, 2, 2, 2, 9, 264, 3, 2, 2, 2, 9, 266, 3, 2, 2, 2, 9, 268, 3, 2, 2, 2, 9, 270, 3, 2, 2, 2, 10, 272, 3, 2, 2, 2, 10, 274, 3, 2, 2, 2, 10, 276, 3, 2, 2, 2, 10, 278, 3, 2, 2, 2, 10, 280, 3, 2, 2, 2, 10, 282, 3, 2, 2, 2, 10, 284, 3, 2, 2, 2, 11, 286, 3, 2, 2, 2, 11, 288, 3, 2, 2, 2, 11, 290, 3, 2, 2, 2, 11, 292, 3, 2, 2, 2, 11, 294, 3, 2, 2, 2, 11, 296, 3, 2, 2, 2, 12, 350, 3, 2, 2, 2, 14, 360, 3, 2, 2, 2, 16, 367, 3, 2, 2, 2, 18, 376, 3, 2, 2, 2, 20, 383, 3, 2, 2, 2, 22, 393, 3, 2, 2, 2, 24, 400, 3, 2, 2, 2, 26, 407, 3, 2, 2, 2, 28, 421, 3, 2, 2, 2, 30, 428, 3, 2, 2, 2, 32, 436, 3, 2, 2, 2, 34, 448, 3, 2, 2, 2, 36, 458, 3, 2, 2, 2, 38, 467, 3, 2, 2, 2, 40, 473, 3, 2, 2, 2, 42, 480, 3, 2, 2, 2, 44, 487, 3, 2, 2, 2, 46, 495, 3, 2, 2, 2, 48, 504, 3, 2, 2, 2, 50, 510, 3, 2, 2, 2, 52, 527, 3, 2, 2, 2, 54, 543, 3, 2, 2, 2, 56, 549, 3, 2, 2, 2, 58, 554, 3, 2, 2, 2, 60, 559, 3, 2, 2, 2, 62, 563, 3, 2, 2, 2, 64, 567, 3, 2, 2, 2, 66, 571, 3, 2, 2, 2, 68, 575, 3, 2, 2, 2, 70, 577, 3, 2, 2, 2, 72, 579, 3, 2, 2, 2, 74, 582, 3, 2, 2, 2, 76, 584, 3, 2, 2, 2, 78, 593, 3, 2, 2, 2, 80, 595, 3, 2, 2, 2, 82, 600, 3, 2, 2, 2, 84, 602, 3, 2, 2, 2, 86, 607, 3, 2, 2, 2, 88, 638, 3, 2, 2, 2, 90, 641, 3, 2, 2, 2, 92, 687, 3, 2, 2, 2, 94, 689, 3, 2, 2, 2, 96, 692, 3, 2, 2, 2, 98, 696, 3, 2, 2, 2, 100, 700, 3, 2, 2, 2, 102, 702, 3, 2, 2, 2, 104, 704, 3, 2, 2, 2, 106, 709, 3, 2, 2, 2, 108, 711, 3, 2, 2, 2, 110, 717, 3, 2, 2, 2, 112, 723, 3, 2, 2, 2, 114, 728, 3, 2, 2, 2, 116, 730, 3, 2, 2, 2, 118, 733, 3, 2, 2, 2, 120, 736, 3, 2, 2, 2, 122, 741, 3, 2, 2, 2, 124, 745, 3, 2, 2, 2, 126, 750, 3, 2, 2, 2, 128, 756, 3, 2, 2, 2, 130, 759, 3, 2, 2, 2, 132, 761, 3, 2, 2, 2, 134, 767, 3, 2, 2, 2, 136, 769, 3, 2, 2, 2, 138, 774, 3, 2, 2, 2, 140, 777, 3, 2, 2, 2, 142, 780, 3, 2, 2, 2, 144, 782, 3, 2, 2, 2, 146, 785, 3, 2, 2, 2, 148, 787, 3, 2, 2, 2, 150, 790, 3, 2, 2, 2, 152, 792, 3, 2, 2, 2, 154, 794, 3, 2, 2, 2, 156, 796, 3, 2, 2, 2, 158, 798, 3, 2, 2, 2, 160, 800, 3, 2, 2, 2, 162, 805, 3, 2, 2, 2, 164, 826, 3, 2, 2, 2, 166, 828, 3, 2, 2, 2, 168, 836, 3, 2, 2, 2, 170, 840, 3, 2, 2, 2, 172, 844, 3, 2, 2, 2, 174, 848, 3, 2, 2, 2, 176, 853, 3, 2, 2, 2, 178, 859, 3, 2, 2, 2, 180, 865, 3, 2, 2, 2, 182, 869, 3, 2, 2, 2, 184, 873, 3, 2, 2, 2, 186, 885, 3, 2, 2, 2, 188, 888, 3, 2, 2, 2, 190, 892, 3, 2, 2, 2, 192, 896, 3, 2, 2, 2, 194, 900, 3, 2, 2, 2, 196, 904, 3, 2, 2, 2, 198, 908, 3, 2, 2, 2, 200, 913, 3, 2, 2, 2, 202, 917, 3, 2, 2, 2, 204, 925, 3, 2, 2, 2, 206, 946, 3, 2, 2, 2, 208, 948, 3, 2, 2, 2, 210, 952, 3, 2, 2, 2, 212, 956, 3, 2, 2, 2, 214, 960, 3, 2, 2, 2, 216, 964, 3, 2, 2, 2, 218, 969, 3, 2, 2, 2, 220, 973, 3, 2, 2, 2, 222, 977, 3, 2, 2, 2, 224, 981, 3, 2, 2, 2, 226, 984, 3, 2, 2, 2, 228, 988, 3, 2, 2, 2, 230, 992, 3, 2, 2, 2, 232, 996, 3, 2, 2, 2, 234, 1000, 3, 2, 2, 2, 236, 1004, 3, 2, 2, 2, 238, 1009, 3, 2, 2, 2, 240, 1014, 3, 2, 2, 2, 242, 1021, 3, 2, 2, 2, 244, 1025, 3, 2, 2, 2, 246, 1029, 3, 2, 2, 2, 248, 1033, 3, 2, 2, 2, 250, 1037, 3, 2, 2, 2, 252, 1041, 3, 2, 2, 2, 254, 1047, 3, 2, 2, 2, 256, 1051, 3, 2, 2, 2, 258, 1055, 3, 2, 2, 2, 260, 1059, 3, 2, 2, 2, 262, 1063, 3, 2, 2, 2, 264, 1067, 3, 2, 2, 2, 266, 1071, 3, 2, 2, 2, 268, 1075, 3, 2, 2, 2, 270, 1079, 3, 2, 2, 2, 272, 1083, 3, 2, 2, 2, 274, 1088, 3, 2, 2, 2, 276, 1092, 3, 2, 2, 2, 278, 1096, 3, 2, 2, 2, 280, 1100, 3, 2, 2, 2, 282, 1104, 3, 2, 2, 2, 284, 1108, 3, 2, 2, 2, 286, 1112, 3, 2, 2, 2, 288, 1117, 3, 2, 2, 2, 290, 1122, 3, 2, 2, 2, 292, 1132, 3, 2, 2, 2, 294, 1136, 3, 2, 2, 2, 296, 1140, 3, 2, 2, 2, 298, 1144, 3, 2, 2, 2, 300, 1146, 3, 2, 2, 2, 302, 1148, 3, 2, 2, 2, 304, 1150, 3, 2, 2, 2, 306, 1152, 3, 2, 2, 2, 308, 1154, 3, 2, 2, 2, 310, 1156, 3, 2, 2, 2, 312, 1158, 3, 2, 2, 2, 314, 1160, 3, 2, 2, 2, 316, 1162, 3, 2, 2, 2, 318, 1164, 3, 2, 2, 2, 320, 1166, 3, 2, 2, 2, 322, 1168, 3, 2, 2, 2, 324, 1170, 3, 2, 2, 2, 326, 1172, 3, 2, 2, 2, 328, 1174, 3, 2, 2, 2, 330, 1176, 3, 2, 2, 2, 332, 1178, 3, 2, 2, 2, 334, 1180, 3, 2, 2, 2, 336, 1182, 3, 2, 2, 2, 338, 1184, 3, 2, 2, 2, 340, 1186, 3, 2, 2, 2, 342, 1188, 3, 2, 2, 2, 344, 1190, 3, 2, 2, 2, 346, 1192, 3, 2, 2, 2, 348, 1194, 3, 2, 2, 2, 350, 351, 5, 304, 148, 2, 351, 352, 5, 314, 153, 2, 352, 353, 5, 334, 163, 2, 353, 354, 5, 334, 163, 2, 354, 355, 5, 306, 149, 2, 355, 356, 5, 302, 147, 2, 356, 357, 5, 336, 164, 2, 357, 358, 3, 2, 2, 2, 358, 359, 8, 2, 2, 2, 359, 13, 3, 2, 2, 2, 360, 361, 5, 304, 148, 2, 361, 362, 5, 332, 162, 2, 362, 363, 5, 326, 159, 2, 363, 364, 5, 328, 160, 2, 364, 365, 3, 2, 2, 2, 365, 366, 8, 3, 3, 2, 366, 15, 3, 2, 2, 2, 367, 368, 5, 306, 149, 2, 368, 369, 5, 324, 158, 2, 369, 370, 5, 332, 162, 2, 370, 371, 5, 314, 153, 2, 371, 372, 5, 302, 147, 2, 372, 373, 5, 312, 152, 2, 373, 374, 3, 2, 2, 2, 374, 375, 8, 4, 4, 2, 375, 17, 3, 2, 2, 2, 376, 377, 5, 306, 149, 2, 377, 378, 5, 340, 166, 2, 378, 379, 5, 298, 145, 2, 379, 380, 5, 320, 156, 2, 380, 381, 3, 2, 2, 2, 381, 382, 8, 5, 2, 2, 382, 19, 3, 2, 2, 2, 383, 384, 5, 306, 149, 2, 384, 385, 5, 344, 168, 2, 385, 386, 5, 328, 160, 2, 386, 387, 5, 320, 156, 2, 387, 388, 5, 298, 145, 2, 388, 389, 5, 314, 153, 2, 389, 390, 5, 324, 158, 2, 390, 391, 3, 2, 2, 2, 391, 392, 8, 6, 5, 2, 392, 21, 3, 2, 2, 2, 393, 394, 5, 308, 150, 2, 394, 395, 5, 332, 162, 2, 395, 396, 5, 326, 159, 2, 396, 397, 5, 322, 157, 2, 397, 398, 3, 2, 2, 2, 398, 399, 8, 7, 6, 2, 399, 23, 3, 2, 2, 2, 400, 401, 5, 310, 151, 2, 401, 402, 5, 332, 162, 2, 402, 403, 5, 326, 159, 2, 403, 404, 5, 318, 155, 2, 404, 405, 3, 2, 2, 2, 405, 406, 8, 8, 2, 2, 406, 25, 3, 2, 2, 2, 407, 408, 5, 314, 153, 2, 408, 409, 5, 324, 158, 2, 409, 410, 5, 320, 156, 2, 410, 411, 5, 314, 153, 2, 411, 412, 5, 324, 158, 2, 412, 413, 5, 306, 149, 2, 413, 414, 5, 334, 163, 2, 414, 415, 5, 336, 164, 2, 415, 416, 5, 298, 145, 2, 416, 417, 5, 336, 164, 2, 417, 418, 5, 334, 163, 2, 418, 419, 3, 2, 2, 2, 419, 420, 8, 9, 2, 2, 420, 27, 3, 2, 2, 2, 421, 422, 5, 318, 155, 2, 422, 423, 5, 306, 149, 2, 423, 424, 5, 306, 149, 2, 424, 425, 5, 328, 160, 2, 425, 426, 3, 2, 2, 2, 426, 427, 8, 10, 3, 2, 427, 29, 3, 2, 2, 2, 428, 429, 5, 320, 156, 2, 429, 430, 5, 314, 153, 2, 430, 431, 5, 322, 157, 2, 431, 432, 5, 314, 153, 2, 432, 433, 5, 336, 164, 2, 433, 434, 3, 2, 2, 2, 434, 435, 8, 11, 2, 2, 435, 31, 3, 2, 2, 2, 436, 437, 5, 322, 157, 2, 437, 438, 5, 340, 166, 2, 438, 439, 5, 84, 38, 2, 439, 440, 5, 306, 149, 2, 440, 441, 5, 344, 168, 2, 441, 442, 5, 328, 160, 2, 442, 443, 5, 298, 145, 2, 443, 444, 5, 324, 158, 2, 444, 445, 5, 304, 148, 2, 445, 446, 3, 2, 2, 2, 446, 447, 8, 12, 7, 2, 447, 33, 3, 2, 2, 2, 448, 449, 5, 328, 160, 2, 449, 450, 5, 332, 162, 2, 450, 451, 5, 326, 159, 2, 451, 452, 5, 316, 154, 2, 452, 453, 5, 306, 149, 2, 453, 454, 5, 302, 147, 2, 454, 455, 5, 336, 164, 2, 455, 456, 3, 2, 2, 2, 456, 457, 8, 13, 3, 2, 457, 35, 3, 2, 2, 2, 458, 459, 5, 332, 162, 2, 459, 460, 5, 306, 149, 2, 460, 461, 5, 324, 158, 2, 461, 462, 5, 298, 145, 2, 462, 463, 5, 322, 157, 2, 463, 464, 5, 306, 149, 2, 464, 465, 3, 2, 2, 2, 465, 466, 8, 14, 8, 2, 466, 37, 3, 2, 2, 2, 467, 468, 5, 332, 162, 2, 468, 469, 5, 326, 159, 2, 469, 470, 5, 342, 167, 2, 470, 471, 3, 2, 2, 2, 471, 472, 8, 15, 2, 2, 472, 39, 3, 2, 2, 2, 473, 474, 5, 334, 163, 2, 474, 475, 5, 312, 152, 2, 475, 476, 5, 326, 159, 2, 476, 477, 5, 342, 167, 2, 477, 478, 3, 2, 2, 2, 478, 479, 8, 16, 9, 2, 479, 41, 3, 2, 2, 2, 480, 481, 5, 334, 163, 2, 481, 482, 5, 326, 159, 2, 482, 483, 5, 332, 162, 2, 483, 484, 5, 336, 164, 2, 484, 485, 3, 2, 2, 2, 485, 486, 8, 17, 2, 2, 486, 43, 3, 2, 2, 2, 487, 488, 5, 334, 163, 2, 488, 489, 5, 336, 164, 2, 489, 490, 5, 298, 145, 2, 490, 491, 5, 336, 164, 2, 491, 492, 5, 334, 163, 2, 492, 493, 3, 2, 2, 2, 493, 494, 8, 18, 2, 2, 494, 45, 3, 2, 2, 2, 495, 496, 5, 342, 167, 2, 496, 497, 5, 312, 152, 2, 497, 498, 5, 306, 149, 2, 498, 499, 5, 332, 162, 2, 499, 500, 5, 306, 149, 2, 500, 501, 3, 2, 2, 2, 501, 502, 8, 19, 2, 2, 502, 47, 3, 2, 2, 2, 503, 505, 10, 2, 2, 2, 504, 503, 3, 2, 2, 2, 505, 506, 3, 2, 2, 2, 506, 504, 3, 2, 2, 2, 506, 507, 3, 2, 2, 2, 507, 508, 3, 2, 2, 2, 508, 509, 8, 20, 2, 2, 509, 49, 3, 2, 2, 2, 510, 511, 7, 49, 2, 2, 511, 512, 7, 49, 2, 2, 512, 516, 3, 2, 2, 2, 513, 515, 10, 3, 2, 2, 514, 513, 3, 2, 2, 2, 515, 518, 3, 2, 2, 2, 516, 514, 3, 2, 2, 2, 516, 517, 3, 2, 2, 2, 517, 520, 3, 2, 2, 2, 518, 516, 3, 2, 2, 2, 519, 521, 7, 15, 2, 2, 520, 519, 3, 2, 2, 2, 520, 521, 3, 2, 2, 2, 521, 523, 3, 2, 2, 2, 522, 524, 7, 12, 2, 2, 523, 522, 3, 2, 2, 2, 523, 524, 3, 2, 2, 2, 524, 525, 3, 2, 2, 2, 525, 526, 8, 21, 10, 2, 526, 51, 3, 2, 2, 2, 527, 528, 7, 49, 2, 2, 528, 529, 7, 44, 2, 2, 529, 534, 3, 2, 2, 2, 530, 533, 5, 52, 22, 2, 531, 533, 11, 2, 2, 2, 532, 530, 3, 2, 2, 2, 532, 531, 3, 2, 2, 2, 533, 536, 3, 2, 2, 2, 534, 535, 3, 2, 2, 2, 534, 532, 3, 2, 2, 2, 535, 537, 3, 2, 2, 2, 536, 534, 3, 2, 2, 2, 537, 538, 7, 44, 2, 2, 538, 539, 7, 49, 2, 2, 539, 540, 3, 2, 2, 2, 540, 541, 8, 22, 10, 2, 541, 53, 3, 2, 2, 2, 542, 544, 9, 4, 2, 2, 543, 542, 3, 2, 2, 2, 544, 545, 3, 2, 2, 2, 545, 543, 3, 2, 2, 2, 545, 546, 3, 2, 2, 2, 546, 547, 3, 2, 2, 2, 547, 548, 8, 23, 10, 2, 548, 55, 3, 2, 2, 2, 549, 550, 5, 160, 76, 2, 550, 551, 3, 2, 2, 2, 551, 552, 8, 24, 11, 2, 552, 553, 8, 24, 12, 2, 553, 57, 3, 2, 2, 2, 554, 555, 5, 66, 29, 2, 555, 556, 3, 2, 2, 2, 556, 557, 8, 25, 13, 2, 557, 558, 8, 25, 14, 2, 558, 59, 3, 2, 2, 2, 559, 560, 5, 54, 23, 2, 560, 561, 3, 2, 2, 2, 561, 562, 8, 26, 10, 2, 562, 61, 3, 2, 2, 2, 563, 564, 5, 50, 21, 2, 564, 565, 3, 2, 2, 2, 565, 566, 8, 27, 10, 2, 566, 63, 3, 2, 2, 2, 567, 568, 5, 52, 22, 2, 568, 569, 3, 2, 2, 2, 569, 570, 8, 28, 10, 2, 570, 65, 3, 2, 2, 2, 571, 572, 7, 126, 2, 2, 572, 573, 3, 2, 2, 2, 573, 574, 8, 29, 14, 2, 574, 67, 3, 2, 2, 2, 575, 576, 9, 5, 2, 2, 576, 69, 3, 2, 2, 2, 577, 578, 9, 6, 2, 2, 578, 71, 3, 2, 2, 2, 579, 580, 7, 94, 2, 2, 580, 581, 9, 7, 2, 2, 581, 73, 3, 2, 2, 2, 582, 583, 10, 8, 2, 2, 583, 75, 3, 2, 2, 2, 584, 586, 9, 9, 2, 2, 585, 587, 9, 10, 2, 2, 586, 585, 3, 2, 2, 2, 586, 587, 3, 2, 2, 2, 587, 589, 3, 2, 2, 2, 588, 590, 5, 68, 30, 2, 589, 588, 3, 2, 2, 2, 590, 591, 3, 2, 2, 2, 591, 589, 3, 2, 2, 2, 591, 592, 3, 2, 2, 2, 592, 77, 3, 2, 2, 2, 593, 594, 7, 66, 2, 2, 594, 79, 3, 2, 2, 2, 595, 596, 7, 98, 2, 2, 596, 81, 3, 2, 2, 2, 597, 601, 10, 11, 2, 2, 598, 599, 7, 98, 2, 2, 599, 601, 7, 98, 2, 2, 600, 597, 3, 2, 2, 2, 600, 598, 3, 2, 2, 2, 601, 83, 3, 2, 2, 2, 602, 603, 7, 97, 2, 2, 603, 85, 3, 2, 2, 2, 604, 608, 5, 70, 31, 2, 605, 608, 5, 68, 30, 2, 606, 608, 5, 84, 38, 2, 607, 604, 3, 2, 2, 2, 607, 605, 3, 2, 2, 2, 607, 606, 3, 2, 2, 2, 608, 87, 3, 2, 2, 2, 609, 614, 7, 36, 2, 2, 610, 613, 5, 72, 32, 2, 611, 613, 5, 74, 33, 2, 612, 610, 3, 2, 2, 2, 612, 611, 3, 2, 2, 2, 613, 616, 3, 2, 2, 2, 614, 612, 3, 2, 2, 2, 614, 615, 3, 2, 2, 2, 615, 617, 3, 2, 2, 2, 616, 614, 3, 2, 2, 2, 617, 639, 7, 36, 2, 2, 618, 619, 7, 36, 2, 2, 619, 620, 7, 36, 2, 2, 620, 621, 7, 36, 2, 2, 621, 625, 3, 2, 2, 2, 622, 624, 10, 3, 2, 2, 623, 622, 3, 2, 2, 2, 624, 627, 3, 2, 2, 2, 625, 626, 3, 2, 2, 2, 625, 623, 3, 2, 2, 2, 626, 628, 3, 2, 2, 2, 627, 625, 3, 2, 2, 2, 628, 629, 7, 36, 2, 2, 629, 630, 7, 36, 2, 2, 630, 631, 7, 36, 2, 2, 631, 633, 3, 2, 2, 2, 632, 634, 7, 36, 2, 2, 633, 632, 3, 2, 2, 2, 633, 634, 3, 2, 2, 2, 634, 636, 3, 2, 2, 2, 635, 637, 7, 36, 2, 2, 636, 635, 3, 2, 2, 2, 636, 637, 3, 2, 2, 2, 637, 639, 3, 2, 2, 2, 638, 609, 3, 2, 2, 2, 638, 618, 3, 2, 2, 2, 639, 89, 3, 2, 2, 2, 640, 642, 5, 68, 30, 2, 641, 640, 3, 2, 2, 2, 642, 643, 3, 2, 2, 2, 643, 641, 3, 2, 2, 2, 643, 644, 3, 2, 2, 2, 644, 91, 3, 2, 2, 2, 645, 647, 5, 68, 30, 2, 646, 645, 3, 2, 2, 2, 647, 648, 3, 2, 2, 2, 648, 646, 3, 2, 2, 2, 648, 649, 3, 2, 2, 2, 649, 650, 3, 2, 2, 2, 650, 654, 5, 106, 49, 2, 651, 653, 5, 68, 30, 2, 652, 651, 3, 2, 2, 2, 653, 656, 3, 2, 2, 2, 654, 652, 3, 2, 2, 2, 654, 655, 3, 2, 2, 2, 655, 688, 3, 2, 2, 2, 656, 654, 3, 2, 2, 2, 657, 659, 5, 106, 49, 2, 658, 660, 5, 68, 30, 2, 659, 658, 3, 2, 2, 2, 660, 661, 3, 2, 2, 2, 661, 659, 3, 2, 2, 2, 661, 662, 3, 2, 2, 2, 662, 688, 3, 2, 2, 2, 663, 665, 5, 68, 30, 2, 664, 663, 3, 2, 2, 2, 665, 666, 3, 2, 2, 2, 666, 664, 3, 2, 2, 2, 666, 667, 3, 2, 2, 2, 667, 675, 3, 2, 2, 2, 668, 672, 5, 106, 49, 2, 669, 671, 5, 68, 30, 2, 670, 669, 3, 2, 2, 2, 671, 674, 3, 2, 2, 2, 672, 670, 3, 2, 2, 2, 672, 673, 3, 2, 2, 2, 673, 676, 3, 2, 2, 2, 674, 672, 3, 2, 2, 2, 675, 668, 3, 2, 2, 2, 675, 676, 3, 2, 2, 2, 676, 677, 3, 2, 2, 2, 677, 678, 5, 76, 34, 2, 678, 688, 3, 2, 2, 2, 679, 681, 5, 106, 49, 2, 680, 682, 5, 68, 30, 2, 681, 680, 3, 2, 2, 2, 682, 683, 3, 2, 2, 2, 683, 681, 3, 2, 2, 2, 683, 684, 3, 2, 2, 2, 684, 685, 3, 2, 2, 2, 685, 686, 5, 76, 34, 2, 686, 688, 3, 2, 2, 2, 687, 646, 3, 2, 2, 2, 687, 657, 3, 2, 2, 2, 687, 664, 3, 2, 2, 2, 687, 679, 3, 2, 2, 2, 688, 93, 3, 2, 2, 2, 689, 690, 5, 300, 146, 2, 690, 691, 5, 346, 169, 2, 691, 95, 3, 2, 2, 2, 692, 693, 5, 298, 145, 2, 693, 694, 5, 324, 158, 2, 694, 695, 5, 304, 148, 2, 695, 97, 3, 2, 2, 2, 696, 697, 5, 298, 145, 2, 697, 698, 5, 334, 163, 2, 698, 699, 5, 302, 147, 2, 699, 99, 3, 2, 2, 2, 700, 701, 7, 63, 2, 2, 701, 101, 3, 2, 2, 2, 702, 703, 7, 46, 2, 2, 703, 103, 3, 2, 2, 2, 704, 705, 5, 304, 148, 2, 705, 706, 5, 306, 149, 2, 706, 707, 5, 334, 163, 2, 707, 708, 5, 302, 147, 2, 708, 105, 3, 2, 2, 2, 709, 710, 7, 48, 2, 2, 710, 107, 3, 2, 2, 2, 711, 712, 5, 308, 150, 2, 712, 713, 5, 298, 145, 2, 713, 714, 5, 320, 156, 2, 714, 715, 5, 334, 163, 2, 715, 716, 5, 306, 149, 2, 716, 109, 3, 2, 2, 2, 717, 718, 5, 308, 150, 2, 718, 719, 5, 314, 153, 2, 719, 720, 5, 332, 162, 2, 720, 721, 5, 334, 163, 2, 721, 722, 5, 336, 164, 2, 722, 111, 3, 2, 2, 2, 723, 724, 5, 320, 156, 2, 724, 725, 5, 298, 145, 2, 725, 726, 5, 334, 163, 2, 726, 727, 5, 336, 164, 2, 727, 113, 3, 2, 2, 2, 728, 729, 7, 42, 2, 2, 729, 115, 3, 2, 2, 2, 730, 731, 5, 314, 153, 2, 731, 732, 5, 324, 158, 2, 732, 117, 3, 2, 2, 2, 733, 734, 5, 314, 153, 2, 734, 735, 5, 334, 163, 2, 735, 119, 3, 2, 2, 2, 736, 737, 5, 320, 156, 2, 737, 738, 5, 314, 153, 2, 738, 739, 5, 318, 155, 2, 739, 740, 5, 306, 149, 2, 740, 121, 3, 2, 2, 2, 741, 742, 5, 324, 158, 2, 742, 743, 5, 326, 159, 2, 743, 744, 5, 336, 164, 2, 744, 123, 3, 2, 2, 2, 745, 746, 5, 324, 158, 2, 746, 747, 5, 338, 165, 2, 747, 748, 5, 320, 156, 2, 748, 749, 5, 320, 156, 2, 749, 125, 3, 2, 2, 2, 750, 751, 5, 324, 158, 2, 751, 752, 5, 338, 165, 2, 752, 753, 5, 320, 156, 2, 753, 754, 5, 320, 156, 2, 754, 755, 5, 334, 163, 2, 755, 127, 3, 2, 2, 2, 756, 757, 5, 326, 159, 2, 757, 758, 5, 332, 162, 2, 758, 129, 3, 2, 2, 2, 759, 760, 7, 65, 2, 2, 760, 131, 3, 2, 2, 2, 761, 762, 5, 332, 162, 2, 762, 763, 5, 320, 156, 2, 763, 764, 5, 314, 153, 2, 764, 765, 5, 318, 155, 2, 765, 766, 5, 306, 149, 2, 766, 133, 3, 2, 2, 2, 767, 768, 7, 43, 2, 2, 768, 135, 3, 2, 2, 2, 769, 770, 5, 336, 164, 2, 770, 771, 5, 332, 162, 2, 771, 772, 5, 338, 165, 2, 772, 773, 5, 306, 149, 2, 773, 137, 3, 2, 2, 2, 774, 775, 7, 63, 2, 2, 775, 776, 7, 63, 2, 2, 776, 139, 3, 2, 2, 2, 777, 778, 7, 35, 2, 2, 778, 779, 7, 63, 2, 2, 779, 141, 3, 2, 2, 2, 780, 781, 7, 62, 2, 2, 781, 143, 3, 2, 2, 2, 782, 783, 7, 62, 2, 2, 783, 784, 7, 63, 2, 2, 784, 145, 3, 2, 2, 2, 785, 786, 7, 64, 2, 2, 786, 147, 3, 2, 2, 2, 787, 788, 7, 64, 2, 2, 788, 789, 7, 63, 2, 2, 789, 149, 3, 2, 2, 2, 790, 791, 7, 45, 2, 2, 791, 151, 3, 2, 2, 2, 792, 793, 7, 47, 2, 2, 793, 153, 3, 2, 2, 2, 794, 795, 7, 44, 2, 2, 795, 155, 3, 2, 2, 2, 796, 797, 7, 49, 2, 2, 797, 157, 3, 2, 2, 2, 798, 799, 7, 39, 2, 2, 799, 159, 3, 2, 2, 2, 800, 801, 7, 93, 2, 2, 801, 802, 3, 2, 2, 2, 802, 803, 8, 76, 2, 2, 803, 804, 8, 76, 2, 2, 804, 161, 3, 2, 2, 2, 805, 806, 7, 95, 2, 2, 806, 807, 3, 2, 2, 2, 807, 808, 8, 77, 14, 2, 808, 809, 8, 77, 14, 2, 809, 163, 3, 2, 2, 2, 810, 814, 5, 70, 31, 2, 811, 813, 5, 86, 39, 2, 812, 811, 3, 2, 2, 2, 813, 816, 3, 2, 2, 2, 814, 812, 3, 2, 2, 2, 814, 815, 3, 2, 2, 2, 815, 827, 3, 2, 2, 2, 816, 814, 3, 2, 2, 2, 817, 820, 5, 84, 38, 2, 818, 820, 5, 78, 35, 2, 819, 817, 3, 2, 2, 2, 819, 818, 3, 2, 2, 2, 820, 822, 3, 2, 2, 2, 821, 823, 5, 86, 39, 2, 822, 821, 3, 2, 2, 2, 823, 824, 3, 2, 2, 2, 824, 822, 3, 2, 2, 2, 824, 825, 3, 2, 2, 2, 825, 827, 3, 2, 2, 2, 826, 810, 3, 2, 2, 2, 826, 819, 3, 2, 2, 2, 827, 165, 3, 2, 2, 2, 828, 830, 5, 80, 36, 2, 829, 831, 5, 82, 37, 2, 830, 829, 3, 2, 2, 2, 831, 832, 3, 2, 2, 2, 832, 830, 3, 2, 2, 2, 832, 833, 3, 2, 2, 2, 833, 834, 3, 2, 2, 2, 834, 835, 5, 80, 36, 2, 835, 167, 3, 2, 2, 2, 836, 837, 5, 50, 21, 2, 837, 838, 3, 2, 2, 2, 838, 839, 8, 80, 10, 2, 839, 169, 3, 2, 2, 2, 840, 841, 5, 52, 22, 2, 841, 842, 3, 2, 2, 2, 842, 843, 8, 81, 10, 2, 843, 171, 3, 2, 2, 2, 844, 845, 5, 54, 23, 2, 845, 846, 3, 2, 2, 2, 846, 847, 8, 82, 10, 2, 847, 173, 3, 2, 2, 2, 848, 849, 5, 66, 29, 2, 849, 850, 3, 2, 2, 2, 850, 851, 8, 83, 13, 2, 851, 852, 8, 83, 14, 2, 852, 175, 3, 2, 2, 2, 853, 854, 5, 160, 76, 2, 854, 855, 3, 2, 2, 2, 855, 856, 8, 84, 11, 2, 856, 857, 8, 84, 6, 2, 857, 858, 8, 84, 6, 2, 858, 177, 3, 2, 2, 2, 859, 860, 5, 162, 77, 2, 860, 861, 3, 2, 2, 2, 861, 862, 8, 85, 15, 2, 862, 863, 8, 85, 14, 2, 863, 864, 8, 85, 14, 2, 864, 179, 3, 2, 2, 2, 865, 866, 5, 102, 47, 2, 866, 867, 3, 2, 2, 2, 867, 868, 8, 86, 16, 2, 868, 181, 3, 2, 2, 2, 869, 870, 5, 100, 46, 2, 870, 871, 3, 2, 2, 2, 871, 872, 8, 87, 17, 2, 872, 183, 3, 2, 2, 2, 873, 874, 5, 322, 157, 2, 874, 875, 5, 306, 149, 2, 875, 876, 5, 336, 164, 2, 876, 877, 5, 298, 145, 2, 877, 878, 5, 304, 148, 2, 878, 879, 5, 298, 145, 2, 879, 880, 5, 336, 164, 2, 880, 881, 5, 298, 145, 2, 881, 185, 3, 2, 2, 2, 882, 886, 10, 12, 2, 2, 883, 884, 7, 49, 2, 2, 884, 886, 10, 13, 2, 2, 885, 882, 3, 2, 2, 2, 885, 883, 3, 2, 2, 2, 886, 187, 3, 2, 2, 2, 887, 889, 5, 186, 89, 2, 888, 887, 3, 2, 2, 2, 889, 890, 3, 2, 2, 2, 890, 888, 3, 2, 2, 2, 890, 891, 3, 2, 2, 2, 891, 189, 3, 2, 2, 2, 892, 893, 5, 166, 79, 2, 893, 894, 3, 2, 2, 2, 894, 895, 8, 91, 18, 2, 895, 191, 3, 2, 2, 2, 896, 897, 5, 50, 21, 2, 897, 898, 3, 2, 2, 2, 898, 899, 8, 92, 10, 2, 899, 193, 3, 2, 2, 2, 900, 901, 5, 52, 22, 2, 901, 902, 3, 2, 2, 2, 902, 903, 8, 93, 10, 2, 903, 195, 3, 2, 2, 2, 904, 905, 5, 54, 23, 2, 905, 906, 3, 2, 2, 2, 906, 907, 8, 94, 10, 2, 907, 197, 3, 2, 2, 2, 908, 909, 5, 66, 29, 2, 909, 910, 3, 2, 2, 2, 910, 911, 8, 95, 13, 2, 911, 912, 8, 95, 14, 2, 912, 199, 3, 2, 2, 2, 913, 914, 5, 106, 49, 2, 914, 915, 3, 2, 2, 2, 915, 916, 8, 96, 19, 2, 916, 201, 3, 2, 2, 2, 917, 918, 5, 102, 47, 2, 918, 919, 3, 2, 2, 2, 919, 920, 8, 97, 16, 2, 920, 203, 3, 2, 2, 2, 921, 926, 5, 70, 31, 2, 922, 926, 5, 68, 30, 2, 923, 926, 5, 84, 38, 2, 924, 926, 5, 154, 73, 2, 925, 921, 3, 2, 2, 2, 925, 922, 3, 2, 2, 2, 925, 923, 3, 2, 2, 2, 925, 924, 3, 2, 2, 2, 926, 205, 3, 2, 2, 2, 927, 930, 5, 70, 31, 2, 928, 930, 5, 154, 73, 2, 929, 927, 3, 2, 2, 2, 929, 928, 3, 2, 2, 2, 930, 934, 3, 2, 2, 2, 931, 933, 5, 204, 98, 2, 932, 931, 3, 2, 2, 2, 933, 936, 3, 2, 2, 2, 934, 932, 3, 2, 2, 2, 934, 935, 3, 2, 2, 2, 935, 947, 3, 2, 2, 2, 936, 934, 3, 2, 2, 2, 937, 940, 5, 84, 38, 2, 938, 940, 5, 78, 35, 2, 939, 937, 3, 2, 2, 2, 939, 938, 3, 2, 2, 2, 940, 942, 3, 2, 2, 2, 941, 943, 5, 204, 98, 2, 942, 941, 3, 2, 2, 2, 943, 944, 3, 2, 2, 2, 944, 942, 3, 2, 2, 2, 944, 945, 3, 2, 2, 2, 945, 947, 3, 2, 2, 2, 946, 929, 3, 2, 2, 2, 946, 939, 3, 2, 2, 2, 947, 207, 3, 2, 2, 2, 948, 949, 5, 166, 79, 2, 949, 950, 3, 2, 2, 2, 950, 951, 8, 100, 18, 2, 951, 209, 3, 2, 2, 2, 952, 953, 5, 50, 21, 2, 953, 954, 3, 2, 2, 2, 954, 955, 8, 101, 10, 2, 955, 211, 3, 2, 2, 2, 956, 957, 5, 52, 22, 2, 957, 958, 3, 2, 2, 2, 958, 959, 8, 102, 10, 2, 959, 213, 3, 2, 2, 2, 960, 961, 5, 54, 23, 2, 961, 962, 3, 2, 2, 2, 962, 963, 8, 103, 10, 2, 963, 215, 3, 2, 2, 2, 964, 965, 5, 66, 29, 2, 965, 966, 3, 2, 2, 2, 966, 967, 8, 104, 13, 2, 967, 968, 8, 104, 14, 2, 968, 217, 3, 2, 2, 2, 969, 970, 5, 100, 46, 2, 970, 971, 3, 2, 2, 2, 971, 972, 8, 105, 17, 2, 972, 219, 3, 2, 2, 2, 973, 974, 5, 102, 47, 2, 974, 975, 3, 2, 2, 2, 975, 976, 8, 106, 16, 2, 976, 221, 3, 2, 2, 2, 977, 978, 5, 106, 49, 2, 978, 979, 3, 2, 2, 2, 979, 980, 8, 107, 19, 2, 980, 223, 3, 2, 2, 2, 981, 982, 5, 298, 145, 2, 982, 983, 5, 334, 163, 2, 983, 225, 3, 2, 2, 2, 984, 985, 5, 166, 79, 2, 985, 986, 3, 2, 2, 2, 986, 987, 8, 109, 18, 2, 987, 227, 3, 2, 2, 2, 988, 989, 5, 206, 99, 2, 989, 990, 3, 2, 2, 2, 990, 991, 8, 110, 20, 2, 991, 229, 3, 2, 2, 2, 992, 993, 5, 50, 21, 2, 993, 994, 3, 2, 2, 2, 994, 995, 8, 111, 10, 2, 995, 231, 3, 2, 2, 2, 996, 997, 5, 52, 22, 2, 997, 998, 3, 2, 2, 2, 998, 999, 8, 112, 10, 2, 999, 233, 3, 2, 2, 2, 1000, 1001, 5, 54, 23, 2, 1001, 1002, 3, 2, 2, 2, 1002, 1003, 8, 113, 10, 2, 1003, 235, 3, 2, 2, 2, 1004, 1005, 5, 66, 29, 2, 1005, 1006, 3, 2, 2, 2, 1006, 1007, 8, 114, 13, 2, 1007, 1008, 8, 114, 14, 2, 1008, 237, 3, 2, 2, 2, 1009, 1010, 5, 326, 159, 2, 1010, 1011, 5, 324, 158, 2, 1011, 1012, 3, 2, 2, 2, 1012, 1013, 8, 115, 21, 2, 1013, 239, 3, 2, 2, 2, 1014, 1015, 5, 342, 167, 2, 1015, 1016, 5, 314, 153, 2, 1016, 1017, 5, 336, 164, 2, 1017, 1018, 5, 312, 152, 2, 1018, 1019, 3, 2, 2, 2, 1019, 1020, 8, 116, 21, 2, 1020, 241, 3, 2, 2, 2, 1021, 1022, 5, 188, 90, 2, 1022, 1023, 3, 2, 2, 2, 1023, 1024, 8, 117, 22, 2, 1024, 243, 3, 2, 2, 2, 1025, 1026, 5, 166, 79, 2, 1026, 1027, 3, 2, 2, 2, 1027, 1028, 8, 118, 18, 2, 1028, 245, 3, 2, 2, 2, 1029, 1030, 5, 50, 21, 2, 1030, 1031, 3, 2, 2, 2, 1031, 1032, 8, 119, 10, 2, 1032, 247, 3, 2, 2, 2, 1033, 1034, 5, 52, 22, 2, 1034, 1035, 3, 2, 2, 2, 1035, 1036, 8, 120, 10, 2, 1036, 249, 3, 2, 2, 2, 1037, 1038, 5, 54, 23, 2, 1038, 1039, 3, 2, 2, 2, 1039, 1040, 8, 121, 10, 2, 1040, 251, 3, 2, 2, 2, 1041, 1042, 5, 66, 29, 2, 1042, 1043, 3, 2, 2, 2, 1043, 1044, 8, 122, 13, 2, 1044, 1045, 8, 122, 14, 2, 1045, 1046, 8, 122, 14, 2, 1046, 253, 3, 2, 2, 2, 1047, 1048, 5, 100, 46, 2, 1048, 1049, 3, 2, 2, 2, 1049, 1050, 8, 123, 17, 2, 1050, 255, 3, 2, 2, 2, 1051, 1052, 5, 102, 47, 2, 1052, 1053, 3, 2, 2, 2, 1053, 1054, 8, 124, 16, 2, 1054, 257, 3, 2, 2, 2, 1055, 1056, 5, 106, 49, 2, 1056, 1057, 3, 2, 2, 2, 1057, 1058, 8, 125, 19, 2, 1058, 259, 3, 2, 2, 2, 1059, 1060, 5, 240, 116, 2, 1060, 1061, 3, 2, 2, 2, 1061, 1062, 8, 126, 23, 2, 1062, 261, 3, 2, 2, 2, 1063, 1064, 5, 206, 99, 2, 1064, 1065, 3, 2, 2, 2, 1065, 1066, 8, 127, 20, 2, 1066, 263, 3, 2, 2, 2, 1067, 1068, 5, 166, 79, 2, 1068, 1069, 3, 2, 2, 2, 1069, 1070, 8, 128, 18, 2, 1070, 265, 3, 2, 2, 2, 1071, 1072, 5, 50, 21, 2, 1072, 1073, 3, 2, 2, 2, 1073, 1074, 8, 129, 10, 2, 1074, 267, 3, 2, 2, 2, 1075, 1076, 5, 52, 22, 2, 1076, 1077, 3, 2, 2, 2, 1077, 1078, 8, 130, 10, 2, 1078, 269, 3, 2, 2, 2, 1079, 1080, 5, 54, 23, 2, 1080, 1081, 3, 2, 2, 2, 1081, 1082, 8, 131, 10, 2, 1082, 271, 3, 2, 2, 2, 1083, 1084, 5, 66, 29, 2, 1084, 1085, 3, 2, 2, 2, 1085, 1086, 8, 132, 13, 2, 1086, 1087, 8, 132, 14, 2, 1087, 273, 3, 2, 2, 2, 1088, 1089, 5, 106, 49, 2, 1089, 1090, 3, 2, 2, 2, 1090, 1091, 8, 133, 19, 2, 1091, 275, 3, 2, 2, 2, 1092, 1093, 5, 166, 79, 2, 1093, 1094, 3, 2, 2, 2, 1094, 1095, 8, 134, 18, 2, 1095, 277, 3, 2, 2, 2, 1096, 1097, 5, 164, 78, 2, 1097, 1098, 3, 2, 2, 2, 1098, 1099, 8, 135, 24, 2, 1099, 279, 3, 2, 2, 2, 1100, 1101, 5, 50, 21, 2, 1101, 1102, 3, 2, 2, 2, 1102, 1103, 8, 136, 10, 2, 1103, 281, 3, 2, 2, 2, 1104, 1105, 5, 52, 22, 2, 1105, 1106, 3, 2, 2, 2, 1106, 1107, 8, 137, 10, 2, 1107, 283, 3, 2, 2, 2, 1108, 1109, 5, 54, 23, 2, 1109, 1110, 3, 2, 2, 2, 1110, 1111, 8, 138, 10, 2, 1111, 285, 3, 2, 2, 2, 1112, 1113, 5, 66, 29, 2, 1113, 1114, 3, 2, 2, 2, 1114, 1115, 8, 139, 13, 2, 1115, 1116, 8, 139, 14, 2, 1116, 287, 3, 2, 2, 2, 1117, 1118, 5, 314, 153, 2, 1118, 1119, 5, 324, 158, 2, 1119, 1120, 5, 308, 150, 2, 1120, 1121, 5, 326, 159, 2, 1121, 289, 3, 2, 2, 2, 1122, 1123, 5, 308, 150, 2, 1123, 1124, 5, 338, 165, 2, 1124, 1125, 5, 324, 158, 2, 1125, 1126, 5, 302, 147, 2, 1126, 1127, 5, 336, 164, 2, 1127, 1128, 5, 314, 153, 2, 1128, 1129, 5, 326, 159, 2, 1129, 1130, 5, 324, 158, 2, 1130, 1131, 5, 334, 163, 2, 1131, 291, 3, 2, 2, 2, 1132, 1133, 5, 50, 21, 2, 1133, 1134, 3, 2, 2, 2, 1134, 1135, 8, 142, 10, 2, 1135, 293, 3, 2, 2, 2, 1136, 1137, 5, 52, 22, 2, 1137, 1138, 3, 2, 2, 2, 1138, 1139, 8, 143, 10, 2, 1139, 295, 3, 2, 2, 2, 1140, 1141, 5, 54, 23, 2, 1141, 1142, 3, 2, 2, 2, 1142, 1143, 8, 144, 10, 2, 1143, 297, 3, 2, 2, 2, 1144, 1145, 9, 14, 2, 2, 1145, 299, 3, 2, 2, 2, 1146, 1147, 9, 15, 2, 2, 1147, 301, 3, 2, 2, 2, 1148, 1149, 9, 16, 2, 2, 1149, 303, 3, 2, 2, 2, 1150, 1151, 9, 17, 2, 2, 1151, 305, 3, 2, 2, 2, 1152, 1153, 9, 9, 2, 2, 1153, 307, 3, 2, 2, 2, 1154, 1155, 9, 18, 2, 2, 1155, 309, 3, 2, 2, 2, 1156, 1157, 9, 19, 2, 2, 1157, 311, 3, 2, 2, 2, 1158, 1159, 9, 20, 2, 2, 1159, 313, 3, 2, 2, 2, 1160, 1161, 9, 21, 2, 2, 1161, 315, 3, 2, 2, 2, 1162, 1163, 9, 22, 2, 2, 1163, 317, 3, 2, 2, 2, 1164, 1165, 9, 23, 2, 2, 1165, 319, 3, 2, 2, 2, 1166, 1167, 9, 24, 2, 2, 1167, 321, 3, 2, 2, 2, 1168, 1169, 9, 25, 2, 2, 1169, 323, 3, 2, 2, 2, 1170, 1171, 9, 26, 2, 2, 1171, 325, 3, 2, 2, 2, 1172, 1173, 9, 27, 2, 2, 1173, 327, 3, 2, 2, 2, 1174, 1175, 9, 28, 2, 2, 1175, 329, 3, 2, 2, 2, 1176, 1177, 9, 29, 2, 2, 1177, 331, 3, 2, 2, 2, 1178, 1179, 9, 30, 2, 2, 1179, 333, 3, 2, 2, 2, 1180, 1181, 9, 31, 2, 2, 1181, 335, 3, 2, 2, 2, 1182, 1183, 9, 32, 2, 2, 1183, 337, 3, 2, 2, 2, 1184, 1185, 9, 33, 2, 2, 1185, 339, 3, 2, 2, 2, 1186, 1187, 9, 34, 2, 2, 1187, 341, 3, 2, 2, 2, 1188, 1189, 9, 35, 2, 2, 1189, 343, 3, 2, 2, 2, 1190, 1191, 9, 36, 2, 2, 1191, 345, 3, 2, 2, 2, 1192, 1193, 9, 37, 2, 2, 1193, 347, 3, 2, 2, 2, 1194, 1195, 9, 38, 2, 2, 1195, 349, 3, 2, 2, 2, 51, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 506, 516, 520, 523, 532, 534, 545, 586, 591, 600, 607, 612, 614, 625, 633, 636, 638, 643, 648, 654, 661, 666, 672, 675, 683, 687, 814, 819, 824, 826, 832, 885, 890, 925, 929, 934, 939, 944, 946, 25, 7, 4, 2, 7, 6, 2, 7, 8, 2, 7, 3, 2, 7, 5, 2, 7, 10, 2, 7, 7, 2, 7, 11, 2, 2, 3, 2, 9, 65, 2, 7, 2, 2, 9, 28, 2, 6, 2, 2, 9, 66, 2, 9, 36, 2, 9, 35, 2, 9, 68, 2, 9, 38, 2, 9, 77, 2, 7, 9, 2, 9, 73, 2, 9, 86, 2, 9, 67, 2] \ No newline at end of file diff --git a/packages/kbn-monaco/src/esql/antlr/esql_lexer.tokens b/packages/kbn-monaco/src/esql/antlr/esql_lexer.tokens index c3160ce1f64725..85a98c3a6d2688 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_lexer.tokens +++ b/packages/kbn-monaco/src/esql/antlr/esql_lexer.tokens @@ -2,92 +2,116 @@ DISSECT=1 DROP=2 ENRICH=3 EVAL=4 -FROM=5 -GROK=6 -KEEP=7 -LIMIT=8 -MV_EXPAND=9 -PROJECT=10 -RENAME=11 -ROW=12 -SHOW=13 -SORT=14 -STATS=15 -WHERE=16 -UNKNOWN_CMD=17 -LINE_COMMENT=18 -MULTILINE_COMMENT=19 -WS=20 -PIPE=21 -STRING=22 -INTEGER_LITERAL=23 -DECIMAL_LITERAL=24 -BY=25 -AND=26 -ASC=27 -ASSIGN=28 -COMMA=29 -DESC=30 -DOT=31 -FALSE=32 -FIRST=33 -LAST=34 -LP=35 -IN=36 -IS=37 -LIKE=38 -NOT=39 -NULL=40 -NULLS=41 -OR=42 -PARAM=43 -RLIKE=44 -RP=45 -TRUE=46 -INFO=47 -FUNCTIONS=48 -UNDERSCORE=49 -EQ=50 -NEQ=51 -LT=52 -LTE=53 -GT=54 -GTE=55 -PLUS=56 -MINUS=57 -ASTERISK=58 -SLASH=59 -PERCENT=60 -OPENING_BRACKET=61 -CLOSING_BRACKET=62 -UNQUOTED_IDENTIFIER=63 -QUOTED_IDENTIFIER=64 -EXPR_LINE_COMMENT=65 -EXPR_MULTILINE_COMMENT=66 -EXPR_WS=67 -AS=68 -METADATA=69 -ON=70 -WITH=71 -SRC_UNQUOTED_IDENTIFIER=72 -SRC_QUOTED_IDENTIFIER=73 -SRC_LINE_COMMENT=74 -SRC_MULTILINE_COMMENT=75 -SRC_WS=76 -'.'=31 -'('=35 -'?'=43 -')'=45 -'_'=49 -'=='=50 -'!='=51 -'<'=52 -'<='=53 -'>'=54 -'>='=55 -'+'=56 -'-'=57 -'*'=58 -'/'=59 -'%'=60 -']'=62 +EXPLAIN=5 +FROM=6 +GROK=7 +INLINESTATS=8 +KEEP=9 +LIMIT=10 +MV_EXPAND=11 +PROJECT=12 +RENAME=13 +ROW=14 +SHOW=15 +SORT=16 +STATS=17 +WHERE=18 +UNKNOWN_CMD=19 +LINE_COMMENT=20 +MULTILINE_COMMENT=21 +WS=22 +EXPLAIN_WS=23 +EXPLAIN_LINE_COMMENT=24 +EXPLAIN_MULTILINE_COMMENT=25 +PIPE=26 +STRING=27 +INTEGER_LITERAL=28 +DECIMAL_LITERAL=29 +BY=30 +AND=31 +ASC=32 +ASSIGN=33 +COMMA=34 +DESC=35 +DOT=36 +FALSE=37 +FIRST=38 +LAST=39 +LP=40 +IN=41 +IS=42 +LIKE=43 +NOT=44 +NULL=45 +NULLS=46 +OR=47 +PARAM=48 +RLIKE=49 +RP=50 +TRUE=51 +EQ=52 +NEQ=53 +LT=54 +LTE=55 +GT=56 +GTE=57 +PLUS=58 +MINUS=59 +ASTERISK=60 +SLASH=61 +PERCENT=62 +OPENING_BRACKET=63 +CLOSING_BRACKET=64 +UNQUOTED_IDENTIFIER=65 +QUOTED_IDENTIFIER=66 +EXPR_LINE_COMMENT=67 +EXPR_MULTILINE_COMMENT=68 +EXPR_WS=69 +METADATA=70 +FROM_UNQUOTED_IDENTIFIER=71 +FROM_LINE_COMMENT=72 +FROM_MULTILINE_COMMENT=73 +FROM_WS=74 +PROJECT_UNQUOTED_IDENTIFIER=75 +PROJECT_LINE_COMMENT=76 +PROJECT_MULTILINE_COMMENT=77 +PROJECT_WS=78 +AS=79 +RENAME_LINE_COMMENT=80 +RENAME_MULTILINE_COMMENT=81 +RENAME_WS=82 +ON=83 +WITH=84 +ENRICH_LINE_COMMENT=85 +ENRICH_MULTILINE_COMMENT=86 +ENRICH_WS=87 +ENRICH_FIELD_LINE_COMMENT=88 +ENRICH_FIELD_MULTILINE_COMMENT=89 +ENRICH_FIELD_WS=90 +MVEXPAND_LINE_COMMENT=91 +MVEXPAND_MULTILINE_COMMENT=92 +MVEXPAND_WS=93 +INFO=94 +FUNCTIONS=95 +SHOW_LINE_COMMENT=96 +SHOW_MULTILINE_COMMENT=97 +SHOW_WS=98 +'|'=26 +'='=33 +','=34 +'.'=36 +'('=40 +'?'=48 +')'=50 +'=='=52 +'!='=53 +'<'=54 +'<='=55 +'>'=56 +'>='=57 +'+'=58 +'-'=59 +'*'=60 +'/'=61 +'%'=62 +']'=64 diff --git a/packages/kbn-monaco/src/esql/antlr/esql_lexer.ts b/packages/kbn-monaco/src/esql/antlr/esql_lexer.ts index 4bbb3eb4968c3d..741ea56ba14084 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_lexer.ts +++ b/packages/kbn-monaco/src/esql/antlr/esql_lexer.ts @@ -21,80 +21,109 @@ export class esql_lexer extends Lexer { public static readonly DROP = 2; public static readonly ENRICH = 3; public static readonly EVAL = 4; - public static readonly FROM = 5; - public static readonly GROK = 6; - public static readonly KEEP = 7; - public static readonly LIMIT = 8; - public static readonly MV_EXPAND = 9; - public static readonly PROJECT = 10; - public static readonly RENAME = 11; - public static readonly ROW = 12; - public static readonly SHOW = 13; - public static readonly SORT = 14; - public static readonly STATS = 15; - public static readonly WHERE = 16; - public static readonly UNKNOWN_CMD = 17; - public static readonly LINE_COMMENT = 18; - public static readonly MULTILINE_COMMENT = 19; - public static readonly WS = 20; - public static readonly PIPE = 21; - public static readonly STRING = 22; - public static readonly INTEGER_LITERAL = 23; - public static readonly DECIMAL_LITERAL = 24; - public static readonly BY = 25; - public static readonly AND = 26; - public static readonly ASC = 27; - public static readonly ASSIGN = 28; - public static readonly COMMA = 29; - public static readonly DESC = 30; - public static readonly DOT = 31; - public static readonly FALSE = 32; - public static readonly FIRST = 33; - public static readonly LAST = 34; - public static readonly LP = 35; - public static readonly IN = 36; - public static readonly IS = 37; - public static readonly LIKE = 38; - public static readonly NOT = 39; - public static readonly NULL = 40; - public static readonly NULLS = 41; - public static readonly OR = 42; - public static readonly PARAM = 43; - public static readonly RLIKE = 44; - public static readonly RP = 45; - public static readonly TRUE = 46; - public static readonly INFO = 47; - public static readonly FUNCTIONS = 48; - public static readonly UNDERSCORE = 49; - public static readonly EQ = 50; - public static readonly NEQ = 51; - public static readonly LT = 52; - public static readonly LTE = 53; - public static readonly GT = 54; - public static readonly GTE = 55; - public static readonly PLUS = 56; - public static readonly MINUS = 57; - public static readonly ASTERISK = 58; - public static readonly SLASH = 59; - public static readonly PERCENT = 60; - public static readonly OPENING_BRACKET = 61; - public static readonly CLOSING_BRACKET = 62; - public static readonly UNQUOTED_IDENTIFIER = 63; - public static readonly QUOTED_IDENTIFIER = 64; - public static readonly EXPR_LINE_COMMENT = 65; - public static readonly EXPR_MULTILINE_COMMENT = 66; - public static readonly EXPR_WS = 67; - public static readonly AS = 68; - public static readonly METADATA = 69; - public static readonly ON = 70; - public static readonly WITH = 71; - public static readonly SRC_UNQUOTED_IDENTIFIER = 72; - public static readonly SRC_QUOTED_IDENTIFIER = 73; - public static readonly SRC_LINE_COMMENT = 74; - public static readonly SRC_MULTILINE_COMMENT = 75; - public static readonly SRC_WS = 76; - public static readonly EXPRESSION = 1; - public static readonly SOURCE_IDENTIFIERS = 2; + public static readonly EXPLAIN = 5; + public static readonly FROM = 6; + public static readonly GROK = 7; + public static readonly INLINESTATS = 8; + public static readonly KEEP = 9; + public static readonly LIMIT = 10; + public static readonly MV_EXPAND = 11; + public static readonly PROJECT = 12; + public static readonly RENAME = 13; + public static readonly ROW = 14; + public static readonly SHOW = 15; + public static readonly SORT = 16; + public static readonly STATS = 17; + public static readonly WHERE = 18; + public static readonly UNKNOWN_CMD = 19; + public static readonly LINE_COMMENT = 20; + public static readonly MULTILINE_COMMENT = 21; + public static readonly WS = 22; + public static readonly EXPLAIN_WS = 23; + public static readonly EXPLAIN_LINE_COMMENT = 24; + public static readonly EXPLAIN_MULTILINE_COMMENT = 25; + public static readonly PIPE = 26; + public static readonly STRING = 27; + public static readonly INTEGER_LITERAL = 28; + public static readonly DECIMAL_LITERAL = 29; + public static readonly BY = 30; + public static readonly AND = 31; + public static readonly ASC = 32; + public static readonly ASSIGN = 33; + public static readonly COMMA = 34; + public static readonly DESC = 35; + public static readonly DOT = 36; + public static readonly FALSE = 37; + public static readonly FIRST = 38; + public static readonly LAST = 39; + public static readonly LP = 40; + public static readonly IN = 41; + public static readonly IS = 42; + public static readonly LIKE = 43; + public static readonly NOT = 44; + public static readonly NULL = 45; + public static readonly NULLS = 46; + public static readonly OR = 47; + public static readonly PARAM = 48; + public static readonly RLIKE = 49; + public static readonly RP = 50; + public static readonly TRUE = 51; + public static readonly EQ = 52; + public static readonly NEQ = 53; + public static readonly LT = 54; + public static readonly LTE = 55; + public static readonly GT = 56; + public static readonly GTE = 57; + public static readonly PLUS = 58; + public static readonly MINUS = 59; + public static readonly ASTERISK = 60; + public static readonly SLASH = 61; + public static readonly PERCENT = 62; + public static readonly OPENING_BRACKET = 63; + public static readonly CLOSING_BRACKET = 64; + public static readonly UNQUOTED_IDENTIFIER = 65; + public static readonly QUOTED_IDENTIFIER = 66; + public static readonly EXPR_LINE_COMMENT = 67; + public static readonly EXPR_MULTILINE_COMMENT = 68; + public static readonly EXPR_WS = 69; + public static readonly METADATA = 70; + public static readonly FROM_UNQUOTED_IDENTIFIER = 71; + public static readonly FROM_LINE_COMMENT = 72; + public static readonly FROM_MULTILINE_COMMENT = 73; + public static readonly FROM_WS = 74; + public static readonly PROJECT_UNQUOTED_IDENTIFIER = 75; + public static readonly PROJECT_LINE_COMMENT = 76; + public static readonly PROJECT_MULTILINE_COMMENT = 77; + public static readonly PROJECT_WS = 78; + public static readonly AS = 79; + public static readonly RENAME_LINE_COMMENT = 80; + public static readonly RENAME_MULTILINE_COMMENT = 81; + public static readonly RENAME_WS = 82; + public static readonly ON = 83; + public static readonly WITH = 84; + public static readonly ENRICH_LINE_COMMENT = 85; + public static readonly ENRICH_MULTILINE_COMMENT = 86; + public static readonly ENRICH_WS = 87; + public static readonly ENRICH_FIELD_LINE_COMMENT = 88; + public static readonly ENRICH_FIELD_MULTILINE_COMMENT = 89; + public static readonly ENRICH_FIELD_WS = 90; + public static readonly MVEXPAND_LINE_COMMENT = 91; + public static readonly MVEXPAND_MULTILINE_COMMENT = 92; + public static readonly MVEXPAND_WS = 93; + public static readonly INFO = 94; + public static readonly FUNCTIONS = 95; + public static readonly SHOW_LINE_COMMENT = 96; + public static readonly SHOW_MULTILINE_COMMENT = 97; + public static readonly SHOW_WS = 98; + public static readonly EXPLAIN_MODE = 1; + public static readonly EXPRESSION_MODE = 2; + public static readonly FROM_MODE = 3; + public static readonly PROJECT_MODE = 4; + public static readonly RENAME_MODE = 5; + public static readonly ENRICH_MODE = 6; + public static readonly ENRICH_FIELD_MODE = 7; + public static readonly MVEXPAND_MODE = 8; + public static readonly SHOW_MODE = 9; // tslint:disable:no-trailing-whitespace public static readonly channelNames: string[] = [ @@ -103,24 +132,40 @@ export class esql_lexer extends Lexer { // tslint:disable:no-trailing-whitespace public static readonly modeNames: string[] = [ - "DEFAULT_MODE", "EXPRESSION", "SOURCE_IDENTIFIERS", + "DEFAULT_MODE", "EXPLAIN_MODE", "EXPRESSION_MODE", "FROM_MODE", "PROJECT_MODE", + "RENAME_MODE", "ENRICH_MODE", "ENRICH_FIELD_MODE", "MVEXPAND_MODE", "SHOW_MODE", ]; public static readonly ruleNames: string[] = [ - "DISSECT", "DROP", "ENRICH", "EVAL", "FROM", "GROK", "KEEP", "LIMIT", - "MV_EXPAND", "PROJECT", "RENAME", "ROW", "SHOW", "SORT", "STATS", "WHERE", - "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", "WS", "PIPE", "DIGIT", - "LETTER", "ESCAPE_SEQUENCE", "UNESCAPED_CHARS", "EXPONENT", "STRING", - "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", "COMMA", - "DESC", "DOT", "FALSE", "FIRST", "LAST", "LP", "IN", "IS", "LIKE", "NOT", - "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", "TRUE", "INFO", "FUNCTIONS", - "UNDERSCORE", "EQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", - "ASTERISK", "SLASH", "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET", + "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK", "INLINESTATS", + "KEEP", "LIMIT", "MV_EXPAND", "PROJECT", "RENAME", "ROW", "SHOW", "SORT", + "STATS", "WHERE", "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", + "WS", "EXPLAIN_OPENING_BRACKET", "EXPLAIN_PIPE", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", + "EXPLAIN_MULTILINE_COMMENT", "PIPE", "DIGIT", "LETTER", "ESCAPE_SEQUENCE", + "UNESCAPED_CHARS", "EXPONENT", "ASPERAND", "BACKQUOTE", "BACKQUOTE_BLOCK", + "UNDERSCORE", "UNQUOTED_ID_BODY", "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", + "BY", "AND", "ASC", "ASSIGN", "COMMA", "DESC", "DOT", "FALSE", "FIRST", + "LAST", "LP", "IN", "IS", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", + "RLIKE", "RP", "TRUE", "EQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", + "MINUS", "ASTERISK", "SLASH", "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", - "EXPR_WS", "SRC_PIPE", "SRC_OPENING_BRACKET", "SRC_CLOSING_BRACKET", "SRC_COMMA", - "SRC_ASSIGN", "AS", "METADATA", "ON", "WITH", "SRC_UNQUOTED_IDENTIFIER", - "SRC_UNQUOTED_IDENTIFIER_PART", "SRC_QUOTED_IDENTIFIER", "SRC_LINE_COMMENT", - "SRC_MULTILINE_COMMENT", "SRC_WS", "A", "B", "C", "D", "E", "F", "G", + "EXPR_WS", "FROM_PIPE", "FROM_OPENING_BRACKET", "FROM_CLOSING_BRACKET", + "FROM_COMMA", "FROM_ASSIGN", "METADATA", "FROM_UNQUOTED_IDENTIFIER_PART", + "FROM_UNQUOTED_IDENTIFIER", "FROM_QUOTED_IDENTIFIER", "FROM_LINE_COMMENT", + "FROM_MULTILINE_COMMENT", "FROM_WS", "PROJECT_PIPE", "PROJECT_DOT", "PROJECT_COMMA", + "UNQUOTED_ID_BODY_WITH_PATTERN", "PROJECT_UNQUOTED_IDENTIFIER", "PROJECT_QUOTED_IDENTIFIER", + "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT", "PROJECT_WS", "RENAME_PIPE", + "RENAME_ASSIGN", "RENAME_COMMA", "RENAME_DOT", "AS", "RENAME_QUOTED_IDENTIFIER", + "RENAME_UNQUOTED_IDENTIFIER", "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", + "RENAME_WS", "ENRICH_PIPE", "ON", "WITH", "ENRICH_POLICY_UNQUOTED_IDENTIFIER", + "ENRICH_QUOTED_IDENTIFIER", "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT", + "ENRICH_WS", "ENRICH_FIELD_PIPE", "ENRICH_FIELD_ASSIGN", "ENRICH_FIELD_COMMA", + "ENRICH_FIELD_DOT", "ENRICH_FIELD_WITH", "ENRICH_FIELD_UNQUOTED_IDENTIFIER", + "ENRICH_FIELD_QUOTED_IDENTIFIER", "ENRICH_FIELD_LINE_COMMENT", "ENRICH_FIELD_MULTILINE_COMMENT", + "ENRICH_FIELD_WS", "MVEXPAND_PIPE", "MVEXPAND_DOT", "MVEXPAND_QUOTED_IDENTIFIER", + "MVEXPAND_UNQUOTED_IDENTIFIER", "MVEXPAND_LINE_COMMENT", "MVEXPAND_MULTILINE_COMMENT", + "MVEXPAND_WS", "SHOW_PIPE", "INFO", "FUNCTIONS", "SHOW_LINE_COMMENT", + "SHOW_MULTILINE_COMMENT", "SHOW_WS", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", ]; @@ -129,26 +174,32 @@ export class esql_lexer extends Lexer { undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, - undefined, undefined, undefined, undefined, undefined, undefined, undefined, - undefined, undefined, undefined, "'.'", undefined, undefined, undefined, - "'('", undefined, undefined, undefined, undefined, undefined, undefined, - undefined, "'?'", undefined, "')'", undefined, undefined, undefined, "'_'", + undefined, undefined, undefined, undefined, undefined, "'|'", undefined, + undefined, undefined, undefined, undefined, undefined, "'='", "','", undefined, + "'.'", undefined, undefined, undefined, "'('", undefined, undefined, undefined, + undefined, undefined, undefined, undefined, "'?'", undefined, "')'", undefined, "'=='", "'!='", "'<'", "'<='", "'>'", "'>='", "'+'", "'-'", "'*'", "'/'", "'%'", undefined, "']'", ]; private static readonly _SYMBOLIC_NAMES: Array = [ - undefined, "DISSECT", "DROP", "ENRICH", "EVAL", "FROM", "GROK", "KEEP", - "LIMIT", "MV_EXPAND", "PROJECT", "RENAME", "ROW", "SHOW", "SORT", "STATS", - "WHERE", "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", "WS", "PIPE", - "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", - "COMMA", "DESC", "DOT", "FALSE", "FIRST", "LAST", "LP", "IN", "IS", "LIKE", - "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", "TRUE", "INFO", - "FUNCTIONS", "UNDERSCORE", "EQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", - "MINUS", "ASTERISK", "SLASH", "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET", - "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", - "EXPR_WS", "AS", "METADATA", "ON", "WITH", "SRC_UNQUOTED_IDENTIFIER", - "SRC_QUOTED_IDENTIFIER", "SRC_LINE_COMMENT", "SRC_MULTILINE_COMMENT", - "SRC_WS", + undefined, "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK", + "INLINESTATS", "KEEP", "LIMIT", "MV_EXPAND", "PROJECT", "RENAME", "ROW", + "SHOW", "SORT", "STATS", "WHERE", "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", + "WS", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", "EXPLAIN_MULTILINE_COMMENT", + "PIPE", "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", "ASC", + "ASSIGN", "COMMA", "DESC", "DOT", "FALSE", "FIRST", "LAST", "LP", "IN", + "IS", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", "TRUE", + "EQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", "SLASH", + "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", + "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", "EXPR_WS", + "METADATA", "FROM_UNQUOTED_IDENTIFIER", "FROM_LINE_COMMENT", "FROM_MULTILINE_COMMENT", + "FROM_WS", "PROJECT_UNQUOTED_IDENTIFIER", "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT", + "PROJECT_WS", "AS", "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", + "RENAME_WS", "ON", "WITH", "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT", + "ENRICH_WS", "ENRICH_FIELD_LINE_COMMENT", "ENRICH_FIELD_MULTILINE_COMMENT", + "ENRICH_FIELD_WS", "MVEXPAND_LINE_COMMENT", "MVEXPAND_MULTILINE_COMMENT", + "MVEXPAND_WS", "INFO", "FUNCTIONS", "SHOW_LINE_COMMENT", "SHOW_MULTILINE_COMMENT", + "SHOW_WS", ]; public static readonly VOCABULARY: Vocabulary = new VocabularyImpl(esql_lexer._LITERAL_NAMES, esql_lexer._SYMBOLIC_NAMES, []); @@ -180,400 +231,599 @@ export class esql_lexer extends Lexer { // @Override public get modeNames(): string[] { return esql_lexer.modeNames; } - private static readonly _serializedATNSegments: number = 2; + private static readonly _serializedATNSegments: number = 3; private static readonly _serializedATNSegment0: string = - "\x03\uC91D\uCABA\u058D\uAFBA\u4F53\u0607\uEA8B\uC241\x02N\u032D\b\x01" + - "\b\x01\b\x01\x04\x02\t\x02\x04\x03\t\x03\x04\x04\t\x04\x04\x05\t\x05\x04" + - "\x06\t\x06\x04\x07\t\x07\x04\b\t\b\x04\t\t\t\x04\n\t\n\x04\v\t\v\x04\f" + - "\t\f\x04\r\t\r\x04\x0E\t\x0E\x04\x0F\t\x0F\x04\x10\t\x10\x04\x11\t\x11" + - "\x04\x12\t\x12\x04\x13\t\x13\x04\x14\t\x14\x04\x15\t\x15\x04\x16\t\x16" + - "\x04\x17\t\x17\x04\x18\t\x18\x04\x19\t\x19\x04\x1A\t\x1A\x04\x1B\t\x1B" + - "\x04\x1C\t\x1C\x04\x1D\t\x1D\x04\x1E\t\x1E\x04\x1F\t\x1F\x04 \t \x04!" + - "\t!\x04\"\t\"\x04#\t#\x04$\t$\x04%\t%\x04&\t&\x04\'\t\'\x04(\t(\x04)\t" + - ")\x04*\t*\x04+\t+\x04,\t,\x04-\t-\x04.\t.\x04/\t/\x040\t0\x041\t1\x04" + - "2\t2\x043\t3\x044\t4\x045\t5\x046\t6\x047\t7\x048\t8\x049\t9\x04:\t:\x04" + - ";\t;\x04<\t<\x04=\t=\x04>\t>\x04?\t?\x04@\t@\x04A\tA\x04B\tB\x04C\tC\x04" + - "D\tD\x04E\tE\x04F\tF\x04G\tG\x04H\tH\x04I\tI\x04J\tJ\x04K\tK\x04L\tL\x04" + - "M\tM\x04N\tN\x04O\tO\x04P\tP\x04Q\tQ\x04R\tR\x04S\tS\x04T\tT\x04U\tU\x04" + - "V\tV\x04W\tW\x04X\tX\x04Y\tY\x04Z\tZ\x04[\t[\x04\\\t\\\x04]\t]\x04^\t" + - "^\x04_\t_\x04`\t`\x04a\ta\x04b\tb\x04c\tc\x04d\td\x04e\te\x04f\tf\x04" + - "g\tg\x04h\th\x04i\ti\x04j\tj\x04k\tk\x04l\tl\x04m\tm\x04n\tn\x04o\to\x04" + - "p\tp\x04q\tq\x04r\tr\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + - "\x02\x03\x02\x03\x02\x03\x02\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03" + - "\x03\x03\x03\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" + - "\x04\x03\x04\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03" + + "\x03\uC91D\uCABA\u058D\uAFBA\u4F53\u0607\uEA8B\uC241\x02d\u04AC\b\x01" + + "\b\x01\b\x01\b\x01\b\x01\b\x01\b\x01\b\x01\b\x01\b\x01\x04\x02\t\x02\x04" + + "\x03\t\x03\x04\x04\t\x04\x04\x05\t\x05\x04\x06\t\x06\x04\x07\t\x07\x04" + + "\b\t\b\x04\t\t\t\x04\n\t\n\x04\v\t\v\x04\f\t\f\x04\r\t\r\x04\x0E\t\x0E" + + "\x04\x0F\t\x0F\x04\x10\t\x10\x04\x11\t\x11\x04\x12\t\x12\x04\x13\t\x13" + + "\x04\x14\t\x14\x04\x15\t\x15\x04\x16\t\x16\x04\x17\t\x17\x04\x18\t\x18" + + "\x04\x19\t\x19\x04\x1A\t\x1A\x04\x1B\t\x1B\x04\x1C\t\x1C\x04\x1D\t\x1D" + + "\x04\x1E\t\x1E\x04\x1F\t\x1F\x04 \t \x04!\t!\x04\"\t\"\x04#\t#\x04$\t" + + "$\x04%\t%\x04&\t&\x04\'\t\'\x04(\t(\x04)\t)\x04*\t*\x04+\t+\x04,\t,\x04" + + "-\t-\x04.\t.\x04/\t/\x040\t0\x041\t1\x042\t2\x043\t3\x044\t4\x045\t5\x04" + + "6\t6\x047\t7\x048\t8\x049\t9\x04:\t:\x04;\t;\x04<\t<\x04=\t=\x04>\t>\x04" + + "?\t?\x04@\t@\x04A\tA\x04B\tB\x04C\tC\x04D\tD\x04E\tE\x04F\tF\x04G\tG\x04" + + "H\tH\x04I\tI\x04J\tJ\x04K\tK\x04L\tL\x04M\tM\x04N\tN\x04O\tO\x04P\tP\x04" + + "Q\tQ\x04R\tR\x04S\tS\x04T\tT\x04U\tU\x04V\tV\x04W\tW\x04X\tX\x04Y\tY\x04" + + "Z\tZ\x04[\t[\x04\\\t\\\x04]\t]\x04^\t^\x04_\t_\x04`\t`\x04a\ta\x04b\t" + + "b\x04c\tc\x04d\td\x04e\te\x04f\tf\x04g\tg\x04h\th\x04i\ti\x04j\tj\x04" + + "k\tk\x04l\tl\x04m\tm\x04n\tn\x04o\to\x04p\tp\x04q\tq\x04r\tr\x04s\ts\x04" + + "t\tt\x04u\tu\x04v\tv\x04w\tw\x04x\tx\x04y\ty\x04z\tz\x04{\t{\x04|\t|\x04" + + "}\t}\x04~\t~\x04\x7F\t\x7F\x04\x80\t\x80\x04\x81\t\x81\x04\x82\t\x82\x04" + + "\x83\t\x83\x04\x84\t\x84\x04\x85\t\x85\x04\x86\t\x86\x04\x87\t\x87\x04" + + "\x88\t\x88\x04\x89\t\x89\x04\x8A\t\x8A\x04\x8B\t\x8B\x04\x8C\t\x8C\x04" + + "\x8D\t\x8D\x04\x8E\t\x8E\x04\x8F\t\x8F\x04\x90\t\x90\x04\x91\t\x91\x04" + + "\x92\t\x92\x04\x93\t\x93\x04\x94\t\x94\x04\x95\t\x95\x04\x96\t\x96\x04" + + "\x97\t\x97\x04\x98\t\x98\x04\x99\t\x99\x04\x9A\t\x9A\x04\x9B\t\x9B\x04" + + "\x9C\t\x9C\x04\x9D\t\x9D\x04\x9E\t\x9E\x04\x9F\t\x9F\x04\xA0\t\xA0\x04" + + "\xA1\t\xA1\x04\xA2\t\xA2\x04\xA3\t\xA3\x04\xA4\t\xA4\x04\xA5\t\xA5\x04" + + "\xA6\t\xA6\x04\xA7\t\xA7\x04\xA8\t\xA8\x04\xA9\t\xA9\x04\xAA\t\xAA\x03" + + "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" + + "\x02\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x04\x03" + + "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x03" + + "\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x06\x03\x06\x03\x06\x03" + "\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x07\x03\x07\x03" + "\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\b\x03\b\x03\b\x03\b\x03\b\x03" + - "\b\x03\b\x03\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03\n\x03\n\x03" + - "\n\x03\n\x03\n\x03\n\x03\n\x03\n\x03\n\x03\n\x03\n\x03\n\x03\v\x03\v\x03" + - "\v\x03\v\x03\v\x03\v\x03\v\x03\v\x03\v\x03\v\x03\f\x03\f\x03\f\x03\f\x03" + - "\f\x03\f\x03\f\x03\f\x03\f\x03\r\x03\r\x03\r\x03\r\x03\r\x03\r\x03\x0E" + - "\x03\x0E\x03\x0E\x03\x0E\x03\x0E\x03\x0E\x03\x0E\x03\x0F\x03\x0F\x03\x0F" + - "\x03\x0F\x03\x0F\x03\x0F\x03\x0F\x03\x10\x03\x10\x03\x10\x03\x10\x03\x10" + - "\x03\x10\x03\x10\x03\x10\x03\x11\x03\x11\x03\x11\x03\x11\x03\x11\x03\x11" + - "\x03\x11\x03\x11\x03\x12\x06\x12\u016A\n\x12\r\x12\x0E\x12\u016B\x03\x12" + - "\x03\x12\x03\x13\x03\x13\x03\x13\x03\x13\x07\x13\u0174\n\x13\f\x13\x0E" + - "\x13\u0177\v\x13\x03\x13\x05\x13\u017A\n\x13\x03\x13\x05\x13\u017D\n\x13" + - "\x03\x13\x03\x13\x03\x14\x03\x14\x03\x14\x03\x14\x03\x14\x07\x14\u0186" + - "\n\x14\f\x14\x0E\x14\u0189\v\x14\x03\x14\x03\x14\x03\x14\x03\x14\x03\x14" + - "\x03\x15\x06\x15\u0191\n\x15\r\x15\x0E\x15\u0192\x03\x15\x03\x15\x03\x16" + - "\x03\x16\x03\x16\x03\x16\x03\x17\x03\x17\x03\x18\x03\x18\x03\x19\x03\x19" + - "\x03\x19\x03\x1A\x03\x1A\x03\x1B\x03\x1B\x05\x1B\u01A6\n\x1B\x03\x1B\x06" + - "\x1B\u01A9\n\x1B\r\x1B\x0E\x1B\u01AA\x03\x1C\x03\x1C\x03\x1C\x07\x1C\u01B0" + - "\n\x1C\f\x1C\x0E\x1C\u01B3\v\x1C\x03\x1C\x03\x1C\x03\x1C\x03\x1C\x03\x1C" + - "\x03\x1C\x07\x1C\u01BB\n\x1C\f\x1C\x0E\x1C\u01BE\v\x1C\x03\x1C\x03\x1C" + - "\x03\x1C\x03\x1C\x03\x1C\x05\x1C\u01C5\n\x1C\x03\x1C\x05\x1C\u01C8\n\x1C" + - "\x05\x1C\u01CA\n\x1C\x03\x1D\x06\x1D\u01CD\n\x1D\r\x1D\x0E\x1D\u01CE\x03" + - "\x1E\x06\x1E\u01D2\n\x1E\r\x1E\x0E\x1E\u01D3\x03\x1E\x03\x1E\x07\x1E\u01D8" + - "\n\x1E\f\x1E\x0E\x1E\u01DB\v\x1E\x03\x1E\x03\x1E\x06\x1E\u01DF\n\x1E\r" + - "\x1E\x0E\x1E\u01E0\x03\x1E\x06\x1E\u01E4\n\x1E\r\x1E\x0E\x1E\u01E5\x03" + - "\x1E\x03\x1E\x07\x1E\u01EA\n\x1E\f\x1E\x0E\x1E\u01ED\v\x1E\x05\x1E\u01EF" + - "\n\x1E\x03\x1E\x03\x1E\x03\x1E\x03\x1E\x06\x1E\u01F5\n\x1E\r\x1E\x0E\x1E" + - "\u01F6\x03\x1E\x03\x1E\x05\x1E\u01FB\n\x1E\x03\x1F\x03\x1F\x03\x1F\x03" + - " \x03 \x03 \x03 \x03!\x03!\x03!\x03!\x03\"\x03\"\x03#\x03#\x03$\x03$\x03" + - "$\x03$\x03$\x03%\x03%\x03&\x03&\x03&\x03&\x03&\x03&\x03\'\x03\'\x03\'" + - "\x03\'\x03\'\x03\'\x03(\x03(\x03(\x03(\x03(\x03)\x03)\x03*\x03*\x03*\x03" + - "+\x03+\x03+\x03,\x03,\x03,\x03,\x03,\x03-\x03-\x03-\x03-\x03.\x03.\x03" + - ".\x03.\x03.\x03/\x03/\x03/\x03/\x03/\x03/\x030\x030\x030\x031\x031\x03" + - "2\x032\x032\x032\x032\x032\x033\x033\x034\x034\x034\x034\x034\x035\x03" + - "5\x035\x035\x035\x036\x036\x036\x036\x036\x036\x036\x036\x036\x036\x03" + - "7\x037\x038\x038\x038\x039\x039\x039\x03:\x03:\x03;\x03;\x03;\x03<\x03" + - "<\x03=\x03=\x03=\x03>\x03>\x03?\x03?\x03@\x03@\x03A\x03A\x03B\x03B\x03" + - "C\x03C\x03C\x03C\x03C\x03D\x03D\x03D\x03D\x03D\x03E\x03E\x03E\x03E\x07" + - "E\u028B\nE\fE\x0EE\u028E\vE\x03E\x03E\x03E\x03E\x06E\u0294\nE\rE\x0EE" + - "\u0295\x05E\u0298\nE\x03F\x03F\x03F\x03F\x07F\u029E\nF\fF\x0EF\u02A1\v" + - "F\x03F\x03F\x03G\x03G\x03G\x03G\x03H\x03H\x03H\x03H\x03I\x03I\x03I\x03" + - "I\x03J\x03J\x03J\x03J\x03J\x03K\x03K\x03K\x03K\x03K\x03K\x03L\x03L\x03" + - "L\x03L\x03L\x03L\x03M\x03M\x03M\x03M\x03N\x03N\x03N\x03N\x03O\x03O\x03" + - "O\x03P\x03P\x03P\x03P\x03P\x03P\x03P\x03P\x03P\x03Q\x03Q\x03Q\x03R\x03" + - "R\x03R\x03R\x03R\x03S\x06S\u02DF\nS\rS\x0ES\u02E0\x03T\x06T\u02E4\nT\r" + - "T\x0ET\u02E5\x03T\x03T\x05T\u02EA\nT\x03U\x03U\x03V\x03V\x03V\x03V\x03" + - "W\x03W\x03W\x03W\x03X\x03X\x03X\x03X\x03Y\x03Y\x03Z\x03Z\x03[\x03[\x03" + - "\\\x03\\\x03]\x03]\x03^\x03^\x03_\x03_\x03`\x03`\x03a\x03a\x03b\x03b\x03" + - "c\x03c\x03d\x03d\x03e\x03e\x03f\x03f\x03g\x03g\x03h\x03h\x03i\x03i\x03" + - "j\x03j\x03k\x03k\x03l\x03l\x03m\x03m\x03n\x03n\x03o\x03o\x03p\x03p\x03" + - "q\x03q\x03r\x03r\x04\u0187\u01BC\x02\x02s\x05\x02\x03\x07\x02\x04\t\x02" + - "\x05\v\x02\x06\r\x02\x07\x0F\x02\b\x11\x02\t\x13\x02\n\x15\x02\v\x17\x02" + - "\f\x19\x02\r\x1B\x02\x0E\x1D\x02\x0F\x1F\x02\x10!\x02\x11#\x02\x12%\x02" + - "\x13\'\x02\x14)\x02\x15+\x02\x16-\x02\x17/\x02\x021\x02\x023\x02\x025" + - "\x02\x027\x02\x029\x02\x18;\x02\x19=\x02\x1A?\x02\x1BA\x02\x1CC\x02\x1D" + - "E\x02\x1EG\x02\x1FI\x02 K\x02!M\x02\"O\x02#Q\x02$S\x02%U\x02&W\x02\'Y" + - "\x02([\x02)]\x02*_\x02+a\x02,c\x02-e\x02.g\x02/i\x020k\x021m\x022o\x02" + - "3q\x024s\x025u\x026w\x027y\x028{\x029}\x02:\x7F\x02;\x81\x02<\x83\x02" + - "=\x85\x02>\x87\x02?\x89\x02@\x8B\x02A\x8D\x02B\x8F\x02C\x91\x02D\x93\x02" + - "E\x95\x02\x02\x97\x02\x02\x99\x02\x02\x9B\x02\x02\x9D\x02\x02\x9F\x02" + - "F\xA1\x02G\xA3\x02H\xA5\x02I\xA7\x02J\xA9\x02\x02\xAB\x02K\xAD\x02L\xAF" + - "\x02M\xB1\x02N\xB3\x02\x02\xB5\x02\x02\xB7\x02\x02\xB9\x02\x02\xBB\x02" + - "\x02\xBD\x02\x02\xBF\x02\x02\xC1\x02\x02\xC3\x02\x02\xC5\x02\x02\xC7\x02" + - "\x02\xC9\x02\x02\xCB\x02\x02\xCD\x02\x02\xCF\x02\x02\xD1\x02\x02\xD3\x02" + - "\x02\xD5\x02\x02\xD7\x02\x02\xD9\x02\x02\xDB\x02\x02\xDD\x02\x02\xDF\x02" + - "\x02\xE1\x02\x02\xE3\x02\x02\xE5\x02\x02\x05\x02\x03\x04(\b\x02\v\f\x0F" + - "\x0F\"\"11]]__\x04\x02\f\f\x0F\x0F\x05\x02\v\f\x0F\x0F\"\"\x03\x022;\x04" + - "\x02C\\c|\x07\x02$$^^ppttvv\x06\x02\f\f\x0F\x0F$$^^\x04\x02GGgg\x04\x02" + - "--//\x04\x02BBaa\x03\x02bb\f\x02\v\f\x0F\x0F\"\"..11??]]__bb~~\x04\x02" + - ",,11\x04\x02CCcc\x04\x02DDdd\x04\x02EEee\x04\x02FFff\x04\x02HHhh\x04\x02" + - "IIii\x04\x02JJjj\x04\x02KKkk\x04\x02LLll\x04\x02MMmm\x04\x02NNnn\x04\x02" + - "OOoo\x04\x02PPpp\x04\x02QQqq\x04\x02RRrr\x04\x02SSss\x04\x02TTtt\x04\x02" + - "UUuu\x04\x02VVvv\x04\x02WWww\x04\x02XXxx\x04\x02YYyy\x04\x02ZZzz\x04\x02" + - "[[{{\x04\x02\\\\||\x02\u0330\x02\x05\x03\x02\x02\x02\x02\x07\x03\x02\x02" + - "\x02\x02\t\x03\x02\x02\x02\x02\v\x03\x02\x02\x02\x02\r\x03\x02\x02\x02" + - "\x02\x0F\x03\x02\x02\x02\x02\x11\x03\x02\x02\x02\x02\x13\x03\x02\x02\x02" + - "\x02\x15\x03\x02\x02\x02\x02\x17\x03\x02\x02\x02\x02\x19\x03\x02\x02\x02" + - "\x02\x1B\x03\x02\x02\x02\x02\x1D\x03\x02\x02\x02\x02\x1F\x03\x02\x02\x02" + - "\x02!\x03\x02\x02\x02\x02#\x03\x02\x02\x02\x02%\x03\x02\x02\x02\x02\'" + - "\x03\x02\x02\x02\x02)\x03\x02\x02\x02\x02+\x03\x02\x02\x02\x03-\x03\x02" + - "\x02\x02\x039\x03\x02\x02\x02\x03;\x03\x02\x02\x02\x03=\x03\x02\x02\x02" + - "\x03?\x03\x02\x02\x02\x03A\x03\x02\x02\x02\x03C\x03\x02\x02\x02\x03E\x03" + - "\x02\x02\x02\x03G\x03\x02\x02\x02\x03I\x03\x02\x02\x02\x03K\x03\x02\x02" + - "\x02\x03M\x03\x02\x02\x02\x03O\x03\x02\x02\x02\x03Q\x03\x02\x02\x02\x03" + - "S\x03\x02\x02\x02\x03U\x03\x02\x02\x02\x03W\x03\x02\x02\x02\x03Y\x03\x02" + - "\x02\x02\x03[\x03\x02\x02\x02\x03]\x03\x02\x02\x02\x03_\x03\x02\x02\x02" + - "\x03a\x03\x02\x02\x02\x03c\x03\x02\x02\x02\x03e\x03\x02\x02\x02\x03g\x03" + - "\x02\x02\x02\x03i\x03\x02\x02\x02\x03k\x03\x02\x02\x02\x03m\x03\x02\x02" + - "\x02\x03o\x03\x02\x02\x02\x03q\x03\x02\x02\x02\x03s\x03\x02\x02\x02\x03" + - "u\x03\x02\x02\x02\x03w\x03\x02\x02\x02\x03y\x03\x02\x02\x02\x03{\x03\x02" + - "\x02\x02\x03}\x03\x02\x02\x02\x03\x7F\x03\x02\x02\x02\x03\x81\x03\x02" + - "\x02\x02\x03\x83\x03\x02\x02\x02\x03\x85\x03\x02\x02\x02\x03\x87\x03\x02" + - "\x02\x02\x03\x89\x03\x02\x02\x02\x03\x8B\x03\x02\x02\x02\x03\x8D\x03\x02" + - "\x02\x02\x03\x8F\x03\x02\x02\x02\x03\x91\x03\x02\x02\x02\x03\x93\x03\x02" + - "\x02\x02\x04\x95\x03\x02\x02\x02\x04\x97\x03\x02\x02\x02\x04\x99\x03\x02" + - "\x02\x02\x04\x9B\x03\x02\x02\x02\x04\x9D\x03\x02\x02\x02\x04\x9F\x03\x02" + - "\x02\x02\x04\xA1\x03\x02\x02\x02\x04\xA3\x03\x02\x02\x02\x04\xA5\x03\x02" + - "\x02\x02\x04\xA7\x03\x02\x02\x02\x04\xAB\x03\x02\x02\x02\x04\xAD\x03\x02" + - "\x02\x02\x04\xAF\x03\x02\x02\x02\x04\xB1\x03\x02\x02\x02\x05\xE7\x03\x02" + - "\x02\x02\x07\xF1\x03\x02\x02\x02\t\xF8\x03\x02\x02\x02\v\u0101\x03\x02" + - "\x02\x02\r\u0108\x03\x02\x02\x02\x0F\u010F\x03\x02\x02\x02\x11\u0116\x03" + - "\x02\x02\x02\x13\u011D\x03\x02\x02\x02\x15\u0125\x03\x02\x02\x02\x17\u0131" + - "\x03\x02\x02\x02\x19\u013B\x03\x02\x02\x02\x1B\u0144\x03\x02\x02\x02\x1D" + - "\u014A\x03\x02\x02\x02\x1F\u0151\x03\x02\x02\x02!\u0158\x03\x02\x02\x02" + - "#\u0160\x03\x02\x02\x02%\u0169\x03\x02\x02\x02\'\u016F\x03\x02\x02\x02" + - ")\u0180\x03\x02\x02\x02+\u0190\x03\x02\x02\x02-\u0196\x03\x02\x02\x02" + - "/\u019A\x03\x02\x02\x021\u019C\x03\x02\x02\x023\u019E\x03\x02\x02\x02" + - "5\u01A1\x03\x02\x02\x027\u01A3\x03\x02\x02\x029\u01C9\x03\x02\x02\x02" + - ";\u01CC\x03\x02\x02\x02=\u01FA\x03\x02\x02\x02?\u01FC\x03\x02\x02\x02" + - "A\u01FF\x03\x02\x02\x02C\u0203\x03\x02\x02\x02E\u0207\x03\x02\x02\x02" + - "G\u0209\x03\x02\x02\x02I\u020B\x03\x02\x02\x02K\u0210\x03\x02\x02\x02" + - "M\u0212\x03\x02\x02\x02O\u0218\x03\x02\x02\x02Q\u021E\x03\x02\x02\x02" + - "S\u0223\x03\x02\x02\x02U\u0225\x03\x02\x02\x02W\u0228\x03\x02\x02\x02" + - "Y\u022B\x03\x02\x02\x02[\u0230\x03\x02\x02\x02]\u0234\x03\x02\x02\x02" + - "_\u0239\x03\x02\x02\x02a\u023F\x03\x02\x02\x02c\u0242\x03\x02\x02\x02" + - "e\u0244\x03\x02\x02\x02g\u024A\x03\x02\x02\x02i\u024C\x03\x02\x02\x02" + - "k\u0251\x03\x02\x02\x02m\u0256\x03\x02\x02\x02o\u0260\x03\x02\x02\x02" + - "q\u0262\x03\x02\x02\x02s\u0265\x03\x02\x02\x02u\u0268\x03\x02\x02\x02" + - "w\u026A\x03\x02\x02\x02y\u026D\x03\x02\x02\x02{\u026F\x03\x02\x02\x02" + - "}\u0272\x03\x02\x02\x02\x7F\u0274\x03\x02\x02\x02\x81\u0276\x03\x02\x02" + - "\x02\x83\u0278\x03\x02\x02\x02\x85\u027A\x03\x02\x02\x02\x87\u027C\x03" + - "\x02\x02\x02\x89\u0281\x03\x02\x02\x02\x8B\u0297\x03\x02\x02\x02\x8D\u0299" + - "\x03\x02\x02\x02\x8F\u02A4\x03\x02\x02\x02\x91\u02A8\x03\x02\x02\x02\x93" + - "\u02AC\x03\x02\x02\x02\x95\u02B0\x03\x02\x02\x02\x97\u02B5\x03\x02\x02" + - "\x02\x99\u02BB\x03\x02\x02\x02\x9B\u02C1\x03\x02\x02\x02\x9D\u02C5\x03" + - "\x02\x02\x02\x9F\u02C9\x03\x02\x02\x02\xA1\u02CC\x03\x02\x02\x02\xA3\u02D5" + - "\x03\x02\x02\x02\xA5\u02D8\x03\x02\x02\x02\xA7\u02DE\x03\x02\x02\x02\xA9" + - "\u02E9\x03\x02\x02\x02\xAB\u02EB\x03\x02\x02\x02\xAD\u02ED\x03\x02\x02" + - "\x02\xAF\u02F1\x03\x02\x02\x02\xB1\u02F5\x03\x02\x02\x02\xB3\u02F9\x03" + - "\x02\x02\x02\xB5\u02FB\x03\x02\x02\x02\xB7\u02FD\x03\x02\x02\x02\xB9\u02FF" + - "\x03\x02\x02\x02\xBB\u0301\x03\x02\x02\x02\xBD\u0303\x03\x02\x02\x02\xBF" + - "\u0305\x03\x02\x02\x02\xC1\u0307\x03\x02\x02\x02\xC3\u0309\x03\x02\x02" + - "\x02\xC5\u030B\x03\x02\x02\x02\xC7\u030D\x03\x02\x02\x02\xC9\u030F\x03" + - "\x02\x02\x02\xCB\u0311\x03\x02\x02\x02\xCD\u0313\x03\x02\x02\x02\xCF\u0315" + - "\x03\x02\x02\x02\xD1\u0317\x03\x02\x02\x02\xD3\u0319\x03\x02\x02\x02\xD5" + - "\u031B\x03\x02\x02\x02\xD7\u031D\x03\x02\x02\x02\xD9\u031F\x03\x02\x02" + - "\x02\xDB\u0321\x03\x02\x02\x02\xDD\u0323\x03\x02\x02\x02\xDF\u0325\x03" + - "\x02\x02\x02\xE1\u0327\x03\x02\x02\x02\xE3\u0329\x03\x02\x02\x02\xE5\u032B" + - "\x03\x02\x02\x02\xE7\xE8\x05\xB9\\\x02\xE8\xE9\x05\xC3a\x02\xE9\xEA\x05" + - "\xD7k\x02\xEA\xEB\x05\xD7k\x02\xEB\xEC\x05\xBB]\x02\xEC\xED\x05\xB7[\x02" + - "\xED\xEE\x05\xD9l\x02\xEE\xEF\x03\x02\x02\x02\xEF\xF0\b\x02\x02\x02\xF0" + - "\x06\x03\x02\x02\x02\xF1\xF2\x05\xB9\\\x02\xF2\xF3\x05\xD5j\x02\xF3\xF4" + - "\x05\xCFg\x02\xF4\xF5\x05\xD1h\x02\xF5\xF6\x03\x02\x02\x02\xF6\xF7\b\x03" + - "\x03\x02\xF7\b\x03\x02\x02\x02\xF8\xF9\x05\xBB]\x02\xF9\xFA\x05\xCDf\x02" + - "\xFA\xFB\x05\xD5j\x02\xFB\xFC\x05\xC3a\x02\xFC\xFD\x05\xB7[\x02\xFD\xFE" + - "\x05\xC1`\x02\xFE\xFF\x03\x02\x02\x02\xFF\u0100\b\x04\x03\x02\u0100\n" + - "\x03\x02\x02\x02\u0101\u0102\x05\xBB]\x02\u0102\u0103\x05\xDDn\x02\u0103" + - "\u0104\x05\xB3Y\x02\u0104\u0105\x05\xC9d\x02\u0105\u0106\x03\x02\x02\x02" + - "\u0106\u0107\b\x05\x02\x02\u0107\f\x03\x02\x02\x02\u0108\u0109\x05\xBD" + - "^\x02\u0109\u010A\x05\xD5j\x02\u010A\u010B\x05\xCFg\x02\u010B\u010C\x05" + - "\xCBe\x02\u010C\u010D\x03\x02\x02\x02\u010D\u010E\b\x06\x03\x02\u010E" + - "\x0E\x03\x02\x02\x02\u010F\u0110\x05\xBF_\x02\u0110\u0111\x05\xD5j\x02" + - "\u0111\u0112\x05\xCFg\x02\u0112\u0113\x05\xC7c\x02\u0113\u0114\x03\x02" + - "\x02\x02\u0114\u0115\b\x07\x02\x02\u0115\x10\x03\x02\x02\x02\u0116\u0117" + - "\x05\xC7c\x02\u0117\u0118\x05\xBB]\x02\u0118\u0119\x05\xBB]\x02\u0119" + - "\u011A\x05\xD1h\x02\u011A\u011B\x03\x02\x02\x02\u011B\u011C\b\b\x03\x02" + - "\u011C\x12\x03\x02\x02\x02\u011D\u011E\x05\xC9d\x02\u011E\u011F\x05\xC3" + - "a\x02\u011F\u0120\x05\xCBe\x02\u0120\u0121\x05\xC3a\x02\u0121\u0122\x05" + - "\xD9l\x02\u0122\u0123\x03\x02\x02\x02\u0123\u0124\b\t\x02\x02\u0124\x14" + - "\x03\x02\x02\x02\u0125\u0126\x05\xCBe\x02\u0126\u0127\x05\xDDn\x02\u0127" + - "\u0128\x05o7\x02\u0128\u0129\x05\xBB]\x02\u0129\u012A\x05\xE1p\x02\u012A" + - "\u012B\x05\xD1h\x02\u012B\u012C\x05\xB3Y\x02\u012C\u012D\x05\xCDf\x02" + - "\u012D\u012E\x05\xB9\\\x02\u012E\u012F\x03\x02\x02\x02\u012F\u0130\b\n" + - "\x03\x02\u0130\x16\x03\x02\x02\x02\u0131\u0132\x05\xD1h\x02\u0132\u0133" + - "\x05\xD5j\x02\u0133\u0134\x05\xCFg\x02\u0134\u0135\x05\xC5b\x02\u0135" + - "\u0136\x05\xBB]\x02\u0136\u0137\x05\xB7[\x02\u0137\u0138\x05\xD9l\x02" + - "\u0138\u0139\x03\x02\x02\x02\u0139\u013A\b\v\x03\x02\u013A\x18\x03\x02" + - "\x02\x02\u013B\u013C\x05\xD5j\x02\u013C\u013D\x05\xBB]\x02\u013D\u013E" + - "\x05\xCDf\x02\u013E\u013F\x05\xB3Y\x02\u013F\u0140\x05\xCBe\x02\u0140" + - "\u0141\x05\xBB]\x02\u0141\u0142\x03\x02\x02\x02\u0142\u0143\b\f\x03\x02" + - "\u0143\x1A\x03\x02\x02\x02\u0144\u0145\x05\xD5j\x02\u0145\u0146\x05\xCF" + - "g\x02\u0146\u0147\x05\xDFo\x02\u0147\u0148\x03\x02\x02\x02\u0148\u0149" + - "\b\r\x02\x02\u0149\x1C\x03\x02\x02\x02\u014A\u014B\x05\xD7k\x02\u014B" + - "\u014C\x05\xC1`\x02\u014C\u014D\x05\xCFg\x02\u014D\u014E\x05\xDFo\x02" + - "\u014E\u014F\x03\x02\x02\x02\u014F\u0150\b\x0E\x02\x02\u0150\x1E\x03\x02" + - "\x02\x02\u0151\u0152\x05\xD7k\x02\u0152\u0153\x05\xCFg\x02\u0153\u0154" + - "\x05\xD5j\x02\u0154\u0155\x05\xD9l\x02\u0155\u0156\x03\x02\x02\x02\u0156" + - "\u0157\b\x0F\x02\x02\u0157 \x03\x02\x02\x02\u0158\u0159\x05\xD7k\x02\u0159" + - "\u015A\x05\xD9l\x02\u015A\u015B\x05\xB3Y\x02\u015B\u015C\x05\xD9l\x02" + - "\u015C\u015D\x05\xD7k\x02\u015D\u015E\x03\x02\x02\x02\u015E\u015F\b\x10" + - "\x02\x02\u015F\"\x03\x02\x02\x02\u0160\u0161\x05\xDFo\x02\u0161\u0162" + - "\x05\xC1`\x02\u0162\u0163\x05\xBB]\x02\u0163\u0164\x05\xD5j\x02\u0164" + - "\u0165\x05\xBB]\x02\u0165\u0166\x03\x02\x02\x02\u0166\u0167\b\x11\x02" + - "\x02\u0167$\x03\x02\x02\x02\u0168\u016A\n\x02\x02\x02\u0169\u0168\x03" + - "\x02\x02\x02\u016A\u016B\x03\x02\x02\x02\u016B\u0169\x03\x02\x02\x02\u016B" + - "\u016C\x03\x02\x02\x02\u016C\u016D\x03\x02\x02\x02\u016D\u016E\b\x12\x02" + - "\x02\u016E&\x03\x02\x02\x02\u016F\u0170\x071\x02\x02\u0170\u0171\x071" + - "\x02\x02\u0171\u0175\x03\x02\x02\x02\u0172\u0174\n\x03\x02\x02\u0173\u0172" + - "\x03\x02\x02\x02\u0174\u0177\x03\x02\x02\x02\u0175\u0173\x03\x02\x02\x02" + - "\u0175\u0176\x03\x02\x02\x02\u0176\u0179\x03\x02\x02\x02\u0177\u0175\x03" + - "\x02\x02\x02\u0178\u017A\x07\x0F\x02\x02\u0179\u0178\x03\x02\x02\x02\u0179" + - "\u017A\x03\x02\x02\x02\u017A\u017C\x03\x02\x02\x02\u017B\u017D\x07\f\x02" + - "\x02\u017C\u017B\x03\x02\x02\x02\u017C\u017D\x03\x02\x02\x02\u017D\u017E" + - "\x03\x02\x02\x02\u017E\u017F\b\x13\x04\x02\u017F(\x03\x02\x02\x02\u0180" + - "\u0181\x071\x02\x02\u0181\u0182\x07,\x02\x02\u0182\u0187\x03\x02\x02\x02" + - "\u0183\u0186\x05)\x14\x02\u0184\u0186\v\x02\x02\x02\u0185\u0183\x03\x02" + - "\x02\x02\u0185\u0184\x03\x02\x02\x02\u0186\u0189\x03\x02\x02\x02\u0187" + - "\u0188\x03\x02\x02\x02\u0187\u0185\x03\x02\x02\x02\u0188\u018A\x03\x02" + - "\x02\x02\u0189\u0187\x03\x02\x02\x02\u018A\u018B\x07,\x02\x02\u018B\u018C" + - "\x071\x02\x02\u018C\u018D\x03\x02\x02\x02\u018D\u018E\b\x14\x04\x02\u018E" + - "*\x03\x02\x02\x02\u018F\u0191\t\x04\x02\x02\u0190\u018F\x03\x02\x02\x02" + - "\u0191\u0192\x03\x02\x02\x02\u0192\u0190\x03\x02\x02\x02\u0192\u0193\x03" + - "\x02\x02\x02\u0193\u0194\x03\x02\x02\x02\u0194\u0195\b\x15\x04\x02\u0195" + - ",\x03\x02\x02\x02\u0196\u0197\x07~\x02\x02\u0197\u0198\x03\x02\x02\x02" + - "\u0198\u0199\b\x16\x05\x02\u0199.\x03\x02\x02\x02\u019A\u019B\t\x05\x02" + - "\x02\u019B0\x03\x02\x02\x02\u019C\u019D\t\x06\x02\x02\u019D2\x03\x02\x02" + - "\x02\u019E\u019F\x07^\x02\x02\u019F\u01A0\t\x07\x02\x02\u01A04\x03\x02" + - "\x02\x02\u01A1\u01A2\n\b\x02\x02\u01A26\x03\x02\x02\x02\u01A3\u01A5\t" + - "\t\x02\x02\u01A4\u01A6\t\n\x02\x02\u01A5\u01A4\x03\x02\x02\x02\u01A5\u01A6" + - "\x03\x02\x02\x02\u01A6\u01A8\x03\x02\x02\x02\u01A7\u01A9\x05/\x17\x02" + - "\u01A8\u01A7\x03\x02\x02\x02\u01A9\u01AA\x03\x02\x02\x02\u01AA\u01A8\x03" + - "\x02\x02\x02\u01AA\u01AB\x03\x02\x02\x02\u01AB8\x03\x02\x02\x02\u01AC" + - "\u01B1\x07$\x02\x02\u01AD\u01B0\x053\x19\x02\u01AE\u01B0\x055\x1A\x02" + - "\u01AF\u01AD\x03\x02\x02\x02\u01AF\u01AE\x03\x02\x02\x02\u01B0\u01B3\x03" + - "\x02\x02\x02\u01B1\u01AF\x03\x02\x02\x02\u01B1\u01B2\x03\x02\x02\x02\u01B2" + - "\u01B4\x03\x02\x02\x02\u01B3\u01B1\x03\x02\x02\x02\u01B4\u01CA\x07$\x02" + - "\x02\u01B5\u01B6\x07$\x02\x02\u01B6\u01B7\x07$\x02\x02\u01B7\u01B8\x07" + - "$\x02\x02\u01B8\u01BC\x03\x02\x02\x02\u01B9\u01BB\n\x03\x02\x02\u01BA" + - "\u01B9\x03\x02\x02\x02\u01BB\u01BE\x03\x02\x02\x02\u01BC\u01BD\x03\x02" + - "\x02\x02\u01BC\u01BA\x03\x02\x02\x02\u01BD\u01BF\x03\x02\x02\x02\u01BE" + - "\u01BC\x03\x02\x02\x02\u01BF\u01C0\x07$\x02\x02\u01C0\u01C1\x07$\x02\x02" + - "\u01C1\u01C2\x07$\x02\x02\u01C2\u01C4\x03\x02\x02\x02\u01C3\u01C5\x07" + - "$\x02\x02\u01C4\u01C3\x03\x02\x02\x02\u01C4\u01C5\x03\x02\x02\x02\u01C5" + - "\u01C7\x03\x02\x02\x02\u01C6\u01C8\x07$\x02\x02\u01C7\u01C6\x03\x02\x02" + - "\x02\u01C7\u01C8\x03\x02\x02\x02\u01C8\u01CA\x03\x02\x02\x02\u01C9\u01AC" + - "\x03\x02\x02\x02\u01C9\u01B5\x03\x02\x02\x02\u01CA:\x03\x02\x02\x02\u01CB" + - "\u01CD\x05/\x17\x02\u01CC\u01CB\x03\x02\x02\x02\u01CD\u01CE\x03\x02\x02" + - "\x02\u01CE\u01CC\x03\x02\x02\x02\u01CE\u01CF\x03\x02\x02\x02\u01CF<\x03" + - "\x02\x02\x02\u01D0\u01D2\x05/\x17\x02\u01D1\u01D0\x03\x02\x02\x02\u01D2" + - "\u01D3\x03\x02\x02\x02\u01D3\u01D1\x03\x02\x02\x02\u01D3\u01D4\x03\x02" + - "\x02\x02\u01D4\u01D5\x03\x02\x02\x02\u01D5\u01D9\x05K%\x02\u01D6\u01D8" + - "\x05/\x17\x02"; + "\b\x03\b\x03\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03\t\x03" + + "\t\x03\t\x03\t\x03\t\x03\n\x03\n\x03\n\x03\n\x03\n\x03\n\x03\n\x03\v\x03" + + "\v\x03\v\x03\v\x03\v\x03\v\x03\v\x03\v\x03\f\x03\f\x03\f\x03\f\x03\f\x03" + + "\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x03\r\x03\r\x03\r\x03\r\x03\r\x03" + + "\r\x03\r\x03\r\x03\r\x03\r\x03\x0E\x03\x0E\x03\x0E\x03\x0E\x03\x0E\x03" + + "\x0E\x03\x0E\x03\x0E\x03\x0E\x03\x0F\x03\x0F\x03\x0F\x03\x0F\x03\x0F\x03" + + "\x0F\x03\x10\x03\x10\x03\x10\x03\x10\x03\x10\x03\x10\x03\x10\x03\x11\x03" + + "\x11\x03\x11\x03\x11\x03\x11\x03\x11\x03\x11\x03\x12\x03\x12\x03\x12\x03" + + "\x12\x03\x12\x03\x12\x03\x12\x03\x12\x03\x13\x03\x13\x03\x13\x03\x13\x03" + + "\x13\x03\x13\x03\x13\x03\x13\x03\x14\x06\x14\u01F9\n\x14\r\x14\x0E\x14" + + "\u01FA\x03\x14\x03\x14\x03\x15\x03\x15\x03\x15\x03\x15\x07\x15\u0203\n" + + "\x15\f\x15\x0E\x15\u0206\v\x15\x03\x15\x05\x15\u0209\n\x15\x03\x15\x05" + + "\x15\u020C\n\x15\x03\x15\x03\x15\x03\x16\x03\x16\x03\x16\x03\x16\x03\x16" + + "\x07\x16\u0215\n\x16\f\x16\x0E\x16\u0218\v\x16\x03\x16\x03\x16\x03\x16" + + "\x03\x16\x03\x16\x03\x17\x06\x17\u0220\n\x17\r\x17\x0E\x17\u0221\x03\x17" + + "\x03\x17\x03\x18\x03\x18\x03\x18\x03\x18\x03\x18\x03\x19\x03\x19\x03\x19" + + "\x03\x19\x03\x19\x03\x1A\x03\x1A\x03\x1A\x03\x1A\x03\x1B\x03\x1B\x03\x1B" + + "\x03\x1B\x03\x1C\x03\x1C\x03\x1C\x03\x1C\x03\x1D\x03\x1D\x03\x1D\x03\x1D" + + "\x03\x1E\x03\x1E\x03\x1F\x03\x1F\x03 \x03 \x03 \x03!\x03!\x03\"\x03\"" + + "\x05\"\u024B\n\"\x03\"\x06\"\u024E\n\"\r\"\x0E\"\u024F\x03#\x03#\x03$" + + "\x03$\x03%\x03%\x03%\x05%\u0259\n%\x03&\x03&\x03\'\x03\'\x03\'\x05\'\u0260" + + "\n\'\x03(\x03(\x03(\x07(\u0265\n(\f(\x0E(\u0268\v(\x03(\x03(\x03(\x03" + + "(\x03(\x03(\x07(\u0270\n(\f(\x0E(\u0273\v(\x03(\x03(\x03(\x03(\x03(\x05" + + "(\u027A\n(\x03(\x05(\u027D\n(\x05(\u027F\n(\x03)\x06)\u0282\n)\r)\x0E" + + ")\u0283\x03*\x06*\u0287\n*\r*\x0E*\u0288\x03*\x03*\x07*\u028D\n*\f*\x0E" + + "*\u0290\v*\x03*\x03*\x06*\u0294\n*\r*\x0E*\u0295\x03*\x06*\u0299\n*\r" + + "*\x0E*\u029A\x03*\x03*\x07*\u029F\n*\f*\x0E*\u02A2\v*\x05*\u02A4\n*\x03" + + "*\x03*\x03*\x03*\x06*\u02AA\n*\r*\x0E*\u02AB\x03*\x03*\x05*\u02B0\n*\x03" + + "+\x03+\x03+\x03,\x03,\x03,\x03,\x03-\x03-\x03-\x03-\x03.\x03.\x03/\x03" + + "/\x030\x030\x030\x030\x030\x031\x031\x032\x032\x032\x032\x032\x032\x03" + + "3\x033\x033\x033\x033\x033\x034\x034\x034\x034\x034\x035\x035\x036\x03" + + "6\x036\x037\x037\x037\x038\x038\x038\x038\x038\x039\x039\x039\x039\x03" + + ":\x03:\x03:\x03:\x03:\x03;\x03;\x03;\x03;\x03;\x03;\x03<\x03<\x03<\x03" + + "=\x03=\x03>\x03>\x03>\x03>\x03>\x03>\x03?\x03?\x03@\x03@\x03@\x03@\x03" + + "@\x03A\x03A\x03A\x03B\x03B\x03B\x03C\x03C\x03D\x03D\x03D\x03E\x03E\x03" + + "F\x03F\x03F\x03G\x03G\x03H\x03H\x03I\x03I\x03J\x03J\x03K\x03K\x03L\x03" + + "L\x03L\x03L\x03L\x03M\x03M\x03M\x03M\x03M\x03N\x03N\x07N\u032D\nN\fN\x0E" + + "N\u0330\vN\x03N\x03N\x05N\u0334\nN\x03N\x06N\u0337\nN\rN\x0EN\u0338\x05" + + "N\u033B\nN\x03O\x03O\x06O\u033F\nO\rO\x0EO\u0340\x03O\x03O\x03P\x03P\x03" + + "P\x03P\x03Q\x03Q\x03Q\x03Q\x03R\x03R\x03R\x03R\x03S\x03S\x03S\x03S\x03" + + "S\x03T\x03T\x03T\x03T\x03T\x03T\x03U\x03U\x03U\x03U\x03U\x03U\x03V\x03" + + "V\x03V\x03V\x03W\x03W\x03W\x03W\x03X\x03X\x03X\x03X\x03X\x03X\x03X\x03" + + "X\x03X\x03Y\x03Y\x03Y\x05Y\u0376\nY\x03Z\x06Z\u0379\nZ\rZ\x0EZ\u037A\x03" + + "[\x03[\x03[\x03[\x03\\\x03\\\x03\\\x03\\\x03]\x03]\x03]\x03]\x03^\x03" + + "^\x03^\x03^\x03_\x03_\x03_\x03_\x03_\x03`\x03`\x03`\x03`\x03a\x03a\x03" + + "a\x03a\x03b\x03b\x03b\x03b\x05b\u039E\nb\x03c\x03c\x05c\u03A2\nc\x03c" + + "\x07c\u03A5\nc\fc\x0Ec\u03A8\vc\x03c\x03c\x05c\u03AC\nc\x03c\x06c\u03AF" + + "\nc\rc\x0Ec\u03B0\x05c\u03B3\nc\x03d\x03d\x03d\x03d\x03e\x03e\x03e\x03" + + "e\x03f\x03f\x03f\x03f\x03g\x03g\x03g\x03g\x03h\x03h\x03h\x03h\x03h\x03" + + "i\x03i\x03i\x03i\x03j\x03j\x03j\x03j\x03k\x03k\x03k\x03k\x03l\x03l\x03" + + "l\x03m\x03m\x03m\x03m\x03n\x03n\x03n\x03n\x03o\x03o\x03o\x03o\x03p\x03" + + "p\x03p\x03p\x03q\x03q\x03q\x03q\x03r\x03r\x03r\x03r\x03r\x03s\x03s\x03" + + "s\x03s\x03s\x03t\x03t\x03t\x03t\x03t\x03t\x03t\x03u\x03u\x03u\x03u\x03" + + "v\x03v\x03v\x03v\x03w\x03w\x03w\x03w\x03x\x03x\x03x\x03x\x03y\x03y\x03" + + "y\x03y\x03z\x03z\x03z\x03z\x03z\x03z\x03{\x03{\x03{\x03{\x03|\x03|\x03" + + "|\x03|\x03}\x03}\x03}\x03}\x03~\x03~\x03~\x03~\x03\x7F\x03\x7F\x03\x7F" + + "\x03\x7F\x03\x80\x03\x80\x03\x80\x03\x80\x03\x81\x03\x81\x03\x81\x03\x81" + + "\x03\x82\x03\x82\x03\x82\x03\x82\x03\x83\x03\x83\x03\x83\x03\x83\x03\x84" + + "\x03\x84\x03\x84\x03\x84\x03\x84\x03\x85\x03\x85\x03\x85\x03\x85\x03\x86" + + "\x03\x86\x03\x86\x03\x86\x03\x87\x03\x87\x03\x87\x03\x87\x03\x88\x03\x88" + + "\x03\x88\x03\x88\x03\x89\x03\x89\x03\x89\x03\x89\x03\x8A\x03\x8A\x03\x8A" + + "\x03\x8A\x03\x8B\x03\x8B\x03\x8B\x03\x8B\x03\x8B\x03\x8C\x03\x8C\x03\x8C" + + "\x03\x8C\x03\x8C\x03\x8D\x03\x8D\x03\x8D\x03\x8D\x03\x8D\x03\x8D\x03\x8D" + + "\x03\x8D\x03\x8D\x03\x8D\x03\x8E\x03\x8E\x03\x8E\x03\x8E\x03\x8F\x03\x8F" + + "\x03\x8F\x03\x8F\x03\x90\x03\x90\x03\x90\x03\x90\x03\x91\x03\x91\x03\x92" + + "\x03\x92\x03\x93\x03\x93\x03\x94\x03\x94\x03\x95\x03\x95\x03\x96\x03\x96" + + "\x03\x97\x03\x97\x03\x98\x03\x98\x03\x99\x03\x99\x03\x9A\x03\x9A\x03\x9B" + + "\x03\x9B\x03\x9C\x03\x9C\x03\x9D\x03\x9D\x03\x9E\x03\x9E\x03\x9F\x03\x9F" + + "\x03\xA0\x03\xA0\x03\xA1\x03\xA1\x03\xA2\x03\xA2\x03\xA3\x03\xA3\x03\xA4" + + "\x03\xA4\x03\xA5\x03\xA5\x03\xA6\x03\xA6\x03\xA7\x03\xA7\x03\xA8\x03\xA8" + + "\x03\xA9\x03\xA9\x03\xAA\x03\xAA\x04\u0216\u0271\x02\x02\xAB\f\x02\x03" + + "\x0E\x02\x04\x10\x02\x05\x12\x02\x06\x14\x02\x07\x16\x02\b\x18\x02\t\x1A" + + "\x02\n\x1C\x02\v\x1E\x02\f \x02\r\"\x02\x0E$\x02\x0F&\x02\x10(\x02\x11" + + "*\x02\x12,\x02\x13.\x02\x140\x02\x152\x02\x164\x02\x176\x02\x188\x02\x02" + + ":\x02\x02<\x02\x19>\x02\x1A@\x02\x1BB\x02\x1CD\x02\x02F\x02\x02H\x02\x02" + + "J\x02\x02L\x02\x02N\x02\x02P\x02\x02R\x02\x02T\x02\x02V\x02\x02X\x02\x1D" + + "Z\x02\x1E\\\x02\x1F^\x02 `\x02!b\x02\"d\x02#f\x02$h\x02%j\x02&l\x02\'" + + "n\x02(p\x02)r\x02*t\x02+v\x02,x\x02-z\x02.|\x02/~\x020\x80\x021\x82\x02" + + "2\x84\x023\x86\x024\x88\x025\x8A\x026\x8C\x027\x8E\x028\x90\x029\x92\x02" + + ":\x94\x02;\x96\x02<\x98\x02=\x9A\x02>\x9C\x02?\x9E\x02@\xA0\x02A\xA2\x02" + + "B\xA4\x02C\xA6\x02D\xA8\x02E\xAA\x02F\xAC\x02G\xAE\x02\x02\xB0\x02\x02" + + "\xB2\x02\x02\xB4\x02\x02\xB6\x02\x02\xB8\x02H\xBA\x02\x02\xBC\x02I\xBE" + + "\x02\x02\xC0\x02J\xC2\x02K\xC4\x02L\xC6\x02\x02\xC8\x02\x02\xCA\x02\x02" + + "\xCC\x02\x02\xCE\x02M\xD0\x02\x02\xD2\x02N\xD4\x02O\xD6\x02P\xD8\x02\x02" + + "\xDA\x02\x02\xDC\x02\x02\xDE\x02\x02\xE0\x02Q\xE2\x02\x02\xE4\x02\x02" + + "\xE6\x02R\xE8\x02S\xEA\x02T\xEC\x02\x02\xEE\x02U\xF0\x02V\xF2\x02\x02" + + "\xF4\x02\x02\xF6\x02W\xF8\x02X\xFA\x02Y\xFC\x02\x02\xFE\x02\x02\u0100" + + "\x02\x02\u0102\x02\x02\u0104\x02\x02\u0106\x02\x02\u0108\x02\x02\u010A" + + "\x02Z\u010C\x02[\u010E\x02\\\u0110\x02\x02\u0112\x02\x02\u0114\x02\x02" + + "\u0116\x02\x02\u0118\x02]\u011A\x02^\u011C\x02_\u011E\x02\x02\u0120\x02" + + "`\u0122\x02a\u0124\x02b\u0126\x02c\u0128\x02d\u012A\x02\x02\u012C\x02" + + "\x02\u012E\x02\x02\u0130\x02\x02\u0132\x02\x02\u0134\x02\x02\u0136\x02" + + "\x02\u0138\x02\x02\u013A\x02\x02\u013C\x02\x02\u013E\x02\x02\u0140\x02" + + "\x02\u0142\x02\x02\u0144\x02\x02\u0146\x02\x02\u0148\x02\x02\u014A\x02" + + "\x02\u014C\x02\x02\u014E\x02\x02\u0150\x02\x02\u0152\x02\x02\u0154\x02" + + "\x02\u0156\x02\x02\u0158\x02\x02\u015A\x02\x02\u015C\x02\x02\f\x02\x03" + + "\x04\x05\x06\x07\b\t\n\v\'\b\x02\v\f\x0F\x0F\"\"11]]__\x04\x02\f\f\x0F" + + "\x0F\x05\x02\v\f\x0F\x0F\"\"\x03\x022;\x04\x02C\\c|\x07\x02$$^^ppttvv" + + "\x06\x02\f\f\x0F\x0F$$^^\x04\x02GGgg\x04\x02--//\x03\x02bb\f\x02\v\f\x0F" + + "\x0F\"\"..11??]]__bb~~\x04\x02,,11\x04\x02CCcc\x04\x02DDdd\x04\x02EEe" + + "e\x04\x02FFff\x04\x02HHhh\x04\x02IIii\x04\x02JJjj\x04\x02KKkk\x04\x02" + + "LLll\x04\x02MMmm\x04\x02NNnn\x04\x02OOoo\x04\x02PPpp\x04\x02QQqq\x04\x02" + + "RRrr\x04\x02SSss\x04\x02TTtt\x04\x02UUuu\x04\x02VVvv\x04\x02WWww\x04\x02" + + "XXxx\x04\x02YYyy\x04\x02ZZzz\x04\x02[[{{\x04\x02\\\\||\x02\u04A8\x02\f" + + "\x03\x02\x02\x02\x02\x0E\x03\x02\x02\x02\x02\x10\x03\x02\x02\x02\x02\x12" + + "\x03\x02\x02\x02\x02\x14\x03\x02\x02\x02\x02\x16\x03\x02\x02\x02\x02\x18" + + "\x03\x02\x02\x02\x02\x1A\x03\x02\x02\x02\x02\x1C\x03\x02\x02\x02\x02\x1E" + + "\x03\x02\x02\x02\x02 \x03\x02\x02\x02\x02\"\x03\x02\x02\x02\x02$\x03\x02" + + "\x02\x02\x02&\x03\x02\x02\x02\x02(\x03\x02\x02\x02\x02*\x03\x02\x02\x02" + + "\x02,\x03\x02\x02\x02\x02.\x03\x02\x02\x02\x020\x03\x02\x02\x02\x022\x03" + + "\x02\x02\x02\x024\x03\x02\x02\x02\x026\x03\x02\x02\x02\x038\x03\x02\x02" + + "\x02\x03:\x03\x02\x02\x02\x03<\x03\x02\x02\x02\x03>\x03\x02\x02\x02\x03" + + "@\x03\x02\x02\x02\x04B\x03\x02\x02\x02\x04X\x03\x02\x02\x02\x04Z\x03\x02" + + "\x02\x02\x04\\\x03\x02\x02\x02\x04^\x03\x02\x02\x02\x04`\x03\x02\x02\x02" + + "\x04b\x03\x02\x02\x02\x04d\x03\x02\x02\x02\x04f\x03\x02\x02\x02\x04h\x03" + + "\x02\x02\x02\x04j\x03\x02\x02\x02\x04l\x03\x02\x02\x02\x04n\x03\x02\x02" + + "\x02\x04p\x03\x02\x02\x02\x04r\x03\x02\x02\x02\x04t\x03\x02\x02\x02\x04" + + "v\x03\x02\x02\x02\x04x\x03\x02\x02\x02\x04z\x03\x02\x02\x02\x04|\x03\x02" + + "\x02\x02\x04~\x03\x02\x02\x02\x04\x80\x03\x02\x02\x02\x04\x82\x03\x02" + + "\x02\x02\x04\x84\x03\x02\x02\x02\x04\x86\x03\x02\x02\x02\x04\x88\x03\x02" + + "\x02\x02\x04\x8A\x03\x02\x02\x02\x04\x8C\x03\x02\x02\x02\x04\x8E\x03\x02" + + "\x02\x02\x04\x90\x03\x02\x02\x02\x04\x92\x03\x02\x02\x02\x04\x94\x03\x02" + + "\x02\x02\x04\x96\x03\x02\x02\x02\x04\x98\x03\x02\x02\x02\x04\x9A\x03\x02" + + "\x02\x02\x04\x9C\x03\x02\x02\x02\x04\x9E\x03\x02\x02\x02\x04\xA0\x03\x02" + + "\x02\x02\x04\xA2\x03\x02\x02\x02\x04\xA4\x03\x02\x02\x02\x04\xA6\x03\x02" + + "\x02\x02\x04\xA8\x03\x02\x02\x02\x04\xAA\x03\x02\x02\x02\x04\xAC\x03\x02" + + "\x02\x02\x05\xAE\x03\x02\x02\x02\x05\xB0\x03\x02\x02\x02\x05\xB2\x03\x02" + + "\x02\x02\x05\xB4\x03\x02\x02\x02\x05\xB6\x03\x02\x02\x02\x05\xB8\x03\x02" + + "\x02\x02\x05\xBC\x03\x02\x02\x02\x05\xBE\x03\x02\x02\x02\x05\xC0\x03\x02" + + "\x02\x02\x05\xC2\x03\x02\x02\x02\x05\xC4\x03\x02\x02\x02\x06\xC6\x03\x02" + + "\x02\x02\x06\xC8\x03\x02\x02\x02\x06\xCA\x03\x02\x02\x02\x06\xCE\x03\x02" + + "\x02\x02\x06\xD0\x03\x02\x02\x02\x06\xD2\x03\x02\x02\x02\x06\xD4\x03\x02" + + "\x02\x02\x06\xD6\x03\x02\x02\x02\x07\xD8\x03\x02\x02\x02\x07\xDA\x03\x02" + + "\x02\x02\x07\xDC\x03\x02\x02\x02\x07\xDE\x03\x02\x02\x02\x07\xE0\x03\x02" + + "\x02\x02\x07\xE2\x03\x02\x02\x02\x07\xE4\x03\x02\x02\x02\x07\xE6\x03\x02" + + "\x02\x02\x07\xE8\x03\x02\x02\x02\x07\xEA\x03\x02\x02\x02\b\xEC\x03\x02" + + "\x02\x02\b\xEE\x03\x02\x02\x02\b\xF0\x03\x02\x02\x02\b\xF2\x03\x02\x02" + + "\x02\b\xF4\x03\x02\x02\x02\b\xF6\x03\x02\x02\x02\b\xF8\x03\x02\x02\x02" + + "\b\xFA\x03\x02\x02\x02\t\xFC\x03\x02\x02\x02\t\xFE\x03\x02\x02\x02\t\u0100" + + "\x03\x02\x02\x02\t\u0102\x03\x02\x02\x02\t\u0104\x03\x02\x02\x02\t\u0106" + + "\x03\x02\x02\x02\t\u0108\x03\x02\x02\x02\t\u010A\x03\x02\x02\x02\t\u010C" + + "\x03\x02\x02\x02\t\u010E\x03\x02\x02\x02\n\u0110\x03\x02\x02\x02\n\u0112" + + "\x03\x02\x02\x02\n\u0114\x03\x02\x02\x02\n\u0116\x03\x02\x02\x02\n\u0118" + + "\x03\x02\x02\x02\n\u011A\x03\x02\x02\x02\n\u011C\x03\x02\x02\x02\v\u011E" + + "\x03\x02\x02\x02\v\u0120\x03\x02\x02\x02\v\u0122\x03\x02\x02\x02\v\u0124" + + "\x03\x02\x02\x02\v\u0126\x03\x02\x02\x02\v\u0128\x03\x02\x02\x02\f\u015E" + + "\x03\x02\x02\x02\x0E\u0168\x03\x02\x02\x02\x10\u016F\x03\x02\x02\x02\x12" + + "\u0178\x03\x02\x02\x02\x14\u017F\x03\x02\x02\x02\x16\u0189\x03\x02\x02" + + "\x02\x18\u0190\x03\x02\x02\x02\x1A\u0197\x03\x02\x02\x02\x1C\u01A5\x03" + + "\x02\x02\x02\x1E\u01AC\x03\x02\x02\x02 \u01B4\x03\x02\x02\x02\"\u01C0" + + "\x03\x02\x02\x02$\u01CA\x03\x02\x02\x02&\u01D3\x03\x02\x02\x02(\u01D9" + + "\x03\x02\x02\x02*\u01E0\x03\x02\x02\x02,\u01E7\x03\x02\x02\x02.\u01EF" + + "\x03\x02\x02\x020\u01F8\x03\x02\x02\x022\u01FE\x03\x02\x02\x024\u020F" + + "\x03\x02\x02\x026\u021F\x03\x02\x02\x028\u0225\x03\x02\x02\x02:\u022A" + + "\x03\x02\x02\x02<\u022F\x03\x02\x02\x02>\u0233\x03\x02\x02\x02@\u0237" + + "\x03\x02\x02\x02B\u023B\x03\x02\x02\x02D\u023F\x03\x02\x02\x02F\u0241" + + "\x03\x02\x02\x02H\u0243\x03\x02\x02\x02J\u0246\x03\x02\x02\x02L\u0248" + + "\x03\x02\x02\x02N\u0251\x03\x02\x02\x02P\u0253\x03\x02\x02\x02R\u0258" + + "\x03\x02\x02\x02T\u025A\x03\x02\x02\x02V\u025F\x03\x02\x02\x02X\u027E" + + "\x03\x02\x02\x02Z\u0281\x03\x02\x02\x02\\\u02AF\x03\x02\x02\x02^\u02B1" + + "\x03\x02\x02\x02`\u02B4\x03\x02\x02\x02b\u02B8\x03\x02\x02\x02d\u02BC" + + "\x03\x02\x02\x02f\u02BE\x03\x02\x02\x02h\u02C0\x03\x02\x02\x02j\u02C5" + + "\x03\x02\x02\x02l\u02C7\x03\x02\x02\x02n\u02CD\x03\x02\x02\x02p\u02D3" + + "\x03\x02\x02\x02r\u02D8\x03\x02\x02\x02t\u02DA\x03\x02\x02\x02v\u02DD" + + "\x03\x02\x02\x02x\u02E0\x03\x02\x02\x02z\u02E5\x03\x02\x02\x02|\u02E9" + + "\x03\x02\x02\x02~\u02EE\x03\x02\x02\x02\x80\u02F4\x03\x02\x02\x02\x82" + + "\u02F7\x03\x02\x02\x02\x84\u02F9\x03\x02\x02\x02\x86\u02FF\x03\x02\x02" + + "\x02\x88\u0301\x03\x02\x02\x02\x8A\u0306\x03\x02\x02\x02\x8C\u0309\x03" + + "\x02\x02\x02\x8E\u030C\x03\x02\x02\x02\x90\u030E\x03\x02\x02\x02\x92\u0311" + + "\x03\x02\x02\x02\x94\u0313\x03\x02\x02\x02\x96\u0316\x03\x02\x02\x02\x98" + + "\u0318\x03\x02\x02\x02\x9A\u031A\x03\x02\x02\x02\x9C\u031C\x03\x02\x02" + + "\x02\x9E\u031E\x03\x02\x02\x02\xA0\u0320\x03\x02\x02\x02\xA2\u0325\x03" + + "\x02\x02\x02\xA4\u033A\x03\x02\x02\x02\xA6\u033C\x03\x02\x02\x02\xA8\u0344" + + "\x03\x02\x02\x02\xAA\u0348\x03\x02\x02\x02\xAC\u034C\x03\x02\x02\x02\xAE" + + "\u0350\x03\x02\x02\x02\xB0\u0355\x03\x02\x02\x02\xB2\u035B\x03\x02\x02" + + "\x02\xB4\u0361\x03\x02\x02\x02\xB6\u0365\x03\x02\x02\x02\xB8\u0369\x03" + + "\x02\x02\x02\xBA\u0375\x03\x02\x02\x02\xBC\u0378\x03\x02\x02\x02\xBE\u037C" + + "\x03\x02\x02\x02\xC0\u0380\x03\x02\x02\x02\xC2\u0384\x03\x02\x02\x02\xC4" + + "\u0388\x03\x02\x02\x02\xC6\u038C\x03\x02\x02\x02\xC8\u0391\x03\x02\x02" + + "\x02\xCA\u0395\x03\x02\x02\x02\xCC\u039D\x03\x02\x02\x02\xCE\u03B2\x03" + + "\x02\x02\x02\xD0\u03B4\x03\x02\x02\x02\xD2\u03B8\x03\x02\x02\x02\xD4\u03BC" + + "\x03\x02\x02\x02\xD6\u03C0\x03\x02\x02\x02\xD8\u03C4\x03\x02\x02\x02\xDA" + + "\u03C9\x03\x02\x02\x02\xDC\u03CD\x03\x02\x02\x02\xDE\u03D1\x03\x02\x02" + + "\x02\xE0\u03D5\x03\x02\x02\x02\xE2\u03D8\x03\x02\x02\x02\xE4\u03DC\x03" + + "\x02\x02\x02\xE6\u03E0\x03\x02\x02\x02\xE8\u03E4\x03\x02\x02\x02\xEA\u03E8" + + "\x03\x02\x02\x02\xEC\u03EC\x03\x02\x02\x02\xEE\u03F1\x03\x02\x02\x02\xF0" + + "\u03F6\x03\x02\x02\x02\xF2\u03FD\x03\x02\x02\x02\xF4\u0401\x03\x02\x02" + + "\x02\xF6\u0405\x03\x02\x02\x02\xF8\u0409\x03\x02\x02\x02\xFA\u040D\x03" + + "\x02\x02\x02\xFC\u0411\x03\x02\x02\x02\xFE\u0417\x03\x02\x02\x02\u0100" + + "\u041B\x03\x02\x02\x02\u0102\u041F\x03\x02\x02\x02\u0104\u0423\x03\x02" + + "\x02\x02\u0106\u0427\x03\x02\x02\x02\u0108\u042B\x03\x02\x02\x02\u010A" + + "\u042F\x03\x02\x02\x02\u010C\u0433\x03\x02\x02\x02\u010E\u0437\x03\x02" + + "\x02\x02\u0110\u043B\x03\x02\x02\x02\u0112\u0440\x03\x02\x02\x02\u0114" + + "\u0444\x03\x02\x02\x02\u0116\u0448\x03\x02\x02\x02\u0118\u044C\x03\x02" + + "\x02\x02\u011A\u0450\x03\x02\x02\x02\u011C\u0454\x03\x02\x02\x02\u011E" + + "\u0458\x03\x02\x02\x02\u0120\u045D\x03\x02\x02\x02\u0122\u0462\x03\x02" + + "\x02\x02\u0124\u046C\x03\x02\x02\x02\u0126\u0470\x03\x02\x02\x02\u0128" + + "\u0474\x03\x02\x02\x02\u012A\u0478\x03\x02\x02\x02\u012C\u047A\x03\x02" + + "\x02\x02\u012E\u047C\x03\x02\x02\x02\u0130\u047E\x03\x02\x02\x02\u0132" + + "\u0480\x03\x02\x02\x02\u0134\u0482\x03\x02\x02\x02\u0136\u0484\x03\x02" + + "\x02\x02\u0138\u0486\x03\x02\x02\x02\u013A\u0488\x03\x02\x02\x02\u013C" + + "\u048A\x03\x02\x02\x02\u013E\u048C\x03\x02\x02\x02\u0140\u048E\x03\x02" + + "\x02\x02\u0142\u0490\x03\x02\x02\x02\u0144\u0492\x03\x02\x02\x02\u0146" + + "\u0494\x03\x02\x02\x02\u0148\u0496\x03\x02\x02\x02\u014A\u0498\x03\x02" + + "\x02\x02\u014C\u049A\x03\x02\x02\x02\u014E\u049C\x03\x02\x02\x02\u0150" + + "\u049E\x03\x02"; private static readonly _serializedATNSegment1: string = - "\u01D7\u01D6\x03\x02\x02\x02\u01D8\u01DB\x03\x02\x02\x02\u01D9\u01D7\x03" + - "\x02\x02\x02\u01D9\u01DA\x03\x02\x02\x02\u01DA\u01FB\x03\x02\x02\x02\u01DB" + - "\u01D9\x03\x02\x02\x02\u01DC\u01DE\x05K%\x02\u01DD\u01DF\x05/\x17\x02" + - "\u01DE\u01DD\x03\x02\x02\x02\u01DF\u01E0\x03\x02\x02\x02\u01E0\u01DE\x03" + - "\x02\x02\x02\u01E0\u01E1\x03\x02\x02\x02\u01E1\u01FB\x03\x02\x02\x02\u01E2" + - "\u01E4\x05/\x17\x02\u01E3\u01E2\x03\x02\x02\x02\u01E4\u01E5\x03\x02\x02" + - "\x02\u01E5\u01E3\x03\x02\x02\x02\u01E5\u01E6\x03\x02\x02\x02\u01E6\u01EE" + - "\x03\x02\x02\x02\u01E7\u01EB\x05K%\x02\u01E8\u01EA\x05/\x17\x02\u01E9" + - "\u01E8\x03\x02\x02\x02\u01EA\u01ED\x03\x02\x02\x02\u01EB\u01E9\x03\x02" + - "\x02\x02\u01EB\u01EC\x03\x02\x02\x02\u01EC\u01EF\x03\x02\x02\x02\u01ED" + - "\u01EB\x03\x02\x02\x02\u01EE\u01E7\x03\x02\x02\x02\u01EE\u01EF\x03\x02" + - "\x02\x02\u01EF\u01F0\x03\x02\x02\x02\u01F0\u01F1\x057\x1B\x02\u01F1\u01FB" + - "\x03\x02\x02\x02\u01F2\u01F4\x05K%\x02\u01F3\u01F5\x05/\x17\x02\u01F4" + - "\u01F3\x03\x02\x02\x02\u01F5\u01F6\x03\x02\x02\x02\u01F6\u01F4\x03\x02" + - "\x02\x02\u01F6\u01F7\x03\x02\x02\x02\u01F7\u01F8\x03\x02\x02\x02\u01F8" + - "\u01F9\x057\x1B\x02\u01F9\u01FB\x03\x02\x02\x02\u01FA\u01D1\x03\x02\x02" + - "\x02\u01FA\u01DC\x03\x02\x02\x02\u01FA\u01E3\x03\x02\x02\x02\u01FA\u01F2" + - "\x03\x02\x02\x02\u01FB>\x03\x02\x02\x02\u01FC\u01FD\x05\xB5Z\x02\u01FD" + - "\u01FE\x05\xE3q\x02\u01FE@\x03\x02\x02\x02\u01FF\u0200\x05\xB3Y\x02\u0200" + - "\u0201\x05\xCDf\x02\u0201\u0202\x05\xB9\\\x02\u0202B\x03\x02\x02\x02\u0203" + - "\u0204\x05\xB3Y\x02\u0204\u0205\x05\xD7k\x02\u0205\u0206\x05\xB7[\x02" + - "\u0206D\x03\x02\x02\x02\u0207\u0208\x07?\x02\x02\u0208F\x03\x02\x02\x02" + - "\u0209\u020A\x07.\x02\x02\u020AH\x03\x02\x02\x02\u020B\u020C\x05\xB9\\" + - "\x02\u020C\u020D\x05\xBB]\x02\u020D\u020E\x05\xD7k\x02\u020E\u020F\x05" + - "\xB7[\x02\u020FJ\x03\x02\x02\x02\u0210\u0211\x070\x02\x02\u0211L\x03\x02" + - "\x02\x02\u0212\u0213\x05\xBD^\x02\u0213\u0214\x05\xB3Y\x02\u0214\u0215" + - "\x05\xC9d\x02\u0215\u0216\x05\xD7k\x02\u0216\u0217\x05\xBB]\x02\u0217" + - "N\x03\x02\x02\x02\u0218\u0219\x05\xBD^\x02\u0219\u021A\x05\xC3a\x02\u021A" + - "\u021B\x05\xD5j\x02\u021B\u021C\x05\xD7k\x02\u021C\u021D\x05\xD9l\x02" + - "\u021DP\x03\x02\x02\x02\u021E\u021F\x05\xC9d\x02\u021F\u0220\x05\xB3Y" + - "\x02\u0220\u0221\x05\xD7k\x02\u0221\u0222\x05\xD9l\x02\u0222R\x03\x02" + - "\x02\x02\u0223\u0224\x07*\x02\x02\u0224T\x03\x02\x02\x02\u0225\u0226\x05" + - "\xC3a\x02\u0226\u0227\x05\xCDf\x02\u0227V\x03\x02\x02\x02\u0228\u0229" + - "\x05\xC3a\x02\u0229\u022A\x05\xD7k\x02\u022AX\x03\x02\x02\x02\u022B\u022C" + - "\x05\xC9d\x02\u022C\u022D\x05\xC3a\x02\u022D\u022E\x05\xC7c\x02\u022E" + - "\u022F\x05\xBB]\x02\u022FZ\x03\x02\x02\x02\u0230\u0231\x05\xCDf\x02\u0231" + - "\u0232\x05\xCFg\x02\u0232\u0233\x05\xD9l\x02\u0233\\\x03\x02\x02\x02\u0234" + - "\u0235\x05\xCDf\x02\u0235\u0236\x05\xDBm\x02\u0236\u0237\x05\xC9d\x02" + - "\u0237\u0238\x05\xC9d\x02\u0238^\x03\x02\x02\x02\u0239\u023A\x05\xCDf" + - "\x02\u023A\u023B\x05\xDBm\x02\u023B\u023C\x05\xC9d\x02\u023C\u023D\x05" + - "\xC9d\x02\u023D\u023E\x05\xD7k\x02\u023E`\x03\x02\x02\x02\u023F\u0240" + - "\x05\xCFg\x02\u0240\u0241\x05\xD5j\x02\u0241b\x03\x02\x02\x02\u0242\u0243" + - "\x07A\x02\x02\u0243d\x03\x02\x02\x02\u0244\u0245\x05\xD5j\x02\u0245\u0246" + - "\x05\xC9d\x02\u0246\u0247\x05\xC3a\x02\u0247\u0248\x05\xC7c\x02\u0248" + - "\u0249\x05\xBB]\x02\u0249f\x03\x02\x02\x02\u024A\u024B\x07+\x02\x02\u024B" + - "h\x03\x02\x02\x02\u024C\u024D\x05\xD9l\x02\u024D\u024E\x05\xD5j\x02\u024E" + - "\u024F\x05\xDBm\x02\u024F\u0250\x05\xBB]\x02\u0250j\x03\x02\x02\x02\u0251" + - "\u0252\x05\xC3a\x02\u0252\u0253\x05\xCDf\x02\u0253\u0254\x05\xBD^\x02" + - "\u0254\u0255\x05\xCFg\x02\u0255l\x03\x02\x02\x02\u0256\u0257\x05\xBD^" + - "\x02\u0257\u0258\x05\xDBm\x02\u0258\u0259\x05\xCDf\x02\u0259\u025A\x05" + - "\xB7[\x02\u025A\u025B\x05\xD9l\x02\u025B\u025C\x05\xC3a\x02\u025C\u025D" + - "\x05\xCFg\x02\u025D\u025E\x05\xCDf\x02\u025E\u025F\x05\xD7k\x02\u025F" + - "n\x03\x02\x02\x02\u0260\u0261\x07a\x02\x02\u0261p\x03\x02\x02\x02\u0262" + - "\u0263\x07?\x02\x02\u0263\u0264\x07?\x02\x02\u0264r\x03\x02\x02\x02\u0265" + - "\u0266\x07#\x02\x02\u0266\u0267\x07?\x02\x02\u0267t\x03\x02\x02\x02\u0268" + - "\u0269\x07>\x02\x02\u0269v\x03\x02\x02\x02\u026A\u026B\x07>\x02\x02\u026B" + - "\u026C\x07?\x02\x02\u026Cx\x03\x02\x02\x02\u026D\u026E\x07@\x02\x02\u026E" + - "z\x03\x02\x02\x02\u026F\u0270\x07@\x02\x02\u0270\u0271\x07?\x02\x02\u0271" + - "|\x03\x02\x02\x02\u0272\u0273\x07-\x02\x02\u0273~\x03\x02\x02\x02\u0274" + - "\u0275\x07/\x02\x02\u0275\x80\x03\x02\x02\x02\u0276\u0277\x07,\x02\x02" + - "\u0277\x82\x03\x02\x02\x02\u0278\u0279\x071\x02\x02\u0279\x84\x03\x02" + - "\x02\x02\u027A\u027B\x07\'\x02\x02\u027B\x86\x03\x02\x02\x02\u027C\u027D" + - "\x07]\x02\x02\u027D\u027E\x03\x02\x02\x02\u027E\u027F\bC\x02\x02\u027F" + - "\u0280\bC\x02\x02\u0280\x88\x03\x02\x02\x02\u0281\u0282\x07_\x02\x02\u0282" + - "\u0283\x03\x02\x02\x02\u0283\u0284\bD\x05\x02\u0284\u0285\bD\x05\x02\u0285" + - "\x8A\x03\x02\x02\x02\u0286\u028C\x051\x18\x02\u0287\u028B\x051\x18\x02" + - "\u0288\u028B\x05/\x17\x02\u0289\u028B\x07a\x02\x02\u028A\u0287\x03\x02" + - "\x02\x02\u028A\u0288\x03\x02\x02\x02\u028A\u0289\x03\x02\x02\x02\u028B" + - "\u028E\x03\x02\x02\x02\u028C\u028A\x03\x02\x02\x02\u028C\u028D\x03\x02" + - "\x02\x02\u028D\u0298\x03\x02\x02\x02\u028E\u028C\x03\x02\x02\x02\u028F" + - "\u0293\t\v\x02\x02\u0290\u0294\x051\x18\x02\u0291\u0294\x05/\x17\x02\u0292" + - "\u0294\x07a\x02\x02\u0293\u0290\x03\x02\x02\x02\u0293\u0291\x03\x02\x02" + - "\x02\u0293\u0292\x03\x02\x02\x02\u0294\u0295\x03\x02\x02\x02\u0295\u0293" + - "\x03\x02\x02\x02\u0295\u0296\x03\x02\x02\x02\u0296\u0298\x03\x02\x02\x02" + - "\u0297\u0286\x03\x02\x02\x02\u0297\u028F\x03\x02\x02\x02\u0298\x8C\x03" + - "\x02\x02\x02\u0299\u029F\x07b\x02\x02\u029A\u029E\n\f\x02\x02\u029B\u029C" + - "\x07b\x02\x02\u029C\u029E\x07b\x02\x02\u029D\u029A\x03\x02\x02\x02\u029D" + - "\u029B\x03\x02\x02\x02\u029E\u02A1\x03\x02\x02\x02\u029F\u029D\x03\x02" + - "\x02\x02\u029F\u02A0\x03\x02\x02\x02\u02A0\u02A2\x03\x02\x02\x02\u02A1" + - "\u029F\x03\x02\x02\x02\u02A2\u02A3\x07b\x02\x02\u02A3\x8E\x03\x02\x02" + - "\x02\u02A4\u02A5\x05\'\x13\x02\u02A5\u02A6\x03\x02\x02\x02\u02A6\u02A7" + - "\bG\x04\x02\u02A7\x90\x03\x02\x02\x02\u02A8\u02A9\x05)\x14\x02\u02A9\u02AA" + - "\x03\x02\x02\x02\u02AA\u02AB\bH\x04\x02\u02AB\x92\x03\x02\x02\x02\u02AC" + - "\u02AD\x05+\x15\x02\u02AD\u02AE\x03\x02\x02\x02\u02AE\u02AF\bI\x04\x02" + - "\u02AF\x94\x03\x02\x02\x02\u02B0\u02B1\x07~\x02\x02\u02B1\u02B2\x03\x02" + - "\x02\x02\u02B2\u02B3\bJ\x06\x02\u02B3\u02B4\bJ\x05\x02\u02B4\x96\x03\x02" + - "\x02\x02\u02B5\u02B6\x07]\x02\x02\u02B6\u02B7\x03\x02\x02\x02\u02B7\u02B8" + - "\bK\x07\x02\u02B8\u02B9\bK\x03\x02\u02B9\u02BA\bK\x03\x02\u02BA\x98\x03" + - "\x02\x02\x02\u02BB\u02BC\x07_\x02\x02\u02BC\u02BD\x03\x02\x02\x02\u02BD" + - "\u02BE\bL\x05\x02\u02BE\u02BF\bL\x05\x02\u02BF\u02C0\bL\b\x02\u02C0\x9A" + - "\x03\x02\x02\x02\u02C1\u02C2\x07.\x02\x02\u02C2\u02C3\x03\x02\x02\x02" + - "\u02C3\u02C4\bM\t\x02\u02C4\x9C\x03\x02\x02\x02\u02C5\u02C6\x07?\x02\x02" + - "\u02C6\u02C7\x03\x02\x02\x02\u02C7\u02C8\bN\n\x02\u02C8\x9E\x03\x02\x02" + - "\x02\u02C9\u02CA\x05\xB3Y\x02\u02CA\u02CB\x05\xD7k\x02\u02CB\xA0\x03\x02" + - "\x02\x02\u02CC\u02CD\x05\xCBe\x02\u02CD\u02CE\x05\xBB]\x02\u02CE\u02CF" + - "\x05\xD9l\x02\u02CF\u02D0\x05\xB3Y\x02\u02D0\u02D1\x05\xB9\\\x02\u02D1" + - "\u02D2\x05\xB3Y\x02\u02D2\u02D3\x05\xD9l\x02\u02D3\u02D4\x05\xB3Y\x02" + - "\u02D4\xA2\x03\x02\x02\x02\u02D5\u02D6\x05\xCFg\x02\u02D6\u02D7\x05\xCD" + - "f\x02\u02D7\xA4\x03\x02\x02\x02\u02D8\u02D9\x05\xDFo\x02\u02D9\u02DA\x05" + - "\xC3a\x02\u02DA\u02DB\x05\xD9l\x02\u02DB\u02DC\x05\xC1`\x02\u02DC\xA6" + - "\x03\x02\x02\x02\u02DD\u02DF\x05\xA9T\x02\u02DE\u02DD\x03\x02\x02\x02" + - "\u02DF\u02E0\x03\x02\x02\x02\u02E0\u02DE\x03\x02\x02\x02\u02E0\u02E1\x03" + - "\x02\x02\x02\u02E1\xA8\x03\x02\x02\x02\u02E2\u02E4\n\r\x02\x02\u02E3\u02E2" + - "\x03\x02\x02\x02\u02E4\u02E5\x03\x02\x02\x02\u02E5\u02E3\x03\x02\x02\x02" + - "\u02E5\u02E6\x03\x02\x02\x02\u02E6\u02EA\x03\x02\x02\x02\u02E7\u02E8\x07" + - "1\x02\x02\u02E8\u02EA\n\x0E\x02\x02\u02E9\u02E3\x03\x02\x02\x02\u02E9" + - "\u02E7\x03\x02\x02\x02\u02EA\xAA\x03\x02\x02\x02\u02EB\u02EC\x05\x8DF" + - "\x02\u02EC\xAC\x03\x02\x02\x02\u02ED\u02EE\x05\'\x13\x02\u02EE\u02EF\x03" + - "\x02\x02\x02\u02EF\u02F0\bV\x04\x02\u02F0\xAE\x03\x02\x02\x02\u02F1\u02F2" + - "\x05)\x14\x02\u02F2\u02F3\x03\x02\x02\x02\u02F3\u02F4\bW\x04\x02\u02F4" + - "\xB0\x03\x02\x02\x02\u02F5\u02F6\x05+\x15\x02\u02F6\u02F7\x03\x02\x02" + - "\x02\u02F7\u02F8\bX\x04\x02\u02F8\xB2\x03\x02\x02\x02\u02F9\u02FA\t\x0F" + - "\x02\x02\u02FA\xB4\x03\x02\x02\x02\u02FB\u02FC\t\x10\x02\x02\u02FC\xB6" + - "\x03\x02\x02\x02\u02FD\u02FE\t\x11\x02\x02\u02FE\xB8\x03\x02\x02\x02\u02FF" + - "\u0300\t\x12\x02\x02\u0300\xBA\x03\x02\x02\x02\u0301\u0302\t\t\x02\x02" + - "\u0302\xBC\x03\x02\x02\x02\u0303\u0304\t\x13\x02\x02\u0304\xBE\x03\x02" + - "\x02\x02\u0305\u0306\t\x14\x02\x02\u0306\xC0\x03\x02\x02\x02\u0307\u0308" + - "\t\x15\x02\x02\u0308\xC2\x03\x02\x02\x02\u0309\u030A\t\x16\x02\x02\u030A" + - "\xC4\x03\x02\x02\x02\u030B\u030C\t\x17\x02\x02\u030C\xC6\x03\x02\x02\x02" + - "\u030D\u030E\t\x18\x02\x02\u030E\xC8\x03\x02\x02\x02\u030F\u0310\t\x19" + - "\x02\x02\u0310\xCA\x03\x02\x02\x02\u0311\u0312\t\x1A\x02\x02\u0312\xCC" + - "\x03\x02\x02\x02\u0313\u0314\t\x1B\x02\x02\u0314\xCE\x03\x02\x02\x02\u0315" + - "\u0316\t\x1C\x02\x02\u0316\xD0\x03\x02\x02\x02\u0317\u0318\t\x1D\x02\x02" + - "\u0318\xD2\x03\x02\x02\x02\u0319\u031A\t\x1E\x02\x02\u031A\xD4\x03\x02" + - "\x02\x02\u031B\u031C\t\x1F\x02\x02\u031C\xD6\x03\x02\x02\x02\u031D\u031E" + - "\t \x02\x02\u031E\xD8\x03\x02\x02\x02\u031F\u0320\t!\x02\x02\u0320\xDA" + - "\x03\x02\x02\x02\u0321\u0322\t\"\x02\x02\u0322\xDC\x03\x02\x02\x02\u0323" + - "\u0324\t#\x02\x02\u0324\xDE\x03\x02\x02\x02\u0325\u0326\t$\x02\x02\u0326" + - "\xE0\x03\x02\x02\x02\u0327\u0328\t%\x02\x02\u0328\xE2\x03\x02\x02\x02" + - "\u0329\u032A\t&\x02\x02\u032A\xE4\x03\x02\x02\x02\u032B\u032C\t\'\x02" + - "\x02\u032C\xE6\x03\x02\x02\x02\'\x02\x03\x04\u016B\u0175\u0179\u017C\u0185" + - "\u0187\u0192\u01A5\u01AA\u01AF\u01B1\u01BC\u01C4\u01C7\u01C9\u01CE\u01D3" + - "\u01D9\u01E0\u01E5\u01EB\u01EE\u01F6\u01FA\u028A\u028C\u0293\u0295\u0297" + - "\u029D\u029F\u02E0\u02E5\u02E9\v\x07\x03\x02\x07\x04\x02\x02\x03\x02\x06" + - "\x02\x02\t\x17\x02\t?\x02\t@\x02\t\x1F\x02\t\x1E\x02"; + "\x02\x02\u0152\u04A0\x03\x02\x02\x02\u0154\u04A2\x03\x02\x02\x02\u0156" + + "\u04A4\x03\x02\x02\x02\u0158\u04A6\x03\x02\x02\x02\u015A\u04A8\x03\x02" + + "\x02\x02\u015C\u04AA\x03\x02\x02\x02\u015E\u015F\x05\u0130\x94\x02\u015F" + + "\u0160\x05\u013A\x99\x02\u0160\u0161\x05\u014E\xA3\x02\u0161\u0162\x05" + + "\u014E\xA3\x02\u0162\u0163\x05\u0132\x95\x02\u0163\u0164\x05\u012E\x93" + + "\x02\u0164\u0165\x05\u0150\xA4\x02\u0165\u0166\x03\x02\x02\x02\u0166\u0167" + + "\b\x02\x02\x02\u0167\r\x03\x02\x02\x02\u0168\u0169\x05\u0130\x94\x02\u0169" + + "\u016A\x05\u014C\xA2\x02\u016A\u016B\x05\u0146\x9F\x02\u016B\u016C\x05" + + "\u0148\xA0\x02\u016C\u016D\x03\x02\x02\x02\u016D\u016E\b\x03\x03\x02\u016E" + + "\x0F\x03\x02\x02\x02\u016F\u0170\x05\u0132\x95\x02\u0170\u0171\x05\u0144" + + "\x9E\x02\u0171\u0172\x05\u014C\xA2\x02\u0172\u0173\x05\u013A\x99\x02\u0173" + + "\u0174\x05\u012E\x93\x02\u0174\u0175\x05\u0138\x98\x02\u0175\u0176\x03" + + "\x02\x02\x02\u0176\u0177\b\x04\x04\x02\u0177\x11\x03\x02\x02\x02\u0178" + + "\u0179\x05\u0132\x95\x02\u0179\u017A\x05\u0154\xA6\x02\u017A\u017B\x05" + + "\u012A\x91\x02\u017B\u017C\x05\u0140\x9C\x02\u017C\u017D\x03\x02\x02\x02" + + "\u017D\u017E\b\x05\x02\x02\u017E\x13\x03\x02\x02\x02\u017F\u0180\x05\u0132" + + "\x95\x02\u0180\u0181\x05\u0158\xA8\x02\u0181\u0182\x05\u0148\xA0\x02\u0182" + + "\u0183\x05\u0140\x9C\x02\u0183\u0184\x05\u012A\x91\x02\u0184\u0185\x05" + + "\u013A\x99\x02\u0185\u0186\x05\u0144\x9E\x02\u0186\u0187\x03\x02\x02\x02" + + "\u0187\u0188\b\x06\x05\x02\u0188\x15\x03\x02\x02\x02\u0189\u018A\x05\u0134" + + "\x96\x02\u018A\u018B\x05\u014C\xA2\x02\u018B\u018C\x05\u0146\x9F\x02\u018C" + + "\u018D\x05\u0142\x9D\x02\u018D\u018E\x03\x02\x02\x02\u018E\u018F\b\x07" + + "\x06\x02\u018F\x17\x03\x02\x02\x02\u0190\u0191\x05\u0136\x97\x02\u0191" + + "\u0192\x05\u014C\xA2\x02\u0192\u0193\x05\u0146\x9F\x02\u0193\u0194\x05" + + "\u013E\x9B\x02\u0194\u0195\x03\x02\x02\x02\u0195\u0196\b\b\x02\x02\u0196" + + "\x19\x03\x02\x02\x02\u0197\u0198\x05\u013A\x99\x02\u0198\u0199\x05\u0144" + + "\x9E\x02\u0199\u019A\x05\u0140\x9C\x02\u019A\u019B\x05\u013A\x99\x02\u019B" + + "\u019C\x05\u0144\x9E\x02\u019C\u019D\x05\u0132\x95\x02\u019D\u019E\x05" + + "\u014E\xA3\x02\u019E\u019F\x05\u0150\xA4\x02\u019F\u01A0\x05\u012A\x91" + + "\x02\u01A0\u01A1\x05\u0150\xA4\x02\u01A1\u01A2\x05\u014E\xA3\x02\u01A2" + + "\u01A3\x03\x02\x02\x02\u01A3\u01A4\b\t\x02\x02\u01A4\x1B\x03\x02\x02\x02" + + "\u01A5\u01A6\x05\u013E\x9B\x02\u01A6\u01A7\x05\u0132\x95\x02\u01A7\u01A8" + + "\x05\u0132\x95\x02\u01A8\u01A9\x05\u0148\xA0\x02\u01A9\u01AA\x03\x02\x02" + + "\x02\u01AA\u01AB\b\n\x03\x02\u01AB\x1D\x03\x02\x02\x02\u01AC\u01AD\x05" + + "\u0140\x9C\x02\u01AD\u01AE\x05\u013A\x99\x02\u01AE\u01AF\x05\u0142\x9D" + + "\x02\u01AF\u01B0\x05\u013A\x99\x02\u01B0\u01B1\x05\u0150\xA4\x02\u01B1" + + "\u01B2\x03\x02\x02\x02\u01B2\u01B3\b\v\x02\x02\u01B3\x1F\x03\x02\x02\x02" + + "\u01B4\u01B5\x05\u0142\x9D\x02\u01B5\u01B6\x05\u0154\xA6\x02\u01B6\u01B7" + + "\x05T&\x02\u01B7\u01B8\x05\u0132\x95\x02\u01B8\u01B9\x05\u0158\xA8\x02" + + "\u01B9\u01BA\x05\u0148\xA0\x02\u01BA\u01BB\x05\u012A\x91\x02\u01BB\u01BC" + + "\x05\u0144\x9E\x02\u01BC\u01BD\x05\u0130\x94\x02\u01BD\u01BE\x03\x02\x02" + + "\x02\u01BE\u01BF\b\f\x07\x02\u01BF!\x03\x02\x02\x02\u01C0\u01C1\x05\u0148" + + "\xA0\x02\u01C1\u01C2\x05\u014C\xA2\x02\u01C2\u01C3\x05\u0146\x9F\x02\u01C3" + + "\u01C4\x05\u013C\x9A\x02\u01C4\u01C5\x05\u0132\x95\x02\u01C5\u01C6\x05" + + "\u012E\x93\x02\u01C6\u01C7\x05\u0150\xA4\x02\u01C7\u01C8\x03\x02\x02\x02" + + "\u01C8\u01C9\b\r\x03\x02\u01C9#\x03\x02\x02\x02\u01CA\u01CB\x05\u014C" + + "\xA2\x02\u01CB\u01CC\x05\u0132\x95\x02\u01CC\u01CD\x05\u0144\x9E\x02\u01CD" + + "\u01CE\x05\u012A\x91\x02\u01CE\u01CF\x05\u0142\x9D\x02\u01CF\u01D0\x05" + + "\u0132\x95\x02\u01D0\u01D1\x03\x02\x02\x02\u01D1\u01D2\b\x0E\b\x02\u01D2" + + "%\x03\x02\x02\x02\u01D3\u01D4\x05\u014C\xA2\x02\u01D4\u01D5\x05\u0146" + + "\x9F\x02\u01D5\u01D6\x05\u0156\xA7\x02\u01D6\u01D7\x03\x02\x02\x02\u01D7" + + "\u01D8\b\x0F\x02\x02\u01D8\'\x03\x02\x02\x02\u01D9\u01DA\x05\u014E\xA3" + + "\x02\u01DA\u01DB\x05\u0138\x98\x02\u01DB\u01DC\x05\u0146\x9F\x02\u01DC" + + "\u01DD\x05\u0156\xA7\x02\u01DD\u01DE\x03\x02\x02\x02\u01DE\u01DF\b\x10" + + "\t\x02\u01DF)\x03\x02\x02\x02\u01E0\u01E1\x05\u014E\xA3\x02\u01E1\u01E2" + + "\x05\u0146\x9F\x02\u01E2\u01E3\x05\u014C\xA2\x02\u01E3\u01E4\x05\u0150" + + "\xA4\x02\u01E4\u01E5\x03\x02\x02\x02\u01E5\u01E6\b\x11\x02\x02\u01E6+" + + "\x03\x02\x02\x02\u01E7\u01E8\x05\u014E\xA3\x02\u01E8\u01E9\x05\u0150\xA4" + + "\x02\u01E9\u01EA\x05\u012A\x91\x02\u01EA\u01EB\x05\u0150\xA4\x02\u01EB" + + "\u01EC\x05\u014E\xA3\x02\u01EC\u01ED\x03\x02\x02\x02\u01ED\u01EE\b\x12" + + "\x02\x02\u01EE-\x03\x02\x02\x02\u01EF\u01F0\x05\u0156\xA7\x02\u01F0\u01F1" + + "\x05\u0138\x98\x02\u01F1\u01F2\x05\u0132\x95\x02\u01F2\u01F3\x05\u014C" + + "\xA2\x02\u01F3\u01F4\x05\u0132\x95\x02\u01F4\u01F5\x03\x02\x02\x02\u01F5" + + "\u01F6\b\x13\x02\x02\u01F6/\x03\x02\x02\x02\u01F7\u01F9\n\x02\x02\x02" + + "\u01F8\u01F7\x03\x02\x02\x02\u01F9\u01FA\x03\x02\x02\x02\u01FA\u01F8\x03" + + "\x02\x02\x02\u01FA\u01FB\x03\x02\x02\x02\u01FB\u01FC\x03\x02\x02\x02\u01FC" + + "\u01FD\b\x14\x02\x02\u01FD1\x03\x02\x02\x02\u01FE\u01FF\x071\x02\x02\u01FF" + + "\u0200\x071\x02\x02\u0200\u0204\x03\x02\x02\x02\u0201\u0203\n\x03\x02" + + "\x02\u0202\u0201\x03\x02\x02\x02\u0203\u0206\x03\x02\x02\x02\u0204\u0202" + + "\x03\x02\x02\x02\u0204\u0205\x03\x02\x02\x02\u0205\u0208\x03\x02\x02\x02" + + "\u0206\u0204\x03\x02\x02\x02\u0207\u0209\x07\x0F\x02\x02\u0208\u0207\x03" + + "\x02\x02\x02\u0208\u0209\x03\x02\x02\x02\u0209\u020B\x03\x02\x02\x02\u020A" + + "\u020C\x07\f\x02\x02\u020B\u020A\x03\x02\x02\x02\u020B\u020C\x03\x02\x02" + + "\x02\u020C\u020D\x03\x02\x02\x02\u020D\u020E\b\x15\n\x02\u020E3\x03\x02" + + "\x02\x02\u020F\u0210\x071\x02\x02\u0210\u0211\x07,\x02\x02\u0211\u0216" + + "\x03\x02\x02\x02\u0212\u0215\x054\x16\x02\u0213\u0215\v\x02\x02\x02\u0214" + + "\u0212\x03\x02\x02\x02\u0214\u0213\x03\x02\x02\x02\u0215\u0218\x03\x02" + + "\x02\x02\u0216\u0217\x03\x02\x02\x02\u0216\u0214\x03\x02\x02\x02\u0217" + + "\u0219\x03\x02\x02\x02\u0218\u0216\x03\x02\x02\x02\u0219\u021A\x07,\x02" + + "\x02\u021A\u021B\x071\x02\x02\u021B\u021C\x03\x02\x02\x02\u021C\u021D" + + "\b\x16\n\x02\u021D5\x03\x02\x02\x02\u021E\u0220\t\x04\x02\x02\u021F\u021E" + + "\x03\x02\x02\x02\u0220\u0221\x03\x02\x02\x02\u0221\u021F\x03\x02\x02\x02" + + "\u0221\u0222\x03\x02\x02\x02\u0222\u0223\x03\x02\x02\x02\u0223\u0224\b" + + "\x17\n\x02\u02247\x03\x02\x02\x02\u0225\u0226\x05\xA0L\x02\u0226\u0227" + + "\x03\x02\x02\x02\u0227\u0228\b\x18\v\x02\u0228\u0229\b\x18\f\x02\u0229" + + "9\x03\x02\x02\x02\u022A\u022B\x05B\x1D\x02\u022B\u022C\x03\x02\x02\x02" + + "\u022C\u022D\b\x19\r\x02\u022D\u022E\b\x19\x0E\x02\u022E;\x03\x02\x02" + + "\x02\u022F\u0230\x056\x17\x02\u0230\u0231\x03\x02\x02\x02\u0231\u0232" + + "\b\x1A\n\x02\u0232=\x03\x02\x02\x02\u0233\u0234\x052\x15\x02\u0234\u0235" + + "\x03\x02\x02\x02\u0235\u0236\b\x1B\n\x02\u0236?\x03\x02\x02\x02\u0237" + + "\u0238\x054\x16\x02\u0238\u0239\x03\x02\x02\x02\u0239\u023A\b\x1C\n\x02" + + "\u023AA\x03\x02\x02\x02\u023B\u023C\x07~\x02\x02\u023C\u023D\x03\x02\x02" + + "\x02\u023D\u023E\b\x1D\x0E\x02\u023EC\x03\x02\x02\x02\u023F\u0240\t\x05" + + "\x02\x02\u0240E\x03\x02\x02\x02\u0241\u0242\t\x06\x02\x02\u0242G\x03\x02" + + "\x02\x02\u0243\u0244\x07^\x02\x02\u0244\u0245\t\x07\x02\x02\u0245I\x03" + + "\x02\x02\x02\u0246\u0247\n\b\x02\x02\u0247K\x03\x02\x02\x02\u0248\u024A" + + "\t\t\x02\x02\u0249\u024B\t\n\x02\x02\u024A\u0249\x03\x02\x02\x02\u024A" + + "\u024B\x03\x02\x02\x02\u024B\u024D\x03\x02\x02\x02\u024C\u024E\x05D\x1E" + + "\x02\u024D\u024C\x03\x02\x02\x02\u024E\u024F\x03\x02\x02\x02\u024F\u024D" + + "\x03\x02\x02\x02\u024F\u0250\x03\x02\x02\x02\u0250M\x03\x02\x02\x02\u0251" + + "\u0252\x07B\x02\x02\u0252O\x03\x02\x02\x02\u0253\u0254\x07b\x02\x02\u0254" + + "Q\x03\x02\x02\x02\u0255\u0259\n\v\x02\x02\u0256\u0257\x07b\x02\x02\u0257" + + "\u0259\x07b\x02\x02\u0258\u0255\x03\x02\x02\x02\u0258\u0256\x03\x02\x02" + + "\x02\u0259S\x03\x02\x02\x02\u025A\u025B\x07a\x02\x02\u025BU\x03\x02\x02" + + "\x02\u025C\u0260\x05F\x1F\x02\u025D\u0260\x05D\x1E\x02\u025E\u0260\x05" + + "T&\x02\u025F\u025C\x03\x02\x02\x02\u025F\u025D\x03\x02\x02\x02\u025F\u025E" + + "\x03\x02\x02\x02\u0260W\x03\x02\x02\x02\u0261\u0266\x07$\x02\x02\u0262" + + "\u0265\x05H \x02\u0263\u0265\x05J!\x02\u0264\u0262\x03\x02\x02\x02\u0264" + + "\u0263\x03\x02\x02\x02\u0265\u0268\x03\x02\x02\x02\u0266\u0264\x03\x02" + + "\x02\x02\u0266\u0267\x03\x02\x02\x02\u0267\u0269\x03\x02\x02\x02\u0268" + + "\u0266\x03\x02\x02\x02\u0269\u027F\x07$\x02\x02\u026A\u026B\x07$\x02\x02" + + "\u026B\u026C\x07$\x02\x02\u026C\u026D\x07$\x02\x02\u026D\u0271\x03\x02" + + "\x02\x02\u026E\u0270\n\x03\x02\x02\u026F\u026E\x03\x02\x02\x02\u0270\u0273" + + "\x03\x02\x02\x02\u0271\u0272\x03\x02\x02\x02\u0271\u026F\x03\x02\x02\x02" + + "\u0272\u0274\x03\x02\x02\x02\u0273\u0271\x03\x02\x02\x02\u0274\u0275\x07" + + "$\x02\x02\u0275\u0276\x07$\x02\x02\u0276\u0277\x07$\x02\x02\u0277\u0279" + + "\x03\x02\x02\x02\u0278\u027A\x07$\x02\x02\u0279\u0278\x03\x02\x02\x02" + + "\u0279\u027A\x03\x02\x02\x02\u027A\u027C\x03\x02\x02\x02\u027B\u027D\x07" + + "$\x02\x02\u027C\u027B\x03\x02\x02\x02\u027C\u027D\x03\x02\x02\x02\u027D" + + "\u027F\x03\x02\x02\x02\u027E\u0261\x03\x02\x02\x02\u027E\u026A\x03\x02" + + "\x02\x02\u027FY\x03\x02\x02\x02\u0280\u0282\x05D\x1E\x02\u0281\u0280\x03" + + "\x02\x02\x02\u0282\u0283\x03\x02\x02\x02\u0283\u0281\x03\x02\x02\x02\u0283" + + "\u0284\x03\x02\x02\x02\u0284[\x03\x02\x02\x02\u0285\u0287\x05D\x1E\x02" + + "\u0286\u0285\x03\x02\x02\x02\u0287\u0288\x03\x02\x02\x02\u0288\u0286\x03" + + "\x02\x02\x02\u0288\u0289\x03\x02\x02\x02\u0289\u028A\x03\x02\x02\x02\u028A" + + "\u028E\x05j1\x02\u028B\u028D\x05D\x1E\x02\u028C\u028B\x03\x02\x02\x02" + + "\u028D\u0290\x03\x02\x02\x02\u028E\u028C\x03\x02\x02\x02\u028E\u028F\x03" + + "\x02\x02\x02\u028F\u02B0\x03\x02\x02\x02\u0290\u028E\x03\x02\x02\x02\u0291" + + "\u0293\x05j1\x02\u0292\u0294\x05D\x1E\x02\u0293\u0292\x03\x02\x02\x02" + + "\u0294\u0295\x03\x02\x02\x02\u0295\u0293\x03\x02\x02\x02\u0295\u0296\x03" + + "\x02\x02\x02\u0296\u02B0\x03\x02\x02\x02\u0297\u0299\x05D\x1E\x02\u0298" + + "\u0297\x03\x02\x02\x02\u0299\u029A\x03\x02\x02\x02\u029A\u0298\x03\x02" + + "\x02\x02\u029A\u029B\x03\x02\x02\x02\u029B\u02A3\x03\x02\x02\x02\u029C" + + "\u02A0\x05j1\x02\u029D\u029F\x05D\x1E\x02\u029E\u029D\x03\x02\x02\x02" + + "\u029F\u02A2\x03\x02\x02\x02\u02A0\u029E\x03\x02\x02\x02\u02A0\u02A1\x03" + + "\x02\x02\x02\u02A1\u02A4\x03\x02\x02\x02\u02A2\u02A0\x03\x02\x02\x02\u02A3" + + "\u029C\x03\x02\x02\x02\u02A3\u02A4\x03\x02\x02\x02\u02A4\u02A5\x03\x02" + + "\x02\x02\u02A5\u02A6\x05L\"\x02\u02A6\u02B0\x03\x02\x02\x02\u02A7\u02A9" + + "\x05j1\x02\u02A8\u02AA\x05D\x1E\x02\u02A9\u02A8\x03\x02\x02\x02\u02AA" + + "\u02AB\x03\x02\x02\x02\u02AB\u02A9\x03\x02\x02\x02\u02AB\u02AC\x03\x02" + + "\x02\x02\u02AC\u02AD\x03\x02\x02\x02\u02AD\u02AE\x05L\"\x02\u02AE\u02B0" + + "\x03\x02\x02\x02\u02AF\u0286\x03\x02\x02\x02\u02AF\u0291\x03\x02\x02\x02" + + "\u02AF\u0298\x03\x02\x02\x02\u02AF\u02A7\x03\x02\x02\x02\u02B0]\x03\x02" + + "\x02\x02\u02B1\u02B2\x05\u012C\x92\x02\u02B2\u02B3\x05\u015A\xA9\x02\u02B3" + + "_\x03\x02\x02\x02\u02B4\u02B5\x05\u012A\x91\x02\u02B5\u02B6\x05\u0144" + + "\x9E\x02\u02B6\u02B7\x05\u0130\x94\x02\u02B7a\x03\x02\x02\x02\u02B8\u02B9" + + "\x05\u012A\x91\x02\u02B9\u02BA\x05\u014E\xA3\x02\u02BA\u02BB\x05\u012E" + + "\x93\x02\u02BBc\x03\x02\x02\x02\u02BC\u02BD\x07?\x02\x02\u02BDe\x03\x02" + + "\x02\x02\u02BE\u02BF\x07.\x02\x02\u02BFg\x03\x02\x02\x02\u02C0\u02C1\x05" + + "\u0130\x94\x02\u02C1\u02C2\x05\u0132\x95\x02\u02C2\u02C3\x05\u014E\xA3" + + "\x02\u02C3\u02C4\x05\u012E\x93\x02\u02C4i\x03\x02\x02\x02\u02C5\u02C6" + + "\x070\x02\x02\u02C6k\x03\x02\x02\x02\u02C7\u02C8\x05\u0134\x96\x02\u02C8" + + "\u02C9\x05\u012A\x91\x02\u02C9\u02CA\x05\u0140\x9C\x02\u02CA\u02CB\x05" + + "\u014E\xA3\x02\u02CB\u02CC\x05\u0132\x95\x02\u02CCm\x03\x02\x02\x02\u02CD" + + "\u02CE\x05\u0134\x96\x02\u02CE\u02CF\x05\u013A\x99\x02\u02CF\u02D0\x05" + + "\u014C\xA2\x02\u02D0\u02D1\x05\u014E\xA3\x02\u02D1\u02D2\x05\u0150\xA4" + + "\x02\u02D2o\x03\x02\x02\x02\u02D3\u02D4\x05\u0140\x9C\x02\u02D4\u02D5" + + "\x05\u012A\x91\x02\u02D5\u02D6\x05\u014E\xA3\x02\u02D6\u02D7\x05\u0150" + + "\xA4\x02\u02D7q\x03\x02\x02\x02\u02D8\u02D9\x07*\x02\x02\u02D9s\x03\x02" + + "\x02\x02\u02DA\u02DB\x05\u013A\x99\x02\u02DB\u02DC\x05\u0144\x9E\x02\u02DC" + + "u\x03\x02\x02\x02\u02DD\u02DE\x05\u013A\x99\x02\u02DE\u02DF\x05\u014E" + + "\xA3\x02\u02DFw\x03\x02\x02\x02\u02E0\u02E1\x05\u0140\x9C\x02\u02E1\u02E2" + + "\x05\u013A\x99\x02\u02E2\u02E3\x05\u013E\x9B\x02\u02E3\u02E4\x05\u0132" + + "\x95\x02\u02E4y\x03\x02\x02\x02\u02E5\u02E6\x05\u0144\x9E\x02\u02E6\u02E7" + + "\x05\u0146\x9F\x02\u02E7\u02E8\x05\u0150\xA4\x02\u02E8{\x03\x02\x02\x02" + + "\u02E9\u02EA\x05\u0144\x9E\x02\u02EA\u02EB\x05\u0152\xA5\x02\u02EB\u02EC" + + "\x05\u0140\x9C\x02\u02EC\u02ED\x05\u0140\x9C\x02\u02ED}\x03\x02\x02\x02" + + "\u02EE\u02EF\x05\u0144\x9E\x02\u02EF\u02F0\x05\u0152\xA5\x02\u02F0\u02F1" + + "\x05\u0140\x9C\x02\u02F1\u02F2\x05\u0140\x9C\x02\u02F2\u02F3\x05\u014E" + + "\xA3\x02\u02F3\x7F\x03\x02\x02\x02\u02F4\u02F5\x05\u0146\x9F\x02\u02F5" + + "\u02F6\x05\u014C\xA2\x02\u02F6\x81\x03\x02\x02\x02\u02F7\u02F8\x07A\x02" + + "\x02\u02F8\x83\x03\x02\x02\x02\u02F9\u02FA\x05\u014C\xA2\x02\u02FA\u02FB" + + "\x05\u0140\x9C\x02\u02FB\u02FC\x05\u013A\x99\x02\u02FC\u02FD\x05\u013E" + + "\x9B\x02\u02FD\u02FE\x05\u0132\x95\x02\u02FE\x85\x03\x02\x02\x02\u02FF" + + "\u0300\x07+\x02\x02\u0300\x87\x03\x02\x02\x02\u0301\u0302\x05\u0150\xA4" + + "\x02\u0302\u0303\x05\u014C\xA2\x02\u0303\u0304\x05\u0152\xA5\x02\u0304" + + "\u0305\x05\u0132\x95\x02\u0305\x89\x03\x02\x02\x02\u0306\u0307\x07?\x02" + + "\x02\u0307\u0308\x07?\x02\x02\u0308\x8B\x03\x02\x02\x02\u0309\u030A\x07" + + "#\x02\x02\u030A\u030B\x07?\x02\x02\u030B\x8D\x03\x02\x02\x02\u030C\u030D" + + "\x07>\x02\x02\u030D\x8F\x03\x02\x02\x02\u030E\u030F\x07>\x02\x02\u030F" + + "\u0310\x07?\x02\x02\u0310\x91\x03\x02\x02\x02\u0311\u0312\x07@\x02\x02" + + "\u0312\x93\x03\x02\x02\x02\u0313\u0314\x07@\x02\x02\u0314\u0315\x07?\x02" + + "\x02\u0315\x95\x03\x02\x02\x02\u0316\u0317\x07-\x02\x02\u0317\x97\x03" + + "\x02\x02\x02\u0318\u0319\x07/\x02\x02\u0319\x99\x03\x02\x02\x02\u031A" + + "\u031B\x07,\x02\x02\u031B\x9B\x03\x02\x02\x02\u031C\u031D\x071\x02\x02" + + "\u031D\x9D\x03\x02\x02\x02\u031E\u031F\x07\'\x02\x02\u031F\x9F\x03\x02" + + "\x02\x02\u0320\u0321\x07]\x02\x02\u0321\u0322\x03\x02\x02\x02\u0322\u0323" + + "\bL\x02\x02\u0323\u0324\bL\x02\x02\u0324\xA1\x03\x02\x02\x02\u0325\u0326" + + "\x07_\x02\x02\u0326\u0327\x03\x02\x02\x02\u0327\u0328\bM\x0E\x02\u0328" + + "\u0329\bM\x0E\x02\u0329\xA3\x03\x02\x02\x02\u032A\u032E\x05F\x1F\x02\u032B" + + "\u032D\x05V\'\x02\u032C\u032B\x03\x02\x02\x02\u032D\u0330\x03\x02\x02" + + "\x02\u032E\u032C\x03\x02\x02\x02\u032E\u032F\x03\x02\x02\x02\u032F\u033B" + + "\x03\x02\x02\x02\u0330\u032E\x03\x02\x02\x02\u0331\u0334\x05T&\x02\u0332" + + "\u0334\x05N#\x02\u0333\u0331\x03\x02\x02\x02\u0333\u0332\x03\x02\x02\x02" + + "\u0334\u0336\x03\x02\x02\x02\u0335\u0337\x05V\'\x02\u0336\u0335\x03\x02" + + "\x02\x02\u0337\u0338\x03\x02\x02\x02\u0338\u0336\x03\x02\x02\x02\u0338" + + "\u0339\x03\x02\x02\x02\u0339\u033B\x03\x02\x02\x02\u033A\u032A\x03\x02" + + "\x02\x02\u033A\u0333\x03\x02\x02\x02\u033B\xA5\x03\x02\x02\x02\u033C\u033E" + + "\x05P$\x02\u033D\u033F\x05R%\x02\u033E\u033D\x03\x02\x02\x02\u033F\u0340" + + "\x03\x02\x02\x02\u0340\u033E\x03\x02\x02\x02\u0340\u0341\x03\x02\x02\x02" + + "\u0341\u0342\x03\x02\x02\x02\u0342\u0343\x05P$\x02\u0343\xA7\x03\x02\x02" + + "\x02\u0344\u0345\x052\x15\x02\u0345\u0346\x03\x02\x02\x02\u0346\u0347" + + "\bP\n\x02\u0347\xA9\x03\x02\x02\x02\u0348\u0349\x054\x16\x02\u0349\u034A" + + "\x03\x02\x02\x02\u034A\u034B\bQ\n\x02\u034B\xAB\x03\x02\x02\x02\u034C" + + "\u034D\x056\x17\x02\u034D\u034E\x03\x02\x02\x02\u034E\u034F\bR\n\x02\u034F" + + "\xAD\x03\x02\x02\x02\u0350\u0351\x05B\x1D\x02\u0351\u0352\x03\x02\x02" + + "\x02\u0352\u0353\bS\r\x02\u0353\u0354\bS\x0E\x02\u0354\xAF\x03\x02\x02" + + "\x02\u0355\u0356\x05\xA0L\x02\u0356\u0357\x03\x02\x02\x02\u0357\u0358" + + "\bT\v\x02\u0358\u0359\bT\x06\x02\u0359\u035A\bT\x06\x02\u035A\xB1\x03" + + "\x02\x02\x02\u035B\u035C\x05\xA2M\x02\u035C\u035D\x03\x02\x02\x02\u035D" + + "\u035E\bU\x0F\x02\u035E\u035F\bU\x0E\x02\u035F\u0360\bU\x0E\x02\u0360" + + "\xB3\x03\x02\x02\x02\u0361\u0362\x05f/\x02\u0362\u0363\x03\x02\x02\x02" + + "\u0363\u0364\bV\x10\x02\u0364\xB5\x03\x02\x02\x02\u0365\u0366\x05d.\x02" + + "\u0366\u0367\x03\x02\x02\x02\u0367\u0368\bW\x11\x02\u0368\xB7\x03\x02" + + "\x02\x02\u0369\u036A\x05\u0142\x9D\x02\u036A\u036B\x05\u0132\x95\x02\u036B" + + "\u036C\x05\u0150\xA4\x02\u036C\u036D\x05\u012A\x91\x02\u036D\u036E\x05" + + "\u0130\x94\x02\u036E\u036F\x05\u012A\x91\x02\u036F\u0370\x05\u0150\xA4" + + "\x02\u0370\u0371\x05\u012A\x91\x02\u0371\xB9\x03\x02\x02\x02\u0372\u0376" + + "\n\f\x02\x02\u0373\u0374\x071\x02\x02\u0374\u0376\n\r\x02\x02\u0375\u0372" + + "\x03\x02\x02\x02\u0375\u0373\x03\x02\x02\x02\u0376\xBB\x03\x02\x02\x02" + + "\u0377\u0379\x05\xBAY\x02\u0378\u0377\x03\x02\x02\x02\u0379\u037A\x03" + + "\x02\x02\x02\u037A\u0378\x03\x02\x02\x02\u037A\u037B\x03\x02\x02\x02\u037B" + + "\xBD\x03\x02\x02\x02\u037C\u037D\x05\xA6O\x02\u037D\u037E\x03\x02\x02" + + "\x02\u037E\u037F\b[\x12\x02\u037F\xBF\x03\x02\x02\x02\u0380\u0381\x05" + + "2\x15\x02\u0381\u0382\x03\x02\x02\x02\u0382\u0383\b\\\n\x02\u0383\xC1" + + "\x03\x02\x02\x02\u0384\u0385\x054\x16\x02\u0385\u0386\x03\x02\x02\x02" + + "\u0386\u0387\b]\n\x02\u0387\xC3\x03\x02\x02\x02\u0388\u0389\x056\x17\x02" + + "\u0389\u038A\x03\x02\x02\x02\u038A\u038B\b^\n\x02\u038B\xC5\x03\x02\x02" + + "\x02\u038C\u038D\x05B\x1D\x02\u038D\u038E\x03\x02\x02\x02\u038E\u038F" + + "\b_\r\x02\u038F\u0390\b_\x0E\x02\u0390\xC7\x03\x02\x02\x02\u0391\u0392" + + "\x05j1\x02\u0392\u0393\x03\x02\x02\x02\u0393\u0394\b`\x13\x02\u0394\xC9" + + "\x03\x02\x02\x02\u0395\u0396\x05f/\x02\u0396\u0397\x03\x02\x02\x02\u0397" + + "\u0398\ba\x10\x02\u0398\xCB\x03\x02\x02\x02\u0399\u039E\x05F\x1F\x02\u039A" + + "\u039E\x05D\x1E\x02\u039B\u039E\x05T&\x02\u039C\u039E\x05\x9AI\x02\u039D" + + "\u0399\x03\x02\x02\x02\u039D\u039A\x03\x02\x02\x02\u039D\u039B\x03\x02" + + "\x02\x02\u039D\u039C\x03\x02\x02\x02\u039E\xCD\x03\x02\x02\x02\u039F\u03A2" + + "\x05F\x1F\x02\u03A0\u03A2\x05\x9AI\x02\u03A1\u039F\x03\x02\x02\x02\u03A1" + + "\u03A0\x03\x02\x02\x02\u03A2\u03A6\x03\x02\x02\x02\u03A3\u03A5\x05\xCC" + + "b\x02\u03A4\u03A3\x03\x02\x02\x02\u03A5\u03A8\x03\x02\x02\x02\u03A6\u03A4" + + "\x03\x02\x02\x02\u03A6\u03A7\x03\x02\x02\x02\u03A7\u03B3\x03\x02\x02\x02" + + "\u03A8\u03A6\x03\x02\x02\x02\u03A9\u03AC\x05T&\x02\u03AA\u03AC\x05N#\x02" + + "\u03AB\u03A9\x03\x02\x02\x02\u03AB\u03AA\x03\x02\x02\x02\u03AC\u03AE\x03" + + "\x02\x02\x02\u03AD\u03AF\x05\xCCb\x02\u03AE\u03AD\x03\x02\x02\x02\u03AF" + + "\u03B0\x03\x02\x02\x02\u03B0\u03AE\x03\x02\x02\x02\u03B0\u03B1\x03\x02" + + "\x02\x02\u03B1\u03B3\x03\x02\x02\x02\u03B2\u03A1\x03\x02\x02\x02\u03B2" + + "\u03AB\x03\x02\x02\x02\u03B3\xCF\x03\x02\x02\x02\u03B4\u03B5\x05\xA6O" + + "\x02\u03B5\u03B6\x03\x02\x02\x02\u03B6\u03B7\bd\x12\x02\u03B7\xD1\x03" + + "\x02\x02\x02\u03B8\u03B9\x052\x15\x02\u03B9\u03BA\x03\x02\x02\x02\u03BA" + + "\u03BB\be\n\x02\u03BB\xD3\x03\x02\x02\x02\u03BC\u03BD\x054\x16\x02\u03BD" + + "\u03BE\x03\x02\x02\x02\u03BE\u03BF\bf\n\x02\u03BF\xD5\x03\x02\x02\x02" + + "\u03C0\u03C1\x056\x17\x02\u03C1\u03C2\x03\x02\x02\x02\u03C2\u03C3\bg\n" + + "\x02\u03C3\xD7\x03\x02\x02\x02\u03C4\u03C5\x05B\x1D\x02\u03C5\u03C6\x03" + + "\x02\x02\x02\u03C6\u03C7\bh\r\x02\u03C7\u03C8\bh\x0E\x02\u03C8\xD9\x03" + + "\x02\x02\x02\u03C9\u03CA\x05d.\x02\u03CA\u03CB\x03\x02\x02\x02\u03CB\u03CC" + + "\bi\x11\x02\u03CC\xDB\x03\x02\x02\x02\u03CD\u03CE\x05f/\x02\u03CE\u03CF" + + "\x03\x02\x02\x02\u03CF\u03D0\bj\x10\x02\u03D0\xDD\x03\x02\x02\x02\u03D1" + + "\u03D2\x05j1\x02\u03D2\u03D3\x03\x02\x02\x02\u03D3\u03D4\bk\x13\x02\u03D4" + + "\xDF\x03\x02\x02\x02\u03D5\u03D6\x05\u012A\x91\x02\u03D6\u03D7\x05\u014E" + + "\xA3\x02\u03D7\xE1\x03\x02\x02\x02\u03D8\u03D9\x05\xA6O\x02\u03D9\u03DA" + + "\x03\x02\x02\x02\u03DA\u03DB\bm\x12\x02\u03DB\xE3\x03\x02\x02\x02\u03DC" + + "\u03DD\x05\xCEc\x02\u03DD\u03DE\x03\x02\x02\x02\u03DE\u03DF\bn\x14\x02" + + "\u03DF\xE5\x03\x02\x02\x02\u03E0\u03E1\x052\x15\x02\u03E1\u03E2\x03\x02" + + "\x02\x02\u03E2\u03E3\bo\n\x02\u03E3\xE7\x03\x02\x02\x02\u03E4\u03E5\x05" + + "4\x16\x02\u03E5\u03E6\x03\x02\x02\x02\u03E6\u03E7\bp\n\x02\u03E7\xE9\x03" + + "\x02\x02\x02\u03E8\u03E9\x056\x17\x02\u03E9\u03EA\x03\x02\x02\x02\u03EA" + + "\u03EB\bq\n\x02\u03EB\xEB\x03\x02\x02\x02\u03EC\u03ED\x05B\x1D\x02\u03ED" + + "\u03EE\x03\x02\x02\x02\u03EE\u03EF\br\r\x02\u03EF\u03F0\br\x0E\x02\u03F0" + + "\xED\x03\x02\x02\x02\u03F1\u03F2\x05\u0146\x9F\x02\u03F2\u03F3\x05\u0144" + + "\x9E\x02\u03F3\u03F4\x03\x02\x02\x02\u03F4\u03F5\bs\x15\x02\u03F5\xEF" + + "\x03\x02\x02\x02\u03F6\u03F7\x05\u0156\xA7\x02\u03F7\u03F8\x05\u013A\x99" + + "\x02\u03F8\u03F9\x05\u0150\xA4\x02\u03F9\u03FA\x05\u0138\x98\x02\u03FA" + + "\u03FB\x03\x02\x02\x02\u03FB\u03FC\bt\x15\x02\u03FC\xF1\x03\x02\x02\x02" + + "\u03FD\u03FE\x05\xBCZ\x02\u03FE\u03FF\x03\x02\x02\x02\u03FF\u0400\bu\x16" + + "\x02\u0400\xF3\x03\x02\x02\x02\u0401\u0402\x05\xA6O\x02\u0402\u0403\x03" + + "\x02\x02\x02\u0403\u0404\bv\x12\x02\u0404\xF5\x03\x02\x02\x02\u0405\u0406" + + "\x052\x15\x02\u0406\u0407\x03\x02\x02\x02\u0407\u0408\bw\n\x02\u0408\xF7" + + "\x03\x02\x02\x02\u0409\u040A\x054\x16\x02\u040A\u040B\x03\x02\x02\x02" + + "\u040B\u040C\bx\n\x02\u040C\xF9\x03\x02\x02\x02\u040D\u040E\x056\x17\x02" + + "\u040E\u040F\x03\x02\x02\x02\u040F\u0410\by\n\x02\u0410\xFB\x03\x02\x02" + + "\x02\u0411\u0412\x05B\x1D\x02\u0412\u0413\x03\x02\x02\x02\u0413\u0414" + + "\bz\r\x02\u0414\u0415\bz\x0E\x02\u0415\u0416\bz\x0E\x02\u0416\xFD\x03" + + "\x02\x02\x02\u0417\u0418\x05d.\x02\u0418\u0419\x03\x02\x02\x02\u0419\u041A" + + "\b{\x11\x02\u041A\xFF\x03\x02\x02\x02\u041B\u041C\x05f/\x02\u041C\u041D" + + "\x03\x02\x02\x02\u041D\u041E\b|\x10\x02\u041E\u0101\x03\x02\x02\x02\u041F" + + "\u0420\x05j1\x02\u0420\u0421\x03\x02\x02\x02\u0421\u0422\b}\x13\x02\u0422" + + "\u0103\x03\x02\x02\x02\u0423\u0424\x05\xF0t\x02\u0424\u0425\x03\x02\x02" + + "\x02\u0425\u0426\b~\x17\x02\u0426\u0105\x03\x02\x02\x02\u0427\u0428\x05" + + "\xCEc\x02\u0428\u0429\x03\x02\x02\x02\u0429\u042A\b\x7F\x14\x02\u042A" + + "\u0107\x03\x02\x02\x02\u042B\u042C\x05\xA6O\x02\u042C\u042D\x03\x02\x02" + + "\x02\u042D\u042E\b\x80\x12\x02\u042E\u0109\x03\x02\x02\x02\u042F\u0430" + + "\x052\x15\x02\u0430\u0431\x03\x02\x02\x02\u0431\u0432\b\x81\n\x02\u0432" + + "\u010B\x03\x02\x02\x02\u0433\u0434\x054\x16\x02\u0434\u0435\x03\x02\x02" + + "\x02\u0435\u0436\b\x82\n\x02\u0436\u010D\x03\x02\x02\x02\u0437\u0438\x05" + + "6\x17\x02\u0438\u0439\x03\x02\x02\x02\u0439\u043A\b\x83\n\x02\u043A\u010F" + + "\x03\x02\x02\x02\u043B\u043C\x05B\x1D\x02\u043C\u043D\x03\x02\x02\x02" + + "\u043D\u043E\b\x84\r\x02\u043E\u043F\b\x84\x0E\x02\u043F\u0111\x03\x02" + + "\x02\x02\u0440\u0441\x05j1\x02\u0441\u0442\x03\x02\x02\x02\u0442\u0443" + + "\b\x85\x13\x02\u0443\u0113\x03\x02\x02\x02\u0444\u0445\x05\xA6O\x02\u0445" + + "\u0446\x03\x02\x02\x02\u0446\u0447\b\x86\x12\x02\u0447\u0115\x03\x02\x02" + + "\x02\u0448\u0449\x05\xA4N\x02\u0449\u044A\x03\x02\x02\x02\u044A\u044B" + + "\b\x87\x18\x02\u044B\u0117\x03\x02\x02\x02\u044C\u044D\x052\x15\x02\u044D" + + "\u044E\x03\x02\x02\x02\u044E\u044F\b\x88\n\x02\u044F\u0119\x03\x02\x02" + + "\x02\u0450\u0451\x054\x16\x02\u0451\u0452\x03\x02\x02\x02\u0452\u0453" + + "\b\x89\n\x02\u0453\u011B\x03\x02\x02\x02\u0454\u0455\x056\x17\x02\u0455" + + "\u0456\x03\x02\x02\x02\u0456\u0457\b\x8A\n\x02\u0457\u011D\x03\x02\x02" + + "\x02\u0458\u0459\x05B\x1D\x02\u0459\u045A\x03\x02\x02\x02\u045A\u045B" + + "\b\x8B\r\x02\u045B\u045C\b\x8B\x0E\x02\u045C\u011F\x03\x02\x02\x02\u045D" + + "\u045E\x05\u013A\x99\x02\u045E\u045F\x05\u0144\x9E\x02\u045F\u0460\x05" + + "\u0134\x96\x02\u0460\u0461\x05\u0146\x9F\x02\u0461\u0121\x03\x02\x02\x02" + + "\u0462\u0463\x05\u0134\x96\x02\u0463\u0464\x05\u0152\xA5\x02\u0464\u0465" + + "\x05\u0144\x9E\x02\u0465\u0466\x05\u012E\x93\x02\u0466\u0467\x05\u0150" + + "\xA4\x02\u0467\u0468\x05\u013A\x99\x02\u0468\u0469\x05\u0146\x9F\x02\u0469" + + "\u046A\x05\u0144\x9E\x02\u046A\u046B\x05\u014E\xA3\x02\u046B\u0123\x03" + + "\x02\x02\x02\u046C\u046D\x052\x15\x02"; + private static readonly _serializedATNSegment2: string = + "\u046D\u046E\x03\x02\x02\x02\u046E\u046F\b\x8E\n\x02\u046F\u0125\x03\x02" + + "\x02\x02\u0470\u0471\x054\x16\x02\u0471\u0472\x03\x02\x02\x02\u0472\u0473" + + "\b\x8F\n\x02\u0473\u0127\x03\x02\x02\x02\u0474\u0475\x056\x17\x02\u0475" + + "\u0476\x03\x02\x02\x02\u0476\u0477\b\x90\n\x02\u0477\u0129\x03\x02\x02" + + "\x02\u0478\u0479\t\x0E\x02\x02\u0479\u012B\x03\x02\x02\x02\u047A\u047B" + + "\t\x0F\x02\x02\u047B\u012D\x03\x02\x02\x02\u047C\u047D\t\x10\x02\x02\u047D" + + "\u012F\x03\x02\x02\x02\u047E\u047F\t\x11\x02\x02\u047F\u0131\x03\x02\x02" + + "\x02\u0480\u0481\t\t\x02\x02\u0481\u0133\x03\x02\x02\x02\u0482\u0483\t" + + "\x12\x02\x02\u0483\u0135\x03\x02\x02\x02\u0484\u0485\t\x13\x02\x02\u0485" + + "\u0137\x03\x02\x02\x02\u0486\u0487\t\x14\x02\x02\u0487\u0139\x03\x02\x02" + + "\x02\u0488\u0489\t\x15\x02\x02\u0489\u013B\x03\x02\x02\x02\u048A\u048B" + + "\t\x16\x02\x02\u048B\u013D\x03\x02\x02\x02\u048C\u048D\t\x17\x02\x02\u048D" + + "\u013F\x03\x02\x02\x02\u048E\u048F\t\x18\x02\x02\u048F\u0141\x03\x02\x02" + + "\x02\u0490\u0491\t\x19\x02\x02\u0491\u0143\x03\x02\x02\x02\u0492\u0493" + + "\t\x1A\x02\x02\u0493\u0145\x03\x02\x02\x02\u0494\u0495\t\x1B\x02\x02\u0495" + + "\u0147\x03\x02\x02\x02\u0496\u0497\t\x1C\x02\x02\u0497\u0149\x03\x02\x02" + + "\x02\u0498\u0499\t\x1D\x02\x02\u0499\u014B\x03\x02\x02\x02\u049A\u049B" + + "\t\x1E\x02\x02\u049B\u014D\x03\x02\x02\x02\u049C\u049D\t\x1F\x02\x02\u049D" + + "\u014F\x03\x02\x02\x02\u049E\u049F\t \x02\x02\u049F\u0151\x03\x02\x02" + + "\x02\u04A0\u04A1\t!\x02\x02\u04A1\u0153\x03\x02\x02\x02\u04A2\u04A3\t" + + "\"\x02\x02\u04A3\u0155\x03\x02\x02\x02\u04A4\u04A5\t#\x02\x02\u04A5\u0157" + + "\x03\x02\x02\x02\u04A6\u04A7\t$\x02\x02\u04A7\u0159\x03\x02\x02\x02\u04A8" + + "\u04A9\t%\x02\x02\u04A9\u015B\x03\x02\x02\x02\u04AA\u04AB\t&\x02\x02\u04AB" + + "\u015D\x03\x02\x02\x023\x02\x03\x04\x05\x06\x07\b\t\n\v\u01FA\u0204\u0208" + + "\u020B\u0214\u0216\u0221\u024A\u024F\u0258\u025F\u0264\u0266\u0271\u0279" + + "\u027C\u027E\u0283\u0288\u028E\u0295\u029A\u02A0\u02A3\u02AB\u02AF\u032E" + + "\u0333\u0338\u033A\u0340\u0375\u037A\u039D\u03A1\u03A6\u03AB\u03B0\u03B2" + + "\x19\x07\x04\x02\x07\x06\x02\x07\b\x02\x07\x03\x02\x07\x05\x02\x07\n\x02" + + "\x07\x07\x02\x07\v\x02\x02\x03\x02\tA\x02\x07\x02\x02\t\x1C\x02\x06\x02" + + "\x02\tB\x02\t$\x02\t#\x02\tD\x02\t&\x02\tM\x02\x07\t\x02\tI\x02\tV\x02" + + "\tC\x02"; public static readonly _serializedATN: string = Utils.join( [ esql_lexer._serializedATNSegment0, esql_lexer._serializedATNSegment1, + esql_lexer._serializedATNSegment2, ], "", ); diff --git a/packages/kbn-monaco/src/esql/antlr/esql_parser.g4 b/packages/kbn-monaco/src/esql/antlr/esql_parser.g4 index aa2e86b6979e1e..9577d28e902547 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_parser.g4 +++ b/packages/kbn-monaco/src/esql/antlr/esql_parser.g4 @@ -20,13 +20,15 @@ query ; sourceCommand - : fromCommand + : explainCommand + | fromCommand | rowCommand | showCommand ; processingCommand : evalCommand + | inlinestatsCommand | limitCommand | keepCommand | sortCommand @@ -96,13 +98,14 @@ field ; fromCommand - : FROM sourceIdentifier (COMMA sourceIdentifier)* metadata? + : FROM fromIdentifier (COMMA fromIdentifier)* metadata? ; metadata - : OPENING_BRACKET METADATA sourceIdentifier (COMMA sourceIdentifier)* CLOSING_BRACKET + : OPENING_BRACKET METADATA fromIdentifier (COMMA fromIdentifier)* CLOSING_BRACKET ; + evalCommand : EVAL fields ; @@ -111,24 +114,37 @@ statsCommand : STATS fields? (BY grouping)? ; +inlinestatsCommand + : INLINESTATS fields (BY grouping)? + ; + grouping : qualifiedName (COMMA qualifiedName)* ; -sourceIdentifier - : SRC_UNQUOTED_IDENTIFIER - | SRC_QUOTED_IDENTIFIER +fromIdentifier + : FROM_UNQUOTED_IDENTIFIER + | QUOTED_IDENTIFIER ; qualifiedName : identifier (DOT identifier)* ; +qualifiedNamePattern + : identifierPattern (DOT identifierPattern)* + ; + identifier : UNQUOTED_IDENTIFIER | QUOTED_IDENTIFIER ; +identifierPattern + : PROJECT_UNQUOTED_IDENTIFIER + | QUOTED_IDENTIFIER + ; + constant : NULL #nullLiteral | integerValue UNQUOTED_IDENTIFIER #qualifiedIntegerLiteral @@ -155,12 +171,12 @@ orderExpression ; keepCommand - : KEEP sourceIdentifier (COMMA sourceIdentifier)* - | PROJECT sourceIdentifier (COMMA sourceIdentifier)* + : KEEP qualifiedNamePattern (COMMA qualifiedNamePattern)* + | PROJECT qualifiedNamePattern (COMMA qualifiedNamePattern)* ; dropCommand - : DROP sourceIdentifier (COMMA sourceIdentifier)* + : DROP qualifiedNamePattern (COMMA qualifiedNamePattern)* ; renameCommand @@ -168,7 +184,7 @@ renameCommand ; renameClause: - oldName=sourceIdentifier AS newName=sourceIdentifier + oldName=qualifiedNamePattern AS newName=qualifiedNamePattern ; dissectCommand @@ -180,7 +196,7 @@ grokCommand ; mvExpandCommand - : MV_EXPAND sourceIdentifier + : MV_EXPAND qualifiedName ; commandOptions @@ -216,15 +232,23 @@ comparisonOperator : EQ | NEQ | LT | LTE | GT | GTE ; +explainCommand + : EXPLAIN subqueryExpression + ; + +subqueryExpression + : OPENING_BRACKET query CLOSING_BRACKET + ; + showCommand : SHOW INFO #showInfo | SHOW FUNCTIONS #showFunctions ; enrichCommand - : ENRICH policyName=sourceIdentifier (ON matchField=sourceIdentifier)? (WITH enrichWithClause (COMMA enrichWithClause)*)? + : ENRICH policyName=fromIdentifier (ON matchField=qualifiedNamePattern)? (WITH enrichWithClause (COMMA enrichWithClause)*)? ; enrichWithClause - : (newName=sourceIdentifier ASSIGN)? enrichField=sourceIdentifier + : (newName=qualifiedNamePattern ASSIGN)? enrichField=qualifiedNamePattern ; \ No newline at end of file diff --git a/packages/kbn-monaco/src/esql/antlr/esql_parser.interp b/packages/kbn-monaco/src/esql/antlr/esql_parser.interp index 649902a25536b7..6c8870cecd9cdc 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_parser.interp +++ b/packages/kbn-monaco/src/esql/antlr/esql_parser.interp @@ -25,11 +25,16 @@ null null null null +'|' null null null null null +null +'=' +',' +null '.' null null @@ -46,9 +51,6 @@ null null ')' null -null -null -'_' '==' '!=' '<' @@ -76,6 +78,26 @@ null null null null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null token symbolic names: null @@ -83,8 +105,10 @@ DISSECT DROP ENRICH EVAL +EXPLAIN FROM GROK +INLINESTATS KEEP LIMIT MV_EXPAND @@ -99,6 +123,9 @@ UNKNOWN_CMD LINE_COMMENT MULTILINE_COMMENT WS +EXPLAIN_WS +EXPLAIN_LINE_COMMENT +EXPLAIN_MULTILINE_COMMENT PIPE STRING INTEGER_LITERAL @@ -125,9 +152,6 @@ PARAM RLIKE RP TRUE -INFO -FUNCTIONS -UNDERSCORE EQ NEQ LT @@ -146,15 +170,35 @@ QUOTED_IDENTIFIER EXPR_LINE_COMMENT EXPR_MULTILINE_COMMENT EXPR_WS -AS METADATA +FROM_UNQUOTED_IDENTIFIER +FROM_LINE_COMMENT +FROM_MULTILINE_COMMENT +FROM_WS +PROJECT_UNQUOTED_IDENTIFIER +PROJECT_LINE_COMMENT +PROJECT_MULTILINE_COMMENT +PROJECT_WS +AS +RENAME_LINE_COMMENT +RENAME_MULTILINE_COMMENT +RENAME_WS ON WITH -SRC_UNQUOTED_IDENTIFIER -SRC_QUOTED_IDENTIFIER -SRC_LINE_COMMENT -SRC_MULTILINE_COMMENT -SRC_WS +ENRICH_LINE_COMMENT +ENRICH_MULTILINE_COMMENT +ENRICH_WS +ENRICH_FIELD_LINE_COMMENT +ENRICH_FIELD_MULTILINE_COMMENT +ENRICH_FIELD_WS +MVEXPAND_LINE_COMMENT +MVEXPAND_MULTILINE_COMMENT +MVEXPAND_WS +INFO +FUNCTIONS +SHOW_LINE_COMMENT +SHOW_MULTILINE_COMMENT +SHOW_WS rule names: singleStatement @@ -175,10 +219,13 @@ fromCommand metadata evalCommand statsCommand +inlinestatsCommand grouping -sourceIdentifier +fromIdentifier qualifiedName +qualifiedNamePattern identifier +identifierPattern constant limitCommand sortCommand @@ -198,10 +245,12 @@ decimalValue integerValue string comparisonOperator +explainCommand +subqueryExpression showCommand enrichCommand enrichWithClause atn: -[3, 51485, 51898, 1421, 44986, 20307, 1543, 60043, 49729, 3, 78, 486, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 100, 10, 3, 12, 3, 14, 3, 103, 11, 3, 3, 4, 3, 4, 3, 4, 5, 4, 108, 10, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 122, 10, 5, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 134, 10, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 7, 7, 141, 10, 7, 12, 7, 14, 7, 144, 11, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 151, 10, 7, 3, 7, 3, 7, 5, 7, 155, 10, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 7, 7, 163, 10, 7, 12, 7, 14, 7, 166, 11, 7, 3, 8, 3, 8, 5, 8, 170, 10, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 5, 8, 177, 10, 8, 3, 8, 3, 8, 3, 8, 5, 8, 182, 10, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 189, 10, 9, 3, 10, 3, 10, 3, 10, 3, 10, 5, 10, 195, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 7, 10, 203, 10, 10, 12, 10, 14, 10, 206, 11, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 5, 11, 215, 10, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 7, 12, 223, 10, 12, 12, 12, 14, 12, 226, 11, 12, 5, 12, 228, 10, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 7, 14, 238, 10, 14, 12, 14, 14, 14, 241, 11, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 5, 15, 248, 10, 15, 3, 16, 3, 16, 3, 16, 3, 16, 7, 16, 254, 10, 16, 12, 16, 14, 16, 257, 11, 16, 3, 16, 5, 16, 260, 10, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 7, 17, 267, 10, 17, 12, 17, 14, 17, 270, 11, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 5, 19, 279, 10, 19, 3, 19, 3, 19, 5, 19, 283, 10, 19, 3, 20, 3, 20, 3, 20, 7, 20, 288, 10, 20, 12, 20, 14, 20, 291, 11, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 7, 22, 298, 10, 22, 12, 22, 14, 22, 301, 11, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 7, 24, 318, 10, 24, 12, 24, 14, 24, 321, 11, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 7, 24, 329, 10, 24, 12, 24, 14, 24, 332, 11, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 7, 24, 340, 10, 24, 12, 24, 14, 24, 343, 11, 24, 3, 24, 3, 24, 5, 24, 347, 10, 24, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 7, 26, 356, 10, 26, 12, 26, 14, 26, 359, 11, 26, 3, 27, 3, 27, 5, 27, 363, 10, 27, 3, 27, 3, 27, 5, 27, 367, 10, 27, 3, 28, 3, 28, 3, 28, 3, 28, 7, 28, 373, 10, 28, 12, 28, 14, 28, 376, 11, 28, 3, 28, 3, 28, 3, 28, 3, 28, 7, 28, 382, 10, 28, 12, 28, 14, 28, 385, 11, 28, 5, 28, 387, 10, 28, 3, 29, 3, 29, 3, 29, 3, 29, 7, 29, 393, 10, 29, 12, 29, 14, 29, 396, 11, 29, 3, 30, 3, 30, 3, 30, 3, 30, 7, 30, 402, 10, 30, 12, 30, 14, 30, 405, 11, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 5, 32, 415, 10, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 7, 35, 427, 10, 35, 12, 35, 14, 35, 430, 11, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 38, 3, 38, 5, 38, 440, 10, 38, 3, 39, 5, 39, 443, 10, 39, 3, 39, 3, 39, 3, 40, 5, 40, 448, 10, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 5, 43, 460, 10, 43, 3, 44, 3, 44, 3, 44, 3, 44, 5, 44, 466, 10, 44, 3, 44, 3, 44, 3, 44, 3, 44, 7, 44, 472, 10, 44, 12, 44, 14, 44, 475, 11, 44, 5, 44, 477, 10, 44, 3, 45, 3, 45, 3, 45, 5, 45, 482, 10, 45, 3, 45, 3, 45, 3, 45, 2, 2, 5, 4, 12, 18, 46, 2, 2, 4, 2, 6, 2, 8, 2, 10, 2, 12, 2, 14, 2, 16, 2, 18, 2, 20, 2, 22, 2, 24, 2, 26, 2, 28, 2, 30, 2, 32, 2, 34, 2, 36, 2, 38, 2, 40, 2, 42, 2, 44, 2, 46, 2, 48, 2, 50, 2, 52, 2, 54, 2, 56, 2, 58, 2, 60, 2, 62, 2, 64, 2, 66, 2, 68, 2, 70, 2, 72, 2, 74, 2, 76, 2, 78, 2, 80, 2, 82, 2, 84, 2, 86, 2, 88, 2, 2, 10, 3, 2, 58, 59, 3, 2, 60, 62, 3, 2, 74, 75, 3, 2, 65, 66, 4, 2, 29, 29, 32, 32, 3, 2, 35, 36, 4, 2, 34, 34, 48, 48, 3, 2, 52, 57, 2, 516, 2, 90, 3, 2, 2, 2, 4, 93, 3, 2, 2, 2, 6, 107, 3, 2, 2, 2, 8, 121, 3, 2, 2, 2, 10, 123, 3, 2, 2, 2, 12, 154, 3, 2, 2, 2, 14, 181, 3, 2, 2, 2, 16, 188, 3, 2, 2, 2, 18, 194, 3, 2, 2, 2, 20, 214, 3, 2, 2, 2, 22, 216, 3, 2, 2, 2, 24, 231, 3, 2, 2, 2, 26, 234, 3, 2, 2, 2, 28, 247, 3, 2, 2, 2, 30, 249, 3, 2, 2, 2, 32, 261, 3, 2, 2, 2, 34, 273, 3, 2, 2, 2, 36, 276, 3, 2, 2, 2, 38, 284, 3, 2, 2, 2, 40, 292, 3, 2, 2, 2, 42, 294, 3, 2, 2, 2, 44, 302, 3, 2, 2, 2, 46, 346, 3, 2, 2, 2, 48, 348, 3, 2, 2, 2, 50, 351, 3, 2, 2, 2, 52, 360, 3, 2, 2, 2, 54, 386, 3, 2, 2, 2, 56, 388, 3, 2, 2, 2, 58, 397, 3, 2, 2, 2, 60, 406, 3, 2, 2, 2, 62, 410, 3, 2, 2, 2, 64, 416, 3, 2, 2, 2, 66, 420, 3, 2, 2, 2, 68, 423, 3, 2, 2, 2, 70, 431, 3, 2, 2, 2, 72, 435, 3, 2, 2, 2, 74, 439, 3, 2, 2, 2, 76, 442, 3, 2, 2, 2, 78, 447, 3, 2, 2, 2, 80, 451, 3, 2, 2, 2, 82, 453, 3, 2, 2, 2, 84, 459, 3, 2, 2, 2, 86, 461, 3, 2, 2, 2, 88, 481, 3, 2, 2, 2, 90, 91, 5, 4, 3, 2, 91, 92, 7, 2, 2, 3, 92, 3, 3, 2, 2, 2, 93, 94, 8, 3, 1, 2, 94, 95, 5, 6, 4, 2, 95, 101, 3, 2, 2, 2, 96, 97, 12, 3, 2, 2, 97, 98, 7, 23, 2, 2, 98, 100, 5, 8, 5, 2, 99, 96, 3, 2, 2, 2, 100, 103, 3, 2, 2, 2, 101, 99, 3, 2, 2, 2, 101, 102, 3, 2, 2, 2, 102, 5, 3, 2, 2, 2, 103, 101, 3, 2, 2, 2, 104, 108, 5, 30, 16, 2, 105, 108, 5, 24, 13, 2, 106, 108, 5, 84, 43, 2, 107, 104, 3, 2, 2, 2, 107, 105, 3, 2, 2, 2, 107, 106, 3, 2, 2, 2, 108, 7, 3, 2, 2, 2, 109, 122, 5, 34, 18, 2, 110, 122, 5, 48, 25, 2, 111, 122, 5, 54, 28, 2, 112, 122, 5, 50, 26, 2, 113, 122, 5, 36, 19, 2, 114, 122, 5, 10, 6, 2, 115, 122, 5, 56, 29, 2, 116, 122, 5, 58, 30, 2, 117, 122, 5, 62, 32, 2, 118, 122, 5, 64, 33, 2, 119, 122, 5, 86, 44, 2, 120, 122, 5, 66, 34, 2, 121, 109, 3, 2, 2, 2, 121, 110, 3, 2, 2, 2, 121, 111, 3, 2, 2, 2, 121, 112, 3, 2, 2, 2, 121, 113, 3, 2, 2, 2, 121, 114, 3, 2, 2, 2, 121, 115, 3, 2, 2, 2, 121, 116, 3, 2, 2, 2, 121, 117, 3, 2, 2, 2, 121, 118, 3, 2, 2, 2, 121, 119, 3, 2, 2, 2, 121, 120, 3, 2, 2, 2, 122, 9, 3, 2, 2, 2, 123, 124, 7, 18, 2, 2, 124, 125, 5, 12, 7, 2, 125, 11, 3, 2, 2, 2, 126, 127, 8, 7, 1, 2, 127, 128, 7, 41, 2, 2, 128, 155, 5, 12, 7, 9, 129, 155, 5, 16, 9, 2, 130, 155, 5, 14, 8, 2, 131, 133, 5, 16, 9, 2, 132, 134, 7, 41, 2, 2, 133, 132, 3, 2, 2, 2, 133, 134, 3, 2, 2, 2, 134, 135, 3, 2, 2, 2, 135, 136, 7, 38, 2, 2, 136, 137, 7, 37, 2, 2, 137, 142, 5, 16, 9, 2, 138, 139, 7, 31, 2, 2, 139, 141, 5, 16, 9, 2, 140, 138, 3, 2, 2, 2, 141, 144, 3, 2, 2, 2, 142, 140, 3, 2, 2, 2, 142, 143, 3, 2, 2, 2, 143, 145, 3, 2, 2, 2, 144, 142, 3, 2, 2, 2, 145, 146, 7, 47, 2, 2, 146, 155, 3, 2, 2, 2, 147, 148, 5, 16, 9, 2, 148, 150, 7, 39, 2, 2, 149, 151, 7, 41, 2, 2, 150, 149, 3, 2, 2, 2, 150, 151, 3, 2, 2, 2, 151, 152, 3, 2, 2, 2, 152, 153, 7, 42, 2, 2, 153, 155, 3, 2, 2, 2, 154, 126, 3, 2, 2, 2, 154, 129, 3, 2, 2, 2, 154, 130, 3, 2, 2, 2, 154, 131, 3, 2, 2, 2, 154, 147, 3, 2, 2, 2, 155, 164, 3, 2, 2, 2, 156, 157, 12, 6, 2, 2, 157, 158, 7, 28, 2, 2, 158, 163, 5, 12, 7, 7, 159, 160, 12, 5, 2, 2, 160, 161, 7, 44, 2, 2, 161, 163, 5, 12, 7, 6, 162, 156, 3, 2, 2, 2, 162, 159, 3, 2, 2, 2, 163, 166, 3, 2, 2, 2, 164, 162, 3, 2, 2, 2, 164, 165, 3, 2, 2, 2, 165, 13, 3, 2, 2, 2, 166, 164, 3, 2, 2, 2, 167, 169, 5, 16, 9, 2, 168, 170, 7, 41, 2, 2, 169, 168, 3, 2, 2, 2, 169, 170, 3, 2, 2, 2, 170, 171, 3, 2, 2, 2, 171, 172, 7, 40, 2, 2, 172, 173, 5, 80, 41, 2, 173, 182, 3, 2, 2, 2, 174, 176, 5, 16, 9, 2, 175, 177, 7, 41, 2, 2, 176, 175, 3, 2, 2, 2, 176, 177, 3, 2, 2, 2, 177, 178, 3, 2, 2, 2, 178, 179, 7, 46, 2, 2, 179, 180, 5, 80, 41, 2, 180, 182, 3, 2, 2, 2, 181, 167, 3, 2, 2, 2, 181, 174, 3, 2, 2, 2, 182, 15, 3, 2, 2, 2, 183, 189, 5, 18, 10, 2, 184, 185, 5, 18, 10, 2, 185, 186, 5, 82, 42, 2, 186, 187, 5, 18, 10, 2, 187, 189, 3, 2, 2, 2, 188, 183, 3, 2, 2, 2, 188, 184, 3, 2, 2, 2, 189, 17, 3, 2, 2, 2, 190, 191, 8, 10, 1, 2, 191, 195, 5, 20, 11, 2, 192, 193, 9, 2, 2, 2, 193, 195, 5, 18, 10, 5, 194, 190, 3, 2, 2, 2, 194, 192, 3, 2, 2, 2, 195, 204, 3, 2, 2, 2, 196, 197, 12, 4, 2, 2, 197, 198, 9, 3, 2, 2, 198, 203, 5, 18, 10, 5, 199, 200, 12, 3, 2, 2, 200, 201, 9, 2, 2, 2, 201, 203, 5, 18, 10, 4, 202, 196, 3, 2, 2, 2, 202, 199, 3, 2, 2, 2, 203, 206, 3, 2, 2, 2, 204, 202, 3, 2, 2, 2, 204, 205, 3, 2, 2, 2, 205, 19, 3, 2, 2, 2, 206, 204, 3, 2, 2, 2, 207, 215, 5, 46, 24, 2, 208, 215, 5, 42, 22, 2, 209, 215, 5, 22, 12, 2, 210, 211, 7, 37, 2, 2, 211, 212, 5, 12, 7, 2, 212, 213, 7, 47, 2, 2, 213, 215, 3, 2, 2, 2, 214, 207, 3, 2, 2, 2, 214, 208, 3, 2, 2, 2, 214, 209, 3, 2, 2, 2, 214, 210, 3, 2, 2, 2, 215, 21, 3, 2, 2, 2, 216, 217, 5, 44, 23, 2, 217, 227, 7, 37, 2, 2, 218, 228, 7, 60, 2, 2, 219, 224, 5, 12, 7, 2, 220, 221, 7, 31, 2, 2, 221, 223, 5, 12, 7, 2, 222, 220, 3, 2, 2, 2, 223, 226, 3, 2, 2, 2, 224, 222, 3, 2, 2, 2, 224, 225, 3, 2, 2, 2, 225, 228, 3, 2, 2, 2, 226, 224, 3, 2, 2, 2, 227, 218, 3, 2, 2, 2, 227, 219, 3, 2, 2, 2, 227, 228, 3, 2, 2, 2, 228, 229, 3, 2, 2, 2, 229, 230, 7, 47, 2, 2, 230, 23, 3, 2, 2, 2, 231, 232, 7, 14, 2, 2, 232, 233, 5, 26, 14, 2, 233, 25, 3, 2, 2, 2, 234, 239, 5, 28, 15, 2, 235, 236, 7, 31, 2, 2, 236, 238, 5, 28, 15, 2, 237, 235, 3, 2, 2, 2, 238, 241, 3, 2, 2, 2, 239, 237, 3, 2, 2, 2, 239, 240, 3, 2, 2, 2, 240, 27, 3, 2, 2, 2, 241, 239, 3, 2, 2, 2, 242, 248, 5, 12, 7, 2, 243, 244, 5, 42, 22, 2, 244, 245, 7, 30, 2, 2, 245, 246, 5, 12, 7, 2, 246, 248, 3, 2, 2, 2, 247, 242, 3, 2, 2, 2, 247, 243, 3, 2, 2, 2, 248, 29, 3, 2, 2, 2, 249, 250, 7, 7, 2, 2, 250, 255, 5, 40, 21, 2, 251, 252, 7, 31, 2, 2, 252, 254, 5, 40, 21, 2, 253, 251, 3, 2, 2, 2, 254, 257, 3, 2, 2, 2, 255, 253, 3, 2, 2, 2, 255, 256, 3, 2, 2, 2, 256, 259, 3, 2, 2, 2, 257, 255, 3, 2, 2, 2, 258, 260, 5, 32, 17, 2, 259, 258, 3, 2, 2, 2, 259, 260, 3, 2, 2, 2, 260, 31, 3, 2, 2, 2, 261, 262, 7, 63, 2, 2, 262, 263, 7, 71, 2, 2, 263, 268, 5, 40, 21, 2, 264, 265, 7, 31, 2, 2, 265, 267, 5, 40, 21, 2, 266, 264, 3, 2, 2, 2, 267, 270, 3, 2, 2, 2, 268, 266, 3, 2, 2, 2, 268, 269, 3, 2, 2, 2, 269, 271, 3, 2, 2, 2, 270, 268, 3, 2, 2, 2, 271, 272, 7, 64, 2, 2, 272, 33, 3, 2, 2, 2, 273, 274, 7, 6, 2, 2, 274, 275, 5, 26, 14, 2, 275, 35, 3, 2, 2, 2, 276, 278, 7, 17, 2, 2, 277, 279, 5, 26, 14, 2, 278, 277, 3, 2, 2, 2, 278, 279, 3, 2, 2, 2, 279, 282, 3, 2, 2, 2, 280, 281, 7, 27, 2, 2, 281, 283, 5, 38, 20, 2, 282, 280, 3, 2, 2, 2, 282, 283, 3, 2, 2, 2, 283, 37, 3, 2, 2, 2, 284, 289, 5, 42, 22, 2, 285, 286, 7, 31, 2, 2, 286, 288, 5, 42, 22, 2, 287, 285, 3, 2, 2, 2, 288, 291, 3, 2, 2, 2, 289, 287, 3, 2, 2, 2, 289, 290, 3, 2, 2, 2, 290, 39, 3, 2, 2, 2, 291, 289, 3, 2, 2, 2, 292, 293, 9, 4, 2, 2, 293, 41, 3, 2, 2, 2, 294, 299, 5, 44, 23, 2, 295, 296, 7, 33, 2, 2, 296, 298, 5, 44, 23, 2, 297, 295, 3, 2, 2, 2, 298, 301, 3, 2, 2, 2, 299, 297, 3, 2, 2, 2, 299, 300, 3, 2, 2, 2, 300, 43, 3, 2, 2, 2, 301, 299, 3, 2, 2, 2, 302, 303, 9, 5, 2, 2, 303, 45, 3, 2, 2, 2, 304, 347, 7, 42, 2, 2, 305, 306, 5, 78, 40, 2, 306, 307, 7, 65, 2, 2, 307, 347, 3, 2, 2, 2, 308, 347, 5, 76, 39, 2, 309, 347, 5, 78, 40, 2, 310, 347, 5, 72, 37, 2, 311, 347, 7, 45, 2, 2, 312, 347, 5, 80, 41, 2, 313, 314, 7, 63, 2, 2, 314, 319, 5, 74, 38, 2, 315, 316, 7, 31, 2, 2, 316, 318, 5, 74, 38, 2, 317, 315, 3, 2, 2, 2, 318, 321, 3, 2, 2, 2, 319, 317, 3, 2, 2, 2, 319, 320, 3, 2, 2, 2, 320, 322, 3, 2, 2, 2, 321, 319, 3, 2, 2, 2, 322, 323, 7, 64, 2, 2, 323, 347, 3, 2, 2, 2, 324, 325, 7, 63, 2, 2, 325, 330, 5, 72, 37, 2, 326, 327, 7, 31, 2, 2, 327, 329, 5, 72, 37, 2, 328, 326, 3, 2, 2, 2, 329, 332, 3, 2, 2, 2, 330, 328, 3, 2, 2, 2, 330, 331, 3, 2, 2, 2, 331, 333, 3, 2, 2, 2, 332, 330, 3, 2, 2, 2, 333, 334, 7, 64, 2, 2, 334, 347, 3, 2, 2, 2, 335, 336, 7, 63, 2, 2, 336, 341, 5, 80, 41, 2, 337, 338, 7, 31, 2, 2, 338, 340, 5, 80, 41, 2, 339, 337, 3, 2, 2, 2, 340, 343, 3, 2, 2, 2, 341, 339, 3, 2, 2, 2, 341, 342, 3, 2, 2, 2, 342, 344, 3, 2, 2, 2, 343, 341, 3, 2, 2, 2, 344, 345, 7, 64, 2, 2, 345, 347, 3, 2, 2, 2, 346, 304, 3, 2, 2, 2, 346, 305, 3, 2, 2, 2, 346, 308, 3, 2, 2, 2, 346, 309, 3, 2, 2, 2, 346, 310, 3, 2, 2, 2, 346, 311, 3, 2, 2, 2, 346, 312, 3, 2, 2, 2, 346, 313, 3, 2, 2, 2, 346, 324, 3, 2, 2, 2, 346, 335, 3, 2, 2, 2, 347, 47, 3, 2, 2, 2, 348, 349, 7, 10, 2, 2, 349, 350, 7, 25, 2, 2, 350, 49, 3, 2, 2, 2, 351, 352, 7, 16, 2, 2, 352, 357, 5, 52, 27, 2, 353, 354, 7, 31, 2, 2, 354, 356, 5, 52, 27, 2, 355, 353, 3, 2, 2, 2, 356, 359, 3, 2, 2, 2, 357, 355, 3, 2, 2, 2, 357, 358, 3, 2, 2, 2, 358, 51, 3, 2, 2, 2, 359, 357, 3, 2, 2, 2, 360, 362, 5, 12, 7, 2, 361, 363, 9, 6, 2, 2, 362, 361, 3, 2, 2, 2, 362, 363, 3, 2, 2, 2, 363, 366, 3, 2, 2, 2, 364, 365, 7, 43, 2, 2, 365, 367, 9, 7, 2, 2, 366, 364, 3, 2, 2, 2, 366, 367, 3, 2, 2, 2, 367, 53, 3, 2, 2, 2, 368, 369, 7, 9, 2, 2, 369, 374, 5, 40, 21, 2, 370, 371, 7, 31, 2, 2, 371, 373, 5, 40, 21, 2, 372, 370, 3, 2, 2, 2, 373, 376, 3, 2, 2, 2, 374, 372, 3, 2, 2, 2, 374, 375, 3, 2, 2, 2, 375, 387, 3, 2, 2, 2, 376, 374, 3, 2, 2, 2, 377, 378, 7, 12, 2, 2, 378, 383, 5, 40, 21, 2, 379, 380, 7, 31, 2, 2, 380, 382, 5, 40, 21, 2, 381, 379, 3, 2, 2, 2, 382, 385, 3, 2, 2, 2, 383, 381, 3, 2, 2, 2, 383, 384, 3, 2, 2, 2, 384, 387, 3, 2, 2, 2, 385, 383, 3, 2, 2, 2, 386, 368, 3, 2, 2, 2, 386, 377, 3, 2, 2, 2, 387, 55, 3, 2, 2, 2, 388, 389, 7, 4, 2, 2, 389, 394, 5, 40, 21, 2, 390, 391, 7, 31, 2, 2, 391, 393, 5, 40, 21, 2, 392, 390, 3, 2, 2, 2, 393, 396, 3, 2, 2, 2, 394, 392, 3, 2, 2, 2, 394, 395, 3, 2, 2, 2, 395, 57, 3, 2, 2, 2, 396, 394, 3, 2, 2, 2, 397, 398, 7, 13, 2, 2, 398, 403, 5, 60, 31, 2, 399, 400, 7, 31, 2, 2, 400, 402, 5, 60, 31, 2, 401, 399, 3, 2, 2, 2, 402, 405, 3, 2, 2, 2, 403, 401, 3, 2, 2, 2, 403, 404, 3, 2, 2, 2, 404, 59, 3, 2, 2, 2, 405, 403, 3, 2, 2, 2, 406, 407, 5, 40, 21, 2, 407, 408, 7, 70, 2, 2, 408, 409, 5, 40, 21, 2, 409, 61, 3, 2, 2, 2, 410, 411, 7, 3, 2, 2, 411, 412, 5, 20, 11, 2, 412, 414, 5, 80, 41, 2, 413, 415, 5, 68, 35, 2, 414, 413, 3, 2, 2, 2, 414, 415, 3, 2, 2, 2, 415, 63, 3, 2, 2, 2, 416, 417, 7, 8, 2, 2, 417, 418, 5, 20, 11, 2, 418, 419, 5, 80, 41, 2, 419, 65, 3, 2, 2, 2, 420, 421, 7, 11, 2, 2, 421, 422, 5, 40, 21, 2, 422, 67, 3, 2, 2, 2, 423, 428, 5, 70, 36, 2, 424, 425, 7, 31, 2, 2, 425, 427, 5, 70, 36, 2, 426, 424, 3, 2, 2, 2, 427, 430, 3, 2, 2, 2, 428, 426, 3, 2, 2, 2, 428, 429, 3, 2, 2, 2, 429, 69, 3, 2, 2, 2, 430, 428, 3, 2, 2, 2, 431, 432, 5, 44, 23, 2, 432, 433, 7, 30, 2, 2, 433, 434, 5, 46, 24, 2, 434, 71, 3, 2, 2, 2, 435, 436, 9, 8, 2, 2, 436, 73, 3, 2, 2, 2, 437, 440, 5, 76, 39, 2, 438, 440, 5, 78, 40, 2, 439, 437, 3, 2, 2, 2, 439, 438, 3, 2, 2, 2, 440, 75, 3, 2, 2, 2, 441, 443, 9, 2, 2, 2, 442, 441, 3, 2, 2, 2, 442, 443, 3, 2, 2, 2, 443, 444, 3, 2, 2, 2, 444, 445, 7, 26, 2, 2, 445, 77, 3, 2, 2, 2, 446, 448, 9, 2, 2, 2, 447, 446, 3, 2, 2, 2, 447, 448, 3, 2, 2, 2, 448, 449, 3, 2, 2, 2, 449, 450, 7, 25, 2, 2, 450, 79, 3, 2, 2, 2, 451, 452, 7, 24, 2, 2, 452, 81, 3, 2, 2, 2, 453, 454, 9, 9, 2, 2, 454, 83, 3, 2, 2, 2, 455, 456, 7, 15, 2, 2, 456, 460, 7, 49, 2, 2, 457, 458, 7, 15, 2, 2, 458, 460, 7, 50, 2, 2, 459, 455, 3, 2, 2, 2, 459, 457, 3, 2, 2, 2, 460, 85, 3, 2, 2, 2, 461, 462, 7, 5, 2, 2, 462, 465, 5, 40, 21, 2, 463, 464, 7, 72, 2, 2, 464, 466, 5, 40, 21, 2, 465, 463, 3, 2, 2, 2, 465, 466, 3, 2, 2, 2, 466, 476, 3, 2, 2, 2, 467, 468, 7, 73, 2, 2, 468, 473, 5, 88, 45, 2, 469, 470, 7, 31, 2, 2, 470, 472, 5, 88, 45, 2, 471, 469, 3, 2, 2, 2, 472, 475, 3, 2, 2, 2, 473, 471, 3, 2, 2, 2, 473, 474, 3, 2, 2, 2, 474, 477, 3, 2, 2, 2, 475, 473, 3, 2, 2, 2, 476, 467, 3, 2, 2, 2, 476, 477, 3, 2, 2, 2, 477, 87, 3, 2, 2, 2, 478, 479, 5, 40, 21, 2, 479, 480, 7, 30, 2, 2, 480, 482, 3, 2, 2, 2, 481, 478, 3, 2, 2, 2, 481, 482, 3, 2, 2, 2, 482, 483, 3, 2, 2, 2, 483, 484, 5, 40, 21, 2, 484, 89, 3, 2, 2, 2, 52, 101, 107, 121, 133, 142, 150, 154, 162, 164, 169, 176, 181, 188, 194, 202, 204, 214, 224, 227, 239, 247, 255, 259, 268, 278, 282, 289, 299, 319, 330, 341, 346, 357, 362, 366, 374, 383, 386, 394, 403, 414, 428, 439, 442, 447, 459, 465, 473, 476, 481] \ No newline at end of file +[3, 51485, 51898, 1421, 44986, 20307, 1543, 60043, 49729, 3, 100, 521, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 110, 10, 3, 12, 3, 14, 3, 113, 11, 3, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 119, 10, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 134, 10, 5, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 146, 10, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 7, 7, 153, 10, 7, 12, 7, 14, 7, 156, 11, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 163, 10, 7, 3, 7, 3, 7, 5, 7, 167, 10, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 7, 7, 175, 10, 7, 12, 7, 14, 7, 178, 11, 7, 3, 8, 3, 8, 5, 8, 182, 10, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 5, 8, 189, 10, 8, 3, 8, 3, 8, 3, 8, 5, 8, 194, 10, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 201, 10, 9, 3, 10, 3, 10, 3, 10, 3, 10, 5, 10, 207, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 7, 10, 215, 10, 10, 12, 10, 14, 10, 218, 11, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 5, 11, 227, 10, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 7, 12, 235, 10, 12, 12, 12, 14, 12, 238, 11, 12, 5, 12, 240, 10, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 7, 14, 250, 10, 14, 12, 14, 14, 14, 253, 11, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 5, 15, 260, 10, 15, 3, 16, 3, 16, 3, 16, 3, 16, 7, 16, 266, 10, 16, 12, 16, 14, 16, 269, 11, 16, 3, 16, 5, 16, 272, 10, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 7, 17, 279, 10, 17, 12, 17, 14, 17, 282, 11, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 5, 19, 291, 10, 19, 3, 19, 3, 19, 5, 19, 295, 10, 19, 3, 20, 3, 20, 3, 20, 3, 20, 5, 20, 301, 10, 20, 3, 21, 3, 21, 3, 21, 7, 21, 306, 10, 21, 12, 21, 14, 21, 309, 11, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 7, 23, 316, 10, 23, 12, 23, 14, 23, 319, 11, 23, 3, 24, 3, 24, 3, 24, 7, 24, 324, 10, 24, 12, 24, 14, 24, 327, 11, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 7, 27, 346, 10, 27, 12, 27, 14, 27, 349, 11, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 7, 27, 357, 10, 27, 12, 27, 14, 27, 360, 11, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 7, 27, 368, 10, 27, 12, 27, 14, 27, 371, 11, 27, 3, 27, 3, 27, 5, 27, 375, 10, 27, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 7, 29, 384, 10, 29, 12, 29, 14, 29, 387, 11, 29, 3, 30, 3, 30, 5, 30, 391, 10, 30, 3, 30, 3, 30, 5, 30, 395, 10, 30, 3, 31, 3, 31, 3, 31, 3, 31, 7, 31, 401, 10, 31, 12, 31, 14, 31, 404, 11, 31, 3, 31, 3, 31, 3, 31, 3, 31, 7, 31, 410, 10, 31, 12, 31, 14, 31, 413, 11, 31, 5, 31, 415, 10, 31, 3, 32, 3, 32, 3, 32, 3, 32, 7, 32, 421, 10, 32, 12, 32, 14, 32, 424, 11, 32, 3, 33, 3, 33, 3, 33, 3, 33, 7, 33, 430, 10, 33, 12, 33, 14, 33, 433, 11, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 5, 35, 443, 10, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 7, 38, 455, 10, 38, 12, 38, 14, 38, 458, 11, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 41, 3, 41, 5, 41, 468, 10, 41, 3, 42, 5, 42, 471, 10, 42, 3, 42, 3, 42, 3, 43, 5, 43, 476, 10, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 5, 48, 495, 10, 48, 3, 49, 3, 49, 3, 49, 3, 49, 5, 49, 501, 10, 49, 3, 49, 3, 49, 3, 49, 3, 49, 7, 49, 507, 10, 49, 12, 49, 14, 49, 510, 11, 49, 5, 49, 512, 10, 49, 3, 50, 3, 50, 3, 50, 5, 50, 517, 10, 50, 3, 50, 3, 50, 3, 50, 2, 2, 5, 4, 12, 18, 51, 2, 2, 4, 2, 6, 2, 8, 2, 10, 2, 12, 2, 14, 2, 16, 2, 18, 2, 20, 2, 22, 2, 24, 2, 26, 2, 28, 2, 30, 2, 32, 2, 34, 2, 36, 2, 38, 2, 40, 2, 42, 2, 44, 2, 46, 2, 48, 2, 50, 2, 52, 2, 54, 2, 56, 2, 58, 2, 60, 2, 62, 2, 64, 2, 66, 2, 68, 2, 70, 2, 72, 2, 74, 2, 76, 2, 78, 2, 80, 2, 82, 2, 84, 2, 86, 2, 88, 2, 90, 2, 92, 2, 94, 2, 96, 2, 98, 2, 2, 11, 3, 2, 60, 61, 3, 2, 62, 64, 4, 2, 68, 68, 73, 73, 3, 2, 67, 68, 4, 2, 68, 68, 77, 77, 4, 2, 34, 34, 37, 37, 3, 2, 40, 41, 4, 2, 39, 39, 53, 53, 3, 2, 54, 59, 2, 550, 2, 100, 3, 2, 2, 2, 4, 103, 3, 2, 2, 2, 6, 118, 3, 2, 2, 2, 8, 133, 3, 2, 2, 2, 10, 135, 3, 2, 2, 2, 12, 166, 3, 2, 2, 2, 14, 193, 3, 2, 2, 2, 16, 200, 3, 2, 2, 2, 18, 206, 3, 2, 2, 2, 20, 226, 3, 2, 2, 2, 22, 228, 3, 2, 2, 2, 24, 243, 3, 2, 2, 2, 26, 246, 3, 2, 2, 2, 28, 259, 3, 2, 2, 2, 30, 261, 3, 2, 2, 2, 32, 273, 3, 2, 2, 2, 34, 285, 3, 2, 2, 2, 36, 288, 3, 2, 2, 2, 38, 296, 3, 2, 2, 2, 40, 302, 3, 2, 2, 2, 42, 310, 3, 2, 2, 2, 44, 312, 3, 2, 2, 2, 46, 320, 3, 2, 2, 2, 48, 328, 3, 2, 2, 2, 50, 330, 3, 2, 2, 2, 52, 374, 3, 2, 2, 2, 54, 376, 3, 2, 2, 2, 56, 379, 3, 2, 2, 2, 58, 388, 3, 2, 2, 2, 60, 414, 3, 2, 2, 2, 62, 416, 3, 2, 2, 2, 64, 425, 3, 2, 2, 2, 66, 434, 3, 2, 2, 2, 68, 438, 3, 2, 2, 2, 70, 444, 3, 2, 2, 2, 72, 448, 3, 2, 2, 2, 74, 451, 3, 2, 2, 2, 76, 459, 3, 2, 2, 2, 78, 463, 3, 2, 2, 2, 80, 467, 3, 2, 2, 2, 82, 470, 3, 2, 2, 2, 84, 475, 3, 2, 2, 2, 86, 479, 3, 2, 2, 2, 88, 481, 3, 2, 2, 2, 90, 483, 3, 2, 2, 2, 92, 486, 3, 2, 2, 2, 94, 494, 3, 2, 2, 2, 96, 496, 3, 2, 2, 2, 98, 516, 3, 2, 2, 2, 100, 101, 5, 4, 3, 2, 101, 102, 7, 2, 2, 3, 102, 3, 3, 2, 2, 2, 103, 104, 8, 3, 1, 2, 104, 105, 5, 6, 4, 2, 105, 111, 3, 2, 2, 2, 106, 107, 12, 3, 2, 2, 107, 108, 7, 28, 2, 2, 108, 110, 5, 8, 5, 2, 109, 106, 3, 2, 2, 2, 110, 113, 3, 2, 2, 2, 111, 109, 3, 2, 2, 2, 111, 112, 3, 2, 2, 2, 112, 5, 3, 2, 2, 2, 113, 111, 3, 2, 2, 2, 114, 119, 5, 90, 46, 2, 115, 119, 5, 30, 16, 2, 116, 119, 5, 24, 13, 2, 117, 119, 5, 94, 48, 2, 118, 114, 3, 2, 2, 2, 118, 115, 3, 2, 2, 2, 118, 116, 3, 2, 2, 2, 118, 117, 3, 2, 2, 2, 119, 7, 3, 2, 2, 2, 120, 134, 5, 34, 18, 2, 121, 134, 5, 38, 20, 2, 122, 134, 5, 54, 28, 2, 123, 134, 5, 60, 31, 2, 124, 134, 5, 56, 29, 2, 125, 134, 5, 36, 19, 2, 126, 134, 5, 10, 6, 2, 127, 134, 5, 62, 32, 2, 128, 134, 5, 64, 33, 2, 129, 134, 5, 68, 35, 2, 130, 134, 5, 70, 36, 2, 131, 134, 5, 96, 49, 2, 132, 134, 5, 72, 37, 2, 133, 120, 3, 2, 2, 2, 133, 121, 3, 2, 2, 2, 133, 122, 3, 2, 2, 2, 133, 123, 3, 2, 2, 2, 133, 124, 3, 2, 2, 2, 133, 125, 3, 2, 2, 2, 133, 126, 3, 2, 2, 2, 133, 127, 3, 2, 2, 2, 133, 128, 3, 2, 2, 2, 133, 129, 3, 2, 2, 2, 133, 130, 3, 2, 2, 2, 133, 131, 3, 2, 2, 2, 133, 132, 3, 2, 2, 2, 134, 9, 3, 2, 2, 2, 135, 136, 7, 20, 2, 2, 136, 137, 5, 12, 7, 2, 137, 11, 3, 2, 2, 2, 138, 139, 8, 7, 1, 2, 139, 140, 7, 46, 2, 2, 140, 167, 5, 12, 7, 9, 141, 167, 5, 16, 9, 2, 142, 167, 5, 14, 8, 2, 143, 145, 5, 16, 9, 2, 144, 146, 7, 46, 2, 2, 145, 144, 3, 2, 2, 2, 145, 146, 3, 2, 2, 2, 146, 147, 3, 2, 2, 2, 147, 148, 7, 43, 2, 2, 148, 149, 7, 42, 2, 2, 149, 154, 5, 16, 9, 2, 150, 151, 7, 36, 2, 2, 151, 153, 5, 16, 9, 2, 152, 150, 3, 2, 2, 2, 153, 156, 3, 2, 2, 2, 154, 152, 3, 2, 2, 2, 154, 155, 3, 2, 2, 2, 155, 157, 3, 2, 2, 2, 156, 154, 3, 2, 2, 2, 157, 158, 7, 52, 2, 2, 158, 167, 3, 2, 2, 2, 159, 160, 5, 16, 9, 2, 160, 162, 7, 44, 2, 2, 161, 163, 7, 46, 2, 2, 162, 161, 3, 2, 2, 2, 162, 163, 3, 2, 2, 2, 163, 164, 3, 2, 2, 2, 164, 165, 7, 47, 2, 2, 165, 167, 3, 2, 2, 2, 166, 138, 3, 2, 2, 2, 166, 141, 3, 2, 2, 2, 166, 142, 3, 2, 2, 2, 166, 143, 3, 2, 2, 2, 166, 159, 3, 2, 2, 2, 167, 176, 3, 2, 2, 2, 168, 169, 12, 6, 2, 2, 169, 170, 7, 33, 2, 2, 170, 175, 5, 12, 7, 7, 171, 172, 12, 5, 2, 2, 172, 173, 7, 49, 2, 2, 173, 175, 5, 12, 7, 6, 174, 168, 3, 2, 2, 2, 174, 171, 3, 2, 2, 2, 175, 178, 3, 2, 2, 2, 176, 174, 3, 2, 2, 2, 176, 177, 3, 2, 2, 2, 177, 13, 3, 2, 2, 2, 178, 176, 3, 2, 2, 2, 179, 181, 5, 16, 9, 2, 180, 182, 7, 46, 2, 2, 181, 180, 3, 2, 2, 2, 181, 182, 3, 2, 2, 2, 182, 183, 3, 2, 2, 2, 183, 184, 7, 45, 2, 2, 184, 185, 5, 86, 44, 2, 185, 194, 3, 2, 2, 2, 186, 188, 5, 16, 9, 2, 187, 189, 7, 46, 2, 2, 188, 187, 3, 2, 2, 2, 188, 189, 3, 2, 2, 2, 189, 190, 3, 2, 2, 2, 190, 191, 7, 51, 2, 2, 191, 192, 5, 86, 44, 2, 192, 194, 3, 2, 2, 2, 193, 179, 3, 2, 2, 2, 193, 186, 3, 2, 2, 2, 194, 15, 3, 2, 2, 2, 195, 201, 5, 18, 10, 2, 196, 197, 5, 18, 10, 2, 197, 198, 5, 88, 45, 2, 198, 199, 5, 18, 10, 2, 199, 201, 3, 2, 2, 2, 200, 195, 3, 2, 2, 2, 200, 196, 3, 2, 2, 2, 201, 17, 3, 2, 2, 2, 202, 203, 8, 10, 1, 2, 203, 207, 5, 20, 11, 2, 204, 205, 9, 2, 2, 2, 205, 207, 5, 18, 10, 5, 206, 202, 3, 2, 2, 2, 206, 204, 3, 2, 2, 2, 207, 216, 3, 2, 2, 2, 208, 209, 12, 4, 2, 2, 209, 210, 9, 3, 2, 2, 210, 215, 5, 18, 10, 5, 211, 212, 12, 3, 2, 2, 212, 213, 9, 2, 2, 2, 213, 215, 5, 18, 10, 4, 214, 208, 3, 2, 2, 2, 214, 211, 3, 2, 2, 2, 215, 218, 3, 2, 2, 2, 216, 214, 3, 2, 2, 2, 216, 217, 3, 2, 2, 2, 217, 19, 3, 2, 2, 2, 218, 216, 3, 2, 2, 2, 219, 227, 5, 52, 27, 2, 220, 227, 5, 44, 23, 2, 221, 227, 5, 22, 12, 2, 222, 223, 7, 42, 2, 2, 223, 224, 5, 12, 7, 2, 224, 225, 7, 52, 2, 2, 225, 227, 3, 2, 2, 2, 226, 219, 3, 2, 2, 2, 226, 220, 3, 2, 2, 2, 226, 221, 3, 2, 2, 2, 226, 222, 3, 2, 2, 2, 227, 21, 3, 2, 2, 2, 228, 229, 5, 48, 25, 2, 229, 239, 7, 42, 2, 2, 230, 240, 7, 62, 2, 2, 231, 236, 5, 12, 7, 2, 232, 233, 7, 36, 2, 2, 233, 235, 5, 12, 7, 2, 234, 232, 3, 2, 2, 2, 235, 238, 3, 2, 2, 2, 236, 234, 3, 2, 2, 2, 236, 237, 3, 2, 2, 2, 237, 240, 3, 2, 2, 2, 238, 236, 3, 2, 2, 2, 239, 230, 3, 2, 2, 2, 239, 231, 3, 2, 2, 2, 239, 240, 3, 2, 2, 2, 240, 241, 3, 2, 2, 2, 241, 242, 7, 52, 2, 2, 242, 23, 3, 2, 2, 2, 243, 244, 7, 16, 2, 2, 244, 245, 5, 26, 14, 2, 245, 25, 3, 2, 2, 2, 246, 251, 5, 28, 15, 2, 247, 248, 7, 36, 2, 2, 248, 250, 5, 28, 15, 2, 249, 247, 3, 2, 2, 2, 250, 253, 3, 2, 2, 2, 251, 249, 3, 2, 2, 2, 251, 252, 3, 2, 2, 2, 252, 27, 3, 2, 2, 2, 253, 251, 3, 2, 2, 2, 254, 260, 5, 12, 7, 2, 255, 256, 5, 44, 23, 2, 256, 257, 7, 35, 2, 2, 257, 258, 5, 12, 7, 2, 258, 260, 3, 2, 2, 2, 259, 254, 3, 2, 2, 2, 259, 255, 3, 2, 2, 2, 260, 29, 3, 2, 2, 2, 261, 262, 7, 8, 2, 2, 262, 267, 5, 42, 22, 2, 263, 264, 7, 36, 2, 2, 264, 266, 5, 42, 22, 2, 265, 263, 3, 2, 2, 2, 266, 269, 3, 2, 2, 2, 267, 265, 3, 2, 2, 2, 267, 268, 3, 2, 2, 2, 268, 271, 3, 2, 2, 2, 269, 267, 3, 2, 2, 2, 270, 272, 5, 32, 17, 2, 271, 270, 3, 2, 2, 2, 271, 272, 3, 2, 2, 2, 272, 31, 3, 2, 2, 2, 273, 274, 7, 65, 2, 2, 274, 275, 7, 72, 2, 2, 275, 280, 5, 42, 22, 2, 276, 277, 7, 36, 2, 2, 277, 279, 5, 42, 22, 2, 278, 276, 3, 2, 2, 2, 279, 282, 3, 2, 2, 2, 280, 278, 3, 2, 2, 2, 280, 281, 3, 2, 2, 2, 281, 283, 3, 2, 2, 2, 282, 280, 3, 2, 2, 2, 283, 284, 7, 66, 2, 2, 284, 33, 3, 2, 2, 2, 285, 286, 7, 6, 2, 2, 286, 287, 5, 26, 14, 2, 287, 35, 3, 2, 2, 2, 288, 290, 7, 19, 2, 2, 289, 291, 5, 26, 14, 2, 290, 289, 3, 2, 2, 2, 290, 291, 3, 2, 2, 2, 291, 294, 3, 2, 2, 2, 292, 293, 7, 32, 2, 2, 293, 295, 5, 40, 21, 2, 294, 292, 3, 2, 2, 2, 294, 295, 3, 2, 2, 2, 295, 37, 3, 2, 2, 2, 296, 297, 7, 10, 2, 2, 297, 300, 5, 26, 14, 2, 298, 299, 7, 32, 2, 2, 299, 301, 5, 40, 21, 2, 300, 298, 3, 2, 2, 2, 300, 301, 3, 2, 2, 2, 301, 39, 3, 2, 2, 2, 302, 307, 5, 44, 23, 2, 303, 304, 7, 36, 2, 2, 304, 306, 5, 44, 23, 2, 305, 303, 3, 2, 2, 2, 306, 309, 3, 2, 2, 2, 307, 305, 3, 2, 2, 2, 307, 308, 3, 2, 2, 2, 308, 41, 3, 2, 2, 2, 309, 307, 3, 2, 2, 2, 310, 311, 9, 4, 2, 2, 311, 43, 3, 2, 2, 2, 312, 317, 5, 48, 25, 2, 313, 314, 7, 38, 2, 2, 314, 316, 5, 48, 25, 2, 315, 313, 3, 2, 2, 2, 316, 319, 3, 2, 2, 2, 317, 315, 3, 2, 2, 2, 317, 318, 3, 2, 2, 2, 318, 45, 3, 2, 2, 2, 319, 317, 3, 2, 2, 2, 320, 325, 5, 50, 26, 2, 321, 322, 7, 38, 2, 2, 322, 324, 5, 50, 26, 2, 323, 321, 3, 2, 2, 2, 324, 327, 3, 2, 2, 2, 325, 323, 3, 2, 2, 2, 325, 326, 3, 2, 2, 2, 326, 47, 3, 2, 2, 2, 327, 325, 3, 2, 2, 2, 328, 329, 9, 5, 2, 2, 329, 49, 3, 2, 2, 2, 330, 331, 9, 6, 2, 2, 331, 51, 3, 2, 2, 2, 332, 375, 7, 47, 2, 2, 333, 334, 5, 84, 43, 2, 334, 335, 7, 67, 2, 2, 335, 375, 3, 2, 2, 2, 336, 375, 5, 82, 42, 2, 337, 375, 5, 84, 43, 2, 338, 375, 5, 78, 40, 2, 339, 375, 7, 50, 2, 2, 340, 375, 5, 86, 44, 2, 341, 342, 7, 65, 2, 2, 342, 347, 5, 80, 41, 2, 343, 344, 7, 36, 2, 2, 344, 346, 5, 80, 41, 2, 345, 343, 3, 2, 2, 2, 346, 349, 3, 2, 2, 2, 347, 345, 3, 2, 2, 2, 347, 348, 3, 2, 2, 2, 348, 350, 3, 2, 2, 2, 349, 347, 3, 2, 2, 2, 350, 351, 7, 66, 2, 2, 351, 375, 3, 2, 2, 2, 352, 353, 7, 65, 2, 2, 353, 358, 5, 78, 40, 2, 354, 355, 7, 36, 2, 2, 355, 357, 5, 78, 40, 2, 356, 354, 3, 2, 2, 2, 357, 360, 3, 2, 2, 2, 358, 356, 3, 2, 2, 2, 358, 359, 3, 2, 2, 2, 359, 361, 3, 2, 2, 2, 360, 358, 3, 2, 2, 2, 361, 362, 7, 66, 2, 2, 362, 375, 3, 2, 2, 2, 363, 364, 7, 65, 2, 2, 364, 369, 5, 86, 44, 2, 365, 366, 7, 36, 2, 2, 366, 368, 5, 86, 44, 2, 367, 365, 3, 2, 2, 2, 368, 371, 3, 2, 2, 2, 369, 367, 3, 2, 2, 2, 369, 370, 3, 2, 2, 2, 370, 372, 3, 2, 2, 2, 371, 369, 3, 2, 2, 2, 372, 373, 7, 66, 2, 2, 373, 375, 3, 2, 2, 2, 374, 332, 3, 2, 2, 2, 374, 333, 3, 2, 2, 2, 374, 336, 3, 2, 2, 2, 374, 337, 3, 2, 2, 2, 374, 338, 3, 2, 2, 2, 374, 339, 3, 2, 2, 2, 374, 340, 3, 2, 2, 2, 374, 341, 3, 2, 2, 2, 374, 352, 3, 2, 2, 2, 374, 363, 3, 2, 2, 2, 375, 53, 3, 2, 2, 2, 376, 377, 7, 12, 2, 2, 377, 378, 7, 30, 2, 2, 378, 55, 3, 2, 2, 2, 379, 380, 7, 18, 2, 2, 380, 385, 5, 58, 30, 2, 381, 382, 7, 36, 2, 2, 382, 384, 5, 58, 30, 2, 383, 381, 3, 2, 2, 2, 384, 387, 3, 2, 2, 2, 385, 383, 3, 2, 2, 2, 385, 386, 3, 2, 2, 2, 386, 57, 3, 2, 2, 2, 387, 385, 3, 2, 2, 2, 388, 390, 5, 12, 7, 2, 389, 391, 9, 7, 2, 2, 390, 389, 3, 2, 2, 2, 390, 391, 3, 2, 2, 2, 391, 394, 3, 2, 2, 2, 392, 393, 7, 48, 2, 2, 393, 395, 9, 8, 2, 2, 394, 392, 3, 2, 2, 2, 394, 395, 3, 2, 2, 2, 395, 59, 3, 2, 2, 2, 396, 397, 7, 11, 2, 2, 397, 402, 5, 46, 24, 2, 398, 399, 7, 36, 2, 2, 399, 401, 5, 46, 24, 2, 400, 398, 3, 2, 2, 2, 401, 404, 3, 2, 2, 2, 402, 400, 3, 2, 2, 2, 402, 403, 3, 2, 2, 2, 403, 415, 3, 2, 2, 2, 404, 402, 3, 2, 2, 2, 405, 406, 7, 14, 2, 2, 406, 411, 5, 46, 24, 2, 407, 408, 7, 36, 2, 2, 408, 410, 5, 46, 24, 2, 409, 407, 3, 2, 2, 2, 410, 413, 3, 2, 2, 2, 411, 409, 3, 2, 2, 2, 411, 412, 3, 2, 2, 2, 412, 415, 3, 2, 2, 2, 413, 411, 3, 2, 2, 2, 414, 396, 3, 2, 2, 2, 414, 405, 3, 2, 2, 2, 415, 61, 3, 2, 2, 2, 416, 417, 7, 4, 2, 2, 417, 422, 5, 46, 24, 2, 418, 419, 7, 36, 2, 2, 419, 421, 5, 46, 24, 2, 420, 418, 3, 2, 2, 2, 421, 424, 3, 2, 2, 2, 422, 420, 3, 2, 2, 2, 422, 423, 3, 2, 2, 2, 423, 63, 3, 2, 2, 2, 424, 422, 3, 2, 2, 2, 425, 426, 7, 15, 2, 2, 426, 431, 5, 66, 34, 2, 427, 428, 7, 36, 2, 2, 428, 430, 5, 66, 34, 2, 429, 427, 3, 2, 2, 2, 430, 433, 3, 2, 2, 2, 431, 429, 3, 2, 2, 2, 431, 432, 3, 2, 2, 2, 432, 65, 3, 2, 2, 2, 433, 431, 3, 2, 2, 2, 434, 435, 5, 46, 24, 2, 435, 436, 7, 81, 2, 2, 436, 437, 5, 46, 24, 2, 437, 67, 3, 2, 2, 2, 438, 439, 7, 3, 2, 2, 439, 440, 5, 20, 11, 2, 440, 442, 5, 86, 44, 2, 441, 443, 5, 74, 38, 2, 442, 441, 3, 2, 2, 2, 442, 443, 3, 2, 2, 2, 443, 69, 3, 2, 2, 2, 444, 445, 7, 9, 2, 2, 445, 446, 5, 20, 11, 2, 446, 447, 5, 86, 44, 2, 447, 71, 3, 2, 2, 2, 448, 449, 7, 13, 2, 2, 449, 450, 5, 44, 23, 2, 450, 73, 3, 2, 2, 2, 451, 456, 5, 76, 39, 2, 452, 453, 7, 36, 2, 2, 453, 455, 5, 76, 39, 2, 454, 452, 3, 2, 2, 2, 455, 458, 3, 2, 2, 2, 456, 454, 3, 2, 2, 2, 456, 457, 3, 2, 2, 2, 457, 75, 3, 2, 2, 2, 458, 456, 3, 2, 2, 2, 459, 460, 5, 48, 25, 2, 460, 461, 7, 35, 2, 2, 461, 462, 5, 52, 27, 2, 462, 77, 3, 2, 2, 2, 463, 464, 9, 9, 2, 2, 464, 79, 3, 2, 2, 2, 465, 468, 5, 82, 42, 2, 466, 468, 5, 84, 43, 2, 467, 465, 3, 2, 2, 2, 467, 466, 3, 2, 2, 2, 468, 81, 3, 2, 2, 2, 469, 471, 9, 2, 2, 2, 470, 469, 3, 2, 2, 2, 470, 471, 3, 2, 2, 2, 471, 472, 3, 2, 2, 2, 472, 473, 7, 31, 2, 2, 473, 83, 3, 2, 2, 2, 474, 476, 9, 2, 2, 2, 475, 474, 3, 2, 2, 2, 475, 476, 3, 2, 2, 2, 476, 477, 3, 2, 2, 2, 477, 478, 7, 30, 2, 2, 478, 85, 3, 2, 2, 2, 479, 480, 7, 29, 2, 2, 480, 87, 3, 2, 2, 2, 481, 482, 9, 10, 2, 2, 482, 89, 3, 2, 2, 2, 483, 484, 7, 7, 2, 2, 484, 485, 5, 92, 47, 2, 485, 91, 3, 2, 2, 2, 486, 487, 7, 65, 2, 2, 487, 488, 5, 4, 3, 2, 488, 489, 7, 66, 2, 2, 489, 93, 3, 2, 2, 2, 490, 491, 7, 17, 2, 2, 491, 495, 7, 96, 2, 2, 492, 493, 7, 17, 2, 2, 493, 495, 7, 97, 2, 2, 494, 490, 3, 2, 2, 2, 494, 492, 3, 2, 2, 2, 495, 95, 3, 2, 2, 2, 496, 497, 7, 5, 2, 2, 497, 500, 5, 42, 22, 2, 498, 499, 7, 85, 2, 2, 499, 501, 5, 46, 24, 2, 500, 498, 3, 2, 2, 2, 500, 501, 3, 2, 2, 2, 501, 511, 3, 2, 2, 2, 502, 503, 7, 86, 2, 2, 503, 508, 5, 98, 50, 2, 504, 505, 7, 36, 2, 2, 505, 507, 5, 98, 50, 2, 506, 504, 3, 2, 2, 2, 507, 510, 3, 2, 2, 2, 508, 506, 3, 2, 2, 2, 508, 509, 3, 2, 2, 2, 509, 512, 3, 2, 2, 2, 510, 508, 3, 2, 2, 2, 511, 502, 3, 2, 2, 2, 511, 512, 3, 2, 2, 2, 512, 97, 3, 2, 2, 2, 513, 514, 5, 46, 24, 2, 514, 515, 7, 35, 2, 2, 515, 517, 3, 2, 2, 2, 516, 513, 3, 2, 2, 2, 516, 517, 3, 2, 2, 2, 517, 518, 3, 2, 2, 2, 518, 519, 5, 46, 24, 2, 519, 99, 3, 2, 2, 2, 54, 111, 118, 133, 145, 154, 162, 166, 174, 176, 181, 188, 193, 200, 206, 214, 216, 226, 236, 239, 251, 259, 267, 271, 280, 290, 294, 300, 307, 317, 325, 347, 358, 369, 374, 385, 390, 394, 402, 411, 414, 422, 431, 442, 456, 467, 470, 475, 494, 500, 508, 511, 516] \ No newline at end of file diff --git a/packages/kbn-monaco/src/esql/antlr/esql_parser.tokens b/packages/kbn-monaco/src/esql/antlr/esql_parser.tokens index c3160ce1f64725..85a98c3a6d2688 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_parser.tokens +++ b/packages/kbn-monaco/src/esql/antlr/esql_parser.tokens @@ -2,92 +2,116 @@ DISSECT=1 DROP=2 ENRICH=3 EVAL=4 -FROM=5 -GROK=6 -KEEP=7 -LIMIT=8 -MV_EXPAND=9 -PROJECT=10 -RENAME=11 -ROW=12 -SHOW=13 -SORT=14 -STATS=15 -WHERE=16 -UNKNOWN_CMD=17 -LINE_COMMENT=18 -MULTILINE_COMMENT=19 -WS=20 -PIPE=21 -STRING=22 -INTEGER_LITERAL=23 -DECIMAL_LITERAL=24 -BY=25 -AND=26 -ASC=27 -ASSIGN=28 -COMMA=29 -DESC=30 -DOT=31 -FALSE=32 -FIRST=33 -LAST=34 -LP=35 -IN=36 -IS=37 -LIKE=38 -NOT=39 -NULL=40 -NULLS=41 -OR=42 -PARAM=43 -RLIKE=44 -RP=45 -TRUE=46 -INFO=47 -FUNCTIONS=48 -UNDERSCORE=49 -EQ=50 -NEQ=51 -LT=52 -LTE=53 -GT=54 -GTE=55 -PLUS=56 -MINUS=57 -ASTERISK=58 -SLASH=59 -PERCENT=60 -OPENING_BRACKET=61 -CLOSING_BRACKET=62 -UNQUOTED_IDENTIFIER=63 -QUOTED_IDENTIFIER=64 -EXPR_LINE_COMMENT=65 -EXPR_MULTILINE_COMMENT=66 -EXPR_WS=67 -AS=68 -METADATA=69 -ON=70 -WITH=71 -SRC_UNQUOTED_IDENTIFIER=72 -SRC_QUOTED_IDENTIFIER=73 -SRC_LINE_COMMENT=74 -SRC_MULTILINE_COMMENT=75 -SRC_WS=76 -'.'=31 -'('=35 -'?'=43 -')'=45 -'_'=49 -'=='=50 -'!='=51 -'<'=52 -'<='=53 -'>'=54 -'>='=55 -'+'=56 -'-'=57 -'*'=58 -'/'=59 -'%'=60 -']'=62 +EXPLAIN=5 +FROM=6 +GROK=7 +INLINESTATS=8 +KEEP=9 +LIMIT=10 +MV_EXPAND=11 +PROJECT=12 +RENAME=13 +ROW=14 +SHOW=15 +SORT=16 +STATS=17 +WHERE=18 +UNKNOWN_CMD=19 +LINE_COMMENT=20 +MULTILINE_COMMENT=21 +WS=22 +EXPLAIN_WS=23 +EXPLAIN_LINE_COMMENT=24 +EXPLAIN_MULTILINE_COMMENT=25 +PIPE=26 +STRING=27 +INTEGER_LITERAL=28 +DECIMAL_LITERAL=29 +BY=30 +AND=31 +ASC=32 +ASSIGN=33 +COMMA=34 +DESC=35 +DOT=36 +FALSE=37 +FIRST=38 +LAST=39 +LP=40 +IN=41 +IS=42 +LIKE=43 +NOT=44 +NULL=45 +NULLS=46 +OR=47 +PARAM=48 +RLIKE=49 +RP=50 +TRUE=51 +EQ=52 +NEQ=53 +LT=54 +LTE=55 +GT=56 +GTE=57 +PLUS=58 +MINUS=59 +ASTERISK=60 +SLASH=61 +PERCENT=62 +OPENING_BRACKET=63 +CLOSING_BRACKET=64 +UNQUOTED_IDENTIFIER=65 +QUOTED_IDENTIFIER=66 +EXPR_LINE_COMMENT=67 +EXPR_MULTILINE_COMMENT=68 +EXPR_WS=69 +METADATA=70 +FROM_UNQUOTED_IDENTIFIER=71 +FROM_LINE_COMMENT=72 +FROM_MULTILINE_COMMENT=73 +FROM_WS=74 +PROJECT_UNQUOTED_IDENTIFIER=75 +PROJECT_LINE_COMMENT=76 +PROJECT_MULTILINE_COMMENT=77 +PROJECT_WS=78 +AS=79 +RENAME_LINE_COMMENT=80 +RENAME_MULTILINE_COMMENT=81 +RENAME_WS=82 +ON=83 +WITH=84 +ENRICH_LINE_COMMENT=85 +ENRICH_MULTILINE_COMMENT=86 +ENRICH_WS=87 +ENRICH_FIELD_LINE_COMMENT=88 +ENRICH_FIELD_MULTILINE_COMMENT=89 +ENRICH_FIELD_WS=90 +MVEXPAND_LINE_COMMENT=91 +MVEXPAND_MULTILINE_COMMENT=92 +MVEXPAND_WS=93 +INFO=94 +FUNCTIONS=95 +SHOW_LINE_COMMENT=96 +SHOW_MULTILINE_COMMENT=97 +SHOW_WS=98 +'|'=26 +'='=33 +','=34 +'.'=36 +'('=40 +'?'=48 +')'=50 +'=='=52 +'!='=53 +'<'=54 +'<='=55 +'>'=56 +'>='=57 +'+'=58 +'-'=59 +'*'=60 +'/'=61 +'%'=62 +']'=64 diff --git a/packages/kbn-monaco/src/esql/antlr/esql_parser.ts b/packages/kbn-monaco/src/esql/antlr/esql_parser.ts index 8e0a4ca8199b8e..90d3da25c8d1ce 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_parser.ts +++ b/packages/kbn-monaco/src/esql/antlr/esql_parser.ts @@ -31,78 +31,100 @@ export class esql_parser extends Parser { public static readonly DROP = 2; public static readonly ENRICH = 3; public static readonly EVAL = 4; - public static readonly FROM = 5; - public static readonly GROK = 6; - public static readonly KEEP = 7; - public static readonly LIMIT = 8; - public static readonly MV_EXPAND = 9; - public static readonly PROJECT = 10; - public static readonly RENAME = 11; - public static readonly ROW = 12; - public static readonly SHOW = 13; - public static readonly SORT = 14; - public static readonly STATS = 15; - public static readonly WHERE = 16; - public static readonly UNKNOWN_CMD = 17; - public static readonly LINE_COMMENT = 18; - public static readonly MULTILINE_COMMENT = 19; - public static readonly WS = 20; - public static readonly PIPE = 21; - public static readonly STRING = 22; - public static readonly INTEGER_LITERAL = 23; - public static readonly DECIMAL_LITERAL = 24; - public static readonly BY = 25; - public static readonly AND = 26; - public static readonly ASC = 27; - public static readonly ASSIGN = 28; - public static readonly COMMA = 29; - public static readonly DESC = 30; - public static readonly DOT = 31; - public static readonly FALSE = 32; - public static readonly FIRST = 33; - public static readonly LAST = 34; - public static readonly LP = 35; - public static readonly IN = 36; - public static readonly IS = 37; - public static readonly LIKE = 38; - public static readonly NOT = 39; - public static readonly NULL = 40; - public static readonly NULLS = 41; - public static readonly OR = 42; - public static readonly PARAM = 43; - public static readonly RLIKE = 44; - public static readonly RP = 45; - public static readonly TRUE = 46; - public static readonly INFO = 47; - public static readonly FUNCTIONS = 48; - public static readonly UNDERSCORE = 49; - public static readonly EQ = 50; - public static readonly NEQ = 51; - public static readonly LT = 52; - public static readonly LTE = 53; - public static readonly GT = 54; - public static readonly GTE = 55; - public static readonly PLUS = 56; - public static readonly MINUS = 57; - public static readonly ASTERISK = 58; - public static readonly SLASH = 59; - public static readonly PERCENT = 60; - public static readonly OPENING_BRACKET = 61; - public static readonly CLOSING_BRACKET = 62; - public static readonly UNQUOTED_IDENTIFIER = 63; - public static readonly QUOTED_IDENTIFIER = 64; - public static readonly EXPR_LINE_COMMENT = 65; - public static readonly EXPR_MULTILINE_COMMENT = 66; - public static readonly EXPR_WS = 67; - public static readonly AS = 68; - public static readonly METADATA = 69; - public static readonly ON = 70; - public static readonly WITH = 71; - public static readonly SRC_UNQUOTED_IDENTIFIER = 72; - public static readonly SRC_QUOTED_IDENTIFIER = 73; - public static readonly SRC_LINE_COMMENT = 74; - public static readonly SRC_MULTILINE_COMMENT = 75; - public static readonly SRC_WS = 76; + public static readonly EXPLAIN = 5; + public static readonly FROM = 6; + public static readonly GROK = 7; + public static readonly INLINESTATS = 8; + public static readonly KEEP = 9; + public static readonly LIMIT = 10; + public static readonly MV_EXPAND = 11; + public static readonly PROJECT = 12; + public static readonly RENAME = 13; + public static readonly ROW = 14; + public static readonly SHOW = 15; + public static readonly SORT = 16; + public static readonly STATS = 17; + public static readonly WHERE = 18; + public static readonly UNKNOWN_CMD = 19; + public static readonly LINE_COMMENT = 20; + public static readonly MULTILINE_COMMENT = 21; + public static readonly WS = 22; + public static readonly EXPLAIN_WS = 23; + public static readonly EXPLAIN_LINE_COMMENT = 24; + public static readonly EXPLAIN_MULTILINE_COMMENT = 25; + public static readonly PIPE = 26; + public static readonly STRING = 27; + public static readonly INTEGER_LITERAL = 28; + public static readonly DECIMAL_LITERAL = 29; + public static readonly BY = 30; + public static readonly AND = 31; + public static readonly ASC = 32; + public static readonly ASSIGN = 33; + public static readonly COMMA = 34; + public static readonly DESC = 35; + public static readonly DOT = 36; + public static readonly FALSE = 37; + public static readonly FIRST = 38; + public static readonly LAST = 39; + public static readonly LP = 40; + public static readonly IN = 41; + public static readonly IS = 42; + public static readonly LIKE = 43; + public static readonly NOT = 44; + public static readonly NULL = 45; + public static readonly NULLS = 46; + public static readonly OR = 47; + public static readonly PARAM = 48; + public static readonly RLIKE = 49; + public static readonly RP = 50; + public static readonly TRUE = 51; + public static readonly EQ = 52; + public static readonly NEQ = 53; + public static readonly LT = 54; + public static readonly LTE = 55; + public static readonly GT = 56; + public static readonly GTE = 57; + public static readonly PLUS = 58; + public static readonly MINUS = 59; + public static readonly ASTERISK = 60; + public static readonly SLASH = 61; + public static readonly PERCENT = 62; + public static readonly OPENING_BRACKET = 63; + public static readonly CLOSING_BRACKET = 64; + public static readonly UNQUOTED_IDENTIFIER = 65; + public static readonly QUOTED_IDENTIFIER = 66; + public static readonly EXPR_LINE_COMMENT = 67; + public static readonly EXPR_MULTILINE_COMMENT = 68; + public static readonly EXPR_WS = 69; + public static readonly METADATA = 70; + public static readonly FROM_UNQUOTED_IDENTIFIER = 71; + public static readonly FROM_LINE_COMMENT = 72; + public static readonly FROM_MULTILINE_COMMENT = 73; + public static readonly FROM_WS = 74; + public static readonly PROJECT_UNQUOTED_IDENTIFIER = 75; + public static readonly PROJECT_LINE_COMMENT = 76; + public static readonly PROJECT_MULTILINE_COMMENT = 77; + public static readonly PROJECT_WS = 78; + public static readonly AS = 79; + public static readonly RENAME_LINE_COMMENT = 80; + public static readonly RENAME_MULTILINE_COMMENT = 81; + public static readonly RENAME_WS = 82; + public static readonly ON = 83; + public static readonly WITH = 84; + public static readonly ENRICH_LINE_COMMENT = 85; + public static readonly ENRICH_MULTILINE_COMMENT = 86; + public static readonly ENRICH_WS = 87; + public static readonly ENRICH_FIELD_LINE_COMMENT = 88; + public static readonly ENRICH_FIELD_MULTILINE_COMMENT = 89; + public static readonly ENRICH_FIELD_WS = 90; + public static readonly MVEXPAND_LINE_COMMENT = 91; + public static readonly MVEXPAND_MULTILINE_COMMENT = 92; + public static readonly MVEXPAND_WS = 93; + public static readonly INFO = 94; + public static readonly FUNCTIONS = 95; + public static readonly SHOW_LINE_COMMENT = 96; + public static readonly SHOW_MULTILINE_COMMENT = 97; + public static readonly SHOW_WS = 98; public static readonly RULE_singleStatement = 0; public static readonly RULE_query = 1; public static readonly RULE_sourceCommand = 2; @@ -121,69 +143,82 @@ export class esql_parser extends Parser { public static readonly RULE_metadata = 15; public static readonly RULE_evalCommand = 16; public static readonly RULE_statsCommand = 17; - public static readonly RULE_grouping = 18; - public static readonly RULE_sourceIdentifier = 19; - public static readonly RULE_qualifiedName = 20; - public static readonly RULE_identifier = 21; - public static readonly RULE_constant = 22; - public static readonly RULE_limitCommand = 23; - public static readonly RULE_sortCommand = 24; - public static readonly RULE_orderExpression = 25; - public static readonly RULE_keepCommand = 26; - public static readonly RULE_dropCommand = 27; - public static readonly RULE_renameCommand = 28; - public static readonly RULE_renameClause = 29; - public static readonly RULE_dissectCommand = 30; - public static readonly RULE_grokCommand = 31; - public static readonly RULE_mvExpandCommand = 32; - public static readonly RULE_commandOptions = 33; - public static readonly RULE_commandOption = 34; - public static readonly RULE_booleanValue = 35; - public static readonly RULE_numericValue = 36; - public static readonly RULE_decimalValue = 37; - public static readonly RULE_integerValue = 38; - public static readonly RULE_string = 39; - public static readonly RULE_comparisonOperator = 40; - public static readonly RULE_showCommand = 41; - public static readonly RULE_enrichCommand = 42; - public static readonly RULE_enrichWithClause = 43; + public static readonly RULE_inlinestatsCommand = 18; + public static readonly RULE_grouping = 19; + public static readonly RULE_fromIdentifier = 20; + public static readonly RULE_qualifiedName = 21; + public static readonly RULE_qualifiedNamePattern = 22; + public static readonly RULE_identifier = 23; + public static readonly RULE_identifierPattern = 24; + public static readonly RULE_constant = 25; + public static readonly RULE_limitCommand = 26; + public static readonly RULE_sortCommand = 27; + public static readonly RULE_orderExpression = 28; + public static readonly RULE_keepCommand = 29; + public static readonly RULE_dropCommand = 30; + public static readonly RULE_renameCommand = 31; + public static readonly RULE_renameClause = 32; + public static readonly RULE_dissectCommand = 33; + public static readonly RULE_grokCommand = 34; + public static readonly RULE_mvExpandCommand = 35; + public static readonly RULE_commandOptions = 36; + public static readonly RULE_commandOption = 37; + public static readonly RULE_booleanValue = 38; + public static readonly RULE_numericValue = 39; + public static readonly RULE_decimalValue = 40; + public static readonly RULE_integerValue = 41; + public static readonly RULE_string = 42; + public static readonly RULE_comparisonOperator = 43; + public static readonly RULE_explainCommand = 44; + public static readonly RULE_subqueryExpression = 45; + public static readonly RULE_showCommand = 46; + public static readonly RULE_enrichCommand = 47; + public static readonly RULE_enrichWithClause = 48; // tslint:disable:no-trailing-whitespace public static readonly ruleNames: string[] = [ "singleStatement", "query", "sourceCommand", "processingCommand", "whereCommand", "booleanExpression", "regexBooleanExpression", "valueExpression", "operatorExpression", "primaryExpression", "functionExpression", "rowCommand", "fields", "field", - "fromCommand", "metadata", "evalCommand", "statsCommand", "grouping", - "sourceIdentifier", "qualifiedName", "identifier", "constant", "limitCommand", - "sortCommand", "orderExpression", "keepCommand", "dropCommand", "renameCommand", - "renameClause", "dissectCommand", "grokCommand", "mvExpandCommand", "commandOptions", + "fromCommand", "metadata", "evalCommand", "statsCommand", "inlinestatsCommand", + "grouping", "fromIdentifier", "qualifiedName", "qualifiedNamePattern", + "identifier", "identifierPattern", "constant", "limitCommand", "sortCommand", + "orderExpression", "keepCommand", "dropCommand", "renameCommand", "renameClause", + "dissectCommand", "grokCommand", "mvExpandCommand", "commandOptions", "commandOption", "booleanValue", "numericValue", "decimalValue", "integerValue", - "string", "comparisonOperator", "showCommand", "enrichCommand", "enrichWithClause", + "string", "comparisonOperator", "explainCommand", "subqueryExpression", + "showCommand", "enrichCommand", "enrichWithClause", ]; private static readonly _LITERAL_NAMES: Array = [ undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, - undefined, undefined, undefined, undefined, undefined, undefined, undefined, - undefined, undefined, undefined, "'.'", undefined, undefined, undefined, - "'('", undefined, undefined, undefined, undefined, undefined, undefined, - undefined, "'?'", undefined, "')'", undefined, undefined, undefined, "'_'", + undefined, undefined, undefined, undefined, undefined, "'|'", undefined, + undefined, undefined, undefined, undefined, undefined, "'='", "','", undefined, + "'.'", undefined, undefined, undefined, "'('", undefined, undefined, undefined, + undefined, undefined, undefined, undefined, "'?'", undefined, "')'", undefined, "'=='", "'!='", "'<'", "'<='", "'>'", "'>='", "'+'", "'-'", "'*'", "'/'", "'%'", undefined, "']'", ]; private static readonly _SYMBOLIC_NAMES: Array = [ - undefined, "DISSECT", "DROP", "ENRICH", "EVAL", "FROM", "GROK", "KEEP", - "LIMIT", "MV_EXPAND", "PROJECT", "RENAME", "ROW", "SHOW", "SORT", "STATS", - "WHERE", "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", "WS", "PIPE", - "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", - "COMMA", "DESC", "DOT", "FALSE", "FIRST", "LAST", "LP", "IN", "IS", "LIKE", - "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", "TRUE", "INFO", - "FUNCTIONS", "UNDERSCORE", "EQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", - "MINUS", "ASTERISK", "SLASH", "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET", - "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", - "EXPR_WS", "AS", "METADATA", "ON", "WITH", "SRC_UNQUOTED_IDENTIFIER", - "SRC_QUOTED_IDENTIFIER", "SRC_LINE_COMMENT", "SRC_MULTILINE_COMMENT", - "SRC_WS", + undefined, "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK", + "INLINESTATS", "KEEP", "LIMIT", "MV_EXPAND", "PROJECT", "RENAME", "ROW", + "SHOW", "SORT", "STATS", "WHERE", "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", + "WS", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", "EXPLAIN_MULTILINE_COMMENT", + "PIPE", "STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", "ASC", + "ASSIGN", "COMMA", "DESC", "DOT", "FALSE", "FIRST", "LAST", "LP", "IN", + "IS", "LIKE", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", "RP", "TRUE", + "EQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", "SLASH", + "PERCENT", "OPENING_BRACKET", "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", + "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", "EXPR_WS", + "METADATA", "FROM_UNQUOTED_IDENTIFIER", "FROM_LINE_COMMENT", "FROM_MULTILINE_COMMENT", + "FROM_WS", "PROJECT_UNQUOTED_IDENTIFIER", "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT", + "PROJECT_WS", "AS", "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", + "RENAME_WS", "ON", "WITH", "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT", + "ENRICH_WS", "ENRICH_FIELD_LINE_COMMENT", "ENRICH_FIELD_MULTILINE_COMMENT", + "ENRICH_FIELD_WS", "MVEXPAND_LINE_COMMENT", "MVEXPAND_MULTILINE_COMMENT", + "MVEXPAND_WS", "INFO", "FUNCTIONS", "SHOW_LINE_COMMENT", "SHOW_MULTILINE_COMMENT", + "SHOW_WS", ]; public static readonly VOCABULARY: Vocabulary = new VocabularyImpl(esql_parser._LITERAL_NAMES, esql_parser._SYMBOLIC_NAMES, []); @@ -214,9 +249,9 @@ export class esql_parser extends Parser { try { this.enterOuterAlt(_localctx, 1); { - this.state = 88; + this.state = 98; this.query(0); - this.state = 89; + this.state = 99; this.match(esql_parser.EOF); } } @@ -258,11 +293,11 @@ export class esql_parser extends Parser { this._ctx = _localctx; _prevctx = _localctx; - this.state = 92; + this.state = 102; this.sourceCommand(); } this._ctx._stop = this._input.tryLT(-1); - this.state = 99; + this.state = 109; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 0, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { @@ -275,18 +310,18 @@ export class esql_parser extends Parser { { _localctx = new CompositeQueryContext(new QueryContext(_parentctx, _parentState)); this.pushNewRecursionContext(_localctx, _startState, esql_parser.RULE_query); - this.state = 94; + this.state = 104; if (!(this.precpred(this._ctx, 1))) { throw new FailedPredicateException(this, "this.precpred(this._ctx, 1)"); } - this.state = 95; + this.state = 105; this.match(esql_parser.PIPE); - this.state = 96; + this.state = 106; this.processingCommand(); } } } - this.state = 101; + this.state = 111; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 0, this._ctx); } @@ -311,27 +346,34 @@ export class esql_parser extends Parser { let _localctx: SourceCommandContext = new SourceCommandContext(this._ctx, this.state); this.enterRule(_localctx, 4, esql_parser.RULE_sourceCommand); try { - this.state = 105; + this.state = 116; this._errHandler.sync(this); switch (this._input.LA(1)) { - case esql_parser.FROM: + case esql_parser.EXPLAIN: this.enterOuterAlt(_localctx, 1); { - this.state = 102; + this.state = 112; + this.explainCommand(); + } + break; + case esql_parser.FROM: + this.enterOuterAlt(_localctx, 2); + { + this.state = 113; this.fromCommand(); } break; case esql_parser.ROW: - this.enterOuterAlt(_localctx, 2); + this.enterOuterAlt(_localctx, 3); { - this.state = 103; + this.state = 114; this.rowCommand(); } break; case esql_parser.SHOW: - this.enterOuterAlt(_localctx, 3); + this.enterOuterAlt(_localctx, 4); { - this.state = 104; + this.state = 115; this.showCommand(); } break; @@ -358,91 +400,98 @@ export class esql_parser extends Parser { let _localctx: ProcessingCommandContext = new ProcessingCommandContext(this._ctx, this.state); this.enterRule(_localctx, 6, esql_parser.RULE_processingCommand); try { - this.state = 119; + this.state = 131; this._errHandler.sync(this); switch (this._input.LA(1)) { case esql_parser.EVAL: this.enterOuterAlt(_localctx, 1); { - this.state = 107; + this.state = 118; this.evalCommand(); } break; - case esql_parser.LIMIT: + case esql_parser.INLINESTATS: this.enterOuterAlt(_localctx, 2); { - this.state = 108; + this.state = 119; + this.inlinestatsCommand(); + } + break; + case esql_parser.LIMIT: + this.enterOuterAlt(_localctx, 3); + { + this.state = 120; this.limitCommand(); } break; case esql_parser.KEEP: case esql_parser.PROJECT: - this.enterOuterAlt(_localctx, 3); + this.enterOuterAlt(_localctx, 4); { - this.state = 109; + this.state = 121; this.keepCommand(); } break; case esql_parser.SORT: - this.enterOuterAlt(_localctx, 4); + this.enterOuterAlt(_localctx, 5); { - this.state = 110; + this.state = 122; this.sortCommand(); } break; case esql_parser.STATS: - this.enterOuterAlt(_localctx, 5); + this.enterOuterAlt(_localctx, 6); { - this.state = 111; + this.state = 123; this.statsCommand(); } break; case esql_parser.WHERE: - this.enterOuterAlt(_localctx, 6); + this.enterOuterAlt(_localctx, 7); { - this.state = 112; + this.state = 124; this.whereCommand(); } break; case esql_parser.DROP: - this.enterOuterAlt(_localctx, 7); + this.enterOuterAlt(_localctx, 8); { - this.state = 113; + this.state = 125; this.dropCommand(); } break; case esql_parser.RENAME: - this.enterOuterAlt(_localctx, 8); + this.enterOuterAlt(_localctx, 9); { - this.state = 114; + this.state = 126; this.renameCommand(); } break; case esql_parser.DISSECT: - this.enterOuterAlt(_localctx, 9); + this.enterOuterAlt(_localctx, 10); { - this.state = 115; + this.state = 127; this.dissectCommand(); } break; case esql_parser.GROK: - this.enterOuterAlt(_localctx, 10); + this.enterOuterAlt(_localctx, 11); { - this.state = 116; + this.state = 128; this.grokCommand(); } break; case esql_parser.ENRICH: - this.enterOuterAlt(_localctx, 11); + this.enterOuterAlt(_localctx, 12); { - this.state = 117; + this.state = 129; this.enrichCommand(); } break; case esql_parser.MV_EXPAND: - this.enterOuterAlt(_localctx, 12); + this.enterOuterAlt(_localctx, 13); { - this.state = 118; + this.state = 130; this.mvExpandCommand(); } break; @@ -471,9 +520,9 @@ export class esql_parser extends Parser { try { this.enterOuterAlt(_localctx, 1); { - this.state = 121; + this.state = 133; this.match(esql_parser.WHERE); - this.state = 122; + this.state = 134; this.booleanExpression(0); } } @@ -511,7 +560,7 @@ export class esql_parser extends Parser { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 152; + this.state = 164; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 6, this._ctx) ) { case 1: @@ -520,9 +569,9 @@ export class esql_parser extends Parser { this._ctx = _localctx; _prevctx = _localctx; - this.state = 125; + this.state = 137; this.match(esql_parser.NOT); - this.state = 126; + this.state = 138; this.booleanExpression(7); } break; @@ -532,7 +581,7 @@ export class esql_parser extends Parser { _localctx = new BooleanDefaultContext(_localctx); this._ctx = _localctx; _prevctx = _localctx; - this.state = 127; + this.state = 139; this.valueExpression(); } break; @@ -542,7 +591,7 @@ export class esql_parser extends Parser { _localctx = new RegexExpressionContext(_localctx); this._ctx = _localctx; _prevctx = _localctx; - this.state = 128; + this.state = 140; this.regexBooleanExpression(); } break; @@ -552,41 +601,41 @@ export class esql_parser extends Parser { _localctx = new LogicalInContext(_localctx); this._ctx = _localctx; _prevctx = _localctx; - this.state = 129; + this.state = 141; this.valueExpression(); - this.state = 131; + this.state = 143; this._errHandler.sync(this); _la = this._input.LA(1); if (_la === esql_parser.NOT) { { - this.state = 130; + this.state = 142; this.match(esql_parser.NOT); } } - this.state = 133; + this.state = 145; this.match(esql_parser.IN); - this.state = 134; + this.state = 146; this.match(esql_parser.LP); - this.state = 135; + this.state = 147; this.valueExpression(); - this.state = 140; + this.state = 152; this._errHandler.sync(this); _la = this._input.LA(1); while (_la === esql_parser.COMMA) { { { - this.state = 136; + this.state = 148; this.match(esql_parser.COMMA); - this.state = 137; + this.state = 149; this.valueExpression(); } } - this.state = 142; + this.state = 154; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 143; + this.state = 155; this.match(esql_parser.RP); } break; @@ -596,27 +645,27 @@ export class esql_parser extends Parser { _localctx = new IsNullContext(_localctx); this._ctx = _localctx; _prevctx = _localctx; - this.state = 145; + this.state = 157; this.valueExpression(); - this.state = 146; + this.state = 158; this.match(esql_parser.IS); - this.state = 148; + this.state = 160; this._errHandler.sync(this); _la = this._input.LA(1); if (_la === esql_parser.NOT) { { - this.state = 147; + this.state = 159; this.match(esql_parser.NOT); } } - this.state = 150; + this.state = 162; this.match(esql_parser.NULL); } break; } this._ctx._stop = this._input.tryLT(-1); - this.state = 162; + this.state = 174; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 8, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { @@ -626,7 +675,7 @@ export class esql_parser extends Parser { } _prevctx = _localctx; { - this.state = 160; + this.state = 172; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 7, this._ctx) ) { case 1: @@ -634,13 +683,13 @@ export class esql_parser extends Parser { _localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState)); (_localctx as LogicalBinaryContext)._left = _prevctx; this.pushNewRecursionContext(_localctx, _startState, esql_parser.RULE_booleanExpression); - this.state = 154; + this.state = 166; if (!(this.precpred(this._ctx, 4))) { throw new FailedPredicateException(this, "this.precpred(this._ctx, 4)"); } - this.state = 155; + this.state = 167; (_localctx as LogicalBinaryContext)._operator = this.match(esql_parser.AND); - this.state = 156; + this.state = 168; (_localctx as LogicalBinaryContext)._right = this.booleanExpression(5); } break; @@ -650,20 +699,20 @@ export class esql_parser extends Parser { _localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState)); (_localctx as LogicalBinaryContext)._left = _prevctx; this.pushNewRecursionContext(_localctx, _startState, esql_parser.RULE_booleanExpression); - this.state = 157; + this.state = 169; if (!(this.precpred(this._ctx, 3))) { throw new FailedPredicateException(this, "this.precpred(this._ctx, 3)"); } - this.state = 158; + this.state = 170; (_localctx as LogicalBinaryContext)._operator = this.match(esql_parser.OR); - this.state = 159; + this.state = 171; (_localctx as LogicalBinaryContext)._right = this.booleanExpression(4); } break; } } } - this.state = 164; + this.state = 176; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 8, this._ctx); } @@ -689,27 +738,27 @@ export class esql_parser extends Parser { this.enterRule(_localctx, 12, esql_parser.RULE_regexBooleanExpression); let _la: number; try { - this.state = 179; + this.state = 191; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 11, this._ctx) ) { case 1: this.enterOuterAlt(_localctx, 1); { - this.state = 165; + this.state = 177; this.valueExpression(); - this.state = 167; + this.state = 179; this._errHandler.sync(this); _la = this._input.LA(1); if (_la === esql_parser.NOT) { { - this.state = 166; + this.state = 178; this.match(esql_parser.NOT); } } - this.state = 169; + this.state = 181; _localctx._kind = this.match(esql_parser.LIKE); - this.state = 170; + this.state = 182; _localctx._pattern = this.string(); } break; @@ -717,21 +766,21 @@ export class esql_parser extends Parser { case 2: this.enterOuterAlt(_localctx, 2); { - this.state = 172; + this.state = 184; this.valueExpression(); - this.state = 174; + this.state = 186; this._errHandler.sync(this); _la = this._input.LA(1); if (_la === esql_parser.NOT) { { - this.state = 173; + this.state = 185; this.match(esql_parser.NOT); } } - this.state = 176; + this.state = 188; _localctx._kind = this.match(esql_parser.RLIKE); - this.state = 177; + this.state = 189; _localctx._pattern = this.string(); } break; @@ -756,14 +805,14 @@ export class esql_parser extends Parser { let _localctx: ValueExpressionContext = new ValueExpressionContext(this._ctx, this.state); this.enterRule(_localctx, 14, esql_parser.RULE_valueExpression); try { - this.state = 186; + this.state = 198; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 12, this._ctx) ) { case 1: _localctx = new ValueExpressionDefaultContext(_localctx); this.enterOuterAlt(_localctx, 1); { - this.state = 181; + this.state = 193; this.operatorExpression(0); } break; @@ -772,11 +821,11 @@ export class esql_parser extends Parser { _localctx = new ComparisonContext(_localctx); this.enterOuterAlt(_localctx, 2); { - this.state = 182; + this.state = 194; (_localctx as ComparisonContext)._left = this.operatorExpression(0); - this.state = 183; + this.state = 195; this.comparisonOperator(); - this.state = 184; + this.state = 196; (_localctx as ComparisonContext)._right = this.operatorExpression(0); } break; @@ -816,7 +865,7 @@ export class esql_parser extends Parser { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 192; + this.state = 204; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 13, this._ctx) ) { case 1: @@ -825,7 +874,7 @@ export class esql_parser extends Parser { this._ctx = _localctx; _prevctx = _localctx; - this.state = 189; + this.state = 201; this.primaryExpression(); } break; @@ -835,7 +884,7 @@ export class esql_parser extends Parser { _localctx = new ArithmeticUnaryContext(_localctx); this._ctx = _localctx; _prevctx = _localctx; - this.state = 190; + this.state = 202; (_localctx as ArithmeticUnaryContext)._operator = this._input.LT(1); _la = this._input.LA(1); if (!(_la === esql_parser.PLUS || _la === esql_parser.MINUS)) { @@ -848,13 +897,13 @@ export class esql_parser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 191; + this.state = 203; this.operatorExpression(3); } break; } this._ctx._stop = this._input.tryLT(-1); - this.state = 202; + this.state = 214; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 15, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { @@ -864,7 +913,7 @@ export class esql_parser extends Parser { } _prevctx = _localctx; { - this.state = 200; + this.state = 212; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 14, this._ctx) ) { case 1: @@ -872,14 +921,14 @@ export class esql_parser extends Parser { _localctx = new ArithmeticBinaryContext(new OperatorExpressionContext(_parentctx, _parentState)); (_localctx as ArithmeticBinaryContext)._left = _prevctx; this.pushNewRecursionContext(_localctx, _startState, esql_parser.RULE_operatorExpression); - this.state = 194; + this.state = 206; if (!(this.precpred(this._ctx, 2))) { throw new FailedPredicateException(this, "this.precpred(this._ctx, 2)"); } - this.state = 195; + this.state = 207; (_localctx as ArithmeticBinaryContext)._operator = this._input.LT(1); _la = this._input.LA(1); - if (!(((((_la - 58)) & ~0x1F) === 0 && ((1 << (_la - 58)) & ((1 << (esql_parser.ASTERISK - 58)) | (1 << (esql_parser.SLASH - 58)) | (1 << (esql_parser.PERCENT - 58)))) !== 0))) { + if (!(((((_la - 60)) & ~0x1F) === 0 && ((1 << (_la - 60)) & ((1 << (esql_parser.ASTERISK - 60)) | (1 << (esql_parser.SLASH - 60)) | (1 << (esql_parser.PERCENT - 60)))) !== 0))) { (_localctx as ArithmeticBinaryContext)._operator = this._errHandler.recoverInline(this); } else { if (this._input.LA(1) === Token.EOF) { @@ -889,7 +938,7 @@ export class esql_parser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 196; + this.state = 208; (_localctx as ArithmeticBinaryContext)._right = this.operatorExpression(3); } break; @@ -899,11 +948,11 @@ export class esql_parser extends Parser { _localctx = new ArithmeticBinaryContext(new OperatorExpressionContext(_parentctx, _parentState)); (_localctx as ArithmeticBinaryContext)._left = _prevctx; this.pushNewRecursionContext(_localctx, _startState, esql_parser.RULE_operatorExpression); - this.state = 197; + this.state = 209; if (!(this.precpred(this._ctx, 1))) { throw new FailedPredicateException(this, "this.precpred(this._ctx, 1)"); } - this.state = 198; + this.state = 210; (_localctx as ArithmeticBinaryContext)._operator = this._input.LT(1); _la = this._input.LA(1); if (!(_la === esql_parser.PLUS || _la === esql_parser.MINUS)) { @@ -916,14 +965,14 @@ export class esql_parser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 199; + this.state = 211; (_localctx as ArithmeticBinaryContext)._right = this.operatorExpression(2); } break; } } } - this.state = 204; + this.state = 216; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 15, this._ctx); } @@ -948,14 +997,14 @@ export class esql_parser extends Parser { let _localctx: PrimaryExpressionContext = new PrimaryExpressionContext(this._ctx, this.state); this.enterRule(_localctx, 18, esql_parser.RULE_primaryExpression); try { - this.state = 212; + this.state = 224; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 16, this._ctx) ) { case 1: _localctx = new ConstantDefaultContext(_localctx); this.enterOuterAlt(_localctx, 1); { - this.state = 205; + this.state = 217; this.constant(); } break; @@ -964,7 +1013,7 @@ export class esql_parser extends Parser { _localctx = new DereferenceContext(_localctx); this.enterOuterAlt(_localctx, 2); { - this.state = 206; + this.state = 218; this.qualifiedName(); } break; @@ -973,7 +1022,7 @@ export class esql_parser extends Parser { _localctx = new FunctionContext(_localctx); this.enterOuterAlt(_localctx, 3); { - this.state = 207; + this.state = 219; this.functionExpression(); } break; @@ -982,11 +1031,11 @@ export class esql_parser extends Parser { _localctx = new ParenthesizedExpressionContext(_localctx); this.enterOuterAlt(_localctx, 4); { - this.state = 208; + this.state = 220; this.match(esql_parser.LP); - this.state = 209; + this.state = 221; this.booleanExpression(0); - this.state = 210; + this.state = 222; this.match(esql_parser.RP); } break; @@ -1014,16 +1063,16 @@ export class esql_parser extends Parser { try { this.enterOuterAlt(_localctx, 1); { - this.state = 214; + this.state = 226; this.identifier(); - this.state = 215; + this.state = 227; this.match(esql_parser.LP); - this.state = 225; + this.state = 237; this._errHandler.sync(this); switch (this._input.LA(1)) { case esql_parser.ASTERISK: { - this.state = 216; + this.state = 228; this.match(esql_parser.ASTERISK); } break; @@ -1043,21 +1092,21 @@ export class esql_parser extends Parser { case esql_parser.QUOTED_IDENTIFIER: { { - this.state = 217; + this.state = 229; this.booleanExpression(0); - this.state = 222; + this.state = 234; this._errHandler.sync(this); _la = this._input.LA(1); while (_la === esql_parser.COMMA) { { { - this.state = 218; + this.state = 230; this.match(esql_parser.COMMA); - this.state = 219; + this.state = 231; this.booleanExpression(0); } } - this.state = 224; + this.state = 236; this._errHandler.sync(this); _la = this._input.LA(1); } @@ -1069,7 +1118,7 @@ export class esql_parser extends Parser { default: break; } - this.state = 227; + this.state = 239; this.match(esql_parser.RP); } } @@ -1094,9 +1143,9 @@ export class esql_parser extends Parser { try { this.enterOuterAlt(_localctx, 1); { - this.state = 229; + this.state = 241; this.match(esql_parser.ROW); - this.state = 230; + this.state = 242; this.fields(); } } @@ -1122,23 +1171,23 @@ export class esql_parser extends Parser { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 232; + this.state = 244; this.field(); - this.state = 237; + this.state = 249; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 19, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 233; + this.state = 245; this.match(esql_parser.COMMA); - this.state = 234; + this.state = 246; this.field(); } } } - this.state = 239; + this.state = 251; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 19, this._ctx); } @@ -1163,13 +1212,13 @@ export class esql_parser extends Parser { let _localctx: FieldContext = new FieldContext(this._ctx, this.state); this.enterRule(_localctx, 26, esql_parser.RULE_field); try { - this.state = 245; + this.state = 257; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 20, this._ctx) ) { case 1: this.enterOuterAlt(_localctx, 1); { - this.state = 240; + this.state = 252; this.booleanExpression(0); } break; @@ -1177,11 +1226,11 @@ export class esql_parser extends Parser { case 2: this.enterOuterAlt(_localctx, 2); { - this.state = 241; + this.state = 253; this.qualifiedName(); - this.state = 242; + this.state = 254; this.match(esql_parser.ASSIGN); - this.state = 243; + this.state = 255; this.booleanExpression(0); } break; @@ -1209,34 +1258,34 @@ export class esql_parser extends Parser { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 247; + this.state = 259; this.match(esql_parser.FROM); - this.state = 248; - this.sourceIdentifier(); - this.state = 253; + this.state = 260; + this.fromIdentifier(); + this.state = 265; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 21, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 249; + this.state = 261; this.match(esql_parser.COMMA); - this.state = 250; - this.sourceIdentifier(); + this.state = 262; + this.fromIdentifier(); } } } - this.state = 255; + this.state = 267; this._errHandler.sync(this); _alt = this.interpreter.adaptivePredict(this._input, 21, this._ctx); } - this.state = 257; + this.state = 269; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 22, this._ctx) ) { case 1: { - this.state = 256; + this.state = 268; this.metadata(); } break; @@ -1265,29 +1314,29 @@ export class esql_parser extends Parser { try { this.enterOuterAlt(_localctx, 1); { - this.state = 259; + this.state = 271; this.match(esql_parser.OPENING_BRACKET); - this.state = 260; + this.state = 272; this.match(esql_parser.METADATA); - this.state = 261; - this.sourceIdentifier(); - this.state = 266; + this.state = 273; + this.fromIdentifier(); + this.state = 278; this._errHandler.sync(this); _la = this._input.LA(1); while (_la === esql_parser.COMMA) { { { - this.state = 262; + this.state = 274; this.match(esql_parser.COMMA); - this.state = 263; - this.sourceIdentifier(); + this.state = 275; + this.fromIdentifier(); } } - this.state = 268; + this.state = 280; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 269; + this.state = 281; this.match(esql_parser.CLOSING_BRACKET); } } @@ -1312,9 +1361,9 @@ export class esql_parser extends Parser { try { this.enterOuterAlt(_localctx, 1); { - this.state = 271; + this.state = 283; this.match(esql_parser.EVAL); - this.state = 272; + this.state = 284; this.fields(); } } @@ -1339,26 +1388,65 @@ export class esql_parser extends Parser { try { this.enterOuterAlt(_localctx, 1); { - this.state = 274; + this.state = 286; this.match(esql_parser.STATS); - this.state = 276; + this.state = 288; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 24, this._ctx) ) { case 1: { - this.state = 275; + this.state = 287; this.fields(); } break; } - this.state = 280; + this.state = 292; this._errHandler.sync(this); switch ( this.interpreter.adaptivePredict(this._input, 25, this._ctx) ) { case 1: { - this.state = 278; + this.state = 290; this.match(esql_parser.BY); - this.state = 279; + this.state = 291; + this.grouping(); + } + break; + } + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public inlinestatsCommand(): InlinestatsCommandContext { + let _localctx: InlinestatsCommandContext = new InlinestatsCommandContext(this._ctx, this.state); + this.enterRule(_localctx, 36, esql_parser.RULE_inlinestatsCommand); + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 294; + this.match(esql_parser.INLINESTATS); + this.state = 295; + this.fields(); + this.state = 298; + this._errHandler.sync(this); + switch ( this.interpreter.adaptivePredict(this._input, 26, this._ctx) ) { + case 1: + { + this.state = 296; + this.match(esql_parser.BY); + this.state = 297; this.grouping(); } break; @@ -1382,30 +1470,30 @@ export class esql_parser extends Parser { // @RuleVersion(0) public grouping(): GroupingContext { let _localctx: GroupingContext = new GroupingContext(this._ctx, this.state); - this.enterRule(_localctx, 36, esql_parser.RULE_grouping); + this.enterRule(_localctx, 38, esql_parser.RULE_grouping); try { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 282; + this.state = 300; this.qualifiedName(); - this.state = 287; + this.state = 305; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 26, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 27, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 283; + this.state = 301; this.match(esql_parser.COMMA); - this.state = 284; + this.state = 302; this.qualifiedName(); } } } - this.state = 289; + this.state = 307; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 26, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 27, this._ctx); } } } @@ -1424,16 +1512,16 @@ export class esql_parser extends Parser { return _localctx; } // @RuleVersion(0) - public sourceIdentifier(): SourceIdentifierContext { - let _localctx: SourceIdentifierContext = new SourceIdentifierContext(this._ctx, this.state); - this.enterRule(_localctx, 38, esql_parser.RULE_sourceIdentifier); + public fromIdentifier(): FromIdentifierContext { + let _localctx: FromIdentifierContext = new FromIdentifierContext(this._ctx, this.state); + this.enterRule(_localctx, 40, esql_parser.RULE_fromIdentifier); let _la: number; try { this.enterOuterAlt(_localctx, 1); { - this.state = 290; + this.state = 308; _la = this._input.LA(1); - if (!(_la === esql_parser.SRC_UNQUOTED_IDENTIFIER || _la === esql_parser.SRC_QUOTED_IDENTIFIER)) { + if (!(_la === esql_parser.QUOTED_IDENTIFIER || _la === esql_parser.FROM_UNQUOTED_IDENTIFIER)) { this._errHandler.recoverInline(this); } else { if (this._input.LA(1) === Token.EOF) { @@ -1462,30 +1550,74 @@ export class esql_parser extends Parser { // @RuleVersion(0) public qualifiedName(): QualifiedNameContext { let _localctx: QualifiedNameContext = new QualifiedNameContext(this._ctx, this.state); - this.enterRule(_localctx, 40, esql_parser.RULE_qualifiedName); + this.enterRule(_localctx, 42, esql_parser.RULE_qualifiedName); try { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 292; + this.state = 310; this.identifier(); - this.state = 297; + this.state = 315; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 27, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 28, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 293; + this.state = 311; this.match(esql_parser.DOT); - this.state = 294; + this.state = 312; this.identifier(); } } } - this.state = 299; + this.state = 317; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 27, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 28, this._ctx); + } + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public qualifiedNamePattern(): QualifiedNamePatternContext { + let _localctx: QualifiedNamePatternContext = new QualifiedNamePatternContext(this._ctx, this.state); + this.enterRule(_localctx, 44, esql_parser.RULE_qualifiedNamePattern); + try { + let _alt: number; + this.enterOuterAlt(_localctx, 1); + { + this.state = 318; + this.identifierPattern(); + this.state = 323; + this._errHandler.sync(this); + _alt = this.interpreter.adaptivePredict(this._input, 29, this._ctx); + while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { + if (_alt === 1) { + { + { + this.state = 319; + this.match(esql_parser.DOT); + this.state = 320; + this.identifierPattern(); + } + } + } + this.state = 325; + this._errHandler.sync(this); + _alt = this.interpreter.adaptivePredict(this._input, 29, this._ctx); } } } @@ -1506,12 +1638,12 @@ export class esql_parser extends Parser { // @RuleVersion(0) public identifier(): IdentifierContext { let _localctx: IdentifierContext = new IdentifierContext(this._ctx, this.state); - this.enterRule(_localctx, 42, esql_parser.RULE_identifier); + this.enterRule(_localctx, 46, esql_parser.RULE_identifier); let _la: number; try { this.enterOuterAlt(_localctx, 1); { - this.state = 300; + this.state = 326; _la = this._input.LA(1); if (!(_la === esql_parser.UNQUOTED_IDENTIFIER || _la === esql_parser.QUOTED_IDENTIFIER)) { this._errHandler.recoverInline(this); @@ -1540,19 +1672,55 @@ export class esql_parser extends Parser { return _localctx; } // @RuleVersion(0) + public identifierPattern(): IdentifierPatternContext { + let _localctx: IdentifierPatternContext = new IdentifierPatternContext(this._ctx, this.state); + this.enterRule(_localctx, 48, esql_parser.RULE_identifierPattern); + let _la: number; + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 328; + _la = this._input.LA(1); + if (!(_la === esql_parser.QUOTED_IDENTIFIER || _la === esql_parser.PROJECT_UNQUOTED_IDENTIFIER)) { + this._errHandler.recoverInline(this); + } else { + if (this._input.LA(1) === Token.EOF) { + this.matchedEOF = true; + } + + this._errHandler.reportMatch(this); + this.consume(); + } + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) public constant(): ConstantContext { let _localctx: ConstantContext = new ConstantContext(this._ctx, this.state); - this.enterRule(_localctx, 44, esql_parser.RULE_constant); + this.enterRule(_localctx, 50, esql_parser.RULE_constant); let _la: number; try { - this.state = 344; + this.state = 372; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 31, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 33, this._ctx) ) { case 1: _localctx = new NullLiteralContext(_localctx); this.enterOuterAlt(_localctx, 1); { - this.state = 302; + this.state = 330; this.match(esql_parser.NULL); } break; @@ -1561,9 +1729,9 @@ export class esql_parser extends Parser { _localctx = new QualifiedIntegerLiteralContext(_localctx); this.enterOuterAlt(_localctx, 2); { - this.state = 303; + this.state = 331; this.integerValue(); - this.state = 304; + this.state = 332; this.match(esql_parser.UNQUOTED_IDENTIFIER); } break; @@ -1572,7 +1740,7 @@ export class esql_parser extends Parser { _localctx = new DecimalLiteralContext(_localctx); this.enterOuterAlt(_localctx, 3); { - this.state = 306; + this.state = 334; this.decimalValue(); } break; @@ -1581,7 +1749,7 @@ export class esql_parser extends Parser { _localctx = new IntegerLiteralContext(_localctx); this.enterOuterAlt(_localctx, 4); { - this.state = 307; + this.state = 335; this.integerValue(); } break; @@ -1590,7 +1758,7 @@ export class esql_parser extends Parser { _localctx = new BooleanLiteralContext(_localctx); this.enterOuterAlt(_localctx, 5); { - this.state = 308; + this.state = 336; this.booleanValue(); } break; @@ -1599,7 +1767,7 @@ export class esql_parser extends Parser { _localctx = new InputParamContext(_localctx); this.enterOuterAlt(_localctx, 6); { - this.state = 309; + this.state = 337; this.match(esql_parser.PARAM); } break; @@ -1608,7 +1776,7 @@ export class esql_parser extends Parser { _localctx = new StringLiteralContext(_localctx); this.enterOuterAlt(_localctx, 7); { - this.state = 310; + this.state = 338; this.string(); } break; @@ -1617,27 +1785,27 @@ export class esql_parser extends Parser { _localctx = new NumericArrayLiteralContext(_localctx); this.enterOuterAlt(_localctx, 8); { - this.state = 311; + this.state = 339; this.match(esql_parser.OPENING_BRACKET); - this.state = 312; + this.state = 340; this.numericValue(); - this.state = 317; + this.state = 345; this._errHandler.sync(this); _la = this._input.LA(1); while (_la === esql_parser.COMMA) { { { - this.state = 313; + this.state = 341; this.match(esql_parser.COMMA); - this.state = 314; + this.state = 342; this.numericValue(); } } - this.state = 319; + this.state = 347; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 320; + this.state = 348; this.match(esql_parser.CLOSING_BRACKET); } break; @@ -1646,27 +1814,27 @@ export class esql_parser extends Parser { _localctx = new BooleanArrayLiteralContext(_localctx); this.enterOuterAlt(_localctx, 9); { - this.state = 322; + this.state = 350; this.match(esql_parser.OPENING_BRACKET); - this.state = 323; + this.state = 351; this.booleanValue(); - this.state = 328; + this.state = 356; this._errHandler.sync(this); _la = this._input.LA(1); while (_la === esql_parser.COMMA) { { { - this.state = 324; + this.state = 352; this.match(esql_parser.COMMA); - this.state = 325; + this.state = 353; this.booleanValue(); } } - this.state = 330; + this.state = 358; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 331; + this.state = 359; this.match(esql_parser.CLOSING_BRACKET); } break; @@ -1675,27 +1843,27 @@ export class esql_parser extends Parser { _localctx = new StringArrayLiteralContext(_localctx); this.enterOuterAlt(_localctx, 10); { - this.state = 333; + this.state = 361; this.match(esql_parser.OPENING_BRACKET); - this.state = 334; + this.state = 362; this.string(); - this.state = 339; + this.state = 367; this._errHandler.sync(this); _la = this._input.LA(1); while (_la === esql_parser.COMMA) { { { - this.state = 335; + this.state = 363; this.match(esql_parser.COMMA); - this.state = 336; + this.state = 364; this.string(); } } - this.state = 341; + this.state = 369; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 342; + this.state = 370; this.match(esql_parser.CLOSING_BRACKET); } break; @@ -1718,13 +1886,13 @@ export class esql_parser extends Parser { // @RuleVersion(0) public limitCommand(): LimitCommandContext { let _localctx: LimitCommandContext = new LimitCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 46, esql_parser.RULE_limitCommand); + this.enterRule(_localctx, 52, esql_parser.RULE_limitCommand); try { this.enterOuterAlt(_localctx, 1); { - this.state = 346; + this.state = 374; this.match(esql_parser.LIMIT); - this.state = 347; + this.state = 375; this.match(esql_parser.INTEGER_LITERAL); } } @@ -1745,32 +1913,32 @@ export class esql_parser extends Parser { // @RuleVersion(0) public sortCommand(): SortCommandContext { let _localctx: SortCommandContext = new SortCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 48, esql_parser.RULE_sortCommand); + this.enterRule(_localctx, 54, esql_parser.RULE_sortCommand); try { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 349; + this.state = 377; this.match(esql_parser.SORT); - this.state = 350; + this.state = 378; this.orderExpression(); - this.state = 355; + this.state = 383; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 32, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 34, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 351; + this.state = 379; this.match(esql_parser.COMMA); - this.state = 352; + this.state = 380; this.orderExpression(); } } } - this.state = 357; + this.state = 385; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 32, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 34, this._ctx); } } } @@ -1791,19 +1959,19 @@ export class esql_parser extends Parser { // @RuleVersion(0) public orderExpression(): OrderExpressionContext { let _localctx: OrderExpressionContext = new OrderExpressionContext(this._ctx, this.state); - this.enterRule(_localctx, 50, esql_parser.RULE_orderExpression); + this.enterRule(_localctx, 56, esql_parser.RULE_orderExpression); let _la: number; try { this.enterOuterAlt(_localctx, 1); { - this.state = 358; + this.state = 386; this.booleanExpression(0); - this.state = 360; + this.state = 388; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 33, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 35, this._ctx) ) { case 1: { - this.state = 359; + this.state = 387; _localctx._ordering = this._input.LT(1); _la = this._input.LA(1); if (!(_la === esql_parser.ASC || _la === esql_parser.DESC)) { @@ -1819,14 +1987,14 @@ export class esql_parser extends Parser { } break; } - this.state = 364; + this.state = 392; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 34, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 36, this._ctx) ) { case 1: { - this.state = 362; + this.state = 390; this.match(esql_parser.NULLS); - this.state = 363; + this.state = 391; _localctx._nullOrdering = this._input.LT(1); _la = this._input.LA(1); if (!(_la === esql_parser.FIRST || _la === esql_parser.LAST)) { @@ -1861,63 +2029,63 @@ export class esql_parser extends Parser { // @RuleVersion(0) public keepCommand(): KeepCommandContext { let _localctx: KeepCommandContext = new KeepCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 52, esql_parser.RULE_keepCommand); + this.enterRule(_localctx, 58, esql_parser.RULE_keepCommand); try { let _alt: number; - this.state = 384; + this.state = 412; this._errHandler.sync(this); switch (this._input.LA(1)) { case esql_parser.KEEP: this.enterOuterAlt(_localctx, 1); { - this.state = 366; + this.state = 394; this.match(esql_parser.KEEP); - this.state = 367; - this.sourceIdentifier(); - this.state = 372; + this.state = 395; + this.qualifiedNamePattern(); + this.state = 400; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 35, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 37, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 368; + this.state = 396; this.match(esql_parser.COMMA); - this.state = 369; - this.sourceIdentifier(); + this.state = 397; + this.qualifiedNamePattern(); } } } - this.state = 374; + this.state = 402; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 35, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 37, this._ctx); } } break; case esql_parser.PROJECT: this.enterOuterAlt(_localctx, 2); { - this.state = 375; + this.state = 403; this.match(esql_parser.PROJECT); - this.state = 376; - this.sourceIdentifier(); - this.state = 381; + this.state = 404; + this.qualifiedNamePattern(); + this.state = 409; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 36, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 38, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 377; + this.state = 405; this.match(esql_parser.COMMA); - this.state = 378; - this.sourceIdentifier(); + this.state = 406; + this.qualifiedNamePattern(); } } } - this.state = 383; + this.state = 411; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 36, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 38, this._ctx); } } break; @@ -1942,32 +2110,32 @@ export class esql_parser extends Parser { // @RuleVersion(0) public dropCommand(): DropCommandContext { let _localctx: DropCommandContext = new DropCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 54, esql_parser.RULE_dropCommand); + this.enterRule(_localctx, 60, esql_parser.RULE_dropCommand); try { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 386; + this.state = 414; this.match(esql_parser.DROP); - this.state = 387; - this.sourceIdentifier(); - this.state = 392; + this.state = 415; + this.qualifiedNamePattern(); + this.state = 420; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 38, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 40, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 388; + this.state = 416; this.match(esql_parser.COMMA); - this.state = 389; - this.sourceIdentifier(); + this.state = 417; + this.qualifiedNamePattern(); } } } - this.state = 394; + this.state = 422; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 38, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 40, this._ctx); } } } @@ -1988,32 +2156,32 @@ export class esql_parser extends Parser { // @RuleVersion(0) public renameCommand(): RenameCommandContext { let _localctx: RenameCommandContext = new RenameCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 56, esql_parser.RULE_renameCommand); + this.enterRule(_localctx, 62, esql_parser.RULE_renameCommand); try { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 395; + this.state = 423; this.match(esql_parser.RENAME); - this.state = 396; + this.state = 424; this.renameClause(); - this.state = 401; + this.state = 429; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 39, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 41, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 397; + this.state = 425; this.match(esql_parser.COMMA); - this.state = 398; + this.state = 426; this.renameClause(); } } } - this.state = 403; + this.state = 431; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 39, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 41, this._ctx); } } } @@ -2034,16 +2202,16 @@ export class esql_parser extends Parser { // @RuleVersion(0) public renameClause(): RenameClauseContext { let _localctx: RenameClauseContext = new RenameClauseContext(this._ctx, this.state); - this.enterRule(_localctx, 58, esql_parser.RULE_renameClause); + this.enterRule(_localctx, 64, esql_parser.RULE_renameClause); try { this.enterOuterAlt(_localctx, 1); { - this.state = 404; - _localctx._oldName = this.sourceIdentifier(); - this.state = 405; + this.state = 432; + _localctx._oldName = this.qualifiedNamePattern(); + this.state = 433; this.match(esql_parser.AS); - this.state = 406; - _localctx._newName = this.sourceIdentifier(); + this.state = 434; + _localctx._newName = this.qualifiedNamePattern(); } } catch (re) { @@ -2063,22 +2231,22 @@ export class esql_parser extends Parser { // @RuleVersion(0) public dissectCommand(): DissectCommandContext { let _localctx: DissectCommandContext = new DissectCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 60, esql_parser.RULE_dissectCommand); + this.enterRule(_localctx, 66, esql_parser.RULE_dissectCommand); try { this.enterOuterAlt(_localctx, 1); { - this.state = 408; + this.state = 436; this.match(esql_parser.DISSECT); - this.state = 409; + this.state = 437; this.primaryExpression(); - this.state = 410; + this.state = 438; this.string(); - this.state = 412; + this.state = 440; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 40, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 42, this._ctx) ) { case 1: { - this.state = 411; + this.state = 439; this.commandOptions(); } break; @@ -2102,15 +2270,15 @@ export class esql_parser extends Parser { // @RuleVersion(0) public grokCommand(): GrokCommandContext { let _localctx: GrokCommandContext = new GrokCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 62, esql_parser.RULE_grokCommand); + this.enterRule(_localctx, 68, esql_parser.RULE_grokCommand); try { this.enterOuterAlt(_localctx, 1); { - this.state = 414; + this.state = 442; this.match(esql_parser.GROK); - this.state = 415; + this.state = 443; this.primaryExpression(); - this.state = 416; + this.state = 444; this.string(); } } @@ -2131,14 +2299,14 @@ export class esql_parser extends Parser { // @RuleVersion(0) public mvExpandCommand(): MvExpandCommandContext { let _localctx: MvExpandCommandContext = new MvExpandCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 64, esql_parser.RULE_mvExpandCommand); + this.enterRule(_localctx, 70, esql_parser.RULE_mvExpandCommand); try { this.enterOuterAlt(_localctx, 1); { - this.state = 418; + this.state = 446; this.match(esql_parser.MV_EXPAND); - this.state = 419; - this.sourceIdentifier(); + this.state = 447; + this.qualifiedName(); } } catch (re) { @@ -2158,30 +2326,30 @@ export class esql_parser extends Parser { // @RuleVersion(0) public commandOptions(): CommandOptionsContext { let _localctx: CommandOptionsContext = new CommandOptionsContext(this._ctx, this.state); - this.enterRule(_localctx, 66, esql_parser.RULE_commandOptions); + this.enterRule(_localctx, 72, esql_parser.RULE_commandOptions); try { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 421; + this.state = 449; this.commandOption(); - this.state = 426; + this.state = 454; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 41, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 43, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 422; + this.state = 450; this.match(esql_parser.COMMA); - this.state = 423; + this.state = 451; this.commandOption(); } } } - this.state = 428; + this.state = 456; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 41, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 43, this._ctx); } } } @@ -2202,15 +2370,15 @@ export class esql_parser extends Parser { // @RuleVersion(0) public commandOption(): CommandOptionContext { let _localctx: CommandOptionContext = new CommandOptionContext(this._ctx, this.state); - this.enterRule(_localctx, 68, esql_parser.RULE_commandOption); + this.enterRule(_localctx, 74, esql_parser.RULE_commandOption); try { this.enterOuterAlt(_localctx, 1); { - this.state = 429; + this.state = 457; this.identifier(); - this.state = 430; + this.state = 458; this.match(esql_parser.ASSIGN); - this.state = 431; + this.state = 459; this.constant(); } } @@ -2231,12 +2399,12 @@ export class esql_parser extends Parser { // @RuleVersion(0) public booleanValue(): BooleanValueContext { let _localctx: BooleanValueContext = new BooleanValueContext(this._ctx, this.state); - this.enterRule(_localctx, 70, esql_parser.RULE_booleanValue); + this.enterRule(_localctx, 76, esql_parser.RULE_booleanValue); let _la: number; try { this.enterOuterAlt(_localctx, 1); { - this.state = 433; + this.state = 461; _la = this._input.LA(1); if (!(_la === esql_parser.FALSE || _la === esql_parser.TRUE)) { this._errHandler.recoverInline(this); @@ -2267,15 +2435,15 @@ export class esql_parser extends Parser { // @RuleVersion(0) public numericValue(): NumericValueContext { let _localctx: NumericValueContext = new NumericValueContext(this._ctx, this.state); - this.enterRule(_localctx, 72, esql_parser.RULE_numericValue); + this.enterRule(_localctx, 78, esql_parser.RULE_numericValue); try { - this.state = 437; + this.state = 465; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 42, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 44, this._ctx) ) { case 1: this.enterOuterAlt(_localctx, 1); { - this.state = 435; + this.state = 463; this.decimalValue(); } break; @@ -2283,7 +2451,7 @@ export class esql_parser extends Parser { case 2: this.enterOuterAlt(_localctx, 2); { - this.state = 436; + this.state = 464; this.integerValue(); } break; @@ -2306,17 +2474,17 @@ export class esql_parser extends Parser { // @RuleVersion(0) public decimalValue(): DecimalValueContext { let _localctx: DecimalValueContext = new DecimalValueContext(this._ctx, this.state); - this.enterRule(_localctx, 74, esql_parser.RULE_decimalValue); + this.enterRule(_localctx, 80, esql_parser.RULE_decimalValue); let _la: number; try { this.enterOuterAlt(_localctx, 1); { - this.state = 440; + this.state = 468; this._errHandler.sync(this); _la = this._input.LA(1); if (_la === esql_parser.PLUS || _la === esql_parser.MINUS) { { - this.state = 439; + this.state = 467; _la = this._input.LA(1); if (!(_la === esql_parser.PLUS || _la === esql_parser.MINUS)) { this._errHandler.recoverInline(this); @@ -2331,7 +2499,7 @@ export class esql_parser extends Parser { } } - this.state = 442; + this.state = 470; this.match(esql_parser.DECIMAL_LITERAL); } } @@ -2352,17 +2520,17 @@ export class esql_parser extends Parser { // @RuleVersion(0) public integerValue(): IntegerValueContext { let _localctx: IntegerValueContext = new IntegerValueContext(this._ctx, this.state); - this.enterRule(_localctx, 76, esql_parser.RULE_integerValue); + this.enterRule(_localctx, 82, esql_parser.RULE_integerValue); let _la: number; try { this.enterOuterAlt(_localctx, 1); { - this.state = 445; + this.state = 473; this._errHandler.sync(this); _la = this._input.LA(1); if (_la === esql_parser.PLUS || _la === esql_parser.MINUS) { { - this.state = 444; + this.state = 472; _la = this._input.LA(1); if (!(_la === esql_parser.PLUS || _la === esql_parser.MINUS)) { this._errHandler.recoverInline(this); @@ -2377,7 +2545,7 @@ export class esql_parser extends Parser { } } - this.state = 447; + this.state = 475; this.match(esql_parser.INTEGER_LITERAL); } } @@ -2398,11 +2566,11 @@ export class esql_parser extends Parser { // @RuleVersion(0) public string(): StringContext { let _localctx: StringContext = new StringContext(this._ctx, this.state); - this.enterRule(_localctx, 78, esql_parser.RULE_string); + this.enterRule(_localctx, 84, esql_parser.RULE_string); try { this.enterOuterAlt(_localctx, 1); { - this.state = 449; + this.state = 477; this.match(esql_parser.STRING); } } @@ -2423,14 +2591,14 @@ export class esql_parser extends Parser { // @RuleVersion(0) public comparisonOperator(): ComparisonOperatorContext { let _localctx: ComparisonOperatorContext = new ComparisonOperatorContext(this._ctx, this.state); - this.enterRule(_localctx, 80, esql_parser.RULE_comparisonOperator); + this.enterRule(_localctx, 86, esql_parser.RULE_comparisonOperator); let _la: number; try { this.enterOuterAlt(_localctx, 1); { - this.state = 451; + this.state = 479; _la = this._input.LA(1); - if (!(((((_la - 50)) & ~0x1F) === 0 && ((1 << (_la - 50)) & ((1 << (esql_parser.EQ - 50)) | (1 << (esql_parser.NEQ - 50)) | (1 << (esql_parser.LT - 50)) | (1 << (esql_parser.LTE - 50)) | (1 << (esql_parser.GT - 50)) | (1 << (esql_parser.GTE - 50)))) !== 0))) { + if (!(((((_la - 52)) & ~0x1F) === 0 && ((1 << (_la - 52)) & ((1 << (esql_parser.EQ - 52)) | (1 << (esql_parser.NEQ - 52)) | (1 << (esql_parser.LT - 52)) | (1 << (esql_parser.LTE - 52)) | (1 << (esql_parser.GT - 52)) | (1 << (esql_parser.GTE - 52)))) !== 0))) { this._errHandler.recoverInline(this); } else { if (this._input.LA(1) === Token.EOF) { @@ -2457,20 +2625,76 @@ export class esql_parser extends Parser { return _localctx; } // @RuleVersion(0) + public explainCommand(): ExplainCommandContext { + let _localctx: ExplainCommandContext = new ExplainCommandContext(this._ctx, this.state); + this.enterRule(_localctx, 88, esql_parser.RULE_explainCommand); + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 481; + this.match(esql_parser.EXPLAIN); + this.state = 482; + this.subqueryExpression(); + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) + public subqueryExpression(): SubqueryExpressionContext { + let _localctx: SubqueryExpressionContext = new SubqueryExpressionContext(this._ctx, this.state); + this.enterRule(_localctx, 90, esql_parser.RULE_subqueryExpression); + try { + this.enterOuterAlt(_localctx, 1); + { + this.state = 484; + this.match(esql_parser.OPENING_BRACKET); + this.state = 485; + this.query(0); + this.state = 486; + this.match(esql_parser.CLOSING_BRACKET); + } + } + catch (re) { + if (re instanceof RecognitionException) { + _localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return _localctx; + } + // @RuleVersion(0) public showCommand(): ShowCommandContext { let _localctx: ShowCommandContext = new ShowCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 82, esql_parser.RULE_showCommand); + this.enterRule(_localctx, 92, esql_parser.RULE_showCommand); try { - this.state = 457; + this.state = 492; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 45, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 47, this._ctx) ) { case 1: _localctx = new ShowInfoContext(_localctx); this.enterOuterAlt(_localctx, 1); { - this.state = 453; + this.state = 488; this.match(esql_parser.SHOW); - this.state = 454; + this.state = 489; this.match(esql_parser.INFO); } break; @@ -2479,9 +2703,9 @@ export class esql_parser extends Parser { _localctx = new ShowFunctionsContext(_localctx); this.enterOuterAlt(_localctx, 2); { - this.state = 455; + this.state = 490; this.match(esql_parser.SHOW); - this.state = 456; + this.state = 491; this.match(esql_parser.FUNCTIONS); } break; @@ -2504,53 +2728,53 @@ export class esql_parser extends Parser { // @RuleVersion(0) public enrichCommand(): EnrichCommandContext { let _localctx: EnrichCommandContext = new EnrichCommandContext(this._ctx, this.state); - this.enterRule(_localctx, 84, esql_parser.RULE_enrichCommand); + this.enterRule(_localctx, 94, esql_parser.RULE_enrichCommand); try { let _alt: number; this.enterOuterAlt(_localctx, 1); { - this.state = 459; + this.state = 494; this.match(esql_parser.ENRICH); - this.state = 460; - _localctx._policyName = this.sourceIdentifier(); - this.state = 463; + this.state = 495; + _localctx._policyName = this.fromIdentifier(); + this.state = 498; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 46, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 48, this._ctx) ) { case 1: { - this.state = 461; + this.state = 496; this.match(esql_parser.ON); - this.state = 462; - _localctx._matchField = this.sourceIdentifier(); + this.state = 497; + _localctx._matchField = this.qualifiedNamePattern(); } break; } - this.state = 474; + this.state = 509; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 48, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 50, this._ctx) ) { case 1: { - this.state = 465; + this.state = 500; this.match(esql_parser.WITH); - this.state = 466; + this.state = 501; this.enrichWithClause(); - this.state = 471; + this.state = 506; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 47, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 49, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 467; + this.state = 502; this.match(esql_parser.COMMA); - this.state = 468; + this.state = 503; this.enrichWithClause(); } } } - this.state = 473; + this.state = 508; this._errHandler.sync(this); - _alt = this.interpreter.adaptivePredict(this._input, 47, this._ctx); + _alt = this.interpreter.adaptivePredict(this._input, 49, this._ctx); } } break; @@ -2574,24 +2798,24 @@ export class esql_parser extends Parser { // @RuleVersion(0) public enrichWithClause(): EnrichWithClauseContext { let _localctx: EnrichWithClauseContext = new EnrichWithClauseContext(this._ctx, this.state); - this.enterRule(_localctx, 86, esql_parser.RULE_enrichWithClause); + this.enterRule(_localctx, 96, esql_parser.RULE_enrichWithClause); try { this.enterOuterAlt(_localctx, 1); { - this.state = 479; + this.state = 514; this._errHandler.sync(this); - switch ( this.interpreter.adaptivePredict(this._input, 49, this._ctx) ) { + switch ( this.interpreter.adaptivePredict(this._input, 51, this._ctx) ) { case 1: { - this.state = 476; - _localctx._newName = this.sourceIdentifier(); - this.state = 477; + this.state = 511; + _localctx._newName = this.qualifiedNamePattern(); + this.state = 512; this.match(esql_parser.ASSIGN); } break; } - this.state = 481; - _localctx._enrichField = this.sourceIdentifier(); + this.state = 516; + _localctx._enrichField = this.qualifiedNamePattern(); } } catch (re) { @@ -2651,7 +2875,7 @@ export class esql_parser extends Parser { } public static readonly _serializedATN: string = - "\x03\uC91D\uCABA\u058D\uAFBA\u4F53\u0607\uEA8B\uC241\x03N\u01E6\x04\x02" + + "\x03\uC91D\uCABA\u058D\uAFBA\u4F53\u0607\uEA8B\uC241\x03d\u0209\x04\x02" + "\t\x02\x04\x03\t\x03\x04\x04\t\x04\x04\x05\t\x05\x04\x06\t\x06\x04\x07" + "\t\x07\x04\b\t\b\x04\t\t\t\x04\n\t\n\x04\v\t\v\x04\f\t\f\x04\r\t\r\x04" + "\x0E\t\x0E\x04\x0F\t\x0F\x04\x10\t\x10\x04\x11\t\x11\x04\x12\t\x12\x04" + @@ -2659,233 +2883,249 @@ export class esql_parser extends Parser { "\x18\t\x18\x04\x19\t\x19\x04\x1A\t\x1A\x04\x1B\t\x1B\x04\x1C\t\x1C\x04" + "\x1D\t\x1D\x04\x1E\t\x1E\x04\x1F\t\x1F\x04 \t \x04!\t!\x04\"\t\"\x04#" + "\t#\x04$\t$\x04%\t%\x04&\t&\x04\'\t\'\x04(\t(\x04)\t)\x04*\t*\x04+\t+" + - "\x04,\t,\x04-\t-\x03\x02\x03\x02\x03\x02\x03\x03\x03\x03\x03\x03\x03\x03" + - "\x03\x03\x03\x03\x07\x03d\n\x03\f\x03\x0E\x03g\v\x03\x03\x04\x03\x04\x03" + - "\x04\x05\x04l\n\x04\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03" + - "\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x05\x05z\n\x05\x03\x06\x03" + - "\x06\x03\x06\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x05" + - "\x07\x86\n\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x07\x07\x8D\n\x07" + - "\f\x07\x0E\x07\x90\v\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x05\x07" + - "\x97\n\x07\x03\x07\x03\x07\x05\x07\x9B\n\x07\x03\x07\x03\x07\x03\x07\x03" + - "\x07\x03\x07\x03\x07\x07\x07\xA3\n\x07\f\x07\x0E\x07\xA6\v\x07\x03\b\x03" + - "\b\x05\b\xAA\n\b\x03\b\x03\b\x03\b\x03\b\x03\b\x05\b\xB1\n\b\x03\b\x03" + - "\b\x03\b\x05\b\xB6\n\b\x03\t\x03\t\x03\t\x03\t\x03\t\x05\t\xBD\n\t\x03" + - "\n\x03\n\x03\n\x03\n\x05\n\xC3\n\n\x03\n\x03\n\x03\n\x03\n\x03\n\x03\n" + - "\x07\n\xCB\n\n\f\n\x0E\n\xCE\v\n\x03\v\x03\v\x03\v\x03\v\x03\v\x03\v\x03" + - "\v\x05\v\xD7\n\v\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x07\f\xDF\n\f\f\f" + - "\x0E\f\xE2\v\f\x05\f\xE4\n\f\x03\f\x03\f\x03\r\x03\r\x03\r\x03\x0E\x03" + - "\x0E\x03\x0E\x07\x0E\xEE\n\x0E\f\x0E\x0E\x0E\xF1\v\x0E\x03\x0F\x03\x0F" + - "\x03\x0F\x03\x0F\x03\x0F\x05\x0F\xF8\n\x0F\x03\x10\x03\x10\x03\x10\x03" + - "\x10\x07\x10\xFE\n\x10\f\x10\x0E\x10\u0101\v\x10\x03\x10\x05\x10\u0104" + - "\n\x10\x03\x11\x03\x11\x03\x11\x03\x11\x03\x11\x07\x11\u010B\n\x11\f\x11" + - "\x0E\x11\u010E\v\x11\x03\x11\x03\x11\x03\x12\x03\x12\x03\x12\x03\x13\x03" + - "\x13\x05\x13\u0117\n\x13\x03\x13\x03\x13\x05\x13\u011B\n\x13\x03\x14\x03" + - "\x14\x03\x14\x07\x14\u0120\n\x14\f\x14\x0E\x14\u0123\v\x14\x03\x15\x03" + - "\x15\x03\x16\x03\x16\x03\x16\x07\x16\u012A\n\x16\f\x16\x0E\x16\u012D\v" + - "\x16\x03\x17\x03\x17\x03\x18\x03\x18\x03\x18\x03\x18\x03\x18\x03\x18\x03" + - "\x18\x03\x18\x03\x18\x03\x18\x03\x18\x03\x18\x03\x18\x07\x18\u013E\n\x18" + - "\f\x18\x0E\x18\u0141\v\x18\x03\x18\x03\x18\x03\x18\x03\x18\x03\x18\x03" + - "\x18\x07\x18\u0149\n\x18\f\x18\x0E\x18\u014C\v\x18\x03\x18\x03\x18\x03" + - "\x18\x03\x18\x03\x18\x03\x18\x07\x18\u0154\n\x18\f\x18\x0E\x18\u0157\v" + - "\x18\x03\x18\x03\x18\x05\x18\u015B\n\x18\x03\x19\x03\x19\x03\x19\x03\x1A" + - "\x03\x1A\x03\x1A\x03\x1A\x07\x1A\u0164\n\x1A\f\x1A\x0E\x1A\u0167\v\x1A" + - "\x03\x1B\x03\x1B\x05\x1B\u016B\n\x1B\x03\x1B\x03\x1B\x05\x1B\u016F\n\x1B" + - "\x03\x1C\x03\x1C\x03\x1C\x03\x1C\x07\x1C\u0175\n\x1C\f\x1C\x0E\x1C\u0178" + - "\v\x1C\x03\x1C\x03\x1C\x03\x1C\x03\x1C\x07\x1C\u017E\n\x1C\f\x1C\x0E\x1C" + - "\u0181\v\x1C\x05\x1C\u0183\n\x1C\x03\x1D\x03\x1D\x03\x1D\x03\x1D\x07\x1D" + - "\u0189\n\x1D\f\x1D\x0E\x1D\u018C\v\x1D\x03\x1E\x03\x1E\x03\x1E\x03\x1E" + - "\x07\x1E\u0192\n\x1E\f\x1E\x0E\x1E\u0195\v\x1E\x03\x1F\x03\x1F\x03\x1F" + - "\x03\x1F\x03 \x03 \x03 \x03 \x05 \u019F\n \x03!\x03!\x03!\x03!\x03\"\x03" + - "\"\x03\"\x03#\x03#\x03#\x07#\u01AB\n#\f#\x0E#\u01AE\v#\x03$\x03$\x03$" + - "\x03$\x03%\x03%\x03&\x03&\x05&\u01B8\n&\x03\'\x05\'\u01BB\n\'\x03\'\x03" + - "\'\x03(\x05(\u01C0\n(\x03(\x03(\x03)\x03)\x03*\x03*\x03+\x03+\x03+\x03" + - "+\x05+\u01CC\n+\x03,\x03,\x03,\x03,\x05,\u01D2\n,\x03,\x03,\x03,\x03," + - "\x07,\u01D8\n,\f,\x0E,\u01DB\v,\x05,\u01DD\n,\x03-\x03-\x03-\x05-\u01E2" + - "\n-\x03-\x03-\x03-\x02\x02\x05\x04\f\x12.\x02\x02\x04\x02\x06\x02\b\x02" + - "\n\x02\f\x02\x0E\x02\x10\x02\x12\x02\x14\x02\x16\x02\x18\x02\x1A\x02\x1C" + - "\x02\x1E\x02 \x02\"\x02$\x02&\x02(\x02*\x02,\x02.\x020\x022\x024\x026" + - "\x028\x02:\x02<\x02>\x02@\x02B\x02D\x02F\x02H\x02J\x02L\x02N\x02P\x02" + - "R\x02T\x02V\x02X\x02\x02\n\x03\x02:;\x03\x02<>\x03\x02JK\x03\x02AB\x04" + - "\x02\x1D\x1D \x03\x02#$\x04\x02\"\"00\x03\x0249\x02\u0204\x02Z\x03\x02" + - "\x02\x02\x04]\x03\x02\x02\x02\x06k\x03\x02\x02\x02\by\x03\x02\x02\x02" + - "\n{\x03\x02\x02\x02\f\x9A\x03\x02\x02\x02\x0E\xB5\x03\x02\x02\x02\x10" + - "\xBC\x03\x02\x02\x02\x12\xC2\x03\x02\x02\x02\x14\xD6\x03\x02\x02\x02\x16" + - "\xD8\x03\x02\x02\x02\x18\xE7\x03\x02\x02\x02\x1A\xEA\x03\x02\x02\x02\x1C" + - "\xF7\x03\x02\x02\x02\x1E\xF9\x03\x02\x02\x02 \u0105\x03\x02\x02\x02\"" + - "\u0111\x03\x02\x02\x02$\u0114\x03\x02\x02\x02&\u011C\x03\x02\x02\x02(" + - "\u0124\x03\x02\x02\x02*\u0126\x03\x02\x02\x02,\u012E\x03\x02\x02\x02." + - "\u015A\x03\x02\x02\x020\u015C\x03\x02\x02\x022\u015F\x03\x02\x02\x024" + - "\u0168\x03\x02\x02\x026\u0182\x03\x02\x02\x028\u0184\x03\x02\x02\x02:" + - "\u018D\x03\x02\x02\x02<\u0196\x03\x02\x02\x02>\u019A\x03\x02\x02\x02@" + - "\u01A0\x03\x02\x02\x02B\u01A4\x03\x02\x02\x02D\u01A7\x03\x02\x02\x02F" + - "\u01AF\x03\x02\x02\x02H\u01B3\x03\x02\x02\x02J\u01B7\x03\x02\x02\x02L" + - "\u01BA\x03\x02\x02\x02N\u01BF\x03\x02\x02\x02P\u01C3\x03\x02\x02\x02R" + - "\u01C5\x03\x02\x02\x02T\u01CB\x03\x02\x02\x02V\u01CD\x03\x02\x02\x02X" + - "\u01E1\x03\x02\x02\x02Z[\x05\x04\x03\x02[\\\x07\x02\x02\x03\\\x03\x03" + - "\x02\x02\x02]^\b\x03\x01\x02^_\x05\x06\x04\x02_e\x03\x02\x02\x02`a\f\x03" + - "\x02\x02ab\x07\x17\x02\x02bd\x05\b\x05\x02c`\x03\x02\x02\x02dg\x03\x02" + - "\x02\x02ec\x03\x02\x02\x02ef\x03\x02\x02\x02f\x05\x03\x02\x02\x02ge\x03" + - "\x02\x02\x02hl\x05\x1E\x10\x02il\x05\x18\r\x02jl\x05T+\x02kh\x03\x02\x02" + - "\x02ki\x03\x02\x02\x02kj\x03\x02\x02\x02l\x07\x03\x02\x02\x02mz\x05\"" + - "\x12\x02nz\x050\x19\x02oz\x056\x1C\x02pz\x052\x1A\x02qz\x05$\x13\x02r" + - "z\x05\n\x06\x02sz\x058\x1D\x02tz\x05:\x1E\x02uz\x05> \x02vz\x05@!\x02" + - "wz\x05V,\x02xz\x05B\"\x02ym\x03\x02\x02\x02yn\x03\x02\x02\x02yo\x03\x02" + - "\x02\x02yp\x03\x02\x02\x02yq\x03\x02\x02\x02yr\x03\x02\x02\x02ys\x03\x02" + - "\x02\x02yt\x03\x02\x02\x02yu\x03\x02\x02\x02yv\x03\x02\x02\x02yw\x03\x02" + - "\x02\x02yx\x03\x02\x02\x02z\t\x03\x02\x02\x02{|\x07\x12\x02\x02|}\x05" + - "\f\x07\x02}\v\x03\x02\x02\x02~\x7F\b\x07\x01\x02\x7F\x80\x07)\x02\x02" + - "\x80\x9B\x05\f\x07\t\x81\x9B\x05\x10\t\x02\x82\x9B\x05\x0E\b\x02\x83\x85" + - "\x05\x10\t\x02\x84\x86\x07)\x02\x02\x85\x84\x03\x02\x02\x02\x85\x86\x03" + - "\x02\x02\x02\x86\x87\x03\x02\x02\x02\x87\x88\x07&\x02\x02\x88\x89\x07" + - "%\x02\x02\x89\x8E\x05\x10\t\x02\x8A\x8B\x07\x1F\x02\x02\x8B\x8D\x05\x10" + - "\t\x02\x8C\x8A\x03\x02\x02\x02\x8D\x90\x03\x02\x02\x02\x8E\x8C\x03\x02" + - "\x02\x02\x8E\x8F\x03\x02\x02\x02\x8F\x91\x03\x02\x02\x02\x90\x8E\x03\x02" + - "\x02\x02\x91\x92\x07/\x02\x02\x92\x9B\x03\x02\x02\x02\x93\x94\x05\x10" + - "\t\x02\x94\x96\x07\'\x02\x02\x95\x97\x07)\x02\x02\x96\x95\x03\x02\x02" + - "\x02\x96\x97\x03\x02\x02\x02\x97\x98\x03\x02\x02\x02\x98\x99\x07*\x02" + - "\x02\x99\x9B\x03\x02\x02\x02\x9A~\x03\x02\x02\x02\x9A\x81\x03\x02\x02" + - "\x02\x9A\x82\x03\x02\x02\x02\x9A\x83\x03\x02\x02\x02\x9A\x93\x03\x02\x02" + - "\x02\x9B\xA4\x03\x02\x02\x02\x9C\x9D\f\x06\x02\x02\x9D\x9E\x07\x1C\x02" + - "\x02\x9E\xA3\x05\f\x07\x07\x9F\xA0\f\x05\x02\x02\xA0\xA1\x07,\x02\x02" + - "\xA1\xA3\x05\f\x07\x06\xA2\x9C\x03\x02\x02\x02\xA2\x9F\x03\x02\x02\x02" + - "\xA3\xA6\x03\x02\x02\x02\xA4\xA2\x03\x02\x02\x02\xA4\xA5\x03\x02\x02\x02" + - "\xA5\r\x03\x02\x02\x02\xA6\xA4\x03\x02\x02\x02\xA7\xA9\x05\x10\t\x02\xA8" + - "\xAA\x07)\x02\x02\xA9\xA8\x03\x02\x02\x02\xA9\xAA\x03\x02\x02\x02\xAA" + - "\xAB\x03\x02\x02\x02\xAB\xAC\x07(\x02\x02\xAC\xAD\x05P)\x02\xAD\xB6\x03" + - "\x02\x02\x02\xAE\xB0\x05\x10\t\x02\xAF\xB1\x07)\x02\x02\xB0\xAF\x03\x02" + - "\x02\x02\xB0\xB1\x03\x02\x02\x02\xB1\xB2\x03\x02\x02\x02\xB2\xB3\x07." + - "\x02\x02\xB3\xB4\x05P)\x02\xB4\xB6\x03\x02\x02\x02\xB5\xA7\x03\x02\x02" + - "\x02\xB5\xAE\x03\x02\x02\x02\xB6\x0F\x03\x02\x02\x02\xB7\xBD\x05\x12\n" + - "\x02\xB8\xB9\x05\x12\n\x02\xB9\xBA\x05R*\x02\xBA\xBB\x05\x12\n\x02\xBB" + - "\xBD\x03\x02\x02\x02\xBC\xB7\x03\x02\x02\x02\xBC\xB8\x03\x02\x02\x02\xBD" + - "\x11\x03\x02\x02\x02\xBE\xBF\b\n\x01\x02\xBF\xC3\x05\x14\v\x02\xC0\xC1" + - "\t\x02\x02\x02\xC1\xC3\x05\x12\n\x05\xC2\xBE\x03\x02\x02\x02\xC2\xC0\x03" + - "\x02\x02\x02\xC3\xCC\x03\x02\x02\x02\xC4\xC5\f\x04\x02\x02\xC5\xC6\t\x03" + - "\x02\x02\xC6\xCB\x05\x12\n\x05\xC7\xC8\f\x03\x02\x02\xC8\xC9\t\x02\x02" + - "\x02\xC9\xCB\x05\x12\n\x04\xCA\xC4\x03\x02\x02\x02\xCA\xC7\x03\x02\x02" + - "\x02\xCB\xCE\x03\x02\x02\x02\xCC\xCA\x03\x02\x02\x02\xCC\xCD\x03\x02\x02" + - "\x02\xCD\x13\x03\x02\x02\x02\xCE\xCC\x03\x02\x02\x02\xCF\xD7\x05.\x18" + - "\x02\xD0\xD7\x05*\x16\x02\xD1\xD7\x05\x16\f\x02\xD2\xD3\x07%\x02\x02\xD3" + - "\xD4\x05\f\x07\x02\xD4\xD5\x07/\x02\x02\xD5\xD7\x03\x02\x02\x02\xD6\xCF" + - "\x03\x02\x02\x02\xD6\xD0\x03\x02\x02\x02\xD6\xD1\x03\x02\x02\x02\xD6\xD2" + - "\x03\x02\x02\x02\xD7\x15\x03\x02\x02\x02\xD8\xD9\x05,\x17\x02\xD9\xE3" + - "\x07%\x02\x02\xDA\xE4\x07<\x02\x02\xDB\xE0\x05\f\x07\x02\xDC\xDD\x07\x1F" + - "\x02\x02\xDD\xDF\x05\f\x07\x02\xDE\xDC\x03\x02\x02\x02\xDF\xE2\x03\x02" + - "\x02\x02\xE0\xDE\x03\x02\x02\x02\xE0\xE1\x03\x02\x02\x02\xE1\xE4\x03\x02" + - "\x02\x02\xE2\xE0\x03\x02\x02\x02\xE3\xDA\x03\x02\x02\x02\xE3\xDB\x03\x02" + - "\x02\x02\xE3\xE4\x03\x02\x02\x02\xE4\xE5\x03\x02\x02\x02\xE5\xE6\x07/" + - "\x02\x02\xE6\x17\x03\x02\x02\x02\xE7\xE8\x07\x0E\x02\x02\xE8\xE9\x05\x1A" + - "\x0E\x02\xE9\x19\x03\x02\x02\x02\xEA\xEF\x05\x1C\x0F\x02\xEB\xEC\x07\x1F" + - "\x02\x02\xEC\xEE\x05\x1C\x0F\x02\xED\xEB\x03\x02\x02\x02\xEE\xF1\x03\x02" + - "\x02\x02\xEF\xED\x03\x02\x02\x02\xEF\xF0\x03\x02\x02\x02\xF0\x1B\x03\x02" + - "\x02\x02\xF1\xEF\x03\x02\x02\x02\xF2\xF8\x05\f\x07\x02\xF3\xF4\x05*\x16" + - "\x02\xF4\xF5\x07\x1E\x02\x02\xF5\xF6\x05\f\x07\x02\xF6\xF8\x03\x02\x02" + - "\x02\xF7\xF2\x03\x02\x02\x02\xF7\xF3\x03\x02\x02\x02\xF8\x1D\x03\x02\x02" + - "\x02\xF9\xFA\x07\x07\x02\x02\xFA\xFF\x05(\x15\x02\xFB\xFC\x07\x1F\x02" + - "\x02\xFC\xFE\x05(\x15\x02\xFD\xFB\x03\x02\x02\x02\xFE\u0101\x03\x02\x02" + - "\x02\xFF\xFD\x03\x02\x02\x02\xFF\u0100\x03\x02\x02\x02\u0100\u0103\x03" + - "\x02\x02\x02\u0101\xFF\x03\x02\x02\x02\u0102\u0104\x05 \x11\x02\u0103" + - "\u0102\x03\x02\x02\x02\u0103\u0104\x03\x02\x02\x02\u0104\x1F\x03\x02\x02" + - "\x02\u0105\u0106\x07?\x02\x02\u0106\u0107\x07G\x02\x02\u0107\u010C\x05" + - "(\x15\x02\u0108\u0109\x07\x1F\x02\x02\u0109\u010B\x05(\x15\x02\u010A\u0108" + - "\x03\x02\x02\x02\u010B\u010E\x03\x02\x02\x02\u010C\u010A\x03\x02\x02\x02" + - "\u010C\u010D\x03\x02\x02\x02\u010D\u010F\x03\x02\x02\x02\u010E\u010C\x03" + - "\x02\x02\x02\u010F\u0110\x07@\x02\x02\u0110!\x03\x02\x02\x02\u0111\u0112" + - "\x07\x06\x02\x02\u0112\u0113\x05\x1A\x0E\x02\u0113#\x03\x02\x02\x02\u0114" + - "\u0116\x07\x11\x02\x02\u0115\u0117\x05\x1A\x0E\x02\u0116\u0115\x03\x02" + - "\x02\x02\u0116\u0117\x03\x02\x02\x02\u0117\u011A\x03\x02\x02\x02\u0118" + - "\u0119\x07\x1B\x02\x02\u0119\u011B\x05&\x14\x02\u011A\u0118\x03\x02\x02" + - "\x02\u011A\u011B\x03\x02\x02\x02\u011B%\x03\x02\x02\x02\u011C\u0121\x05" + - "*\x16\x02\u011D\u011E\x07\x1F\x02\x02\u011E\u0120\x05*\x16\x02\u011F\u011D" + - "\x03\x02\x02\x02\u0120\u0123\x03\x02\x02\x02\u0121\u011F\x03\x02\x02\x02" + - "\u0121\u0122\x03\x02\x02\x02\u0122\'\x03\x02\x02\x02\u0123\u0121\x03\x02" + - "\x02\x02\u0124\u0125\t\x04\x02\x02\u0125)\x03\x02\x02\x02\u0126\u012B" + - "\x05,\x17\x02\u0127\u0128\x07!\x02\x02\u0128\u012A\x05,\x17\x02\u0129" + - "\u0127\x03\x02\x02\x02\u012A\u012D\x03\x02\x02\x02\u012B\u0129\x03\x02" + - "\x02\x02\u012B\u012C\x03\x02\x02\x02\u012C+\x03\x02\x02\x02\u012D\u012B" + - "\x03\x02\x02\x02\u012E\u012F\t\x05\x02\x02\u012F-\x03\x02\x02\x02\u0130" + - "\u015B\x07*\x02\x02\u0131\u0132\x05N(\x02\u0132\u0133\x07A\x02\x02\u0133" + - "\u015B\x03\x02\x02\x02\u0134\u015B\x05L\'\x02\u0135\u015B\x05N(\x02\u0136" + - "\u015B\x05H%\x02\u0137\u015B\x07-\x02\x02\u0138\u015B\x05P)\x02\u0139" + - "\u013A\x07?\x02\x02\u013A\u013F\x05J&\x02\u013B\u013C\x07\x1F\x02\x02" + - "\u013C\u013E\x05J&\x02\u013D\u013B\x03\x02\x02\x02\u013E\u0141\x03\x02" + - "\x02\x02\u013F\u013D\x03\x02\x02\x02\u013F\u0140\x03\x02\x02\x02\u0140" + - "\u0142\x03\x02\x02\x02\u0141\u013F\x03\x02\x02\x02\u0142\u0143\x07@\x02" + - "\x02\u0143\u015B\x03\x02\x02\x02\u0144\u0145\x07?\x02\x02\u0145\u014A" + - "\x05H%\x02\u0146\u0147\x07\x1F\x02\x02\u0147\u0149\x05H%\x02\u0148\u0146" + - "\x03\x02\x02\x02\u0149\u014C\x03\x02\x02\x02\u014A\u0148\x03\x02\x02\x02" + - "\u014A\u014B\x03\x02\x02\x02\u014B\u014D\x03\x02\x02\x02\u014C\u014A\x03" + - "\x02\x02\x02\u014D\u014E\x07@\x02\x02\u014E\u015B\x03\x02\x02\x02\u014F" + - "\u0150\x07?\x02\x02\u0150\u0155\x05P)\x02\u0151\u0152\x07\x1F\x02\x02" + - "\u0152\u0154\x05P)\x02\u0153\u0151\x03\x02\x02\x02\u0154\u0157\x03\x02" + - "\x02\x02\u0155\u0153\x03\x02\x02\x02\u0155\u0156\x03\x02\x02\x02\u0156" + - "\u0158\x03\x02\x02\x02\u0157\u0155\x03\x02\x02\x02\u0158\u0159\x07@\x02" + - "\x02\u0159\u015B\x03\x02\x02\x02\u015A\u0130\x03\x02\x02\x02\u015A\u0131" + - "\x03\x02\x02\x02\u015A\u0134\x03\x02\x02\x02\u015A\u0135\x03\x02\x02\x02" + - "\u015A\u0136\x03\x02\x02\x02\u015A\u0137\x03\x02\x02\x02\u015A\u0138\x03" + - "\x02\x02\x02\u015A\u0139\x03\x02\x02\x02\u015A\u0144\x03\x02\x02\x02\u015A" + - "\u014F\x03\x02\x02\x02\u015B/\x03\x02\x02\x02\u015C\u015D\x07\n\x02\x02" + - "\u015D\u015E\x07\x19\x02\x02\u015E1\x03\x02\x02\x02\u015F\u0160\x07\x10" + - "\x02\x02\u0160\u0165\x054\x1B\x02\u0161\u0162\x07\x1F\x02\x02\u0162\u0164" + - "\x054\x1B\x02\u0163\u0161\x03\x02\x02\x02\u0164\u0167\x03\x02\x02\x02" + - "\u0165\u0163\x03\x02\x02\x02\u0165\u0166\x03\x02\x02\x02\u01663\x03\x02" + - "\x02\x02\u0167\u0165\x03\x02\x02\x02\u0168\u016A\x05\f\x07\x02\u0169\u016B" + - "\t\x06\x02\x02\u016A\u0169\x03\x02\x02\x02\u016A\u016B\x03\x02\x02\x02" + - "\u016B\u016E\x03\x02\x02\x02\u016C\u016D\x07+\x02\x02\u016D\u016F\t\x07" + - "\x02\x02\u016E\u016C\x03\x02\x02\x02\u016E\u016F\x03\x02\x02\x02\u016F" + - "5\x03\x02\x02\x02\u0170\u0171\x07\t\x02\x02\u0171\u0176\x05(\x15\x02\u0172" + - "\u0173\x07\x1F\x02\x02\u0173\u0175\x05(\x15\x02\u0174\u0172\x03\x02\x02" + - "\x02\u0175\u0178\x03\x02\x02\x02\u0176\u0174\x03\x02\x02\x02\u0176\u0177" + - "\x03\x02\x02\x02\u0177\u0183\x03\x02\x02\x02\u0178\u0176\x03\x02\x02\x02" + - "\u0179\u017A\x07\f\x02\x02\u017A\u017F\x05(\x15\x02\u017B\u017C\x07\x1F" + - "\x02\x02\u017C\u017E\x05(\x15\x02\u017D\u017B\x03\x02\x02\x02\u017E\u0181" + - "\x03\x02\x02\x02\u017F\u017D\x03\x02\x02\x02\u017F\u0180\x03\x02\x02\x02" + - "\u0180\u0183\x03\x02\x02\x02\u0181\u017F\x03\x02\x02\x02\u0182\u0170\x03" + - "\x02\x02\x02\u0182\u0179\x03\x02\x02\x02\u01837\x03\x02\x02\x02\u0184" + - "\u0185\x07\x04\x02\x02\u0185\u018A\x05(\x15\x02\u0186\u0187\x07\x1F\x02" + - "\x02\u0187\u0189\x05(\x15\x02\u0188\u0186\x03\x02\x02\x02\u0189\u018C" + - "\x03\x02\x02\x02\u018A\u0188\x03\x02\x02\x02\u018A\u018B\x03\x02\x02\x02" + - "\u018B9\x03\x02\x02\x02\u018C\u018A\x03\x02\x02\x02\u018D\u018E\x07\r" + - "\x02\x02\u018E\u0193\x05<\x1F\x02\u018F\u0190\x07\x1F\x02\x02\u0190\u0192" + - "\x05<\x1F\x02\u0191\u018F\x03\x02\x02\x02\u0192\u0195\x03\x02\x02\x02" + - "\u0193\u0191\x03\x02\x02\x02\u0193\u0194\x03\x02\x02\x02\u0194;\x03\x02" + - "\x02\x02\u0195\u0193\x03\x02\x02\x02\u0196\u0197\x05(\x15\x02\u0197\u0198" + - "\x07F\x02\x02\u0198\u0199\x05(\x15\x02\u0199=\x03\x02\x02\x02\u019A\u019B" + - "\x07\x03\x02\x02\u019B\u019C\x05\x14\v\x02\u019C\u019E\x05P)\x02\u019D" + - "\u019F\x05D#\x02\u019E\u019D\x03\x02\x02\x02\u019E\u019F\x03\x02\x02\x02" + - "\u019F?\x03\x02\x02\x02\u01A0\u01A1\x07\b\x02\x02\u01A1\u01A2\x05\x14" + - "\v\x02\u01A2\u01A3\x05P)\x02\u01A3A\x03\x02\x02\x02\u01A4\u01A5\x07\v" + - "\x02\x02\u01A5\u01A6\x05(\x15\x02\u01A6C\x03\x02\x02\x02\u01A7\u01AC\x05" + - "F$\x02\u01A8\u01A9\x07\x1F\x02\x02\u01A9\u01AB\x05F$\x02\u01AA\u01A8\x03" + - "\x02\x02\x02\u01AB\u01AE\x03\x02\x02\x02\u01AC\u01AA\x03\x02\x02\x02\u01AC" + - "\u01AD\x03\x02\x02\x02\u01ADE\x03\x02\x02\x02\u01AE\u01AC\x03\x02\x02" + - "\x02\u01AF\u01B0\x05,\x17\x02\u01B0\u01B1\x07\x1E\x02\x02\u01B1\u01B2" + - "\x05.\x18\x02\u01B2G\x03\x02\x02\x02\u01B3\u01B4\t\b\x02\x02\u01B4I\x03" + - "\x02\x02\x02\u01B5\u01B8\x05L\'\x02\u01B6\u01B8\x05N(\x02\u01B7\u01B5" + - "\x03\x02\x02\x02\u01B7\u01B6\x03\x02\x02\x02\u01B8K\x03\x02\x02\x02\u01B9" + - "\u01BB\t\x02\x02\x02\u01BA\u01B9\x03\x02\x02\x02\u01BA\u01BB\x03\x02\x02" + - "\x02\u01BB\u01BC\x03\x02\x02\x02\u01BC\u01BD\x07\x1A\x02\x02\u01BDM\x03" + - "\x02\x02\x02\u01BE\u01C0\t\x02\x02\x02\u01BF\u01BE\x03\x02\x02\x02\u01BF" + - "\u01C0\x03\x02\x02\x02\u01C0\u01C1\x03\x02\x02\x02\u01C1\u01C2\x07\x19" + - "\x02\x02\u01C2O\x03\x02\x02\x02\u01C3\u01C4\x07\x18\x02\x02\u01C4Q\x03" + - "\x02\x02\x02\u01C5\u01C6\t\t\x02\x02\u01C6S\x03\x02\x02\x02\u01C7\u01C8" + - "\x07\x0F\x02\x02\u01C8\u01CC\x071\x02\x02\u01C9\u01CA\x07\x0F\x02\x02" + - "\u01CA\u01CC\x072\x02\x02\u01CB\u01C7\x03\x02\x02\x02\u01CB\u01C9\x03" + - "\x02\x02\x02\u01CCU\x03\x02\x02\x02\u01CD\u01CE\x07\x05\x02\x02\u01CE" + - "\u01D1\x05(\x15\x02\u01CF\u01D0\x07H\x02\x02\u01D0\u01D2\x05(\x15\x02" + - "\u01D1\u01CF\x03\x02\x02\x02\u01D1\u01D2\x03\x02\x02\x02\u01D2\u01DC\x03" + - "\x02\x02\x02\u01D3\u01D4\x07I\x02\x02\u01D4\u01D9\x05X-\x02\u01D5\u01D6" + - "\x07\x1F\x02\x02\u01D6\u01D8\x05X-\x02\u01D7\u01D5\x03\x02\x02\x02\u01D8" + - "\u01DB\x03\x02\x02\x02\u01D9\u01D7\x03\x02\x02\x02\u01D9\u01DA\x03\x02" + - "\x02\x02\u01DA\u01DD\x03\x02\x02\x02\u01DB\u01D9\x03\x02\x02\x02\u01DC" + - "\u01D3\x03\x02\x02\x02\u01DC\u01DD\x03\x02\x02\x02\u01DDW\x03\x02\x02" + - "\x02\u01DE\u01DF\x05(\x15\x02\u01DF\u01E0\x07\x1E\x02\x02\u01E0\u01E2" + - "\x03\x02\x02\x02\u01E1\u01DE\x03\x02\x02\x02\u01E1\u01E2\x03\x02\x02\x02" + - "\u01E2\u01E3\x03\x02\x02\x02\u01E3\u01E4\x05(\x15\x02\u01E4Y\x03\x02\x02" + - "\x024eky\x85\x8E\x96\x9A\xA2\xA4\xA9\xB0\xB5\xBC\xC2\xCA\xCC\xD6\xE0\xE3" + - "\xEF\xF7\xFF\u0103\u010C\u0116\u011A\u0121\u012B\u013F\u014A\u0155\u015A" + - "\u0165\u016A\u016E\u0176\u017F\u0182\u018A\u0193\u019E\u01AC\u01B7\u01BA" + - "\u01BF\u01CB\u01D1\u01D9\u01DC\u01E1"; + "\x04,\t,\x04-\t-\x04.\t.\x04/\t/\x040\t0\x041\t1\x042\t2\x03\x02\x03\x02" + + "\x03\x02\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x07\x03n\n\x03" + + "\f\x03\x0E\x03q\v\x03\x03\x04\x03\x04\x03\x04\x03\x04\x05\x04w\n\x04\x03" + + "\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03" + + "\x05\x03\x05\x03\x05\x03\x05\x05\x05\x86\n\x05\x03\x06\x03\x06\x03\x06" + + "\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x05\x07\x92\n" + + "\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x07\x07\x99\n\x07\f\x07\x0E" + + "\x07\x9C\v\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03\x07\x05\x07\xA3\n\x07" + + "\x03\x07\x03\x07\x05\x07\xA7\n\x07\x03\x07\x03\x07\x03\x07\x03\x07\x03" + + "\x07\x03\x07\x07\x07\xAF\n\x07\f\x07\x0E\x07\xB2\v\x07\x03\b\x03\b\x05" + + "\b\xB6\n\b\x03\b\x03\b\x03\b\x03\b\x03\b\x05\b\xBD\n\b\x03\b\x03\b\x03" + + "\b\x05\b\xC2\n\b\x03\t\x03\t\x03\t\x03\t\x03\t\x05\t\xC9\n\t\x03\n\x03" + + "\n\x03\n\x03\n\x05\n\xCF\n\n\x03\n\x03\n\x03\n\x03\n\x03\n\x03\n\x07\n" + + "\xD7\n\n\f\n\x0E\n\xDA\v\n\x03\v\x03\v\x03\v\x03\v\x03\v\x03\v\x03\v\x05" + + "\v\xE3\n\v\x03\f\x03\f\x03\f\x03\f\x03\f\x03\f\x07\f\xEB\n\f\f\f\x0E\f" + + "\xEE\v\f\x05\f\xF0\n\f\x03\f\x03\f\x03\r\x03\r\x03\r\x03\x0E\x03\x0E\x03" + + "\x0E\x07\x0E\xFA\n\x0E\f\x0E\x0E\x0E\xFD\v\x0E\x03\x0F\x03\x0F\x03\x0F" + + "\x03\x0F\x03\x0F\x05\x0F\u0104\n\x0F\x03\x10\x03\x10\x03\x10\x03\x10\x07" + + "\x10\u010A\n\x10\f\x10\x0E\x10\u010D\v\x10\x03\x10\x05\x10\u0110\n\x10" + + "\x03\x11\x03\x11\x03\x11\x03\x11\x03\x11\x07\x11\u0117\n\x11\f\x11\x0E" + + "\x11\u011A\v\x11\x03\x11\x03\x11\x03\x12\x03\x12\x03\x12\x03\x13\x03\x13" + + "\x05\x13\u0123\n\x13\x03\x13\x03\x13\x05\x13\u0127\n\x13\x03\x14\x03\x14" + + "\x03\x14\x03\x14\x05\x14\u012D\n\x14\x03\x15\x03\x15\x03\x15\x07\x15\u0132" + + "\n\x15\f\x15\x0E\x15\u0135\v\x15\x03\x16\x03\x16\x03\x17\x03\x17\x03\x17" + + "\x07\x17\u013C\n\x17\f\x17\x0E\x17\u013F\v\x17\x03\x18\x03\x18\x03\x18" + + "\x07\x18\u0144\n\x18\f\x18\x0E\x18\u0147\v\x18\x03\x19\x03\x19\x03\x1A" + + "\x03\x1A\x03\x1B\x03\x1B\x03\x1B\x03\x1B\x03\x1B\x03\x1B\x03\x1B\x03\x1B" + + "\x03\x1B\x03\x1B\x03\x1B\x03\x1B\x03\x1B\x07\x1B\u015A\n\x1B\f\x1B\x0E" + + "\x1B\u015D\v\x1B\x03\x1B\x03\x1B\x03\x1B\x03\x1B\x03\x1B\x03\x1B\x07\x1B" + + "\u0165\n\x1B\f\x1B\x0E\x1B\u0168\v\x1B\x03\x1B\x03\x1B\x03\x1B\x03\x1B" + + "\x03\x1B\x03\x1B\x07\x1B\u0170\n\x1B\f\x1B\x0E\x1B\u0173\v\x1B\x03\x1B" + + "\x03\x1B\x05\x1B\u0177\n\x1B\x03\x1C\x03\x1C\x03\x1C\x03\x1D\x03\x1D\x03" + + "\x1D\x03\x1D\x07\x1D\u0180\n\x1D\f\x1D\x0E\x1D\u0183\v\x1D\x03\x1E\x03" + + "\x1E\x05\x1E\u0187\n\x1E\x03\x1E\x03\x1E\x05\x1E\u018B\n\x1E\x03\x1F\x03" + + "\x1F\x03\x1F\x03\x1F\x07\x1F\u0191\n\x1F\f\x1F\x0E\x1F\u0194\v\x1F\x03" + + "\x1F\x03\x1F\x03\x1F\x03\x1F\x07\x1F\u019A\n\x1F\f\x1F\x0E\x1F\u019D\v" + + "\x1F\x05\x1F\u019F\n\x1F\x03 \x03 \x03 \x03 \x07 \u01A5\n \f \x0E \u01A8" + + "\v \x03!\x03!\x03!\x03!\x07!\u01AE\n!\f!\x0E!\u01B1\v!\x03\"\x03\"\x03" + + "\"\x03\"\x03#\x03#\x03#\x03#\x05#\u01BB\n#\x03$\x03$\x03$\x03$\x03%\x03" + + "%\x03%\x03&\x03&\x03&\x07&\u01C7\n&\f&\x0E&\u01CA\v&\x03\'\x03\'\x03\'" + + "\x03\'\x03(\x03(\x03)\x03)\x05)\u01D4\n)\x03*\x05*\u01D7\n*\x03*\x03*" + + "\x03+\x05+\u01DC\n+\x03+\x03+\x03,\x03,\x03-\x03-\x03.\x03.\x03.\x03/" + + "\x03/\x03/\x03/\x030\x030\x030\x030\x050\u01EF\n0\x031\x031\x031\x031" + + "\x051\u01F5\n1\x031\x031\x031\x031\x071\u01FB\n1\f1\x0E1\u01FE\v1\x05" + + "1\u0200\n1\x032\x032\x032\x052\u0205\n2\x032\x032\x032\x02\x02\x05\x04" + + "\f\x123\x02\x02\x04\x02\x06\x02\b\x02\n\x02\f\x02\x0E\x02\x10\x02\x12" + + "\x02\x14\x02\x16\x02\x18\x02\x1A\x02\x1C\x02\x1E\x02 \x02\"\x02$\x02&" + + "\x02(\x02*\x02,\x02.\x020\x022\x024\x026\x028\x02:\x02<\x02>\x02@\x02" + + "B\x02D\x02F\x02H\x02J\x02L\x02N\x02P\x02R\x02T\x02V\x02X\x02Z\x02\\\x02" + + "^\x02`\x02b\x02\x02\v\x03\x02<=\x03\x02>@\x04\x02DDII\x03\x02CD\x04\x02" + + "DDMM\x04\x02\"\"%%\x03\x02()\x04\x02\'\'55\x03\x026;\x02\u0226\x02d\x03" + + "\x02\x02\x02\x04g\x03\x02\x02\x02\x06v\x03\x02\x02\x02\b\x85\x03\x02\x02" + + "\x02\n\x87\x03\x02\x02\x02\f\xA6\x03\x02\x02\x02\x0E\xC1\x03\x02\x02\x02" + + "\x10\xC8\x03\x02\x02\x02\x12\xCE\x03\x02\x02\x02\x14\xE2\x03\x02\x02\x02" + + "\x16\xE4\x03\x02\x02\x02\x18\xF3\x03\x02\x02\x02\x1A\xF6\x03\x02\x02\x02" + + "\x1C\u0103\x03\x02\x02\x02\x1E\u0105\x03\x02\x02\x02 \u0111\x03\x02\x02" + + "\x02\"\u011D\x03\x02\x02\x02$\u0120\x03\x02\x02\x02&\u0128\x03\x02\x02" + + "\x02(\u012E\x03\x02\x02\x02*\u0136\x03\x02\x02\x02,\u0138\x03\x02\x02" + + "\x02.\u0140\x03\x02\x02\x020\u0148\x03\x02\x02\x022\u014A\x03\x02\x02" + + "\x024\u0176\x03\x02\x02\x026\u0178\x03\x02\x02\x028\u017B\x03\x02\x02" + + "\x02:\u0184\x03\x02\x02\x02<\u019E\x03\x02\x02\x02>\u01A0\x03\x02\x02" + + "\x02@\u01A9\x03\x02\x02\x02B\u01B2\x03\x02\x02\x02D\u01B6\x03\x02\x02" + + "\x02F\u01BC\x03\x02\x02\x02H\u01C0\x03\x02\x02\x02J\u01C3\x03\x02\x02" + + "\x02L\u01CB\x03\x02\x02\x02N\u01CF\x03\x02\x02\x02P\u01D3\x03\x02\x02" + + "\x02R\u01D6\x03\x02\x02\x02T\u01DB\x03\x02\x02\x02V\u01DF\x03\x02\x02" + + "\x02X\u01E1\x03\x02\x02\x02Z\u01E3\x03\x02\x02\x02\\\u01E6\x03\x02\x02" + + "\x02^\u01EE\x03\x02\x02\x02`\u01F0\x03\x02\x02\x02b\u0204\x03\x02\x02" + + "\x02de\x05\x04\x03\x02ef\x07\x02\x02\x03f\x03\x03\x02\x02\x02gh\b\x03" + + "\x01\x02hi\x05\x06\x04\x02io\x03\x02\x02\x02jk\f\x03\x02\x02kl\x07\x1C" + + "\x02\x02ln\x05\b\x05\x02mj\x03\x02\x02\x02nq\x03\x02\x02\x02om\x03\x02" + + "\x02\x02op\x03\x02\x02\x02p\x05\x03\x02\x02\x02qo\x03\x02\x02\x02rw\x05" + + "Z.\x02sw\x05\x1E\x10\x02tw\x05\x18\r\x02uw\x05^0\x02vr\x03\x02\x02\x02" + + "vs\x03\x02\x02\x02vt\x03\x02\x02\x02vu\x03\x02\x02\x02w\x07\x03\x02\x02" + + "\x02x\x86\x05\"\x12\x02y\x86\x05&\x14\x02z\x86\x056\x1C\x02{\x86\x05<" + + "\x1F\x02|\x86\x058\x1D\x02}\x86\x05$\x13\x02~\x86\x05\n\x06\x02\x7F\x86" + + "\x05> \x02\x80\x86\x05@!\x02\x81\x86\x05D#\x02\x82\x86\x05F$\x02\x83\x86" + + "\x05`1\x02\x84\x86\x05H%\x02\x85x\x03\x02\x02\x02\x85y\x03\x02\x02\x02" + + "\x85z\x03\x02\x02\x02\x85{\x03\x02\x02\x02\x85|\x03\x02\x02\x02\x85}\x03" + + "\x02\x02\x02\x85~\x03\x02\x02\x02\x85\x7F\x03\x02\x02\x02\x85\x80\x03" + + "\x02\x02\x02\x85\x81\x03\x02\x02\x02\x85\x82\x03\x02\x02\x02\x85\x83\x03" + + "\x02\x02\x02\x85\x84\x03\x02\x02\x02\x86\t\x03\x02\x02\x02\x87\x88\x07" + + "\x14\x02\x02\x88\x89\x05\f\x07\x02\x89\v\x03\x02\x02\x02\x8A\x8B\b\x07" + + "\x01\x02\x8B\x8C\x07.\x02\x02\x8C\xA7\x05\f\x07\t\x8D\xA7\x05\x10\t\x02" + + "\x8E\xA7\x05\x0E\b\x02\x8F\x91\x05\x10\t\x02\x90\x92\x07.\x02\x02\x91" + + "\x90\x03\x02\x02\x02\x91\x92\x03\x02\x02\x02\x92\x93\x03\x02\x02\x02\x93" + + "\x94\x07+\x02\x02\x94\x95\x07*\x02\x02\x95\x9A\x05\x10\t\x02\x96\x97\x07" + + "$\x02\x02\x97\x99\x05\x10\t\x02\x98\x96\x03\x02\x02\x02\x99\x9C\x03\x02" + + "\x02\x02\x9A\x98\x03\x02\x02\x02\x9A\x9B\x03\x02\x02\x02\x9B\x9D\x03\x02" + + "\x02\x02\x9C\x9A\x03\x02\x02\x02\x9D\x9E\x074\x02\x02\x9E\xA7\x03\x02" + + "\x02\x02\x9F\xA0\x05\x10\t\x02\xA0\xA2\x07,\x02\x02\xA1\xA3\x07.\x02\x02" + + "\xA2\xA1\x03\x02\x02\x02\xA2\xA3\x03\x02\x02\x02\xA3\xA4\x03\x02\x02\x02" + + "\xA4\xA5\x07/\x02\x02\xA5\xA7\x03\x02\x02\x02\xA6\x8A\x03\x02\x02\x02" + + "\xA6\x8D\x03\x02\x02\x02\xA6\x8E\x03\x02\x02\x02\xA6\x8F\x03\x02\x02\x02" + + "\xA6\x9F\x03\x02\x02\x02\xA7\xB0\x03\x02\x02\x02\xA8\xA9\f\x06\x02\x02" + + "\xA9\xAA\x07!\x02\x02\xAA\xAF\x05\f\x07\x07\xAB\xAC\f\x05\x02\x02\xAC" + + "\xAD\x071\x02\x02\xAD\xAF\x05\f\x07\x06\xAE\xA8\x03\x02\x02\x02\xAE\xAB" + + "\x03\x02\x02\x02\xAF\xB2\x03\x02\x02\x02\xB0\xAE\x03\x02\x02\x02\xB0\xB1" + + "\x03\x02\x02\x02\xB1\r\x03\x02\x02\x02\xB2\xB0\x03\x02\x02\x02\xB3\xB5" + + "\x05\x10\t\x02\xB4\xB6\x07.\x02\x02\xB5\xB4\x03\x02\x02\x02\xB5\xB6\x03" + + "\x02\x02\x02\xB6\xB7\x03\x02\x02\x02\xB7\xB8\x07-\x02\x02\xB8\xB9\x05" + + "V,\x02\xB9\xC2\x03\x02\x02\x02\xBA\xBC\x05\x10\t\x02\xBB\xBD\x07.\x02" + + "\x02\xBC\xBB\x03\x02\x02\x02\xBC\xBD\x03\x02\x02\x02\xBD\xBE\x03\x02\x02" + + "\x02\xBE\xBF\x073\x02\x02\xBF\xC0\x05V,\x02\xC0\xC2\x03\x02\x02\x02\xC1" + + "\xB3\x03\x02\x02\x02\xC1\xBA\x03\x02\x02\x02\xC2\x0F\x03\x02\x02\x02\xC3" + + "\xC9\x05\x12\n\x02\xC4\xC5\x05\x12\n\x02\xC5\xC6\x05X-\x02\xC6\xC7\x05" + + "\x12\n\x02\xC7\xC9\x03\x02\x02\x02\xC8\xC3\x03\x02\x02\x02\xC8\xC4\x03" + + "\x02\x02\x02\xC9\x11\x03\x02\x02\x02\xCA\xCB\b\n\x01\x02\xCB\xCF\x05\x14" + + "\v\x02\xCC\xCD\t\x02\x02\x02\xCD\xCF\x05\x12\n\x05\xCE\xCA\x03\x02\x02" + + "\x02\xCE\xCC\x03\x02\x02\x02\xCF\xD8\x03\x02\x02\x02\xD0\xD1\f\x04\x02" + + "\x02\xD1\xD2\t\x03\x02\x02\xD2\xD7\x05\x12\n\x05\xD3\xD4\f\x03\x02\x02" + + "\xD4\xD5\t\x02\x02\x02\xD5\xD7\x05\x12\n\x04\xD6\xD0\x03\x02\x02\x02\xD6" + + "\xD3\x03\x02\x02\x02\xD7\xDA\x03\x02\x02\x02\xD8\xD6\x03\x02\x02\x02\xD8" + + "\xD9\x03\x02\x02\x02\xD9\x13\x03\x02\x02\x02\xDA\xD8\x03\x02\x02\x02\xDB" + + "\xE3\x054\x1B\x02\xDC\xE3\x05,\x17\x02\xDD\xE3\x05\x16\f\x02\xDE\xDF\x07" + + "*\x02\x02\xDF\xE0\x05\f\x07\x02\xE0\xE1\x074\x02\x02\xE1\xE3\x03\x02\x02" + + "\x02\xE2\xDB\x03\x02\x02\x02\xE2\xDC\x03\x02\x02\x02\xE2\xDD\x03\x02\x02" + + "\x02\xE2\xDE\x03\x02\x02\x02\xE3\x15\x03\x02\x02\x02\xE4\xE5\x050\x19" + + "\x02\xE5\xEF\x07*\x02\x02\xE6\xF0\x07>\x02\x02\xE7\xEC\x05\f\x07\x02\xE8" + + "\xE9\x07$\x02\x02\xE9\xEB\x05\f\x07\x02\xEA\xE8\x03\x02\x02\x02\xEB\xEE" + + "\x03\x02\x02\x02\xEC\xEA\x03\x02\x02\x02\xEC\xED\x03\x02\x02\x02\xED\xF0" + + "\x03\x02\x02\x02\xEE\xEC\x03\x02\x02\x02\xEF\xE6\x03\x02\x02\x02\xEF\xE7" + + "\x03\x02\x02\x02\xEF\xF0\x03\x02\x02\x02\xF0\xF1\x03\x02\x02\x02\xF1\xF2" + + "\x074\x02\x02\xF2\x17\x03\x02\x02\x02\xF3\xF4\x07\x10\x02\x02\xF4\xF5" + + "\x05\x1A\x0E\x02\xF5\x19\x03\x02\x02\x02\xF6\xFB\x05\x1C\x0F\x02\xF7\xF8" + + "\x07$\x02\x02\xF8\xFA\x05\x1C\x0F\x02\xF9\xF7\x03\x02\x02\x02\xFA\xFD" + + "\x03\x02\x02\x02\xFB\xF9\x03\x02\x02\x02\xFB\xFC\x03\x02\x02\x02\xFC\x1B" + + "\x03\x02\x02\x02\xFD\xFB\x03\x02\x02\x02\xFE\u0104\x05\f\x07\x02\xFF\u0100" + + "\x05,\x17\x02\u0100\u0101\x07#\x02\x02\u0101\u0102\x05\f\x07\x02\u0102" + + "\u0104\x03\x02\x02\x02\u0103\xFE\x03\x02\x02\x02\u0103\xFF\x03\x02\x02" + + "\x02\u0104\x1D\x03\x02\x02\x02\u0105\u0106\x07\b\x02\x02\u0106\u010B\x05" + + "*\x16\x02\u0107\u0108\x07$\x02\x02\u0108\u010A\x05*\x16\x02\u0109\u0107" + + "\x03\x02\x02\x02\u010A\u010D\x03\x02\x02\x02\u010B\u0109\x03\x02\x02\x02" + + "\u010B\u010C\x03\x02\x02\x02\u010C\u010F\x03\x02\x02\x02\u010D\u010B\x03" + + "\x02\x02\x02\u010E\u0110\x05 \x11\x02\u010F\u010E\x03\x02\x02\x02\u010F" + + "\u0110\x03\x02\x02\x02\u0110\x1F\x03\x02\x02\x02\u0111\u0112\x07A\x02" + + "\x02\u0112\u0113\x07H\x02\x02\u0113\u0118\x05*\x16\x02\u0114\u0115\x07" + + "$\x02\x02\u0115\u0117\x05*\x16\x02\u0116\u0114\x03\x02\x02\x02\u0117\u011A" + + "\x03\x02\x02\x02\u0118\u0116\x03\x02\x02\x02\u0118\u0119\x03\x02\x02\x02" + + "\u0119\u011B\x03\x02\x02\x02\u011A\u0118\x03\x02\x02\x02\u011B\u011C\x07" + + "B\x02\x02\u011C!\x03\x02\x02\x02\u011D\u011E\x07\x06\x02\x02\u011E\u011F" + + "\x05\x1A\x0E\x02\u011F#\x03\x02\x02\x02\u0120\u0122\x07\x13\x02\x02\u0121" + + "\u0123\x05\x1A\x0E\x02\u0122\u0121\x03\x02\x02\x02\u0122\u0123\x03\x02" + + "\x02\x02\u0123\u0126\x03\x02\x02\x02\u0124\u0125\x07 \x02\x02\u0125\u0127" + + "\x05(\x15\x02\u0126\u0124\x03\x02\x02\x02\u0126\u0127\x03\x02\x02\x02" + + "\u0127%\x03\x02\x02\x02\u0128\u0129\x07\n\x02\x02\u0129\u012C\x05\x1A" + + "\x0E\x02\u012A\u012B\x07 \x02\x02\u012B\u012D\x05(\x15\x02\u012C\u012A" + + "\x03\x02\x02\x02\u012C\u012D\x03\x02\x02\x02\u012D\'\x03\x02\x02\x02\u012E" + + "\u0133\x05,\x17\x02\u012F\u0130\x07$\x02\x02\u0130\u0132\x05,\x17\x02" + + "\u0131\u012F\x03\x02\x02\x02\u0132\u0135\x03\x02\x02\x02\u0133\u0131\x03" + + "\x02\x02\x02\u0133\u0134\x03\x02\x02\x02\u0134)\x03\x02\x02\x02\u0135" + + "\u0133\x03\x02\x02\x02\u0136\u0137\t\x04\x02\x02\u0137+\x03\x02\x02\x02" + + "\u0138\u013D\x050\x19\x02\u0139\u013A\x07&\x02\x02\u013A\u013C\x050\x19" + + "\x02\u013B\u0139\x03\x02\x02\x02\u013C\u013F\x03\x02\x02\x02\u013D\u013B" + + "\x03\x02\x02\x02\u013D\u013E\x03\x02\x02\x02\u013E-\x03\x02\x02\x02\u013F" + + "\u013D\x03\x02\x02\x02\u0140\u0145\x052\x1A\x02\u0141\u0142\x07&\x02\x02" + + "\u0142\u0144\x052\x1A\x02\u0143\u0141\x03\x02\x02\x02\u0144\u0147\x03" + + "\x02\x02\x02\u0145\u0143\x03\x02\x02\x02\u0145\u0146\x03\x02\x02\x02\u0146" + + "/\x03\x02\x02\x02\u0147\u0145\x03\x02\x02\x02\u0148\u0149\t\x05\x02\x02" + + "\u01491\x03\x02\x02\x02\u014A\u014B\t\x06\x02\x02\u014B3\x03\x02\x02\x02" + + "\u014C\u0177\x07/\x02\x02\u014D\u014E\x05T+\x02\u014E\u014F\x07C\x02\x02" + + "\u014F\u0177\x03\x02\x02\x02\u0150\u0177\x05R*\x02\u0151\u0177\x05T+\x02" + + "\u0152\u0177\x05N(\x02\u0153\u0177\x072\x02\x02\u0154\u0177\x05V,\x02" + + "\u0155\u0156\x07A\x02\x02\u0156\u015B\x05P)\x02\u0157\u0158\x07$\x02\x02" + + "\u0158\u015A\x05P)\x02\u0159\u0157\x03\x02\x02\x02\u015A\u015D\x03\x02" + + "\x02\x02\u015B\u0159\x03\x02\x02\x02\u015B\u015C\x03\x02\x02\x02\u015C" + + "\u015E\x03\x02\x02\x02\u015D\u015B\x03\x02\x02\x02\u015E\u015F\x07B\x02" + + "\x02\u015F\u0177\x03\x02\x02\x02\u0160\u0161\x07A\x02\x02\u0161\u0166" + + "\x05N(\x02\u0162\u0163\x07$\x02\x02\u0163\u0165\x05N(\x02\u0164\u0162" + + "\x03\x02\x02\x02\u0165\u0168\x03\x02\x02\x02\u0166\u0164\x03\x02\x02\x02" + + "\u0166\u0167\x03\x02\x02\x02\u0167\u0169\x03\x02\x02\x02\u0168\u0166\x03" + + "\x02\x02\x02\u0169\u016A\x07B\x02\x02\u016A\u0177\x03\x02\x02\x02\u016B" + + "\u016C\x07A\x02\x02\u016C\u0171\x05V,\x02\u016D\u016E\x07$\x02\x02\u016E" + + "\u0170\x05V,\x02\u016F\u016D\x03\x02\x02\x02\u0170\u0173\x03\x02\x02\x02" + + "\u0171\u016F\x03\x02\x02\x02\u0171\u0172\x03\x02\x02\x02\u0172\u0174\x03" + + "\x02\x02\x02\u0173\u0171\x03\x02\x02\x02\u0174\u0175\x07B\x02\x02\u0175" + + "\u0177\x03\x02\x02\x02\u0176\u014C\x03\x02\x02\x02\u0176\u014D\x03\x02" + + "\x02\x02\u0176\u0150\x03\x02\x02\x02\u0176\u0151\x03\x02\x02\x02\u0176" + + "\u0152\x03\x02\x02\x02\u0176\u0153\x03\x02\x02\x02\u0176\u0154\x03\x02" + + "\x02\x02\u0176\u0155\x03\x02\x02\x02\u0176\u0160\x03\x02\x02\x02\u0176" + + "\u016B\x03\x02\x02\x02\u01775\x03\x02\x02\x02\u0178\u0179\x07\f\x02\x02" + + "\u0179\u017A\x07\x1E\x02\x02\u017A7\x03\x02\x02\x02\u017B\u017C\x07\x12" + + "\x02\x02\u017C\u0181\x05:\x1E\x02\u017D\u017E\x07$\x02\x02\u017E\u0180" + + "\x05:\x1E\x02\u017F\u017D\x03\x02\x02\x02\u0180\u0183\x03\x02\x02\x02" + + "\u0181\u017F\x03\x02\x02\x02\u0181\u0182\x03\x02\x02\x02\u01829\x03\x02" + + "\x02\x02\u0183\u0181\x03\x02\x02\x02\u0184\u0186\x05\f\x07\x02\u0185\u0187" + + "\t\x07\x02\x02\u0186\u0185\x03\x02\x02\x02\u0186\u0187\x03\x02\x02\x02" + + "\u0187\u018A\x03\x02\x02\x02\u0188\u0189\x070\x02\x02\u0189\u018B\t\b" + + "\x02\x02\u018A\u0188\x03\x02\x02\x02\u018A\u018B\x03\x02\x02\x02\u018B" + + ";\x03\x02\x02\x02\u018C\u018D\x07\v\x02\x02\u018D\u0192\x05.\x18\x02\u018E" + + "\u018F\x07$\x02\x02\u018F\u0191\x05.\x18\x02\u0190\u018E\x03\x02\x02\x02" + + "\u0191\u0194\x03\x02\x02\x02\u0192\u0190\x03\x02\x02\x02\u0192\u0193\x03" + + "\x02\x02\x02\u0193\u019F\x03\x02\x02\x02\u0194\u0192\x03\x02\x02\x02\u0195" + + "\u0196\x07\x0E\x02\x02\u0196\u019B\x05.\x18\x02\u0197\u0198\x07$\x02\x02" + + "\u0198\u019A\x05.\x18\x02\u0199\u0197\x03\x02\x02\x02\u019A\u019D\x03" + + "\x02\x02\x02\u019B\u0199\x03\x02\x02\x02\u019B\u019C\x03\x02\x02\x02\u019C" + + "\u019F\x03\x02\x02\x02\u019D\u019B\x03\x02\x02\x02\u019E\u018C\x03\x02" + + "\x02\x02\u019E\u0195\x03\x02\x02\x02\u019F=\x03\x02\x02\x02\u01A0\u01A1" + + "\x07\x04\x02\x02\u01A1\u01A6\x05.\x18\x02\u01A2\u01A3\x07$\x02\x02\u01A3" + + "\u01A5\x05.\x18\x02\u01A4\u01A2\x03\x02\x02\x02\u01A5\u01A8\x03\x02\x02" + + "\x02\u01A6\u01A4\x03\x02\x02\x02\u01A6\u01A7\x03\x02\x02\x02\u01A7?\x03" + + "\x02\x02\x02\u01A8\u01A6\x03\x02\x02\x02\u01A9\u01AA\x07\x0F\x02\x02\u01AA" + + "\u01AF\x05B\"\x02\u01AB\u01AC\x07$\x02\x02\u01AC\u01AE\x05B\"\x02\u01AD" + + "\u01AB\x03\x02\x02\x02\u01AE\u01B1\x03\x02\x02\x02\u01AF\u01AD\x03\x02" + + "\x02\x02\u01AF\u01B0\x03\x02\x02\x02\u01B0A\x03\x02\x02\x02\u01B1\u01AF" + + "\x03\x02\x02\x02\u01B2\u01B3\x05.\x18\x02\u01B3\u01B4\x07Q\x02\x02\u01B4" + + "\u01B5\x05.\x18\x02\u01B5C\x03\x02\x02\x02\u01B6\u01B7\x07\x03\x02\x02" + + "\u01B7\u01B8\x05\x14\v\x02\u01B8\u01BA\x05V,\x02\u01B9\u01BB\x05J&\x02" + + "\u01BA\u01B9\x03\x02\x02\x02\u01BA\u01BB\x03\x02\x02\x02\u01BBE\x03\x02" + + "\x02\x02\u01BC\u01BD\x07\t\x02\x02\u01BD\u01BE\x05\x14\v\x02\u01BE\u01BF" + + "\x05V,\x02\u01BFG\x03\x02\x02\x02\u01C0\u01C1\x07\r\x02\x02\u01C1\u01C2" + + "\x05,\x17\x02\u01C2I\x03\x02\x02\x02\u01C3\u01C8\x05L\'\x02\u01C4\u01C5" + + "\x07$\x02\x02\u01C5\u01C7\x05L\'\x02\u01C6\u01C4\x03\x02\x02\x02\u01C7" + + "\u01CA\x03\x02\x02\x02\u01C8\u01C6\x03\x02\x02\x02\u01C8\u01C9\x03\x02" + + "\x02\x02\u01C9K\x03\x02\x02\x02\u01CA\u01C8\x03\x02\x02\x02\u01CB\u01CC" + + "\x050\x19\x02\u01CC\u01CD\x07#\x02\x02\u01CD\u01CE\x054\x1B\x02\u01CE" + + "M\x03\x02\x02\x02\u01CF\u01D0\t\t\x02\x02\u01D0O\x03\x02\x02\x02\u01D1" + + "\u01D4\x05R*\x02\u01D2\u01D4\x05T+\x02\u01D3\u01D1\x03\x02\x02\x02\u01D3" + + "\u01D2\x03\x02\x02\x02\u01D4Q\x03\x02\x02\x02\u01D5\u01D7\t\x02\x02\x02" + + "\u01D6\u01D5\x03\x02\x02\x02\u01D6\u01D7\x03\x02\x02\x02\u01D7\u01D8\x03" + + "\x02\x02\x02\u01D8\u01D9\x07\x1F\x02\x02\u01D9S\x03\x02\x02\x02\u01DA" + + "\u01DC\t\x02\x02\x02\u01DB\u01DA\x03\x02\x02\x02\u01DB\u01DC\x03\x02\x02" + + "\x02\u01DC\u01DD\x03\x02\x02\x02\u01DD\u01DE\x07\x1E\x02\x02\u01DEU\x03" + + "\x02\x02\x02\u01DF\u01E0\x07\x1D\x02\x02\u01E0W\x03\x02\x02\x02\u01E1" + + "\u01E2\t\n\x02\x02\u01E2Y\x03\x02\x02\x02\u01E3\u01E4\x07\x07\x02\x02" + + "\u01E4\u01E5\x05\\/\x02\u01E5[\x03\x02\x02\x02\u01E6\u01E7\x07A\x02\x02" + + "\u01E7\u01E8\x05\x04\x03\x02\u01E8\u01E9\x07B\x02\x02\u01E9]\x03\x02\x02" + + "\x02\u01EA\u01EB\x07\x11\x02\x02\u01EB\u01EF\x07`\x02\x02\u01EC\u01ED" + + "\x07\x11\x02\x02\u01ED\u01EF\x07a\x02\x02\u01EE\u01EA\x03\x02\x02\x02" + + "\u01EE\u01EC\x03\x02\x02\x02\u01EF_\x03\x02\x02\x02\u01F0\u01F1\x07\x05" + + "\x02\x02\u01F1\u01F4\x05*\x16\x02\u01F2\u01F3\x07U\x02\x02\u01F3\u01F5" + + "\x05.\x18\x02\u01F4\u01F2\x03\x02\x02\x02\u01F4\u01F5\x03\x02\x02\x02" + + "\u01F5\u01FF\x03\x02\x02\x02\u01F6\u01F7\x07V\x02\x02\u01F7\u01FC\x05" + + "b2\x02\u01F8\u01F9\x07$\x02\x02\u01F9\u01FB\x05b2\x02\u01FA\u01F8\x03" + + "\x02\x02\x02\u01FB\u01FE\x03\x02\x02\x02\u01FC\u01FA\x03\x02\x02\x02\u01FC" + + "\u01FD\x03\x02\x02\x02\u01FD\u0200\x03\x02\x02\x02\u01FE\u01FC\x03\x02" + + "\x02\x02\u01FF\u01F6\x03\x02\x02\x02\u01FF\u0200\x03\x02\x02\x02\u0200" + + "a\x03\x02\x02\x02\u0201\u0202\x05.\x18\x02\u0202\u0203\x07#\x02\x02\u0203" + + "\u0205\x03\x02\x02\x02\u0204\u0201\x03\x02\x02\x02\u0204\u0205\x03\x02" + + "\x02\x02\u0205\u0206\x03\x02\x02\x02\u0206\u0207\x05.\x18\x02\u0207c\x03" + + "\x02\x02\x026ov\x85\x91\x9A\xA2\xA6\xAE\xB0\xB5\xBC\xC1\xC8\xCE\xD6\xD8" + + "\xE2\xEC\xEF\xFB\u0103\u010B\u010F\u0118\u0122\u0126\u012C\u0133\u013D" + + "\u0145\u015B\u0166\u0171\u0176\u0181\u0186\u018A\u0192\u019B\u019E\u01A6" + + "\u01AF\u01BA\u01C8\u01D3\u01D6\u01DB\u01EE\u01F4\u01FC\u01FF\u0204"; public static __ATN: ATN; public static get _ATN(): ATN { if (!esql_parser.__ATN) { @@ -2981,6 +3221,9 @@ export class CompositeQueryContext extends QueryContext { export class SourceCommandContext extends ParserRuleContext { + public explainCommand(): ExplainCommandContext | undefined { + return this.tryGetRuleContext(0, ExplainCommandContext); + } public fromCommand(): FromCommandContext | undefined { return this.tryGetRuleContext(0, FromCommandContext); } @@ -3014,6 +3257,9 @@ export class ProcessingCommandContext extends ParserRuleContext { public evalCommand(): EvalCommandContext | undefined { return this.tryGetRuleContext(0, EvalCommandContext); } + public inlinestatsCommand(): InlinestatsCommandContext | undefined { + return this.tryGetRuleContext(0, InlinestatsCommandContext); + } public limitCommand(): LimitCommandContext | undefined { return this.tryGetRuleContext(0, LimitCommandContext); } @@ -3690,13 +3936,13 @@ export class FieldContext extends ParserRuleContext { export class FromCommandContext extends ParserRuleContext { public FROM(): TerminalNode { return this.getToken(esql_parser.FROM, 0); } - public sourceIdentifier(): SourceIdentifierContext[]; - public sourceIdentifier(i: number): SourceIdentifierContext; - public sourceIdentifier(i?: number): SourceIdentifierContext | SourceIdentifierContext[] { + public fromIdentifier(): FromIdentifierContext[]; + public fromIdentifier(i: number): FromIdentifierContext; + public fromIdentifier(i?: number): FromIdentifierContext | FromIdentifierContext[] { if (i === undefined) { - return this.getRuleContexts(SourceIdentifierContext); + return this.getRuleContexts(FromIdentifierContext); } else { - return this.getRuleContext(i, SourceIdentifierContext); + return this.getRuleContext(i, FromIdentifierContext); } } public COMMA(): TerminalNode[]; @@ -3734,13 +3980,13 @@ export class FromCommandContext extends ParserRuleContext { export class MetadataContext extends ParserRuleContext { public OPENING_BRACKET(): TerminalNode { return this.getToken(esql_parser.OPENING_BRACKET, 0); } public METADATA(): TerminalNode { return this.getToken(esql_parser.METADATA, 0); } - public sourceIdentifier(): SourceIdentifierContext[]; - public sourceIdentifier(i: number): SourceIdentifierContext; - public sourceIdentifier(i?: number): SourceIdentifierContext | SourceIdentifierContext[] { + public fromIdentifier(): FromIdentifierContext[]; + public fromIdentifier(i: number): FromIdentifierContext; + public fromIdentifier(i?: number): FromIdentifierContext | FromIdentifierContext[] { if (i === undefined) { - return this.getRuleContexts(SourceIdentifierContext); + return this.getRuleContexts(FromIdentifierContext); } else { - return this.getRuleContext(i, SourceIdentifierContext); + return this.getRuleContext(i, FromIdentifierContext); } } public CLOSING_BRACKET(): TerminalNode { return this.getToken(esql_parser.CLOSING_BRACKET, 0); } @@ -3827,6 +4073,35 @@ export class StatsCommandContext extends ParserRuleContext { } +export class InlinestatsCommandContext extends ParserRuleContext { + public INLINESTATS(): TerminalNode { return this.getToken(esql_parser.INLINESTATS, 0); } + public fields(): FieldsContext { + return this.getRuleContext(0, FieldsContext); + } + public BY(): TerminalNode | undefined { return this.tryGetToken(esql_parser.BY, 0); } + public grouping(): GroupingContext | undefined { + return this.tryGetRuleContext(0, GroupingContext); + } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return esql_parser.RULE_inlinestatsCommand; } + // @Override + public enterRule(listener: esql_parserListener): void { + if (listener.enterInlinestatsCommand) { + listener.enterInlinestatsCommand(this); + } + } + // @Override + public exitRule(listener: esql_parserListener): void { + if (listener.exitInlinestatsCommand) { + listener.exitInlinestatsCommand(this); + } + } +} + + export class GroupingContext extends ParserRuleContext { public qualifiedName(): QualifiedNameContext[]; public qualifiedName(i: number): QualifiedNameContext; @@ -3866,24 +4141,24 @@ export class GroupingContext extends ParserRuleContext { } -export class SourceIdentifierContext extends ParserRuleContext { - public SRC_UNQUOTED_IDENTIFIER(): TerminalNode | undefined { return this.tryGetToken(esql_parser.SRC_UNQUOTED_IDENTIFIER, 0); } - public SRC_QUOTED_IDENTIFIER(): TerminalNode | undefined { return this.tryGetToken(esql_parser.SRC_QUOTED_IDENTIFIER, 0); } +export class FromIdentifierContext extends ParserRuleContext { + public FROM_UNQUOTED_IDENTIFIER(): TerminalNode | undefined { return this.tryGetToken(esql_parser.FROM_UNQUOTED_IDENTIFIER, 0); } + public QUOTED_IDENTIFIER(): TerminalNode | undefined { return this.tryGetToken(esql_parser.QUOTED_IDENTIFIER, 0); } constructor(parent: ParserRuleContext | undefined, invokingState: number) { super(parent, invokingState); } // @Override - public get ruleIndex(): number { return esql_parser.RULE_sourceIdentifier; } + public get ruleIndex(): number { return esql_parser.RULE_fromIdentifier; } // @Override public enterRule(listener: esql_parserListener): void { - if (listener.enterSourceIdentifier) { - listener.enterSourceIdentifier(this); + if (listener.enterFromIdentifier) { + listener.enterFromIdentifier(this); } } // @Override public exitRule(listener: esql_parserListener): void { - if (listener.exitSourceIdentifier) { - listener.exitSourceIdentifier(this); + if (listener.exitFromIdentifier) { + listener.exitFromIdentifier(this); } } } @@ -3928,6 +4203,45 @@ export class QualifiedNameContext extends ParserRuleContext { } +export class QualifiedNamePatternContext extends ParserRuleContext { + public identifierPattern(): IdentifierPatternContext[]; + public identifierPattern(i: number): IdentifierPatternContext; + public identifierPattern(i?: number): IdentifierPatternContext | IdentifierPatternContext[] { + if (i === undefined) { + return this.getRuleContexts(IdentifierPatternContext); + } else { + return this.getRuleContext(i, IdentifierPatternContext); + } + } + public DOT(): TerminalNode[]; + public DOT(i: number): TerminalNode; + public DOT(i?: number): TerminalNode | TerminalNode[] { + if (i === undefined) { + return this.getTokens(esql_parser.DOT); + } else { + return this.getToken(esql_parser.DOT, i); + } + } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return esql_parser.RULE_qualifiedNamePattern; } + // @Override + public enterRule(listener: esql_parserListener): void { + if (listener.enterQualifiedNamePattern) { + listener.enterQualifiedNamePattern(this); + } + } + // @Override + public exitRule(listener: esql_parserListener): void { + if (listener.exitQualifiedNamePattern) { + listener.exitQualifiedNamePattern(this); + } + } +} + + export class IdentifierContext extends ParserRuleContext { public UNQUOTED_IDENTIFIER(): TerminalNode | undefined { return this.tryGetToken(esql_parser.UNQUOTED_IDENTIFIER, 0); } public QUOTED_IDENTIFIER(): TerminalNode | undefined { return this.tryGetToken(esql_parser.QUOTED_IDENTIFIER, 0); } @@ -3951,6 +4265,29 @@ export class IdentifierContext extends ParserRuleContext { } +export class IdentifierPatternContext extends ParserRuleContext { + public PROJECT_UNQUOTED_IDENTIFIER(): TerminalNode | undefined { return this.tryGetToken(esql_parser.PROJECT_UNQUOTED_IDENTIFIER, 0); } + public QUOTED_IDENTIFIER(): TerminalNode | undefined { return this.tryGetToken(esql_parser.QUOTED_IDENTIFIER, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return esql_parser.RULE_identifierPattern; } + // @Override + public enterRule(listener: esql_parserListener): void { + if (listener.enterIdentifierPattern) { + listener.enterIdentifierPattern(this); + } + } + // @Override + public exitRule(listener: esql_parserListener): void { + if (listener.exitIdentifierPattern) { + listener.exitIdentifierPattern(this); + } + } +} + + export class ConstantContext extends ParserRuleContext { constructor(parent: ParserRuleContext | undefined, invokingState: number) { super(parent, invokingState); @@ -4317,13 +4654,13 @@ export class OrderExpressionContext extends ParserRuleContext { export class KeepCommandContext extends ParserRuleContext { public KEEP(): TerminalNode | undefined { return this.tryGetToken(esql_parser.KEEP, 0); } - public sourceIdentifier(): SourceIdentifierContext[]; - public sourceIdentifier(i: number): SourceIdentifierContext; - public sourceIdentifier(i?: number): SourceIdentifierContext | SourceIdentifierContext[] { + public qualifiedNamePattern(): QualifiedNamePatternContext[]; + public qualifiedNamePattern(i: number): QualifiedNamePatternContext; + public qualifiedNamePattern(i?: number): QualifiedNamePatternContext | QualifiedNamePatternContext[] { if (i === undefined) { - return this.getRuleContexts(SourceIdentifierContext); + return this.getRuleContexts(QualifiedNamePatternContext); } else { - return this.getRuleContext(i, SourceIdentifierContext); + return this.getRuleContext(i, QualifiedNamePatternContext); } } public COMMA(): TerminalNode[]; @@ -4358,13 +4695,13 @@ export class KeepCommandContext extends ParserRuleContext { export class DropCommandContext extends ParserRuleContext { public DROP(): TerminalNode { return this.getToken(esql_parser.DROP, 0); } - public sourceIdentifier(): SourceIdentifierContext[]; - public sourceIdentifier(i: number): SourceIdentifierContext; - public sourceIdentifier(i?: number): SourceIdentifierContext | SourceIdentifierContext[] { + public qualifiedNamePattern(): QualifiedNamePatternContext[]; + public qualifiedNamePattern(i: number): QualifiedNamePatternContext; + public qualifiedNamePattern(i?: number): QualifiedNamePatternContext | QualifiedNamePatternContext[] { if (i === undefined) { - return this.getRuleContexts(SourceIdentifierContext); + return this.getRuleContexts(QualifiedNamePatternContext); } else { - return this.getRuleContext(i, SourceIdentifierContext); + return this.getRuleContext(i, QualifiedNamePatternContext); } } public COMMA(): TerminalNode[]; @@ -4437,16 +4774,16 @@ export class RenameCommandContext extends ParserRuleContext { export class RenameClauseContext extends ParserRuleContext { - public _oldName: SourceIdentifierContext; - public _newName: SourceIdentifierContext; + public _oldName: QualifiedNamePatternContext; + public _newName: QualifiedNamePatternContext; public AS(): TerminalNode { return this.getToken(esql_parser.AS, 0); } - public sourceIdentifier(): SourceIdentifierContext[]; - public sourceIdentifier(i: number): SourceIdentifierContext; - public sourceIdentifier(i?: number): SourceIdentifierContext | SourceIdentifierContext[] { + public qualifiedNamePattern(): QualifiedNamePatternContext[]; + public qualifiedNamePattern(i: number): QualifiedNamePatternContext; + public qualifiedNamePattern(i?: number): QualifiedNamePatternContext | QualifiedNamePatternContext[] { if (i === undefined) { - return this.getRuleContexts(SourceIdentifierContext); + return this.getRuleContexts(QualifiedNamePatternContext); } else { - return this.getRuleContext(i, SourceIdentifierContext); + return this.getRuleContext(i, QualifiedNamePatternContext); } } constructor(parent: ParserRuleContext | undefined, invokingState: number) { @@ -4530,8 +4867,8 @@ export class GrokCommandContext extends ParserRuleContext { export class MvExpandCommandContext extends ParserRuleContext { public MV_EXPAND(): TerminalNode { return this.getToken(esql_parser.MV_EXPAND, 0); } - public sourceIdentifier(): SourceIdentifierContext { - return this.getRuleContext(0, SourceIdentifierContext); + public qualifiedName(): QualifiedNameContext { + return this.getRuleContext(0, QualifiedNameContext); } constructor(parent: ParserRuleContext | undefined, invokingState: number) { super(parent, invokingState); @@ -4767,6 +5104,57 @@ export class ComparisonOperatorContext extends ParserRuleContext { } +export class ExplainCommandContext extends ParserRuleContext { + public EXPLAIN(): TerminalNode { return this.getToken(esql_parser.EXPLAIN, 0); } + public subqueryExpression(): SubqueryExpressionContext { + return this.getRuleContext(0, SubqueryExpressionContext); + } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return esql_parser.RULE_explainCommand; } + // @Override + public enterRule(listener: esql_parserListener): void { + if (listener.enterExplainCommand) { + listener.enterExplainCommand(this); + } + } + // @Override + public exitRule(listener: esql_parserListener): void { + if (listener.exitExplainCommand) { + listener.exitExplainCommand(this); + } + } +} + + +export class SubqueryExpressionContext extends ParserRuleContext { + public OPENING_BRACKET(): TerminalNode { return this.getToken(esql_parser.OPENING_BRACKET, 0); } + public query(): QueryContext { + return this.getRuleContext(0, QueryContext); + } + public CLOSING_BRACKET(): TerminalNode { return this.getToken(esql_parser.CLOSING_BRACKET, 0); } + constructor(parent: ParserRuleContext | undefined, invokingState: number) { + super(parent, invokingState); + } + // @Override + public get ruleIndex(): number { return esql_parser.RULE_subqueryExpression; } + // @Override + public enterRule(listener: esql_parserListener): void { + if (listener.enterSubqueryExpression) { + listener.enterSubqueryExpression(this); + } + } + // @Override + public exitRule(listener: esql_parserListener): void { + if (listener.exitSubqueryExpression) { + listener.exitSubqueryExpression(this); + } + } +} + + export class ShowCommandContext extends ParserRuleContext { constructor(parent: ParserRuleContext | undefined, invokingState: number) { super(parent, invokingState); @@ -4820,17 +5208,11 @@ export class ShowFunctionsContext extends ShowCommandContext { export class EnrichCommandContext extends ParserRuleContext { - public _policyName: SourceIdentifierContext; - public _matchField: SourceIdentifierContext; + public _policyName: FromIdentifierContext; + public _matchField: QualifiedNamePatternContext; public ENRICH(): TerminalNode { return this.getToken(esql_parser.ENRICH, 0); } - public sourceIdentifier(): SourceIdentifierContext[]; - public sourceIdentifier(i: number): SourceIdentifierContext; - public sourceIdentifier(i?: number): SourceIdentifierContext | SourceIdentifierContext[] { - if (i === undefined) { - return this.getRuleContexts(SourceIdentifierContext); - } else { - return this.getRuleContext(i, SourceIdentifierContext); - } + public fromIdentifier(): FromIdentifierContext { + return this.getRuleContext(0, FromIdentifierContext); } public ON(): TerminalNode | undefined { return this.tryGetToken(esql_parser.ON, 0); } public WITH(): TerminalNode | undefined { return this.tryGetToken(esql_parser.WITH, 0); } @@ -4843,6 +5225,9 @@ export class EnrichCommandContext extends ParserRuleContext { return this.getRuleContext(i, EnrichWithClauseContext); } } + public qualifiedNamePattern(): QualifiedNamePatternContext | undefined { + return this.tryGetRuleContext(0, QualifiedNamePatternContext); + } public COMMA(): TerminalNode[]; public COMMA(i: number): TerminalNode; public COMMA(i?: number): TerminalNode | TerminalNode[] { @@ -4873,15 +5258,15 @@ export class EnrichCommandContext extends ParserRuleContext { export class EnrichWithClauseContext extends ParserRuleContext { - public _newName: SourceIdentifierContext; - public _enrichField: SourceIdentifierContext; - public sourceIdentifier(): SourceIdentifierContext[]; - public sourceIdentifier(i: number): SourceIdentifierContext; - public sourceIdentifier(i?: number): SourceIdentifierContext | SourceIdentifierContext[] { + public _newName: QualifiedNamePatternContext; + public _enrichField: QualifiedNamePatternContext; + public qualifiedNamePattern(): QualifiedNamePatternContext[]; + public qualifiedNamePattern(i: number): QualifiedNamePatternContext; + public qualifiedNamePattern(i?: number): QualifiedNamePatternContext | QualifiedNamePatternContext[] { if (i === undefined) { - return this.getRuleContexts(SourceIdentifierContext); + return this.getRuleContexts(QualifiedNamePatternContext); } else { - return this.getRuleContext(i, SourceIdentifierContext); + return this.getRuleContext(i, QualifiedNamePatternContext); } } public ASSIGN(): TerminalNode | undefined { return this.tryGetToken(esql_parser.ASSIGN, 0); } diff --git a/packages/kbn-monaco/src/esql/antlr/esql_parser_listener.ts b/packages/kbn-monaco/src/esql/antlr/esql_parser_listener.ts index ff67f81aeab09c..de114f648d0b05 100644 --- a/packages/kbn-monaco/src/esql/antlr/esql_parser_listener.ts +++ b/packages/kbn-monaco/src/esql/antlr/esql_parser_listener.ts @@ -4,8 +4,6 @@ import { ParseTreeListener } from "antlr4ts/tree/ParseTreeListener"; -import { ValueExpressionDefaultContext } from "./esql_parser"; -import { ComparisonContext } from "./esql_parser"; import { NullLiteralContext } from "./esql_parser"; import { QualifiedIntegerLiteralContext } from "./esql_parser"; import { DecimalLiteralContext } from "./esql_parser"; @@ -16,23 +14,25 @@ import { StringLiteralContext } from "./esql_parser"; import { NumericArrayLiteralContext } from "./esql_parser"; import { BooleanArrayLiteralContext } from "./esql_parser"; import { StringArrayLiteralContext } from "./esql_parser"; +import { SingleCommandQueryContext } from "./esql_parser"; +import { CompositeQueryContext } from "./esql_parser"; +import { OperatorExpressionDefaultContext } from "./esql_parser"; +import { ArithmeticUnaryContext } from "./esql_parser"; +import { ArithmeticBinaryContext } from "./esql_parser"; +import { ValueExpressionDefaultContext } from "./esql_parser"; +import { ComparisonContext } from "./esql_parser"; import { ShowInfoContext } from "./esql_parser"; import { ShowFunctionsContext } from "./esql_parser"; import { ConstantDefaultContext } from "./esql_parser"; import { DereferenceContext } from "./esql_parser"; import { FunctionContext } from "./esql_parser"; import { ParenthesizedExpressionContext } from "./esql_parser"; -import { SingleCommandQueryContext } from "./esql_parser"; -import { CompositeQueryContext } from "./esql_parser"; import { LogicalNotContext } from "./esql_parser"; import { BooleanDefaultContext } from "./esql_parser"; import { RegexExpressionContext } from "./esql_parser"; import { LogicalBinaryContext } from "./esql_parser"; import { LogicalInContext } from "./esql_parser"; import { IsNullContext } from "./esql_parser"; -import { OperatorExpressionDefaultContext } from "./esql_parser"; -import { ArithmeticUnaryContext } from "./esql_parser"; -import { ArithmeticBinaryContext } from "./esql_parser"; import { SingleStatementContext } from "./esql_parser"; import { QueryContext } from "./esql_parser"; import { SourceCommandContext } from "./esql_parser"; @@ -51,10 +51,13 @@ import { FromCommandContext } from "./esql_parser"; import { MetadataContext } from "./esql_parser"; import { EvalCommandContext } from "./esql_parser"; import { StatsCommandContext } from "./esql_parser"; +import { InlinestatsCommandContext } from "./esql_parser"; import { GroupingContext } from "./esql_parser"; -import { SourceIdentifierContext } from "./esql_parser"; +import { FromIdentifierContext } from "./esql_parser"; import { QualifiedNameContext } from "./esql_parser"; +import { QualifiedNamePatternContext } from "./esql_parser"; import { IdentifierContext } from "./esql_parser"; +import { IdentifierPatternContext } from "./esql_parser"; import { ConstantContext } from "./esql_parser"; import { LimitCommandContext } from "./esql_parser"; import { SortCommandContext } from "./esql_parser"; @@ -74,6 +77,8 @@ import { DecimalValueContext } from "./esql_parser"; import { IntegerValueContext } from "./esql_parser"; import { StringContext } from "./esql_parser"; import { ComparisonOperatorContext } from "./esql_parser"; +import { ExplainCommandContext } from "./esql_parser"; +import { SubqueryExpressionContext } from "./esql_parser"; import { ShowCommandContext } from "./esql_parser"; import { EnrichCommandContext } from "./esql_parser"; import { EnrichWithClauseContext } from "./esql_parser"; @@ -84,32 +89,6 @@ import { EnrichWithClauseContext } from "./esql_parser"; * `esql_parser`. */ export interface esql_parserListener extends ParseTreeListener { - /** - * Enter a parse tree produced by the `valueExpressionDefault` - * labeled alternative in `esql_parser.valueExpression`. - * @param ctx the parse tree - */ - enterValueExpressionDefault?: (ctx: ValueExpressionDefaultContext) => void; - /** - * Exit a parse tree produced by the `valueExpressionDefault` - * labeled alternative in `esql_parser.valueExpression`. - * @param ctx the parse tree - */ - exitValueExpressionDefault?: (ctx: ValueExpressionDefaultContext) => void; - - /** - * Enter a parse tree produced by the `comparison` - * labeled alternative in `esql_parser.valueExpression`. - * @param ctx the parse tree - */ - enterComparison?: (ctx: ComparisonContext) => void; - /** - * Exit a parse tree produced by the `comparison` - * labeled alternative in `esql_parser.valueExpression`. - * @param ctx the parse tree - */ - exitComparison?: (ctx: ComparisonContext) => void; - /** * Enter a parse tree produced by the `nullLiteral` * labeled alternative in `esql_parser.constant`. @@ -240,6 +219,97 @@ export interface esql_parserListener extends ParseTreeListener { */ exitStringArrayLiteral?: (ctx: StringArrayLiteralContext) => void; + /** + * Enter a parse tree produced by the `singleCommandQuery` + * labeled alternative in `esql_parser.query`. + * @param ctx the parse tree + */ + enterSingleCommandQuery?: (ctx: SingleCommandQueryContext) => void; + /** + * Exit a parse tree produced by the `singleCommandQuery` + * labeled alternative in `esql_parser.query`. + * @param ctx the parse tree + */ + exitSingleCommandQuery?: (ctx: SingleCommandQueryContext) => void; + + /** + * Enter a parse tree produced by the `compositeQuery` + * labeled alternative in `esql_parser.query`. + * @param ctx the parse tree + */ + enterCompositeQuery?: (ctx: CompositeQueryContext) => void; + /** + * Exit a parse tree produced by the `compositeQuery` + * labeled alternative in `esql_parser.query`. + * @param ctx the parse tree + */ + exitCompositeQuery?: (ctx: CompositeQueryContext) => void; + + /** + * Enter a parse tree produced by the `operatorExpressionDefault` + * labeled alternative in `esql_parser.operatorExpression`. + * @param ctx the parse tree + */ + enterOperatorExpressionDefault?: (ctx: OperatorExpressionDefaultContext) => void; + /** + * Exit a parse tree produced by the `operatorExpressionDefault` + * labeled alternative in `esql_parser.operatorExpression`. + * @param ctx the parse tree + */ + exitOperatorExpressionDefault?: (ctx: OperatorExpressionDefaultContext) => void; + + /** + * Enter a parse tree produced by the `arithmeticUnary` + * labeled alternative in `esql_parser.operatorExpression`. + * @param ctx the parse tree + */ + enterArithmeticUnary?: (ctx: ArithmeticUnaryContext) => void; + /** + * Exit a parse tree produced by the `arithmeticUnary` + * labeled alternative in `esql_parser.operatorExpression`. + * @param ctx the parse tree + */ + exitArithmeticUnary?: (ctx: ArithmeticUnaryContext) => void; + + /** + * Enter a parse tree produced by the `arithmeticBinary` + * labeled alternative in `esql_parser.operatorExpression`. + * @param ctx the parse tree + */ + enterArithmeticBinary?: (ctx: ArithmeticBinaryContext) => void; + /** + * Exit a parse tree produced by the `arithmeticBinary` + * labeled alternative in `esql_parser.operatorExpression`. + * @param ctx the parse tree + */ + exitArithmeticBinary?: (ctx: ArithmeticBinaryContext) => void; + + /** + * Enter a parse tree produced by the `valueExpressionDefault` + * labeled alternative in `esql_parser.valueExpression`. + * @param ctx the parse tree + */ + enterValueExpressionDefault?: (ctx: ValueExpressionDefaultContext) => void; + /** + * Exit a parse tree produced by the `valueExpressionDefault` + * labeled alternative in `esql_parser.valueExpression`. + * @param ctx the parse tree + */ + exitValueExpressionDefault?: (ctx: ValueExpressionDefaultContext) => void; + + /** + * Enter a parse tree produced by the `comparison` + * labeled alternative in `esql_parser.valueExpression`. + * @param ctx the parse tree + */ + enterComparison?: (ctx: ComparisonContext) => void; + /** + * Exit a parse tree produced by the `comparison` + * labeled alternative in `esql_parser.valueExpression`. + * @param ctx the parse tree + */ + exitComparison?: (ctx: ComparisonContext) => void; + /** * Enter a parse tree produced by the `showInfo` * labeled alternative in `esql_parser.showCommand`. @@ -318,32 +388,6 @@ export interface esql_parserListener extends ParseTreeListener { */ exitParenthesizedExpression?: (ctx: ParenthesizedExpressionContext) => void; - /** - * Enter a parse tree produced by the `singleCommandQuery` - * labeled alternative in `esql_parser.query`. - * @param ctx the parse tree - */ - enterSingleCommandQuery?: (ctx: SingleCommandQueryContext) => void; - /** - * Exit a parse tree produced by the `singleCommandQuery` - * labeled alternative in `esql_parser.query`. - * @param ctx the parse tree - */ - exitSingleCommandQuery?: (ctx: SingleCommandQueryContext) => void; - - /** - * Enter a parse tree produced by the `compositeQuery` - * labeled alternative in `esql_parser.query`. - * @param ctx the parse tree - */ - enterCompositeQuery?: (ctx: CompositeQueryContext) => void; - /** - * Exit a parse tree produced by the `compositeQuery` - * labeled alternative in `esql_parser.query`. - * @param ctx the parse tree - */ - exitCompositeQuery?: (ctx: CompositeQueryContext) => void; - /** * Enter a parse tree produced by the `logicalNot` * labeled alternative in `esql_parser.booleanExpression`. @@ -422,45 +466,6 @@ export interface esql_parserListener extends ParseTreeListener { */ exitIsNull?: (ctx: IsNullContext) => void; - /** - * Enter a parse tree produced by the `operatorExpressionDefault` - * labeled alternative in `esql_parser.operatorExpression`. - * @param ctx the parse tree - */ - enterOperatorExpressionDefault?: (ctx: OperatorExpressionDefaultContext) => void; - /** - * Exit a parse tree produced by the `operatorExpressionDefault` - * labeled alternative in `esql_parser.operatorExpression`. - * @param ctx the parse tree - */ - exitOperatorExpressionDefault?: (ctx: OperatorExpressionDefaultContext) => void; - - /** - * Enter a parse tree produced by the `arithmeticUnary` - * labeled alternative in `esql_parser.operatorExpression`. - * @param ctx the parse tree - */ - enterArithmeticUnary?: (ctx: ArithmeticUnaryContext) => void; - /** - * Exit a parse tree produced by the `arithmeticUnary` - * labeled alternative in `esql_parser.operatorExpression`. - * @param ctx the parse tree - */ - exitArithmeticUnary?: (ctx: ArithmeticUnaryContext) => void; - - /** - * Enter a parse tree produced by the `arithmeticBinary` - * labeled alternative in `esql_parser.operatorExpression`. - * @param ctx the parse tree - */ - enterArithmeticBinary?: (ctx: ArithmeticBinaryContext) => void; - /** - * Exit a parse tree produced by the `arithmeticBinary` - * labeled alternative in `esql_parser.operatorExpression`. - * @param ctx the parse tree - */ - exitArithmeticBinary?: (ctx: ArithmeticBinaryContext) => void; - /** * Enter a parse tree produced by `esql_parser.singleStatement`. * @param ctx the parse tree @@ -659,6 +664,17 @@ export interface esql_parserListener extends ParseTreeListener { */ exitStatsCommand?: (ctx: StatsCommandContext) => void; + /** + * Enter a parse tree produced by `esql_parser.inlinestatsCommand`. + * @param ctx the parse tree + */ + enterInlinestatsCommand?: (ctx: InlinestatsCommandContext) => void; + /** + * Exit a parse tree produced by `esql_parser.inlinestatsCommand`. + * @param ctx the parse tree + */ + exitInlinestatsCommand?: (ctx: InlinestatsCommandContext) => void; + /** * Enter a parse tree produced by `esql_parser.grouping`. * @param ctx the parse tree @@ -671,15 +687,15 @@ export interface esql_parserListener extends ParseTreeListener { exitGrouping?: (ctx: GroupingContext) => void; /** - * Enter a parse tree produced by `esql_parser.sourceIdentifier`. + * Enter a parse tree produced by `esql_parser.fromIdentifier`. * @param ctx the parse tree */ - enterSourceIdentifier?: (ctx: SourceIdentifierContext) => void; + enterFromIdentifier?: (ctx: FromIdentifierContext) => void; /** - * Exit a parse tree produced by `esql_parser.sourceIdentifier`. + * Exit a parse tree produced by `esql_parser.fromIdentifier`. * @param ctx the parse tree */ - exitSourceIdentifier?: (ctx: SourceIdentifierContext) => void; + exitFromIdentifier?: (ctx: FromIdentifierContext) => void; /** * Enter a parse tree produced by `esql_parser.qualifiedName`. @@ -692,6 +708,17 @@ export interface esql_parserListener extends ParseTreeListener { */ exitQualifiedName?: (ctx: QualifiedNameContext) => void; + /** + * Enter a parse tree produced by `esql_parser.qualifiedNamePattern`. + * @param ctx the parse tree + */ + enterQualifiedNamePattern?: (ctx: QualifiedNamePatternContext) => void; + /** + * Exit a parse tree produced by `esql_parser.qualifiedNamePattern`. + * @param ctx the parse tree + */ + exitQualifiedNamePattern?: (ctx: QualifiedNamePatternContext) => void; + /** * Enter a parse tree produced by `esql_parser.identifier`. * @param ctx the parse tree @@ -703,6 +730,17 @@ export interface esql_parserListener extends ParseTreeListener { */ exitIdentifier?: (ctx: IdentifierContext) => void; + /** + * Enter a parse tree produced by `esql_parser.identifierPattern`. + * @param ctx the parse tree + */ + enterIdentifierPattern?: (ctx: IdentifierPatternContext) => void; + /** + * Exit a parse tree produced by `esql_parser.identifierPattern`. + * @param ctx the parse tree + */ + exitIdentifierPattern?: (ctx: IdentifierPatternContext) => void; + /** * Enter a parse tree produced by `esql_parser.constant`. * @param ctx the parse tree @@ -912,6 +950,28 @@ export interface esql_parserListener extends ParseTreeListener { */ exitComparisonOperator?: (ctx: ComparisonOperatorContext) => void; + /** + * Enter a parse tree produced by `esql_parser.explainCommand`. + * @param ctx the parse tree + */ + enterExplainCommand?: (ctx: ExplainCommandContext) => void; + /** + * Exit a parse tree produced by `esql_parser.explainCommand`. + * @param ctx the parse tree + */ + exitExplainCommand?: (ctx: ExplainCommandContext) => void; + + /** + * Enter a parse tree produced by `esql_parser.subqueryExpression`. + * @param ctx the parse tree + */ + enterSubqueryExpression?: (ctx: SubqueryExpressionContext) => void; + /** + * Exit a parse tree produced by `esql_parser.subqueryExpression`. + * @param ctx the parse tree + */ + exitSubqueryExpression?: (ctx: SubqueryExpressionContext) => void; + /** * Enter a parse tree produced by `esql_parser.showCommand`. * @param ctx the parse tree diff --git a/packages/kbn-monaco/src/esql/lib/ast/ast_helpers.ts b/packages/kbn-monaco/src/esql/lib/ast/ast_helpers.ts index d6e8ea7d0a0384..1a7dc441608726 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/ast_helpers.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/ast_helpers.ts @@ -162,23 +162,24 @@ export function computeLocationExtends(fn: ESQLFunction) { // Note: do not import esql_parser or bundle size will grow up by ~500 kb function getQuotedText(ctx: ParserRuleContext) { - return ( - ctx.tryGetToken(73 /* esql_parser.SRC_QUOTED_IDENTIFIER*/, 0) || - ctx.tryGetToken(64 /* esql_parser.QUOTED_IDENTIFIER */, 0) - ); + return [66 /* esql_parser.QUOTED_IDENTIFIER */, 72 /* esql_parser.FROM_QUOTED_IDENTIFIER */] + .map((keyCode) => ctx.tryGetToken(keyCode, 0)) + .filter(nonNullable)[0]; } function getUnquotedText(ctx: ParserRuleContext) { - return ( - ctx.tryGetToken(72 /* esql_parser.SRC_UNQUOTED_IDENTIFIER */, 0) || - ctx.tryGetToken(63 /* esql_parser.UNQUOTED_IDENTIFIER */, 0) - ); + return [ + 65 /* esql_parser.UNQUOTED_IDENTIFIER */, 71 /* esql_parser.FROM_UNQUOTED_IDENTIFIER */, + 76 /* esql_parser.PROJECT_UNQUOTED_IDENTIFIER */, + ] + .map((keyCode) => ctx.tryGetToken(keyCode, 0)) + .filter(nonNullable)[0]; } const TICKS_REGEX = /(`)/g; function isQuoted(text: string | undefined) { - return text && TICKS_REGEX.test(text); + return text && /^(`)/.test(text); } export function sanifyIdentifierString(ctx: ParserRuleContext) { @@ -189,6 +190,10 @@ export function sanifyIdentifierString(ctx: ParserRuleContext) { ); } +export function wrapIdentifierAsArray(identifierCtx: T | T[]): T[] { + return Array.isArray(identifierCtx) ? identifierCtx : [identifierCtx]; +} + export function createSource( ctx: ParserRuleContext, type: 'index' | 'policy' = 'index' @@ -219,9 +224,9 @@ export function createColumn(ctx: ParserRuleContext): ESQLColumn { const text = sanifyIdentifierString(ctx); const hasQuotes = Boolean(getQuotedText(ctx) || isQuoted(ctx.text)); return { - type: 'column', + type: 'column' as const, name: text, - text, + text: ctx.text, location: getPosition(ctx.start, ctx.stop), incomplete: Boolean(ctx.exception || text === ''), quoted: hasQuotes, diff --git a/packages/kbn-monaco/src/esql/lib/ast/ast_walker.ts b/packages/kbn-monaco/src/esql/lib/ast/ast_walker.ts index 677bc4694e05a8..3916dc68d1ece7 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/ast_walker.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/ast_walker.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import type { ParserRuleContext } from 'antlr4ts/ParserRuleContext'; import { ArithmeticBinaryContext, ArithmeticUnaryContext, @@ -36,8 +37,8 @@ import { LogicalBinaryContext, LogicalInContext, LogicalNotContext, - type MetadataContext, - type MvExpandCommandContext, + MetadataContext, + MvExpandCommandContext, NullLiteralContext, NumericArrayLiteralContext, NumericValueContext, @@ -49,13 +50,13 @@ import { QualifiedIntegerLiteralContext, RegexBooleanExpressionContext, type RenameClauseContext, - SourceIdentifierContext, type StatsCommandContext, StringArrayLiteralContext, StringContext, StringLiteralContext, type ValueExpressionContext, ValueExpressionDefaultContext, + FromIdentifierContext, } from '../../antlr/esql_parser'; import { createSource, @@ -71,6 +72,7 @@ import { sanifyIdentifierString, computeLocationExtends, createColumnStar, + wrapIdentifierAsArray, } from './ast_helpers'; import { getPosition } from './ast_position_utils'; import type { @@ -82,15 +84,22 @@ import type { } from './types'; export function collectAllSourceIdentifiers(ctx: FromCommandContext): ESQLAstItem[] { - return ctx.getRuleContexts(SourceIdentifierContext).map((sourceCtx) => createSource(sourceCtx)); + return ctx.getRuleContexts(FromIdentifierContext).map((sourceCtx) => createSource(sourceCtx)); } -export function collectAllColumnIdentifiers( +function extractIdentifiers( ctx: KeepCommandContext | DropCommandContext | MvExpandCommandContext | MetadataContext -): ESQLAstItem[] { - const identifiers = ( - Array.isArray(ctx.sourceIdentifier()) ? ctx.sourceIdentifier() : [ctx.sourceIdentifier()] - ) as SourceIdentifierContext[]; +) { + if (ctx instanceof MetadataContext) { + return wrapIdentifierAsArray(ctx.fromIdentifier()); + } + if (ctx instanceof MvExpandCommandContext) { + return wrapIdentifierAsArray(ctx.qualifiedName()); + } + return wrapIdentifierAsArray(ctx.qualifiedNamePattern()); +} + +function makeColumnsOutOfIdentifiers(identifiers: ParserRuleContext[]) { const args: ESQLColumn[] = identifiers .filter((child) => child.text) @@ -100,6 +109,13 @@ export function collectAllColumnIdentifiers( return args; } +export function collectAllColumnIdentifiers( + ctx: KeepCommandContext | DropCommandContext | MvExpandCommandContext | MetadataContext +): ESQLAstItem[] { + const identifiers = extractIdentifiers(ctx); + return makeColumnsOutOfIdentifiers(identifiers); +} + export function getPolicyName(ctx: EnrichCommandContext) { if (!ctx._policyName) { return []; @@ -111,7 +127,7 @@ export function getMatchField(ctx: EnrichCommandContext) { if (!ctx._matchField) { return []; } - const identifier = ctx.sourceIdentifier(1); + const identifier = ctx.qualifiedNamePattern(); if (identifier) { const fn = createOption(ctx.ON()!.text.toLowerCase(), ctx); if (identifier.text) { diff --git a/packages/kbn-monaco/src/esql/lib/ast/definitions/commands.ts b/packages/kbn-monaco/src/esql/lib/ast/definitions/commands.ts index 4404bf00b5fad2..e727cffd83a1e2 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/definitions/commands.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/definitions/commands.ts @@ -56,7 +56,7 @@ export const commandDefinitions: CommandDefinition[] = [ options: [], signature: { multipleParams: false, - params: [{ name: 'functions', type: 'string', values: ['functions', 'info'] }], + params: [{ name: 'functions', type: 'function' }], }, }, { diff --git a/packages/kbn-monaco/src/esql/lib/ast/shared/variables.ts b/packages/kbn-monaco/src/esql/lib/ast/shared/variables.ts index 3f93ce50b71c3e..71fd4ce8176a22 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/shared/variables.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/shared/variables.ts @@ -136,7 +136,7 @@ export function collectVariables( // just save the entire expression as variable string const expressionType = 'number'; addToVariableOccurrencies(variables, { - name: expressionOperation.text, + name: expressionOperation.text.replace(/`/g, ''), type: expressionType, location: expressionOperation.location, }); diff --git a/packages/kbn-monaco/src/esql/lib/ast/validation/validation.test.ts b/packages/kbn-monaco/src/esql/lib/ast/validation/validation.test.ts index 0df20ac7d88f45..246b8673974201 100644 --- a/packages/kbn-monaco/src/esql/lib/ast/validation/validation.test.ts +++ b/packages/kbn-monaco/src/esql/lib/ast/validation/validation.test.ts @@ -226,18 +226,18 @@ describe('validation logic', () => { ['eval', 'stats', 'rename', 'limit', 'keep', 'drop', 'mv_expand', 'dissect', 'grok'].map( (command) => testErrorsAndWarnings(command, [ - `SyntaxError: expected {FROM, ROW, SHOW} but found "${command}"`, + `SyntaxError: expected {EXPLAIN, FROM, ROW, SHOW} but found "${command}"`, ]) ); }); describe('from', () => { - testErrorsAndWarnings('f', ['SyntaxError: expected {FROM, ROW, SHOW} but found "f"']); + testErrorsAndWarnings('f', ['SyntaxError: expected {EXPLAIN, FROM, ROW, SHOW} but found "f"']); testErrorsAndWarnings(`from `, [ - "SyntaxError: missing {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} at ''", + "SyntaxError: missing {QUOTED_IDENTIFIER, FROM_UNQUOTED_IDENTIFIER} at ''", ]); testErrorsAndWarnings(`from index,`, [ - "SyntaxError: missing {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} at ''", + "SyntaxError: missing {QUOTED_IDENTIFIER, FROM_UNQUOTED_IDENTIFIER} at ''", ]); testErrorsAndWarnings(`from assignment = 1`, [ 'SyntaxError: expected {, PIPE, COMMA, OPENING_BRACKET} but found "="', @@ -495,7 +495,10 @@ describe('validation logic', () => { testErrorsAndWarnings('show functions', []); testErrorsAndWarnings('show info', []); testErrorsAndWarnings('show functions blah', [ - "SyntaxError: extraneous input 'blah' expecting ", + "SyntaxError: token recognition error at: 'b'", + "SyntaxError: token recognition error at: 'l'", + "SyntaxError: token recognition error at: 'a'", + "SyntaxError: token recognition error at: 'h'", ]); }); @@ -521,18 +524,25 @@ describe('validation logic', () => { describe('keep', () => { testErrorsAndWarnings('from index | keep ', [ - `SyntaxError: missing {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} at ''`, + `SyntaxError: missing {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} at ''`, ]); testErrorsAndWarnings('from index | keep stringField, numberField, dateField', []); testErrorsAndWarnings('from index | keep `stringField`, `numberField`, `dateField`', []); - testErrorsAndWarnings('from index | keep 4.5', ['Unknown column [4.5]']); + testErrorsAndWarnings('from index | keep 4.5', [ + "SyntaxError: token recognition error at: '4'", + "SyntaxError: token recognition error at: '5'", + "SyntaxError: missing {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} at '.'", + "SyntaxError: missing {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} at ''", + 'Unknown column [.]', + ]); + testErrorsAndWarnings('from index | keep `4.5`', ['Unknown column [4.5]']); testErrorsAndWarnings('from index | keep missingField, numberField, dateField', [ 'Unknown column [missingField]', ]); testErrorsAndWarnings('from index | keep `any#Char$ field`', []); testErrorsAndWarnings( 'from index | project ', - [`SyntaxError: missing {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} at ''`], + [`SyntaxError: missing {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} at ''`], ['PROJECT command is no longer supported, please use KEEP instead'] ); testErrorsAndWarnings( @@ -569,10 +579,16 @@ describe('validation logic', () => { describe('drop', () => { testErrorsAndWarnings('from index | drop ', [ - `SyntaxError: missing {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} at ''`, + `SyntaxError: missing {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} at ''`, ]); testErrorsAndWarnings('from index | drop stringField, numberField, dateField', []); - testErrorsAndWarnings('from index | drop 4.5', ['Unknown column [4.5]']); + testErrorsAndWarnings('from index | drop 4.5', [ + "SyntaxError: token recognition error at: '4'", + "SyntaxError: token recognition error at: '5'", + "SyntaxError: missing {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} at '.'", + "SyntaxError: missing {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} at ''", + 'Unknown column [.]', + ]); testErrorsAndWarnings('from index | drop missingField, numberField, dateField', [ 'Unknown column [missingField]', ]); @@ -603,7 +619,7 @@ describe('validation logic', () => { describe('mv_expand', () => { testErrorsAndWarnings('from a | mv_expand ', [ - "SyntaxError: missing {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} at ''", + "SyntaxError: missing {UNQUOTED_IDENTIFIER, QUOTED_IDENTIFIER} at ''", ]); testErrorsAndWarnings('from a | mv_expand stringField', [ 'Mv_expand only supports list type values, found [stringField] of type string', @@ -612,7 +628,8 @@ describe('validation logic', () => { testErrorsAndWarnings(`from a | mv_expand listField`, []); testErrorsAndWarnings('from a | mv_expand listField, b', [ - 'SyntaxError: expected {, PIPE} but found ","', + "SyntaxError: token recognition error at: ','", + "SyntaxError: extraneous input 'b' expecting ", ]); testErrorsAndWarnings('row a = "a" | mv_expand a', [ @@ -623,20 +640,20 @@ describe('validation logic', () => { describe('rename', () => { testErrorsAndWarnings('from a | rename', [ - "SyntaxError: missing {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} at ''", + "SyntaxError: missing {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} at ''", ]); testErrorsAndWarnings('from a | rename stringField', [ - 'SyntaxError: expected {AS} but found ""', + 'SyntaxError: expected {DOT, AS} but found ""', ]); testErrorsAndWarnings('from a | rename a', [ - 'SyntaxError: expected {AS} but found ""', + 'SyntaxError: expected {DOT, AS} but found ""', 'Unknown column [a]', ]); testErrorsAndWarnings('from a | rename stringField as', [ - "SyntaxError: missing {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} at ''", + "SyntaxError: missing {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} at ''", ]); testErrorsAndWarnings('from a | rename missingField as', [ - "SyntaxError: missing {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} at ''", + "SyntaxError: missing {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} at ''", 'Unknown column [missingField]', ]); testErrorsAndWarnings('from a | rename stringField as b', []); @@ -644,7 +661,9 @@ describe('validation logic', () => { testErrorsAndWarnings('from a | rename stringField As b', []); testErrorsAndWarnings('from a | rename stringField As b, b AS c', []); testErrorsAndWarnings('from a | rename fn() as a', [ - 'Unknown column [fn()]', + "SyntaxError: token recognition error at: '('", + "SyntaxError: token recognition error at: ')'", + 'Unknown column [fn]', 'Unknown column [a]', ]); testErrorsAndWarnings('from a | eval numberField + 1 | rename `numberField + 1` as a', []); @@ -653,7 +672,7 @@ describe('validation logic', () => { [] ); testErrorsAndWarnings('from a | eval numberField + 1 | rename `numberField + 1` as ', [ - "SyntaxError: missing {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} at ''", + "SyntaxError: missing {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} at ''", ]); testErrorsAndWarnings('from a | rename s* as strings', [ 'Using wildcards (*) in rename is not allowed [s*]', @@ -1129,6 +1148,14 @@ describe('validation logic', () => { 'SyntaxError: expected {, PIPE, COMMA, DOT} but found "("', 'Unknown column [percentile]', ]); + testErrorsAndWarnings('from a | stats count(`numberField`)', []); + + for (const subCommand of ['keep', 'drop', 'eval']) { + testErrorsAndWarnings( + `from a | stats count(\`numberField\`) | ${subCommand} \`count(\`\`numberField\`\`)\` `, + [] + ); + } testErrorsAndWarnings( 'from a | stats avg(numberField) by stringField, percentile(numberField) by ipField', @@ -1312,22 +1339,22 @@ describe('validation logic', () => { describe('enrich', () => { testErrorsAndWarnings(`from a | enrich`, [ - "SyntaxError: missing {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} at ''", + "SyntaxError: missing {QUOTED_IDENTIFIER, FROM_UNQUOTED_IDENTIFIER} at ''", ]); testErrorsAndWarnings(`from a | enrich policy `, []); testErrorsAndWarnings(`from a | enrich missing-policy `, ['Unknown policy [missing-policy]']); testErrorsAndWarnings(`from a | enrich policy on `, [ - "SyntaxError: missing {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} at ''", + "SyntaxError: missing {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} at ''", ]); testErrorsAndWarnings(`from a | enrich policy on b `, ['Unknown column [b]']); testErrorsAndWarnings(`from a | enrich policy on numberField with `, [ - 'SyntaxError: expected {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} but found ""', + 'SyntaxError: expected {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} but found ""', ]); testErrorsAndWarnings(`from a | enrich policy on numberField with var0 `, [ 'Unknown column [var0]', ]); testErrorsAndWarnings(`from a | enrich policy on numberField with var0 = `, [ - "SyntaxError: missing {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} at ''", + "SyntaxError: missing {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} at ''", 'Unknown column [var0]', ]); testErrorsAndWarnings(`from a | enrich policy on numberField with var0 = c `, [ @@ -1339,8 +1366,8 @@ describe('validation logic', () => { // `Unknown column [stringField]`, // ]); testErrorsAndWarnings(`from a | enrich policy on numberField with var0 = , `, [ - "SyntaxError: missing {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} at ','", - 'SyntaxError: expected {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} but found ""', + "SyntaxError: missing {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} at ','", + 'SyntaxError: expected {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} but found ""', 'Unknown column [var0]', ]); testErrorsAndWarnings(`from a | enrich policy on numberField with var0 = otherField, var1 `, [ @@ -1352,7 +1379,7 @@ describe('validation logic', () => { [] ); testErrorsAndWarnings(`from a | enrich policy on numberField with var0 = otherField, var1 = `, [ - "SyntaxError: missing {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} at ''", + "SyntaxError: missing {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} at ''", 'Unknown column [var1]', ]); @@ -1361,7 +1388,7 @@ describe('validation logic', () => { [] ); testErrorsAndWarnings(`from a | enrich policy with `, [ - 'SyntaxError: expected {SRC_UNQUOTED_IDENTIFIER, SRC_QUOTED_IDENTIFIER} but found ""', + 'SyntaxError: expected {QUOTED_IDENTIFIER, PROJECT_UNQUOTED_IDENTIFIER} but found ""', ]); testErrorsAndWarnings(`from a | enrich policy with otherField`, []); testErrorsAndWarnings(`from a | enrich policy | eval otherField`, []); From 3c75764e0763ce6adee5a2aac51a0e4216492363 Mon Sep 17 00:00:00 2001 From: Mike Pellegrini Date: Wed, 20 Dec 2023 08:29:12 -0500 Subject: [PATCH 023/116] Fix warnings generated by the model selection list (#173629) ## Summary Fix DOM attribute warnings generated by the model selection list. This approach uses the [`option.data` prop](https://eui.elastic.co/#/forms/selectable#rendering-the-options) to pass custom data for option rendering, which prevents the custom data from being added to the rendered DOM element. --- .../ml_inference/model_select.test.tsx | 27 ++++++++++++++----- .../pipelines/ml_inference/model_select.tsx | 27 ++++++++++++------- .../ml_inference/model_select_option.test.tsx | 8 +++--- .../ml_inference/model_select_option.tsx | 8 ++---- 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select.test.tsx index f82c0ffb3b1c84..c8a970751643a2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select.test.tsx @@ -83,11 +83,15 @@ describe('ModelSelect', () => { const selectable = wrapper.find(EuiSelectable); expect(selectable.prop('options')).toEqual([ { - modelId: 'model_1', + data: { + modelId: 'model_1', + }, label: 'model_1', }, { - modelId: 'model_2', + data: { + modelId: 'model_2', + }, label: 'model_2', }, ]); @@ -114,7 +118,10 @@ describe('ModelSelect', () => { const wrapper = shallow(); expect(wrapper.find(EuiSelectable)).toHaveLength(1); const selectable = wrapper.find(EuiSelectable); - selectable.simulate('change', [{ modelId: 'model_1' }, { modelId: 'model_2', checked: 'on' }]); + selectable.simulate('change', [ + { data: { modelId: 'model_1' } }, + { data: { modelId: 'model_2' }, checked: 'on' }, + ]); expect(MOCK_ACTIONS.setInferencePipelineConfiguration).toHaveBeenCalledWith( expect.objectContaining({ inferenceConfig: undefined, @@ -130,8 +137,8 @@ describe('ModelSelect', () => { expect(wrapper.find(EuiSelectable)).toHaveLength(1); const selectable = wrapper.find(EuiSelectable); selectable.simulate('change', [ - { modelId: 'model_1' }, - { modelId: 'model_2', isPlaceholder: true, checked: 'on' }, + { data: { modelId: 'model_1' } }, + { data: { modelId: 'model_2', isPlaceholder: true }, checked: 'on' }, ]); expect(MOCK_ACTIONS.setInferencePipelineConfiguration).toHaveBeenCalledWith( expect.objectContaining({ @@ -146,7 +153,10 @@ describe('ModelSelect', () => { const wrapper = shallow(); expect(wrapper.find(EuiSelectable)).toHaveLength(1); const selectable = wrapper.find(EuiSelectable); - selectable.simulate('change', [{ modelId: 'model_1' }, { modelId: 'model_2', checked: 'on' }]); + selectable.simulate('change', [ + { data: { modelId: 'model_1' } }, + { data: { modelId: 'model_2' }, checked: 'on' }, + ]); expect(MOCK_ACTIONS.setInferencePipelineConfiguration).toHaveBeenCalledWith( expect.objectContaining({ pipelineName: 'my-index-model_2', @@ -168,7 +178,10 @@ describe('ModelSelect', () => { const wrapper = shallow(); expect(wrapper.find(EuiSelectable)).toHaveLength(1); const selectable = wrapper.find(EuiSelectable); - selectable.simulate('change', [{ modelId: 'model_1' }, { modelId: 'model_2', checked: 'on' }]); + selectable.simulate('change', [ + { data: { modelId: 'model_1' } }, + { data: { modelId: 'model_2' }, checked: 'on' }, + ]); expect(MOCK_ACTIONS.setInferencePipelineConfiguration).toHaveBeenCalledWith( expect.objectContaining({ pipelineName: 'user-pipeline', diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select.tsx index 6f5fc424aef0b8..853bcb41a080f7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select.tsx @@ -18,6 +18,7 @@ import { EuiPanel, EuiScreenReaderLive, EuiSelectable, + EuiSelectableOption, EuiText, EuiTextColor, EuiTitle, @@ -31,9 +32,13 @@ import { MlModel, MlModelDeploymentState } from '../../../../../../../common/typ import { LicenseBadge } from './license_badge'; import { ModelSelectLogic } from './model_select_logic'; -import { ModelSelectOption, ModelSelectOptionProps } from './model_select_option'; +import { ModelSelectOption } from './model_select_option'; import { normalizeModelName } from './utils'; +type EuiSelectableOptionWithMlModelData = EuiSelectableOption & { + data: MlModel; +}; + export const DeployModelButton: React.FC<{ onClick: () => void; modelId: string; @@ -297,33 +302,37 @@ export const ModelSelect: React.FC = () => { const maxVisibleOptions = 4.5; const [listHeight, setListHeight] = useState(maxVisibleOptions * rowHeight); - const getModelSelectOptionProps = (models: MlModel[]): ModelSelectOptionProps[] => + const getModelSelectOptionProps = (models: MlModel[]): EuiSelectableOptionWithMlModelData[] => (models ?? []).map((model) => ({ - ...model, label: model.modelId, checked: model.modelId === modelID ? 'on' : undefined, + data: { ...model }, })); - const onChange = (options: ModelSelectOptionProps[]) => { + const onChange = (options: EuiSelectableOptionWithMlModelData[]) => { const selectedModelOption = options.find((option) => option.checked === 'on'); setInferencePipelineConfiguration({ ...configuration, inferenceConfig: undefined, - modelID: selectedModelOption?.modelId ?? '', - isModelPlaceholderSelected: selectedModelOption?.isPlaceholder ?? false, + modelID: selectedModelOption?.data.modelId ?? '', + isModelPlaceholderSelected: selectedModelOption?.data.isPlaceholder ?? false, fieldMappings: undefined, pipelineName: isPipelineNameUserSupplied ? pipelineName - : indexName + '-' + normalizeModelName(selectedModelOption?.modelId ?? ''), + : indexName + '-' + normalizeModelName(selectedModelOption?.data.modelId ?? ''), }); }; - const onSearchChange = (_: string, matchingOptions: ModelSelectOptionProps[]) => { + const onSearchChange = (_: string, matchingOptions: EuiSelectableOptionWithMlModelData[]) => { setListHeight(Math.min(maxVisibleOptions, matchingOptions.length) * rowHeight); }; - const renderOption = (option: ModelSelectOptionProps) => ; + const renderOption = (option: EuiSelectableOptionWithMlModelData) => { + const { data, ...optionExclData } = option; + const flattenedOption = { ...optionExclData, ...data }; + return ; + }; return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_option.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_option.test.tsx index 81d022aedfb74f..bcf4eb8342db13 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_option.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_option.test.tsx @@ -11,15 +11,15 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { EuiText } from '@elastic/eui'; +import { EuiSelectableOption, EuiText } from '@elastic/eui'; -import { MlModelDeploymentState } from '../../../../../../../common/types/ml'; +import { MlModel, MlModelDeploymentState } from '../../../../../../../common/types/ml'; import { TrainedModelHealth } from '../ml_model_health'; import { LicenseBadge } from './license_badge'; -import { ModelSelectOption, ModelSelectOptionProps } from './model_select_option'; +import { ModelSelectOption } from './model_select_option'; -const DEFAULT_PROPS: ModelSelectOptionProps = { +const DEFAULT_PROPS: EuiSelectableOption = { modelId: 'model_1', type: 'ner', label: 'Model 1', diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_option.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_option.tsx index ced26293cd68d1..b3728ab6f2c7f1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_option.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_option.tsx @@ -10,6 +10,7 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, + EuiSelectableOption, EuiText, EuiTextColor, EuiTextTruncate, @@ -22,12 +23,7 @@ import { TrainedModelHealth } from '../ml_model_health'; import { LicenseBadge } from './license_badge'; -export type ModelSelectOptionProps = MlModel & { - label: string; - checked?: 'on'; -}; - -export const ModelSelectOption: React.FC = ({ +export const ModelSelectOption: React.FC> = ({ modelId, title, description, From 909e501de6a9a170ba503c07339a8ab1d0ff72d7 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 20 Dec 2023 08:29:39 -0500 Subject: [PATCH 024/116] skip failing test suite (#173165) --- .../observability/observability_log_explorer/header_menu.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test_serverless/functional/test_suites/observability/observability_log_explorer/header_menu.ts b/x-pack/test_serverless/functional/test_suites/observability/observability_log_explorer/header_menu.ts index 14d8dd94376de6..0bb8da7a911b95 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/observability_log_explorer/header_menu.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/observability_log_explorer/header_menu.ts @@ -22,7 +22,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'svlCommonNavigation', ]); - describe('Header menu', () => { + // Failing: See https://github.com/elastic/kibana/issues/173165 + describe.skip('Header menu', () => { before(async () => { await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); await esArchiver.load( From b35e323718497338d7101f36253208bb3c301c1b Mon Sep 17 00:00:00 2001 From: Konrad Szwarc Date: Wed, 20 Dec 2023 14:41:39 +0100 Subject: [PATCH 025/116] [EDR Workflows][Osquery] Prevent querying offline agents (#173300) closes https://github.com/elastic/security-team/issues/8138 This PR resolves the bug that allowed users to run a query against an offline agent using a query from their query history. Before: https://github.com/elastic/kibana/assets/29123534/7742faee-8389-41ab-a8bf-9b0f6d70a26f After: https://github.com/elastic/kibana/assets/29123534/c4ff0213-8266-4fc1-a989-99bee8e93975 --- .../osquery/public/agents/agent_grouper.ts | 2 +- .../osquery/public/agents/agents_table.tsx | 65 ++++++++++--------- .../osquery/public/agents/helpers.test.ts | 2 + .../plugins/osquery/public/agents/helpers.ts | 13 +++- x-pack/plugins/osquery/public/agents/types.ts | 1 + .../osquery/public/agents/use_all_agents.ts | 37 ++++++----- .../live_queries/form/agents_table_field.tsx | 6 ++ 7 files changed, 75 insertions(+), 51 deletions(-) diff --git a/x-pack/plugins/osquery/public/agents/agent_grouper.ts b/x-pack/plugins/osquery/public/agents/agent_grouper.ts index 1375c30437d60b..86f6bcbd422459 100644 --- a/x-pack/plugins/osquery/public/agents/agent_grouper.ts +++ b/x-pack/plugins/osquery/public/agents/agent_grouper.ts @@ -35,7 +35,7 @@ export const generateAgentOption = ( disabled: agent.status !== 'online', label: `${agent.local_metadata.host.hostname} (${agent.local_metadata.elastic.agent.id})`, key: agent.local_metadata.elastic.agent.id, - color: getColor(groupType), + color: agent.status !== 'online' ? 'danger' : getColor(groupType), value: { groupType, groups: { diff --git a/x-pack/plugins/osquery/public/agents/agents_table.tsx b/x-pack/plugins/osquery/public/agents/agents_table.tsx index f6b80e670f95b1..c7b6fdd432fa31 100644 --- a/x-pack/plugins/osquery/public/agents/agents_table.tsx +++ b/x-pack/plugins/osquery/public/agents/agents_table.tsx @@ -5,8 +5,8 @@ * 2.0. */ -import { find } from 'lodash/fp'; -import React, { useCallback, useEffect, useRef, useState } from 'react'; +import { find, isEmpty } from 'lodash/fp'; +import React, { useCallback, useEffect, useRef, useState, useMemo } from 'react'; import { EuiComboBox, EuiHealth, @@ -40,7 +40,7 @@ import { NO_AGENT_AVAILABLE_TITLE, } from './translations'; -import type { SelectedGroups, AgentOptionValue, GroupOption, AgentSelection } from './types'; +import type { GroupOption, AgentSelection } from './types'; import { AGENT_GROUP_KEY } from './types'; interface AgentsTableProps { @@ -70,48 +70,45 @@ const AgentsTableComponent: React.FC = ({ agentSelection, onCh const { isLoading: agentsLoading, + isRefetching: agentsRefetching, data: agentList, isFetched: agentsFetched, } = useAllAgents(debouncedSearchValue, { perPage, + agentIds: agentSelection?.agents, }); // option related const [options, setOptions] = useState([]); const [selectedOptions, setSelectedOptions] = useState([]); - const [numAgentsSelected, setNumAgentsSelected] = useState(0); const defaultValueInitialized = useRef(false); + const numAgentsSelected = useMemo(() => { + const { newAgentSelection, selectedAgents, selectedGroups } = + generateAgentSelection(selectedOptions); + if (newAgentSelection.allAgentsSelected) { + return agentList?.total ?? 0; + } else { + const checkAgent = generateAgentCheck(selectedGroups); + + return ( + // filter out all the agents counted by selected policies and platforms + selectedAgents.filter(checkAgent).length + + // add the number of agents added via policy and platform groups + getNumAgentsInGrouping(selectedGroups) - + // subtract the number of agents double counted by policy/platform selections + getNumOverlapped(selectedGroups, agentList?.groups?.overlap ?? {}) + ); + } + }, [agentList?.groups?.overlap, agentList?.total, selectedOptions]); + const onSelection = useCallback( (selection: GroupOption[]) => { - // TODO?: optimize this by making the selection computation incremental - const { - newAgentSelection, - selectedAgents, - selectedGroups, - }: { - newAgentSelection: AgentSelection; - selectedAgents: AgentOptionValue[]; - selectedGroups: SelectedGroups; - } = generateAgentSelection(selection); - if (newAgentSelection.allAgentsSelected) { - setNumAgentsSelected(agentList?.total ?? 0); - } else { - const checkAgent = generateAgentCheck(selectedGroups); - setNumAgentsSelected( - // filter out all the agents counted by selected policies and platforms - selectedAgents.filter(checkAgent).length + - // add the number of agents added via policy and platform groups - getNumAgentsInGrouping(selectedGroups) - - // subtract the number of agents double counted by policy/platform selections - getNumOverlapped(selectedGroups, agentList?.groups?.overlap ?? {}) - ); - } - + const { newAgentSelection } = generateAgentSelection(selection); onChange(newAgentSelection); setSelectedOptions(selection); }, - [agentList?.groups?.overlap, agentList?.total, onChange] + [onChange] ); useEffect(() => { @@ -132,7 +129,13 @@ const AgentsTableComponent: React.FC = ({ agentSelection, onCh } }; - if (agentSelection && !defaultValueInitialized.current && options.length) { + if ( + agentSelection && + !isEmpty(agentSelection) && + !defaultValueInitialized.current && + options.length && + !agentsRefetching + ) { if (agentSelection.allAgentsSelected) { const allAgentsOptions = find(['label', ALL_AGENTS_LABEL], options); @@ -150,7 +153,7 @@ const AgentsTableComponent: React.FC = ({ agentSelection, onCh handleSelectedOptions(agentSelection.agents, AGENT_SELECTION_LABEL); } } - }, [agentSelection, onSelection, options, selectedOptions]); + }, [agentSelection, agentsFetched, agentsRefetching, onSelection, options, selectedOptions]); useEffect(() => { if (agentsFetched && agentList?.groups) { diff --git a/x-pack/plugins/osquery/public/agents/helpers.test.ts b/x-pack/plugins/osquery/public/agents/helpers.test.ts index 067aebc57944e4..bdf4d2628e360e 100644 --- a/x-pack/plugins/osquery/public/agents/helpers.test.ts +++ b/x-pack/plugins/osquery/public/agents/helpers.test.ts @@ -19,6 +19,7 @@ describe('generateAgentSelection', () => { expect(newAgentSelection).toEqual({ agents: [], allAgentsSelected: false, + offlineAgentsSelected: false, platformsSelected: [], policiesSelected: [], }); @@ -47,6 +48,7 @@ describe('generateAgentSelection', () => { expect(newAgentSelection).toEqual({ agents: [], allAgentsSelected: false, + offlineAgentsSelected: false, platformsSelected: platformOptions.map(({ value: { id } }) => id), policiesSelected: policyOptions.map(({ value: { id } }) => id), }); diff --git a/x-pack/plugins/osquery/public/agents/helpers.ts b/x-pack/plugins/osquery/public/agents/helpers.ts index b84c6e4957286b..83c14ec0dcdac6 100644 --- a/x-pack/plugins/osquery/public/agents/helpers.ts +++ b/x-pack/plugins/osquery/public/agents/helpers.ts @@ -67,12 +67,19 @@ export const generateAgentCheck = }) .every((a) => !a); -export const generateAgentSelection = (selection: GroupOption[]) => { +export const generateAgentSelection = ( + selection: GroupOption[] +): { + newAgentSelection: AgentSelection; + selectedAgents: AgentOptionValue[]; + selectedGroups: SelectedGroups; +} => { const newAgentSelection: AgentSelection = { agents: [], allAgentsSelected: false, platformsSelected: [], policiesSelected: [], + offlineAgentsSelected: false, }; // parse through the selections to be able to determine how many are actually selected const selectedAgents: AgentOptionValue[] = []; @@ -116,6 +123,10 @@ export const generateAgentSelection = (selection: GroupOption[]) => { } newAgentSelection.agents.push(key); + if (opt.disabled) { + newAgentSelection.offlineAgentsSelected = true; + } + break; default: // this should never happen! diff --git a/x-pack/plugins/osquery/public/agents/types.ts b/x-pack/plugins/osquery/public/agents/types.ts index 6f443641b227bc..813c8a6276a026 100644 --- a/x-pack/plugins/osquery/public/agents/types.ts +++ b/x-pack/plugins/osquery/public/agents/types.ts @@ -30,6 +30,7 @@ export interface AgentSelection { allAgentsSelected: boolean; platformsSelected: string[]; policiesSelected: string[]; + offlineAgentsSelected?: boolean; } interface BaseGroupOption { diff --git a/x-pack/plugins/osquery/public/agents/use_all_agents.ts b/x-pack/plugins/osquery/public/agents/use_all_agents.ts index d0ea65c6bab05b..12b98bccc0ed57 100644 --- a/x-pack/plugins/osquery/public/agents/use_all_agents.ts +++ b/x-pack/plugins/osquery/public/agents/use_all_agents.ts @@ -18,11 +18,12 @@ import { useOsqueryPolicies } from './use_osquery_policies'; interface RequestOptions { perPage?: number; page?: number; + agentIds?: string[]; } // TODO: break out the paginated vs all cases into separate hooks export const useAllAgents = (searchValue = '', opts: RequestOptions = { perPage: 9000 }) => { - const { perPage } = opts; + const { perPage, agentIds } = opts; const { http } = useKibana().services; const setErrorToast = useErrorToast(); @@ -32,9 +33,9 @@ export const useAllAgents = (searchValue = '', opts: RequestOptions = { perPage: agents: Agent[]; groups: ReturnType; total: number; - }>( - ['agents', osqueryPolicies, searchValue, perPage], - () => { + }>({ + queryKey: ['agents', osqueryPolicies, searchValue, perPage, agentIds], + queryFn: () => { let kuery = ''; if (osqueryPolicies?.length) { @@ -43,7 +44,9 @@ export const useAllAgents = (searchValue = '', opts: RequestOptions = { perPage: if (searchValue) { kuery += ` and (local_metadata.host.hostname:*${searchValue}* or local_metadata.elastic.agent.id:*${searchValue}*)`; } else { - kuery += ` and (status:online)`; + kuery += ` and (status:online ${ + agentIds?.length ? `or local_metadata.elastic.agent.id:(${agentIds.join(' or ')})` : '' + })`; } } @@ -55,18 +58,16 @@ export const useAllAgents = (searchValue = '', opts: RequestOptions = { perPage: }, }); }, - { - enabled: isFetched && !!osqueryPolicies?.length, - onSuccess: () => setErrorToast(), - onError: (error) => - // @ts-expect-error update types - setErrorToast(error?.body, { - title: i18n.translate('xpack.osquery.agents.fetchError', { - defaultMessage: 'Error while fetching agents', - }), - // @ts-expect-error update types - toastMessage: error?.body?.error, + enabled: isFetched && !!osqueryPolicies?.length, + onSuccess: () => setErrorToast(), + onError: (error) => + // @ts-expect-error update types + setErrorToast(error?.body, { + title: i18n.translate('xpack.osquery.agents.fetchError', { + defaultMessage: 'Error while fetching agents', }), - } - ); + // @ts-expect-error update types + toastMessage: error?.body?.error, + }), + }); }; diff --git a/x-pack/plugins/osquery/public/live_queries/form/agents_table_field.tsx b/x-pack/plugins/osquery/public/live_queries/form/agents_table_field.tsx index eab43c5982b801..078a9c712fc08e 100644 --- a/x-pack/plugins/osquery/public/live_queries/form/agents_table_field.tsx +++ b/x-pack/plugins/osquery/public/live_queries/form/agents_table_field.tsx @@ -14,6 +14,12 @@ import type { AgentSelection } from '../../agents/types'; const checkAgentsLength = (agentsSelection: AgentSelection) => { if (!isEmpty(agentsSelection)) { + if (agentsSelection.offlineAgentsSelected) { + return i18n.translate('xpack.osquery.pack.queryFlyoutForm.osqueryAgentsOfflineErrorMessage', { + defaultMessage: 'Some agents are offline', + }); + } + const isValid = !!( agentsSelection.allAgentsSelected || agentsSelection.agents?.length || From 9023497cb52be81a7180262a14d95f10cb8bf40c Mon Sep 17 00:00:00 2001 From: Marco Liberati Date: Wed, 20 Dec 2023 14:44:54 +0100 Subject: [PATCH 026/116] [ES|QL] Display the correct language string (#173721) ## Summary Fixes the action title to use the correct language name Screenshot 2023-12-20 at 11 29 34 --- x-pack/plugins/lens/public/embeddable/embeddable.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx index e5d34db62ba75d..c1dd7901f38220 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx @@ -21,6 +21,7 @@ import { isOfQueryType, getAggregateQueryMode, ExecutionContextSearch, + getLanguageDisplayName, } from '@kbn/es-query'; import type { PaletteOutput } from '@kbn/coloring'; import { @@ -740,7 +741,7 @@ export class Embeddable } const query = this.savedVis?.state.query as unknown as AggregateQuery; const language = getAggregateQueryMode(query); - return String(language).toUpperCase(); + return getLanguageDisplayName(language).toUpperCase(); } /** From 2c51f63dd1c91a5f5d5eaa68b22db7abadce6b8c Mon Sep 17 00:00:00 2001 From: Pete Harverson Date: Wed, 20 Dec 2023 14:00:27 +0000 Subject: [PATCH 027/116] [ML] Enhances toast notifications to improve error reporting (#173362) ## Summary Several enhancements to the error toast notifications in the ML plugin to improve error reporting. The bulk of the changes are to add 'See the full error' buttons to the toasts allowing the user to see further details on the error that has occurred. Also makes minor edits to some of the error messages to improve clarity. Also closes #171839 by changes to `x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js` so that the the 'Jobs started successfully' toast is only shown if 1 or more jobs have been started successfully. Fixes #171839 ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../components/full_time_range_selector.tsx | 11 ++--- .../full_time_range_selector_service.test.ts | 6 ++- .../full_time_range_selector_service.ts | 11 ++--- .../alerting/ml_anomaly_alert_trigger.tsx | 13 +++--- .../custom_url_editor/list.test.tsx | 8 ++++ .../custom_urls/custom_url_editor/list.tsx | 10 ++--- .../components/custom_urls/custom_urls.tsx | 45 ++++++++++--------- .../rule_editor/rule_editor_flyout.js | 43 +++++++++--------- .../rule_editor/rule_editor_flyout.test.js | 5 +++ .../jobs/jobs_list/components/utils.js | 24 +++++----- .../util/model_memory_estimator.ts | 6 ++- .../components/time_range_step/time_range.tsx | 3 +- .../jobs/new_job/recognize/page.tsx | 21 ++++----- .../memory_usage/memory_tree_map/tree_map.tsx | 2 +- .../nodes_overview/nodes_list.tsx | 2 +- .../model_management/models_list.tsx | 4 +- .../components/notifications_list.tsx | 2 +- .../routing/routes/new_job/recognize.tsx | 8 ++-- .../settings/anomaly_detection_settings.tsx | 10 +++-- .../settings/calendars/edit/new_calendar.js | 19 ++++---- .../calendars/edit/new_calendar.test.js | 5 +++ .../settings/calendars/list/calendars_list.js | 8 ++++ .../filter_lists/edit/edit_filter_list.js | 18 ++++---- .../edit/edit_filter_list.test.js | 9 ++++ .../filter_lists/list/filter_lists.js | 15 ++++++- .../application/settings/settings.test.tsx | 2 +- 26 files changed, 186 insertions(+), 124 deletions(-) diff --git a/x-pack/packages/ml/date_picker/src/components/full_time_range_selector.tsx b/x-pack/packages/ml/date_picker/src/components/full_time_range_selector.tsx index cb890172bbdd9f..5fd828feb8fa4e 100644 --- a/x-pack/packages/ml/date_picker/src/components/full_time_range_selector.tsx +++ b/x-pack/packages/ml/date_picker/src/components/full_time_range_selector.tsx @@ -118,14 +118,15 @@ export const FullTimeRangeSelector: FC = (props) => callback(fullTimeRange); } } catch (e) { - toasts.addDanger( - i18n.translate( + toasts.addError(e, { + title: i18n.translate( 'xpack.ml.datePicker.fullTimeRangeSelector.errorSettingTimeRangeNotification', { - defaultMessage: 'An error occurred setting the time range.', + defaultMessage: + 'An error occurred setting the time range. Please set the desired start and end times.', } - ) - ); + ), + }); } }, [ timefilter, diff --git a/x-pack/packages/ml/date_picker/src/services/full_time_range_selector_service.test.ts b/x-pack/packages/ml/date_picker/src/services/full_time_range_selector_service.test.ts index c38357d77dbc7b..285bae4fd199bc 100644 --- a/x-pack/packages/ml/date_picker/src/services/full_time_range_selector_service.test.ts +++ b/x-pack/packages/ml/date_picker/src/services/full_time_range_selector_service.test.ts @@ -20,7 +20,11 @@ import { getTimeFieldRange } from './time_field_range'; const mockParamsFactory = () => ({ timefilter: { setTime: jest.fn() } as unknown as TimefilterContract, dataView: { getIndexPattern: jest.fn(), getRuntimeMappings: jest.fn() } as unknown as DataView, - toasts: { addWarning: jest.fn(), addDanger: jest.fn() } as unknown as ToastsStart, + toasts: { + addWarning: jest.fn(), + addDanger: jest.fn(), + addError: jest.fn(), + } as unknown as ToastsStart, }); describe('setFullTimeRange', () => { diff --git a/x-pack/packages/ml/date_picker/src/services/full_time_range_selector_service.ts b/x-pack/packages/ml/date_picker/src/services/full_time_range_selector_service.ts index c4cdd23995ae77..6d824989c13e0e 100644 --- a/x-pack/packages/ml/date_picker/src/services/full_time_range_selector_service.ts +++ b/x-pack/packages/ml/date_picker/src/services/full_time_range_selector_service.ts @@ -81,14 +81,15 @@ export async function setFullTimeRange( }); } } catch (error) { - toasts.addDanger( - i18n.translate( + toasts.addError(error, { + title: i18n.translate( 'xpack.ml.datePicker.fullTimeRangeSelector.errorSettingTimeRangeNotification', { - defaultMessage: 'An error occurred setting the time range.', + defaultMessage: + 'An error occurred setting the time range. Please set the desired start and end times.', } - ) - ); + ), + }); } } diff --git a/x-pack/plugins/ml/public/alerting/ml_anomaly_alert_trigger.tsx b/x-pack/plugins/ml/public/alerting/ml_anomaly_alert_trigger.tsx index 3262fbd6cac7fc..45bf7b1ca613bb 100644 --- a/x-pack/plugins/ml/public/alerting/ml_anomaly_alert_trigger.tsx +++ b/x-pack/plugins/ml/public/alerting/ml_anomaly_alert_trigger.tsx @@ -16,6 +16,7 @@ import { JobSelectorControl } from './job_selector'; import { useMlKibana } from '../application/contexts/kibana'; import { jobsApiProvider } from '../application/services/ml_api_service/jobs'; import { HttpService } from '../application/services/http_service'; +import { useToastNotificationService } from '../application/services/toast_notification_service'; import { SeverityControl } from '../application/components/severity_control'; import { ResultTypeSelector } from './result_type_selector'; import { alertingApiProvider } from '../application/services/ml_api_service/alerting'; @@ -44,11 +45,11 @@ const MlAnomalyAlertTrigger: FC = ({ }) => { const { services: { http }, - notifications: { toasts }, } = useMlKibana(); const mlHttpService = useMemo(() => new HttpService(http), [http]); const adJobsApiService = useMemo(() => jobsApiProvider(mlHttpService), [mlHttpService]); const alertingApiService = useMemo(() => alertingApiProvider(mlHttpService), [mlHttpService]); + const { displayErrorToast } = useToastNotificationService(); const [jobConfigs, setJobConfigs] = useState([]); @@ -74,13 +75,13 @@ const MlAnomalyAlertTrigger: FC = ({ const jobs = await adJobsApiService.jobs(jobsAndGroupIds); setJobConfigs(jobs); } catch (e) { - toasts.danger({ - title: i18n.translate('xpack.ml.anomalyDetectionAlert.errorFetchingJobs', { + displayErrorToast( + e, + i18n.translate('xpack.ml.anomalyDetectionAlert.errorFetchingJobs', { defaultMessage: 'Unable to fetch jobs configuration', }), - body: e.message, - toastLifeTimeMs: 5000, - }); + 5000 + ); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [jobsAndGroupIds]); diff --git a/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/list.test.tsx b/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/list.test.tsx index 7f2bd05fe92087..f061dbb96f16fc 100644 --- a/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/list.test.tsx +++ b/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/list.test.tsx @@ -13,6 +13,14 @@ import { CustomUrlList, CustomUrlListProps } from './list'; jest.mock('../../../contexts/kibana'); +jest.mock('../../../services/toast_notification_service', () => ({ + useToastNotificationService: () => { + return { + displayErrorToast: jest.fn(), + }; + }, +})); + function prepareTest(setCustomUrlsFn: jest.Mock) { const customUrls = [ { diff --git a/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/list.tsx b/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/list.tsx index 3ee39cb6117648..a4de96f6626002 100644 --- a/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/list.tsx +++ b/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/list.tsx @@ -29,6 +29,7 @@ import { import { parseUrlState } from '@kbn/ml-url-state'; import { useMlKibana } from '../../../contexts/kibana'; +import { useToastNotificationService } from '../../../services/toast_notification_service'; import { isValidLabel, openCustomUrlWindow } from '../../../util/custom_url_utils'; import { getTestUrl } from './utils'; @@ -68,10 +69,10 @@ export const CustomUrlList: FC = ({ const { services: { http, - notifications, data: { dataViews }, }, } = useMlKibana(); + const { displayErrorToast } = useToastNotificationService(); const [expandedUrlIndex, setExpandedUrlIndex] = useState(null); const onLabelChange = (e: ChangeEvent, index: number) => { @@ -161,11 +162,8 @@ export const CustomUrlList: FC = ({ const testUrl = await getTestUrl(job, customUrl, timefieldName, undefined, isPartialDFAJob); openCustomUrlWindow(testUrl, customUrl, http.basePath.get()); } catch (error) { - // eslint-disable-next-line no-console - console.error('Error obtaining URL for test:', error); - - const { toasts } = notifications; - toasts.addDanger( + displayErrorToast( + error, i18n.translate( 'xpack.ml.customUrlEditorList.obtainingUrlToTestConfigurationErrorMessage', { diff --git a/x-pack/plugins/ml/public/application/components/custom_urls/custom_urls.tsx b/x-pack/plugins/ml/public/application/components/custom_urls/custom_urls.tsx index b020a87b36c1bd..c64f7f3ee28613 100644 --- a/x-pack/plugins/ml/public/application/components/custom_urls/custom_urls.tsx +++ b/x-pack/plugins/ml/public/application/components/custom_urls/custom_urls.tsx @@ -29,6 +29,10 @@ import type { DataViewListItem } from '@kbn/data-views-plugin/common'; import type { MlUrlConfig } from '@kbn/ml-anomaly-utils'; import { isDataFrameAnalyticsConfigs } from '@kbn/ml-data-frame-analytics-utils'; import type { DashboardService, DashboardItems } from '../../services/dashboard_service'; +import { + ToastNotificationService, + toastNotificationServiceProvider, +} from '../../services/toast_notification_service'; import type { MlKibanaReactContextValue } from '../../contexts/kibana'; import { CustomUrlEditor, CustomUrlList } from './custom_url_editor'; import { @@ -58,6 +62,8 @@ interface CustomUrlsProps extends CustomUrlsWrapperProps { } class CustomUrlsUI extends Component { + private toastNotificationService: ToastNotificationService | undefined; + constructor(props: CustomUrlsProps) { super(props); @@ -79,16 +85,17 @@ class CustomUrlsUI extends Component { componentDidMount() { const { toasts } = this.props.kibana.services.notifications; + this.toastNotificationService = toastNotificationServiceProvider(toasts); const { dashboardService } = this.props; + dashboardService .fetchDashboards() .then((dashboards) => { this.setState({ dashboards }); }) - .catch((resp) => { - // eslint-disable-next-line no-console - console.error('Error loading list of dashboards:', resp); - toasts.addDanger( + .catch((error) => { + this.toastNotificationService!.displayErrorToast( + error, i18n.translate( 'xpack.ml.jobsList.editJobFlyout.customUrls.loadSavedDashboardsErrorNotificationMessage', { @@ -102,10 +109,9 @@ class CustomUrlsUI extends Component { .then((dataViewListItems) => { this.setState({ dataViewListItems }); }) - .catch((resp) => { - // eslint-disable-next-line no-console - console.error('Error loading list of dashboards:', resp); - toasts.addDanger( + .catch((error) => { + this.toastNotificationService!.displayErrorToast( + error, i18n.translate( 'xpack.ml.jobsList.editJobFlyout.customUrls.loadDataViewsErrorNotificationMessage', { @@ -148,11 +154,9 @@ class CustomUrlsUI extends Component { this.props.setCustomUrls(customUrls); this.setState({ editorOpen: false }); }) - .catch((error: Error) => { - // eslint-disable-next-line no-console - console.error('Error building custom URL from settings:', error); - const { toasts } = this.props.kibana.services.notifications; - toasts.addDanger( + .catch((error) => { + this.toastNotificationService!.displayErrorToast( + error, i18n.translate( 'xpack.ml.jobsList.editJobFlyout.customUrls.addNewUrlErrorNotificationMessage', { @@ -167,7 +171,6 @@ class CustomUrlsUI extends Component { onTestButtonClick = () => { const { http: { basePath }, - notifications: { toasts }, data: { dataViews }, dashboard, } = this.props.kibana.services; @@ -194,10 +197,9 @@ class CustomUrlsUI extends Component { .then((testUrl) => { openCustomUrlWindow(testUrl, customUrl, basePath.get()); }) - .catch((resp) => { - // eslint-disable-next-line no-console - console.error('Error obtaining URL for test:', resp); - toasts.addWarning( + .catch((error) => { + this.toastNotificationService!.displayErrorToast( + error, i18n.translate( 'xpack.ml.jobsList.editJobFlyout.customUrls.getTestUrlErrorNotificationMessage', { @@ -210,10 +212,9 @@ class CustomUrlsUI extends Component { } ); }) - .catch((resp) => { - // eslint-disable-next-line no-console - console.error('Error building custom URL from settings:', resp); - toasts.addWarning( + .catch((error) => { + this.toastNotificationService!.displayErrorToast( + error, i18n.translate( 'xpack.ml.jobsList.editJobFlyout.customUrls.buildUrlErrorNotificationMessage', { diff --git a/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js b/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js index 907933ad290c3e..0e21de91dbbb9d 100644 --- a/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js +++ b/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js @@ -32,7 +32,6 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { withKibana } from '@kbn/kibana-react-plugin/public'; -import { extractErrorMessage } from '@kbn/ml-error-utils'; import { ML_DETECTOR_RULE_ACTION, ML_DETECTOR_RULE_CONDITIONS_NOT_SUPPORTED_FUNCTIONS, @@ -55,6 +54,7 @@ import { import { getPartitioningFieldNames } from '../../../../common/util/job_utils'; import { mlJobService } from '../../services/job_service'; +import { toastNotificationServiceProvider } from '../../services/toast_notification_service'; import { ml } from '../../services/ml_api_service'; class RuleEditorFlyoutUI extends Component { @@ -83,6 +83,9 @@ class RuleEditorFlyoutUI extends Component { } componentDidMount() { + this.toastNotificationService = toastNotificationServiceProvider( + this.props.kibana.services.notifications.toasts + ); if (typeof this.props.setShowFunction === 'function') { this.props.setShowFunction(this.showFlyout); } @@ -105,8 +108,7 @@ class RuleEditorFlyoutUI extends Component { i18n.translate( 'xpack.ml.ruleEditor.ruleEditorFlyout.unableToConfigureRulesNotificationMesssage', { - defaultMessage: - 'Unable to configure job rules as an error occurred obtaining details for job ID {jobId}', + defaultMessage: 'Unable to configure job rules as no job found with ID {jobId}', values: { jobId: anomaly.jobId }, } ) @@ -153,10 +155,9 @@ class RuleEditorFlyoutUI extends Component { filterListIds, }); }) - .catch((resp) => { - console.log('Error loading list of filters:', resp); - const { toasts } = this.props.kibana.services.notifications; - toasts.addDanger( + .catch((error) => { + this.toastNotificationService.displayErrorToast( + error, i18n.translate( 'xpack.ml.ruleEditor.ruleEditorFlyout.errorWithLoadingFilterListsNotificationMesssage', { @@ -374,8 +375,8 @@ class RuleEditorFlyoutUI extends Component { } }) .catch((error) => { - console.error(error); - toasts.addDanger( + this.toastNotificationService.displayErrorToast( + error, i18n.translate( 'xpack.ml.ruleEditor.ruleEditorFlyout.errorWithSavingChangesToJobDetectorRulesNotificationMessage', { @@ -426,18 +427,16 @@ class RuleEditorFlyoutUI extends Component { } }) .catch((error) => { - console.error(error); - let errorMessage = i18n.translate( - 'xpack.ml.ruleEditor.ruleEditorFlyout.errorWithDeletingRuleFromJobDetectorNotificationMessage', - { - defaultMessage: 'Error deleting rule from {jobId} detector', - values: { jobId }, - } + this.toastNotificationService.displayErrorToast( + error, + i18n.translate( + 'xpack.ml.ruleEditor.ruleEditorFlyout.errorWithDeletingRuleFromJobDetectorNotificationMessage', + { + defaultMessage: 'Error deleting rule from {jobId} detector', + values: { jobId }, + } + ) ); - if (error.error) { - errorMessage += ` : ${extractErrorMessage(error.error)}`; - } - toasts.addDanger(errorMessage); }); }; @@ -467,8 +466,8 @@ class RuleEditorFlyoutUI extends Component { } }) .catch((error) => { - console.log(`Error adding ${item} to filter ${filterId}:`, error); - toasts.addDanger( + this.toastNotificationService.displayErrorToast( + error, i18n.translate( 'xpack.ml.ruleEditor.ruleEditorFlyout.errorWithAddingItemToFilterListNotificationMessage', { diff --git a/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.test.js b/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.test.js index 290d815271dcce..67ace1427eb13e 100644 --- a/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.test.js +++ b/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.test.js @@ -93,6 +93,11 @@ function prepareTest() { }, }, }, + notifications: { + toasts: { + addDanger: () => {}, + }, + }, }, }, }; diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js index 840b34ca70cebb..ffa9e8eecf0eee 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js @@ -185,17 +185,19 @@ function showResults(resp, action) { } const toastNotifications = getToastNotifications(); - toastNotifications.addSuccess( - i18n.translate('xpack.ml.jobsList.actionExecuteSuccessfullyNotificationMessage', { - defaultMessage: - '{successesJobsCount, plural, one{{successJob}} other{# jobs}} {actionTextPT} successfully', - values: { - successesJobsCount: successes.length, - successJob: successes[0], - actionTextPT, - }, - }) - ); + if (successes.length > 0) { + toastNotifications.addSuccess( + i18n.translate('xpack.ml.jobsList.actionExecuteSuccessfullyNotificationMessage', { + defaultMessage: + '{successesJobsCount, plural, one{{successJob}} other{# jobs}} {actionTextPT} successfully', + values: { + successesJobsCount: successes.length, + successJob: successes[0], + actionTextPT, + }, + }) + ); + } if (failures.length > 0) { failures.forEach((f) => { diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.ts index 52d4d771062173..ebc8820e255661 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.ts @@ -123,7 +123,11 @@ export const useModelMemoryEstimator = ( title: i18n.translate('xpack.ml.newJob.wizard.estimateModelMemoryError', { defaultMessage: 'Model memory limit could not be calculated', }), - text: extractErrorMessage(error), + text: i18n.translate('xpack.ml.newJob.wizard.estimateModelMemoryErrorText', { + defaultMessage: + '{errorText}. You can proceed with creating the job, but check for warning messages once the job is running that the configured limit has not been exceeded.', + values: { errorText: extractErrorMessage(error) }, + }), }); }) ); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/time_range_step/time_range.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/time_range_step/time_range.tsx index d93eb690c31d9a..9849864811bc4c 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/time_range_step/time_range.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/time_range_step/time_range.tsx @@ -113,7 +113,8 @@ export const TimeRangeStep: FC = ({ setCurrentStep, isCurrentStep }) const { toasts } = services.notifications; toasts.addDanger( i18n.translate('xpack.ml.newJob.wizard.timeRangeStep.fullTimeRangeError', { - defaultMessage: 'An error occurred obtaining the time range for the index', + defaultMessage: + 'An error occurred obtaining the time range for the index. Please set the desired start and end times.', }) ); } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/recognize/page.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/recognize/page.tsx index fe2c5dfa966aaf..1feab0193d0871 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/recognize/page.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/recognize/page.tsx @@ -234,21 +234,22 @@ export const Page: FC = ({ moduleId, existingGroupIds }) => { ); } catch (e) { setSaveState(SAVE_STATE.FAILED); - // eslint-disable-next-line no-console - console.error('Error setting up module', e); const { toasts } = notifications; - toasts.addDanger({ + toasts.addError(e, { title: i18n.translate('xpack.ml.newJob.recognize.moduleSetupFailedWarningTitle', { defaultMessage: 'Error setting up module {moduleId}', values: { moduleId }, }), - text: i18n.translate('xpack.ml.newJob.recognize.moduleSetupFailedWarningDescription', { - defaultMessage: - 'An error occurred trying to create the {count, plural, one {job} other {jobs}} in the module.', - values: { - count: jobs.length, - }, - }), + toastMessage: i18n.translate( + 'xpack.ml.newJob.recognize.moduleSetupFailedWarningDescription', + { + defaultMessage: + 'An error occurred trying to create the {count, plural, one {job} other {jobs}} in the module.', + values: { + count: jobs.length, + }, + } + ), }); } }, diff --git a/x-pack/plugins/ml/public/application/memory_usage/memory_tree_map/tree_map.tsx b/x-pack/plugins/ml/public/application/memory_usage/memory_tree_map/tree_map.tsx index ebbae3fff924ff..e8851124e3399a 100644 --- a/x-pack/plugins/ml/public/application/memory_usage/memory_tree_map/tree_map.tsx +++ b/x-pack/plugins/ml/public/application/memory_usage/memory_tree_map/tree_map.tsx @@ -126,7 +126,7 @@ export const JobMemoryTreeMap: FC = ({ node, type, height }) => { displayErrorToast( error, i18n.translate('xpack.ml.memoryUsage.treeMap.fetchFailedErrorMessage', { - defaultMessage: 'Models memory usage fetch failed', + defaultMessage: 'Error loading model memory usage data', }) ); } diff --git a/x-pack/plugins/ml/public/application/memory_usage/nodes_overview/nodes_list.tsx b/x-pack/plugins/ml/public/application/memory_usage/nodes_overview/nodes_list.tsx index a8e5848aaef1a7..8c2bfa15a08913 100644 --- a/x-pack/plugins/ml/public/application/memory_usage/nodes_overview/nodes_list.tsx +++ b/x-pack/plugins/ml/public/application/memory_usage/nodes_overview/nodes_list.tsx @@ -84,7 +84,7 @@ export const NodesList: FC = ({ compactView = false }) => { displayErrorToast( e, i18n.translate('xpack.ml.trainedModels.nodesList.nodesFetchError', { - defaultMessage: 'Nodes fetch failed', + defaultMessage: 'Error loading overview on machine learning nodes', }) ); setIsLoading(false); diff --git a/x-pack/plugins/ml/public/application/model_management/models_list.tsx b/x-pack/plugins/ml/public/application/model_management/models_list.tsx index dd766d10c36d1a..a12d55cd22beda 100644 --- a/x-pack/plugins/ml/public/application/model_management/models_list.tsx +++ b/x-pack/plugins/ml/public/application/model_management/models_list.tsx @@ -305,7 +305,7 @@ export const ModelsList: FC = ({ displayErrorToast( error, i18n.translate('xpack.ml.trainedModels.modelsList.fetchFailedErrorMessage', { - defaultMessage: 'Models fetch failed', + defaultMessage: 'Error loading trained models', }) ); } @@ -383,7 +383,7 @@ export const ModelsList: FC = ({ displayErrorToast( error, i18n.translate('xpack.ml.trainedModels.modelsList.fetchModelStatsErrorMessage', { - defaultMessage: 'Fetch model stats failed', + defaultMessage: 'Error loading trained models statistics', }) ); return false; diff --git a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx index 850ce45fde123d..c603fcde74df1b 100644 --- a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx +++ b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx @@ -136,7 +136,7 @@ export const NotificationsList: FC = () => { displayErrorToast( error, i18n.translate('xpack.ml.notifications.fetchFailedError', { - defaultMessage: 'Fetch notifications failed', + defaultMessage: 'Error loading list of notifications', }) ); } diff --git a/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx b/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx index ff783fe2260af8..caf6a7674373a8 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx @@ -105,18 +105,16 @@ const CheckViewOrCreateWrapper: FC = ({ location }) => { } }) .catch(async (err: Error) => { - // eslint-disable-next-line no-console - console.error(`Error checking whether jobs in module ${moduleId} exists`, err); - toasts.addWarning({ + toasts.addError(err, { title: i18n.translate('xpack.ml.newJob.recognize.moduleCheckJobsExistWarningTitle', { defaultMessage: 'Error checking module {moduleId}', values: { moduleId }, }), - text: i18n.translate( + toastMessage: i18n.translate( 'xpack.ml.newJob.recognize.moduleCheckJobsExistWarningDescription', { defaultMessage: - 'An error occurred trying to check whether the jobs in the module have been created.', + 'An error occurred checking whether the jobs in the module have been created. Search the list for matching jobs or create new jobs.', } ), }); diff --git a/x-pack/plugins/ml/public/application/settings/anomaly_detection_settings.tsx b/x-pack/plugins/ml/public/application/settings/anomaly_detection_settings.tsx index 4a19bc96c8c677..17dea3ca3536fb 100644 --- a/x-pack/plugins/ml/public/application/settings/anomaly_detection_settings.tsx +++ b/x-pack/plugins/ml/public/application/settings/anomaly_detection_settings.tsx @@ -22,8 +22,8 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { AnomalyDetectionSettingsContext } from './anomaly_detection_settings_context'; -import { useNotifications } from '../contexts/kibana'; import { ml } from '../services/ml_api_service'; +import { useToastNotificationService } from '../services/toast_notification_service'; import { ML_PAGES } from '../../../common/constants/locator'; import { useCreateAndNavigateToMlLink } from '../contexts/kibana/use_create_url'; @@ -35,7 +35,7 @@ export const AnomalyDetectionSettings: FC = () => { AnomalyDetectionSettingsContext ); - const { toasts } = useNotifications(); + const { displayErrorToast } = useToastNotificationService(); const redirectToCalendarList = useCreateAndNavigateToMlLink(ML_PAGES.CALENDARS_MANAGE); const redirectToNewCalendarPage = useCreateAndNavigateToMlLink(ML_PAGES.CALENDARS_NEW); const redirectToFilterLists = useCreateAndNavigateToMlLink(ML_PAGES.FILTER_LISTS_MANAGE); @@ -53,7 +53,8 @@ export const AnomalyDetectionSettings: FC = () => { const calendars = await ml.calendars(); setCalendarsCount(calendars.length); } catch (e) { - toasts.addDanger( + displayErrorToast( + e, i18n.translate('xpack.ml.settings.anomalyDetection.loadingCalendarsCountErrorMessage', { defaultMessage: 'An error occurred obtaining the count of calendars', }) @@ -66,7 +67,8 @@ export const AnomalyDetectionSettings: FC = () => { const filterLists = await ml.filters.filtersStats(); setFilterListsCount(filterLists.length); } catch (e) { - toasts.addDanger( + displayErrorToast( + e, i18n.translate('xpack.ml.settings.anomalyDetection.loadingFilterListCountErrorMessage', { defaultMessage: 'An error occurred obtaining the count of filter lists', }) diff --git a/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.js b/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.js index ce1dfe7cd970fe..6375dfab798577 100644 --- a/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.js +++ b/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.js @@ -20,6 +20,7 @@ import { ml } from '../../../services/ml_api_service'; import { withKibana } from '@kbn/kibana-react-plugin/public'; import { GLOBAL_CALENDAR } from '../../../../../common/constants/calendars'; import { ML_PAGES } from '../../../../../common/constants/locator'; +import { toastNotificationServiceProvider } from '../../../services/toast_notification_service'; import { getDocLinks } from '../../../util/dependency_cache'; import { HelpMenu } from '../../../components/help_menu'; @@ -54,6 +55,9 @@ class NewCalendarUI extends Component { } componentDidMount() { + this.toastNotificationService = toastNotificationServiceProvider( + this.props.kibana.services.notifications.toasts + ); this.formSetup(); } @@ -118,10 +122,9 @@ class NewCalendarUI extends Component { isGlobalCalendar, }); } catch (error) { - console.log(error); this.setState({ loading: false }); - const { toasts } = this.props.kibana.services.notifications; - toasts.addDanger( + this.toastNotificationService.displayErrorToast( + error, i18n.translate('xpack.ml.calendarsEdit.errorWithLoadingCalendarFromDataErrorMessage', { defaultMessage: 'An error occurred loading calendar form data. Try refreshing the page.', }) @@ -160,10 +163,9 @@ class NewCalendarUI extends Component { await ml.addCalendar(calendar); await this.returnToCalendarsManagementPage(); } catch (error) { - console.log('Error saving calendar', error); this.setState({ saving: false }); - const { toasts } = this.props.kibana.services.notifications; - toasts.addDanger( + this.toastNotificationService.displayErrorToast( + error, i18n.translate('xpack.ml.calendarsEdit.errorWithCreatingCalendarErrorMessage', { defaultMessage: 'An error occurred creating calendar {calendarId}', values: { calendarId: calendar.calendarId }, @@ -181,10 +183,9 @@ class NewCalendarUI extends Component { await ml.updateCalendar(calendar); await this.returnToCalendarsManagementPage(); } catch (error) { - console.log('Error saving calendar', error); this.setState({ saving: false }); - const { toasts } = this.props.kibana.services.notifications; - toasts.addDanger( + this.toastNotificationService.displayErrorToast( + error, i18n.translate('xpack.ml.calendarsEdit.errorWithUpdatingCalendarErrorMessage', { defaultMessage: 'An error occurred saving calendar {calendarId}. Try refreshing the page.', diff --git a/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.test.js b/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.test.js index 299c1340e85995..4e9a16858f816d 100644 --- a/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.test.js +++ b/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.test.js @@ -117,6 +117,11 @@ const props = { }, }, }, + notifications: { + toasts: { + addDanger: () => {}, + }, + }, }, }, }; diff --git a/x-pack/plugins/ml/public/application/settings/calendars/list/calendars_list.js b/x-pack/plugins/ml/public/application/settings/calendars/list/calendars_list.js index a3bb900ca1ce23..27c6b4de8389cf 100644 --- a/x-pack/plugins/ml/public/application/settings/calendars/list/calendars_list.js +++ b/x-pack/plugins/ml/public/application/settings/calendars/list/calendars_list.js @@ -13,6 +13,7 @@ import { EuiConfirmModal, EUI_MODAL_CONFIRM_BUTTON } from '@elastic/eui'; import { CalendarsListHeader } from './header'; import { CalendarsListTable } from './table'; import { ml } from '../../../services/ml_api_service'; +import { toastNotificationServiceProvider } from '../../../services/toast_notification_service'; import { mlNodesAvailable } from '../../../ml_nodes_check/check_ml_nodes'; import { deleteCalendars } from './delete_calendars'; import { i18n } from '@kbn/i18n'; @@ -58,6 +59,13 @@ export class CalendarsListUI extends Component { defaultMessage: 'An error occurred loading the list of calendars.', }) ); + const toastNotificationService = toastNotificationServiceProvider(toasts); + toastNotificationService.displayErrorToast( + error, + i18n.translate('xpack.ml.calendarsList.errorWithLoadingListOfCalendarsErrorMessage', { + defaultMessage: 'An error occurred loading the list of calendars.', + }) + ); } }; diff --git a/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.js b/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.js index 1c6dc162f505f2..d05484a9d3b893 100644 --- a/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.js +++ b/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.js @@ -31,6 +31,7 @@ import { EditFilterListToolbar } from './toolbar'; import { ItemsGrid } from '../../../components/items_grid'; import { isValidFilterListId, saveFilterList } from './utils'; import { ml } from '../../../services/ml_api_service'; +import { toastNotificationServiceProvider } from '../../../services/toast_notification_service'; import { ML_PAGES } from '../../../../../common/constants/locator'; import { getDocLinks } from '../../../util/dependency_cache'; import { HelpMenu } from '../../../components/help_menu'; @@ -93,6 +94,9 @@ export class EditFilterListUI extends Component { } componentDidMount() { + this.toastNotificationService = toastNotificationServiceProvider( + this.props.kibana.services.notifications.toasts + ); const filterId = this.props.filterId; if (filterId !== undefined) { this.loadFilterList(filterId); @@ -117,10 +121,9 @@ export class EditFilterListUI extends Component { .then((filter) => { this.setLoadedFilterState(filter); }) - .catch((resp) => { - console.log(`Error loading filter ${filterId}:`, resp); - const { toasts } = this.props.kibana.services.notifications; - toasts.addDanger( + .catch((error) => { + this.toastNotificationService.displayErrorToast( + error, i18n.translate( 'xpack.ml.settings.filterLists.editFilterList.loadingDetailsOfFilterErrorMessage', { @@ -287,10 +290,9 @@ export class EditFilterListUI extends Component { this.setLoadedFilterState(savedFilter); this.returnToFiltersList(); }) - .catch((resp) => { - console.log(`Error saving filter ${filterId}:`, resp); - const { toasts } = this.props.kibana.services.notifications; - toasts.addDanger( + .catch((error) => { + this.toastNotificationService.displayErrorToast( + error, i18n.translate('xpack.ml.settings.filterLists.editFilterList.savingFilterErrorMessage', { defaultMessage: 'An error occurred saving filter {filterId}', values: { diff --git a/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.test.js b/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.test.js index 45c43e04daa683..e3e740f1f7d783 100644 --- a/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.test.js +++ b/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.test.js @@ -59,6 +59,15 @@ import { EditFilterList } from './edit_filter_list'; const props = { canCreateFilter: true, canDeleteFilter: true, + kibana: { + services: { + notifications: { + toasts: { + addWarning: () => {}, + }, + }, + }, + }, }; function prepareEditTest() { diff --git a/x-pack/plugins/ml/public/application/settings/filter_lists/list/filter_lists.js b/x-pack/plugins/ml/public/application/settings/filter_lists/list/filter_lists.js index 352856c6fcf51c..a55473a731322d 100644 --- a/x-pack/plugins/ml/public/application/settings/filter_lists/list/filter_lists.js +++ b/x-pack/plugins/ml/public/application/settings/filter_lists/list/filter_lists.js @@ -19,6 +19,7 @@ import { withKibana } from '@kbn/kibana-react-plugin/public'; import { FilterListsHeader } from './header'; import { FilterListsTable } from './table'; import { ml } from '../../../services/ml_api_service'; +import { toastNotificationServiceProvider } from '../../../services/toast_notification_service'; import { getDocLinks } from '../../../util/dependency_cache'; import { HelpMenu } from '../../../components/help_menu'; @@ -69,8 +70,8 @@ export class FilterListsUI extends Component { .then((filterLists) => { this.setFilterLists(filterLists); }) - .catch((resp) => { - console.log('Error loading list of filters:', resp); + .catch((error) => { + console.log('Error loading list of filters:', error); const { toasts } = this.props.kibana.services.notifications; toasts.addDanger( i18n.translate( @@ -80,6 +81,16 @@ export class FilterListsUI extends Component { } ) ); + const toastNotificationService = toastNotificationServiceProvider(toasts); + toastNotificationService.displayErrorToast( + error, + i18n.translate( + 'xpack.ml.settings.filterLists.filterLists.loadingFilterListsErrorMessage', + { + defaultMessage: 'An error occurred loading the filter lists', + } + ) + ); }); }; diff --git a/x-pack/plugins/ml/public/application/settings/settings.test.tsx b/x-pack/plugins/ml/public/application/settings/settings.test.tsx index ad3847e011371c..89ad2a965df916 100644 --- a/x-pack/plugins/ml/public/application/settings/settings.test.tsx +++ b/x-pack/plugins/ml/public/application/settings/settings.test.tsx @@ -18,7 +18,7 @@ jest.mock('../components/help_menu', () => ({ jest.mock('../contexts/kibana', () => ({ useNotifications: () => { return { - toasts: { addDanger: jest.fn() }, + toasts: { addDanger: jest.fn(), addError: jest.fn() }, }; }, useMlKibana: () => { From a47417c2aa82eecb64d9bc219be8d4ab9f8b60f3 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Wed, 20 Dec 2023 15:00:43 +0100 Subject: [PATCH 028/116] [Index management] Skip DSL cits (#173649) --- .../index_template_wizard/template_create.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx index 367437e5c5346e..2bd505b4fa7aa6 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx @@ -608,7 +608,7 @@ describe('', () => { }); }); - describe('DSL', () => { + describe.skip('DSL', () => { beforeEach(async () => { await act(async () => { testBed = await setup(httpSetup); From f82e83d7b8ae2f7d9c5d11d2ab84bae365b919e2 Mon Sep 17 00:00:00 2001 From: Thom Heymann <190132+thomheymann@users.noreply.github.com> Date: Wed, 20 Dec 2023 14:03:38 +0000 Subject: [PATCH 029/116] [Logs UI] Indicate when viewing a widget (embedded logs) in Logs Stream (#173480) Resolves #171103 ## Summary This PR adds an indication when viewing a widget (embedded logs) in Logs Stream. It also adds to ability to revert back to default Logs Stream view. ## Screenshot Logs stream app when viewing a widget (embedded logs): Screenshot 2023-12-19 at 22 40 53 Also moved warning callout on Settings page to the top so users know what settings apply to before making changes: Screenshot 2023-12-20 at 09 35 15 --- .../asset_details/hooks/use_data_views.ts | 11 +++ .../public/hooks/use_log_view_reference.ts | 11 ++- .../logs/settings/inline_log_view_callout.tsx | 22 +++-- .../source_configuration_settings.tsx | 92 +++++++++---------- .../components/stream_page_template.tsx | 84 ++++++++++++++--- .../components/tabs/logs/logs_tab_content.tsx | 4 + .../translations/translations/fr-FR.json | 5 +- .../translations/translations/ja-JP.json | 5 +- .../translations/translations/zh-CN.json | 5 +- 9 files changed, 153 insertions(+), 86 deletions(-) diff --git a/x-pack/plugins/infra/public/components/asset_details/hooks/use_data_views.ts b/x-pack/plugins/infra/public/components/asset_details/hooks/use_data_views.ts index ec299be484f2d4..d8883b9c2079aa 100644 --- a/x-pack/plugins/infra/public/components/asset_details/hooks/use_data_views.ts +++ b/x-pack/plugins/infra/public/components/asset_details/hooks/use_data_views.ts @@ -7,10 +7,14 @@ import useAsync from 'react-use/lib/useAsync'; import createContainer from 'constate'; +import { i18n } from '@kbn/i18n'; +import { findInventoryModel } from '@kbn/metrics-data-access-plugin/common'; import { useLogViewReference } from '../../../hooks/use_log_view_reference'; import { useDataMetricsAdHocDataView } from '../../../hooks/use_metrics_adhoc_data_view'; +import { useAssetDetailsRenderPropsContext } from './use_asset_details_render_props'; const useDataViews = ({ metricAlias }: { metricAlias: string }) => { + const { asset } = useAssetDetailsRenderPropsContext(); const { dataView: metricsDataView, loading: metricsDataViewLoading } = useDataMetricsAdHocDataView({ metricAlias }); const { @@ -19,6 +23,13 @@ const useDataViews = ({ metricAlias }: { metricAlias: string }) => { loading: logsReferenceLoading, } = useLogViewReference({ id: 'asset-details-logs-view', + name: i18n.translate('xpack.infra.hostsViewPage.tabs.logs.assetLogsWidgetName', { + defaultMessage: 'Logs from {type} "{name}"', + values: { + name: asset.name, + type: findInventoryModel(asset.type).singularDisplayName, + }, + }), }); const { value: logsDataView, loading: logsDataViewLoading } = useAsync( diff --git a/x-pack/plugins/infra/public/hooks/use_log_view_reference.ts b/x-pack/plugins/infra/public/hooks/use_log_view_reference.ts index d8c063767a8d18..56ba82b6973385 100644 --- a/x-pack/plugins/infra/public/hooks/use_log_view_reference.ts +++ b/x-pack/plugins/infra/public/hooks/use_log_view_reference.ts @@ -14,9 +14,14 @@ import { useKibanaContextForPlugin } from './use_kibana'; interface Props { id: string; + /** + * Human readable name of log view. + * Will be displayed as the page title when navigating to "View in Logs". + * */ + name: string; extraFields?: string[]; } -export const useLogViewReference = ({ id, extraFields = [] }: Props) => { +export const useLogViewReference = ({ id, name, extraFields = [] }: Props) => { const { services: { logsShared }, } = useKibanaContextForPlugin(); @@ -33,8 +38,8 @@ export const useLogViewReference = ({ id, extraFields = [] }: Props) => { type: 'log-view-inline', id, attributes: { - name: 'Hosts Logs View', - description: 'Default view for hosts logs tab', + name, + description: '', logIndices: defaultLogView.attributes.logIndices, logColumns: [ { diff --git a/x-pack/plugins/infra/public/pages/logs/settings/inline_log_view_callout.tsx b/x-pack/plugins/infra/public/pages/logs/settings/inline_log_view_callout.tsx index ed332f97ea471b..d3db5745284903 100644 --- a/x-pack/plugins/infra/public/pages/logs/settings/inline_log_view_callout.tsx +++ b/x-pack/plugins/infra/public/pages/logs/settings/inline_log_view_callout.tsx @@ -7,7 +7,6 @@ import { EuiButton } from '@elastic/eui'; import { EuiCallOut } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -19,26 +18,29 @@ export const InlineLogViewCallout = ({ return ( + } > <>

- {i18n.translate('xpack.infra.logs.settings.inlineLogViewCalloutDescription', { - defaultMessage: - 'An inline Log View is currently being used, changes will be synchronized to the URL, but they will not be persisted.', - })} +

diff --git a/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx b/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx index 482a2fe48dd004..557fe1cfab3146 100644 --- a/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx +++ b/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx @@ -101,6 +101,14 @@ export const LogsSettingsPage = () => { + {isInlineLogView && ( + + + + + + + )} { isLoading fill > - Loading + {i18n.translate('xpack.infra.logsSettingsPage.loadingButtonLabel', { + defaultMessage: 'Loading', + })}
) : ( - <> - {isInlineLogView && ( - - - - - - - )} - - - { - sourceConfigurationFormElement.resetValue(); - }} - > - - - - - - - - - - + + + { + sourceConfigurationFormElement.resetValue(); + }} + > + + + + + + + + + )} )} diff --git a/x-pack/plugins/infra/public/pages/logs/stream/components/stream_page_template.tsx b/x-pack/plugins/infra/public/pages/logs/stream/components/stream_page_template.tsx index fb9c26676d01c8..5ea865351ef385 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/components/stream_page_template.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/components/stream_page_template.tsx @@ -8,24 +8,78 @@ import { APP_WRAPPER_CLASS } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; import React from 'react'; +import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiBadge, EuiToolTip } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; import { fullHeightContentStyles } from '../../../../page_template.styles'; import { LogsPageTemplate, LogsPageTemplateProps } from '../../shared/page_template'; -export const LogStreamPageTemplate: React.FC = React.memo((props) => ( -
- -
-)); +export const LogStreamPageTemplate: React.FC = (props) => { + const { logView, isInlineLogView, revertToDefaultLogView } = useLogViewContext(); + return ( +
+ + {logView.attributes.name} + + + } + > + + + + + + + ) : ( + streamTitle + ), + breadcrumbs: isInlineLogView + ? [ + { + text: ( + + + + + + + + + ), + color: 'primary', + 'aria-current': false, + 'data-test-subj': 'infraAssetDetailsReturnButton', + href: '#', + onClick: revertToDefaultLogView, + }, + ] + : undefined, + }} + pageSectionProps={{ + contentProps: { + css: fullHeightContentStyles, + }, + }} + {...props} + /> +
+ ); +}; const streamTitle = i18n.translate('xpack.infra.logs.streamPageTitle', { defaultMessage: 'Stream', diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx index 331cc35722998c..c977c1fde37a99 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx @@ -9,6 +9,7 @@ import React, { useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { LogStream } from '@kbn/logs-shared-plugin/public'; +import { i18n } from '@kbn/i18n'; import { InfraLoadingPanel } from '../../../../../../components/loading'; import { useHostsViewContext } from '../../../hooks/use_hosts_view'; import { useUnifiedSearchContext } from '../../../hooks/use_unified_search'; @@ -35,6 +36,9 @@ export const LogsTabContent = () => { const { logViewReference: logView, loading: logViewLoading } = useLogViewReference({ id: 'hosts-logs-view', + name: i18n.translate('xpack.infra.hostsViewPage.tabs.logs.LogsByHostWidgetName', { + defaultMessage: 'Logs by host', + }), extraFields: ['host.name'], }); diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 00510fafcbb58a..99be3d9af29237 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -20415,9 +20415,6 @@ "xpack.infra.logs.search.previousButtonLabel": "Précédent", "xpack.infra.logs.search.searchInLogsAriaLabel": "rechercher", "xpack.infra.logs.search.searchInLogsPlaceholder": "Recherche", - "xpack.infra.logs.settings.inlineLogViewCalloutButtonText": "Revenir à la vue de log (persistante) par défaut", - "xpack.infra.logs.settings.inlineLogViewCalloutDescription": "Une vue de log en ligne est actuellement utilisée. Les modifications seront synchronisées avec l'URL, mais elles ne seront pas conservées.", - "xpack.infra.logs.settings.inlineLogViewCalloutTitle": "Vue de log en ligne utilisée", "xpack.infra.logs.startStreamingButtonLabel": "Diffuser en direct", "xpack.infra.logs.stopStreamingButtonLabel": "Arrêter la diffusion", "xpack.infra.logs.streamPageTitle": "Flux", @@ -43295,4 +43292,4 @@ "xpack.serverlessObservability.nav.projectSettings": "Paramètres de projet", "xpack.serverlessObservability.nav.visualizations": "Visualisations" } -} +} \ No newline at end of file diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 8d313440282b55..cf450dbeeb29c9 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -20428,9 +20428,6 @@ "xpack.infra.logs.search.previousButtonLabel": "前へ", "xpack.infra.logs.search.searchInLogsAriaLabel": "検索", "xpack.infra.logs.search.searchInLogsPlaceholder": "検索", - "xpack.infra.logs.settings.inlineLogViewCalloutButtonText": "デフォルト(永続)ログビューに戻す", - "xpack.infra.logs.settings.inlineLogViewCalloutDescription": "現在インラインログビューが使用されています。変更はURLと同期されますが、永続しません。", - "xpack.infra.logs.settings.inlineLogViewCalloutTitle": "使用中のインラインログビュー", "xpack.infra.logs.startStreamingButtonLabel": "ライブストリーム", "xpack.infra.logs.stopStreamingButtonLabel": "ストリーム停止", "xpack.infra.logs.streamPageTitle": "ストリーム", @@ -43286,4 +43283,4 @@ "xpack.serverlessObservability.nav.projectSettings": "プロジェクト設定", "xpack.serverlessObservability.nav.visualizations": "ビジュアライゼーション" } -} +} \ No newline at end of file diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 3cd194aabd49e3..9cabcd3ccab48f 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -20428,9 +20428,6 @@ "xpack.infra.logs.search.previousButtonLabel": "上一页", "xpack.infra.logs.search.searchInLogsAriaLabel": "搜索", "xpack.infra.logs.search.searchInLogsPlaceholder": "搜索", - "xpack.infra.logs.settings.inlineLogViewCalloutButtonText": "恢复到默认(持久化)日志视图", - "xpack.infra.logs.settings.inlineLogViewCalloutDescription": "当前正使用内联日志视图,更改将同步到该 URL,但它们无法持久。", - "xpack.infra.logs.settings.inlineLogViewCalloutTitle": "正使用内联日志视图", "xpack.infra.logs.startStreamingButtonLabel": "实时流式传输", "xpack.infra.logs.stopStreamingButtonLabel": "停止流式传输", "xpack.infra.logs.streamPageTitle": "流式传输", @@ -43279,4 +43276,4 @@ "xpack.serverlessObservability.nav.projectSettings": "项目设置", "xpack.serverlessObservability.nav.visualizations": "可视化" } -} +} \ No newline at end of file From c3b3194ea06bc5e22b6da798b814cab812cd01e1 Mon Sep 17 00:00:00 2001 From: Dan Panzarella Date: Wed, 20 Dec 2023 09:05:43 -0500 Subject: [PATCH 030/116] [Security Solution] Disable package v2 detection for now (#173686) --- .../common/endpoint/utils/package_v2.ts | 17 ++++++++++------- .../e2e/artifacts/artifacts_mocked_data.cy.ts | 2 +- .../apps/endpoint/endpoint_list.ts | 2 +- .../apps/integrations/policy_details.ts | 2 +- .../apis/endpoint_response_actions/execute.ts | 2 +- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/security_solution/common/endpoint/utils/package_v2.ts b/x-pack/plugins/security_solution/common/endpoint/utils/package_v2.ts index fffa55ccbe5149..5aec9e894ad8bc 100644 --- a/x-pack/plugins/security_solution/common/endpoint/utils/package_v2.ts +++ b/x-pack/plugins/security_solution/common/endpoint/utils/package_v2.ts @@ -5,14 +5,17 @@ * 2.0. */ -import semverLte from 'semver/functions/lte'; +// import semverLte from 'semver/functions/lte'; -function parseSemver(semver: string) { - return semver.includes('-') ? semver.substring(0, semver.indexOf('-')) : semver; -} +// function parseSemver(semver: string) { +// return semver.includes('-') ? semver.substring(0, semver.indexOf('-')) : semver; +// } -const MIN_ENDPOINT_PACKAGE_V2_VERSION = '8.13.0'; +// until a release is confirmed, or another feature-detection method is used, do not automatically +// switch to "v2" logic +// const MIN_ENDPOINT_PACKAGE_V2_VERSION = '8.13.0'; export function isEndpointPackageV2(version: string) { - const parsedVersion = parseSemver(version); - return semverLte(MIN_ENDPOINT_PACKAGE_V2_VERSION, parsedVersion); + // const parsedVersion = parseSemver(version); + // return semverLte(MIN_ENDPOINT_PACKAGE_V2_VERSION, parsedVersion); + return false; } diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/artifacts_mocked_data.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/artifacts_mocked_data.cy.ts index 55a1035ca89693..8d21ff38043640 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/artifacts_mocked_data.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/artifacts_mocked_data.cy.ts @@ -32,7 +32,7 @@ const loginWithoutAccess = (url: string) => { }; // Flaky: https://github.com/elastic/kibana/issues/171168 -describe.skip('Artifacts pages', { tags: ['@ess', '@serverless'] }, () => { +describe('Artifacts pages', { tags: ['@ess', '@serverless'] }, () => { let endpointData: ReturnTypeFromChainable | undefined; before(() => { diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts index e4d9b91e579b7e..6f9c89bd8c930c 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts @@ -87,7 +87,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { // FLAKY: https://github.com/elastic/kibana/issues/170357 // FLAKY: https://github.com/elastic/kibana/issues/173670 - describe.skip('endpoint list', function () { + describe('endpoint list', function () { targetTags(this, ['@ess', '@serverless']); let indexedData: IndexedHostsAndAlertsResponse; diff --git a/x-pack/test/security_solution_endpoint/apps/integrations/policy_details.ts b/x-pack/test/security_solution_endpoint/apps/integrations/policy_details.ts index a2b1feaabd7cd3..f4d587daf64f14 100644 --- a/x-pack/test/security_solution_endpoint/apps/integrations/policy_details.ts +++ b/x-pack/test/security_solution_endpoint/apps/integrations/policy_details.ts @@ -30,7 +30,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { // FLAKY: https://github.com/elastic/kibana/issues/171653 // FLAKY: https://github.com/elastic/kibana/issues/171654 - describe.skip('When on the Endpoint Policy Details Page', function () { + describe('When on the Endpoint Policy Details Page', function () { targetTags(this, ['@ess', '@serverless']); let indexedData: IndexedHostsAndAlertsResponse; diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/endpoint_response_actions/execute.ts b/x-pack/test/security_solution_endpoint_api_int/apis/endpoint_response_actions/execute.ts index 401ff25fee6209..341f874e8e3305 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/endpoint_response_actions/execute.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/endpoint_response_actions/execute.ts @@ -18,7 +18,7 @@ export default function ({ getService }: FtrProviderContext) { // FLAKY: https://github.com/elastic/kibana/issues/171666 // FLAKY: https://github.com/elastic/kibana/issues/171667 - describe.skip('Endpoint `execute` response action', function () { + describe('Endpoint `execute` response action', function () { targetTags(this, ['@ess', '@serverless']); let indexedData: IndexedHostsAndAlertsResponse; From 9d1feb5febfc5c4192d2ab11bf17555971e17195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20G=C3=BCrkan=20YALAMAN?= Date: Wed, 20 Dec 2023 15:20:46 +0100 Subject: [PATCH 031/116] [Enterprise Search]Fix cursor jumping form inputs. (#173659) ## Summary Moved all inputs to separate components with internal inner values. https://github.com/elastic/kibana/assets/1410658/2155049d-d6bc-4c28-8ddb-0201af080a9d ### Checklist Delete any items that are not applicable to this PR. - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../connector_configuration_field.tsx | 192 ++++++++++++------ 1 file changed, 128 insertions(+), 64 deletions(-) diff --git a/packages/kbn-search-connectors/components/configuration/connector_configuration_field.tsx b/packages/kbn-search-connectors/components/configuration/connector_configuration_field.tsx index 01950617511a47..cb9108a783fdb2 100644 --- a/packages/kbn-search-connectors/components/configuration/connector_configuration_field.tsx +++ b/packages/kbn-search-connectors/components/configuration/connector_configuration_field.tsx @@ -41,6 +41,109 @@ interface ConnectorConfigurationFieldProps { setConfigValue: (value: number | string | boolean | null) => void; } +interface ConfigInputFieldProps { + configEntry: ConfigEntryView; + isLoading: boolean; + validateAndSetConfigValue: (value: string) => void; +} +export const ConfigInputField: React.FC = ({ + configEntry, + isLoading, + validateAndSetConfigValue, +}) => { + const { isValid, required, placeholder, value } = configEntry; + const [innerValue, setInnerValue] = useState(value); + return ( + { + setInnerValue(event.target.value); + validateAndSetConfigValue(event.target.value); + }} + placeholder={placeholder} + /> + ); +}; + +export const ConfigInputTextArea: React.FC = ({ + isLoading, + configEntry, + validateAndSetConfigValue, +}) => { + const { isValid, required, placeholder, value } = configEntry; + const [innerValue, setInnerValue] = useState(value); + return ( + { + setInnerValue(event.target.value); + validateAndSetConfigValue(event.target.value); + }} + placeholder={placeholder} + /> + ); +}; + +export const ConfigSensitiveTextArea: React.FC = ({ + isLoading, + configEntry, + validateAndSetConfigValue, +}) => { + const { key, label, tooltip } = configEntry; + return ( + + +

{label}

+
+ + + +
+ ) : ( +

{label}

+ ) + } + > + + + ); +}; +export const ConfigInputPassword: React.FC = ({ + isLoading, + configEntry, + validateAndSetConfigValue, +}) => { + const { required, value } = configEntry; + const [innerValue, setInnerValue] = useState(value); + return ( + { + setInnerValue(event.target.value); + validateAndSetConfigValue(event.target.value); + }} + /> + ); +}; + export const ConnectorConfigurationField: React.FC = ({ configEntry, isLoading, @@ -53,18 +156,7 @@ export const ConnectorConfigurationField: React.FC { - validateAndSetConfigValue(event.target.value); - }} - placeholder={placeholder} + ); case DisplayType.TEXTAREA: const textarea = ( - { - validateAndSetConfigValue(event.target.value); - }} + ); return sensitive ? ( - - -

{label}

-
- - - -
- ) : ( -

{label}

- ) - } - > - {textarea} - + ) : ( textarea ); @@ -210,24 +281,17 @@ export const ConnectorConfigurationField: React.FC { - validateAndSetConfigValue(event.target.value); - }} + ) : ( - { - validateAndSetConfigValue(event.target.value); - }} + ); } From 891d79b9e7bbdab31a7f0df8f8ccd10f87fcf1c2 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 20 Dec 2023 14:44:33 +0000 Subject: [PATCH 032/116] fix(NA): skip plugin-helpers assets optimization when no ui (#173703) This fixes a bug where the asset optimization script will try to run even when we don't have any ui plugin generated. --- .../kbn-plugin-helpers/src/tasks/brotli_compress_bundles.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/kbn-plugin-helpers/src/tasks/brotli_compress_bundles.ts b/packages/kbn-plugin-helpers/src/tasks/brotli_compress_bundles.ts index f04d707b279e99..ef03cb86c7aa09 100644 --- a/packages/kbn-plugin-helpers/src/tasks/brotli_compress_bundles.ts +++ b/packages/kbn-plugin-helpers/src/tasks/brotli_compress_bundles.ts @@ -20,7 +20,11 @@ import { TaskContext } from '../task_context'; const asyncPipeline = promisify(pipeline); -export async function brotliCompressBundles({ buildDir, log }: TaskContext) { +export async function brotliCompressBundles({ buildDir, log, plugin }: TaskContext) { + if (!plugin.manifest.ui) { + return; + } + const compressDir = Path.resolve(buildDir, 'target/public'); log.info( From 3d76e3932e5816395737905ce4585f2c920086f4 Mon Sep 17 00:00:00 2001 From: Achyut Jhunjhunwala Date: Wed, 20 Dec 2023 15:50:30 +0100 Subject: [PATCH 033/116] [APM UI] Add option to pass number of services to a scenario (#173737) ## Summary This PR adds an option to pass number of services to the scenario running `many_services` as running 500 services on the CI causes it to fail With this change, the scenario can now be run like this ``` node scripts/synthtrace many_services.ts --scenarioOpts.services=2 ``` --- packages/kbn-apm-synthtrace/src/scenarios/many_services.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/kbn-apm-synthtrace/src/scenarios/many_services.ts b/packages/kbn-apm-synthtrace/src/scenarios/many_services.ts index 705d425d8d9321..68a5432f1a29a9 100644 --- a/packages/kbn-apm-synthtrace/src/scenarios/many_services.ts +++ b/packages/kbn-apm-synthtrace/src/scenarios/many_services.ts @@ -14,8 +14,8 @@ import { withClient } from '../lib/utils/with_client'; const ENVIRONMENT = getSynthtraceEnvironment(__filename); -const scenario: Scenario = async ({ logger }) => { - const numServices = 500; +const scenario: Scenario = async ({ logger, scenarioOpts = { services: 500 } }) => { + const numServices = scenarioOpts.services; const languages = ['go', 'dotnet', 'java', 'python']; const services = ['web', 'order-processing', 'api-backend', 'proxy']; const agentVersions: Record = { From bada436def0188812f759e9b0ec27106afd03a5b Mon Sep 17 00:00:00 2001 From: Luke G <11671118+lgestc@users.noreply.github.com> Date: Wed, 20 Dec 2023 16:08:56 +0100 Subject: [PATCH 034/116] [Security Solution] Fix flaky timeline pagination tests (#173531) ## Summary Fixes https://github.com/elastic/kibana/issues/169413 https://github.com/elastic/kibana/issues/169619 and colocates related tests cases. Flaky TR pipeline: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4614 --- .../investigations/timelines/pagination.cy.ts | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/pagination.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/pagination.cy.ts index dcf847224067af..4c64f23167578b 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/pagination.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/pagination.cy.ts @@ -24,39 +24,34 @@ import { hostsUrl } from '../../../urls/navigation'; // Flaky on serverless const defaultPageSize = 25; -// FLAKY: https://github.com/elastic/kibana/issues/169413 -describe.skip('Pagination', { tags: ['@ess', '@serverless'] }, () => { - before(() => { - cy.task('esArchiverLoad', { archiveName: 'timeline' }); - }); +describe('Timeline Pagination', { tags: ['@ess', '@serverless'] }, () => { beforeEach(() => { + cy.task('esArchiverLoad', { archiveName: 'timeline' }); login(); visitWithTimeRange(hostsUrl('allHosts')); openTimelineUsingToggle(); populateTimeline(); }); - after(() => { + afterEach(() => { cy.task('esArchiverUnload', 'timeline'); }); - it(`should have ${defaultPageSize} events in the page by default`, () => { + it(`should paginate records correctly`, () => { + // should have ${defaultPageSize} events in the page by default cy.get(TIMELINE_EVENT).should('have.length', defaultPageSize); - }); - it('should be able to go to next / previous page', () => { + // should be able to go to next / previous page cy.get(`${TIMELINE_FLYOUT} ${TIMELINE_EVENTS_COUNT_NEXT_PAGE}`).first().click(); cy.get(`${TIMELINE_FLYOUT} ${TIMELINE_EVENTS_COUNT_PREV_PAGE}`).first().click(); - }); - it(`should select ${defaultPageSize} items per page by default`, () => { + // should select ${defaultPageSize} items per page by default cy.get(TIMELINE_EVENTS_COUNT_PER_PAGE).should('contain.text', defaultPageSize); - }); - it('should be able to change items count per page with the dropdown', () => { + // should be able to change items count per page with the dropdown const itemsPerPage = 100; - cy.get(TIMELINE_EVENTS_COUNT_PER_PAGE_BTN).first().click({ force: true }); + cy.get(TIMELINE_EVENTS_COUNT_PER_PAGE_BTN).first().click(); cy.get(TIMELINE_EVENTS_COUNT_PER_PAGE_OPTION(itemsPerPage)).click(); cy.get(TIMELINE_EVENTS_COUNT_PER_PAGE).should('not.have.text', '0'); cy.get(TIMELINE_EVENTS_COUNT_PER_PAGE) From cdb10478ce1270e8ce0ec37ddff98888e92f0af7 Mon Sep 17 00:00:00 2001 From: Georgii Gorbachev Date: Wed, 20 Dec 2023 16:18:21 +0100 Subject: [PATCH 035/116] [Security Solution] Skip flaky Rule Management tests (#173730) **Resolves: https://github.com/elastic/kibana/issues/173469** ## Summary This PR: - Skips flaky Rule Management tests that occurred recently and haven't been already skipped by Kibana Operations. - Adds `TODO` comments with links to the corresponding tickets. We will be working on fixing and unskipping these and a few other tests in January as part of https://github.com/elastic/kibana/issues/173731. --- .../prebuilt_rules/management/fleet_integration.ts | 3 ++- .../rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/prebuilt_rules/management/fleet_integration.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/prebuilt_rules/management/fleet_integration.ts index 0eff0a25c2cb82..5453ff5b34c773 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/prebuilt_rules/management/fleet_integration.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/prebuilt_rules/management/fleet_integration.ts @@ -33,7 +33,8 @@ export default ({ getService }: FtrProviderContext): void => { * Unlike other tests that use mocks, this test uses actual rules from the * package storage and checks that they are installed. */ - it('should install prebuilt rules from the package storage', async () => { + // TODO: Fix and unskip https://github.com/elastic/kibana/issues/172107 + it.skip('should install prebuilt rules from the package storage', async () => { // Verify that status is empty before package installation const statusBeforePackageInstallation = await getPrebuiltRulesAndTimelinesStatus(supertest); expect(statusBeforePackageInstallation.rules_installed).toBe(0); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts index 9a4d3cdc1b1d4e..f6df3e59bab932 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts @@ -74,6 +74,7 @@ const ruleNameToAssert = 'Custom rule name with actions'; const expectedExistingSlackMessage = 'Existing slack action'; const expectedSlackMessage = 'Slack action test message'; +// TODO: Fix and unskip in Serverless https://github.com/elastic/kibana/issues/171101 describe( 'Detection rules, bulk edit of rule actions', { tags: ['@ess', '@serverless', '@brokenInServerless', '@brokenInServerlessQA'] }, From 0503b820dee2fed2f59c6091a7000748e3dfb2d7 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 20 Dec 2023 17:19:48 +0200 Subject: [PATCH 036/116] [ES|QL] Creates charts from the dashboard (#171973) ## Summary Closes https://github.com/elastic/kibana/issues/165928 Enables the creation of ES|QL charts from the dashboard. ![esql](https://github.com/elastic/kibana/assets/17003240/86dd5594-d130-4fb7-b495-29ddbaee5e5b) The implementation is using UIActions which I think is the correct way to register a new panel action to a dashboard. Lens is responsible to register the ESQL panel action and owns the code. ### How it works - A new ES|QL panel has been added to the dashboard toolbar registered by a ui action - A new panel is been created with a default esql query `from | limit 10` - This results to a datatable and opens the flyout - If a user clicks cancel then the embeddable is being removed ### Checklist - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../add_panel_action_menu_items.test.ts | 40 ++++++ .../top_nav/add_panel_action_menu_items.ts | 52 +++++++ .../top_nav/dashboard_editing_toolbar.tsx | 48 +++++-- .../dashboard_app/top_nav/editor_menu.tsx | 48 ++++++- src/plugins/dashboard/public/plugin.tsx | 15 ++- .../public/services/plugin_services.stub.ts | 2 + .../public/services/plugin_services.ts | 2 + .../dashboard/public/services/types.ts | 2 + .../public/services/ui_actions/types.ts | 13 ++ .../ui_actions/ui_actions_service.stub.ts | 17 +++ .../services/ui_actions/ui_actions_service.ts | 25 ++++ .../dashboard/public/triggers/index.ts | 20 +++ .../dashboard/group6/dashboard_esql_chart.ts | 73 ++++++++++ .../functional/apps/dashboard/group6/index.ts | 1 + .../services/dashboard/add_panel.ts | 4 + .../shared/edit_on_the_fly/flyout_wrapper.tsx | 18 ++- .../get_edit_lens_configuration.tsx | 4 + .../lens_configuration_flyout.test.tsx | 10 ++ .../lens_configuration_flyout.tsx | 15 ++- .../shared/edit_on_the_fly/types.ts | 5 + x-pack/plugins/lens/public/async_services.ts | 3 +- .../lens/public/embeddable/embeddable.tsx | 8 +- x-pack/plugins/lens/public/plugin.ts | 10 +- .../open_lens_config/create_action.test.tsx | 41 ++++++ .../open_lens_config/create_action.tsx | 67 +++++++++ .../open_lens_config/create_action_helpers.ts | 127 ++++++++++++++++++ .../{action.test.tsx => edit_action.test.tsx} | 2 +- .../{action.tsx => edit_action.tsx} | 8 +- .../{helpers.ts => edit_action_helpers.ts} | 17 ++- 29 files changed, 663 insertions(+), 34 deletions(-) create mode 100644 src/plugins/dashboard/public/dashboard_app/top_nav/add_panel_action_menu_items.test.ts create mode 100644 src/plugins/dashboard/public/dashboard_app/top_nav/add_panel_action_menu_items.ts create mode 100644 src/plugins/dashboard/public/services/ui_actions/types.ts create mode 100644 src/plugins/dashboard/public/services/ui_actions/ui_actions_service.stub.ts create mode 100644 src/plugins/dashboard/public/services/ui_actions/ui_actions_service.ts create mode 100644 src/plugins/dashboard/public/triggers/index.ts create mode 100644 test/functional/apps/dashboard/group6/dashboard_esql_chart.ts create mode 100644 x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action.test.tsx create mode 100644 x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action.tsx create mode 100644 x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts rename x-pack/plugins/lens/public/trigger_actions/open_lens_config/{action.test.tsx => edit_action.test.tsx} (98%) rename x-pack/plugins/lens/public/trigger_actions/open_lens_config/{action.tsx => edit_action.tsx} (88%) rename x-pack/plugins/lens/public/trigger_actions/open_lens_config/{helpers.ts => edit_action_helpers.ts} (85%) diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/add_panel_action_menu_items.test.ts b/src/plugins/dashboard/public/dashboard_app/top_nav/add_panel_action_menu_items.test.ts new file mode 100644 index 00000000000000..024a7518aba0c1 --- /dev/null +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/add_panel_action_menu_items.test.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { getAddPanelActionMenuItems } from './add_panel_action_menu_items'; + +describe('getAddPanelActionMenuItems', () => { + it('returns the items correctly', async () => { + const registeredActions = [ + { + id: 'ACTION_CREATE_ESQL_CHART', + type: 'ACTION_CREATE_ESQL_CHART', + getDisplayName: () => 'Action name', + getIconType: () => 'pencil', + getDisplayNameTooltip: () => 'Action tooltip', + isCompatible: () => Promise.resolve(true), + execute: jest.fn(), + }, + ]; + const items = getAddPanelActionMenuItems(registeredActions, jest.fn(), jest.fn(), jest.fn()); + expect(items).toStrictEqual([ + { + 'data-test-subj': 'create-action-Action name', + icon: 'pencil', + name: 'Action name', + onClick: expect.any(Function), + toolTipContent: 'Action tooltip', + }, + ]); + }); + + it('returns empty array if no actions have been registered', async () => { + const items = getAddPanelActionMenuItems([], jest.fn(), jest.fn(), jest.fn()); + expect(items).toStrictEqual([]); + }); +}); diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/add_panel_action_menu_items.ts b/src/plugins/dashboard/public/dashboard_app/top_nav/add_panel_action_menu_items.ts new file mode 100644 index 00000000000000..3df83438879823 --- /dev/null +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/add_panel_action_menu_items.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import type { ActionExecutionContext, Action } from '@kbn/ui-actions-plugin/public'; +import type { EmbeddableFactory } from '@kbn/embeddable-plugin/public'; +import { addPanelMenuTrigger } from '../../triggers'; + +const onAddPanelActionClick = + (action: Action, context: ActionExecutionContext, closePopover: () => void) => + (event: React.MouseEvent) => { + closePopover(); + if (event.currentTarget instanceof HTMLAnchorElement) { + if ( + !event.defaultPrevented && // onClick prevented default + event.button === 0 && + (!event.currentTarget.target || event.currentTarget.target === '_self') && + !(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) + ) { + event.preventDefault(); + action.execute(context); + } + } else action.execute(context); + }; + +export const getAddPanelActionMenuItems = ( + actions: Array> | undefined, + createNewEmbeddable: (embeddableFactory: EmbeddableFactory) => void, + deleteEmbeddable: (embeddableId: string) => void, + closePopover: () => void +) => { + return ( + actions?.map((item) => { + const context = { + createNewEmbeddable, + deleteEmbeddable, + trigger: addPanelMenuTrigger, + }; + const actionName = item.getDisplayName(context); + return { + name: actionName, + icon: item.getIconType(context), + onClick: onAddPanelActionClick(item, context, closePopover), + 'data-test-subj': `create-action-${actionName}`, + toolTipContent: item?.getDisplayNameTooltip?.(context), + }; + }) ?? [] + ); +}; diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx index 6afdf1429663b1..e39e227da06438 100644 --- a/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx @@ -80,8 +80,17 @@ export function DashboardEditingToolbar({ isDisabled }: { isDisabled?: boolean } [stateTransferService, dashboard, search.session, trackUiMetric] ); + /** + * embeddableFactory: Required, you can get the factory from embeddableStart.getEmbeddableFactory() + * initialInput: Optional, use it in case you want to pass your own input to the factory + * dismissNotification: Optional, if not passed a toast will appear in the dashboard + */ const createNewEmbeddable = useCallback( - async (embeddableFactory: EmbeddableFactory) => { + async ( + embeddableFactory: EmbeddableFactory, + initialInput?: Partial, + dismissNotification?: boolean + ) => { if (trackUiMetric) { trackUiMetric(METRIC_TYPE.CLICK, embeddableFactory.type); } @@ -89,12 +98,19 @@ export function DashboardEditingToolbar({ isDisabled }: { isDisabled?: boolean } let explicitInput: Partial; let attributes: unknown; try { - const explicitInputReturn = await embeddableFactory.getExplicitInput(undefined, dashboard); - if (isExplicitInputWithAttributes(explicitInputReturn)) { - explicitInput = explicitInputReturn.newInput; - attributes = explicitInputReturn.attributes; + if (initialInput) { + explicitInput = initialInput; } else { - explicitInput = explicitInputReturn; + const explicitInputReturn = await embeddableFactory.getExplicitInput( + undefined, + dashboard + ); + if (isExplicitInputWithAttributes(explicitInputReturn)) { + explicitInput = explicitInputReturn.newInput; + attributes = explicitInputReturn.attributes; + } else { + explicitInput = explicitInputReturn; + } } } catch (e) { // error likely means user canceled embeddable creation @@ -110,19 +126,31 @@ export function DashboardEditingToolbar({ isDisabled }: { isDisabled?: boolean } if (newEmbeddable) { dashboard.setScrollToPanelId(newEmbeddable.id); dashboard.setHighlightPanelId(newEmbeddable.id); - toasts.addSuccess({ - title: dashboardReplacePanelActionStrings.getSuccessMessage(newEmbeddable.getTitle()), - 'data-test-subj': 'addEmbeddableToDashboardSuccess', - }); + + if (!dismissNotification) { + toasts.addSuccess({ + title: dashboardReplacePanelActionStrings.getSuccessMessage(newEmbeddable.getTitle()), + 'data-test-subj': 'addEmbeddableToDashboardSuccess', + }); + } } + return newEmbeddable; }, [trackUiMetric, dashboard, toasts] ); + const deleteEmbeddable = useCallback( + (embeddableId: string) => { + dashboard.removeEmbeddable(embeddableId); + }, + [dashboard] + ); + const extraButtons = [ , () => void; /** Handler for creating a new embeddable of a specified type */ createNewEmbeddable: (embeddableFactory: EmbeddableFactory) => void; + /** Handler for deleting an embeddable */ + deleteEmbeddable: (embeddableId: string) => void; } interface FactoryGroup { @@ -44,7 +49,13 @@ interface UnwrappedEmbeddableFactory { isEditable: boolean; } -export const EditorMenu = ({ createNewVisType, createNewEmbeddable, isDisabled }: Props) => { +export const EditorMenu = ({ + createNewVisType, + createNewEmbeddable, + deleteEmbeddable, + isDisabled, +}: Props) => { + const isMounted = useRef(false); const { embeddable, visualizations: { @@ -52,6 +63,7 @@ export const EditorMenu = ({ createNewVisType, createNewEmbeddable, isDisabled } getByGroup: getVisTypesByGroup, showNewVisModal, }, + uiActions, } = pluginServices.getServices(); const { euiTheme } = useEuiTheme(); @@ -64,6 +76,10 @@ export const EditorMenu = ({ createNewVisType, createNewEmbeddable, isDisabled } UnwrappedEmbeddableFactory[] >([]); + const [addPanelActions, setAddPanelActions] = useState> | undefined>( + undefined + ); + useEffect(() => { Promise.all( embeddableFactories.map>(async (factory) => ({ @@ -121,6 +137,28 @@ export const EditorMenu = ({ createNewVisType, createNewEmbeddable, isDisabled } let panelCount = 1 + aggBasedPanelID; + useEffect(() => { + isMounted.current = true; + + return () => { + isMounted.current = false; + }; + }, []); + + // Retrieve ADD_PANEL_TRIGGER actions + useEffect(() => { + async function loadPanelActions() { + const registeredActions = await uiActions?.getTriggerCompatibleActions?.( + ADD_PANEL_TRIGGER, + {} + ); + if (isMounted.current) { + setAddPanelActions(registeredActions); + } + } + loadPanelActions(); + }, [uiActions]); + factories.forEach(({ factory }) => { const { grouping } = factory; @@ -236,6 +274,12 @@ export const EditorMenu = ({ createNewVisType, createNewEmbeddable, isDisabled } })), ...promotedVisTypes.map(getVisTypeMenuItem), + ...getAddPanelActionMenuItems( + addPanelActions, + createNewEmbeddable, + deleteEmbeddable, + closePopover + ), ]; if (aggsBasedVisTypes.length > 0) { initialPanelItems.push({ diff --git a/src/plugins/dashboard/public/plugin.tsx b/src/plugins/dashboard/public/plugin.tsx index 98af5088967f2d..4c75362485b6a0 100644 --- a/src/plugins/dashboard/public/plugin.tsx +++ b/src/plugins/dashboard/public/plugin.tsx @@ -70,6 +70,7 @@ import { import { DashboardMountContextProps } from './dashboard_app/types'; import type { FindDashboardsService } from './services/dashboard_content_management/types'; import { CONTENT_ID, LATEST_VERSION } from '../common/content_management'; +import { addPanelMenuTrigger } from './triggers'; export interface DashboardFeatureFlagConfig { allowByValueEmbeddables: boolean; @@ -149,11 +150,23 @@ export class DashboardPlugin public setup( core: CoreSetup, - { share, embeddable, home, urlForwarding, data, contentManagement }: DashboardSetupDependencies + { + share, + embeddable, + home, + urlForwarding, + data, + contentManagement, + uiActions, + }: DashboardSetupDependencies ): DashboardSetup { this.dashboardFeatureFlagConfig = this.initializerContext.config.get(); + // this trigger enables external consumers to register actions for + // adding items to the add panel menu + uiActions.registerTrigger(addPanelMenuTrigger); + if (share) { this.locator = share.url.locators.create( new DashboardAppLocatorDefinition({ diff --git a/src/plugins/dashboard/public/services/plugin_services.stub.ts b/src/plugins/dashboard/public/services/plugin_services.stub.ts index b77888f1293f54..e61aab184b09c5 100644 --- a/src/plugins/dashboard/public/services/plugin_services.stub.ts +++ b/src/plugins/dashboard/public/services/plugin_services.stub.ts @@ -43,6 +43,7 @@ import { savedObjectsManagementServiceFactory } from './saved_objects_management import { contentManagementServiceFactory } from './content_management/content_management_service.stub'; import { serverlessServiceFactory } from './serverless/serverless_service.stub'; import { noDataPageServiceFactory } from './no_data_page/no_data_page_service.stub'; +import { uiActionsServiceFactory } from './ui_actions/ui_actions_service.stub'; export const providers: PluginServiceProviders = { dashboardContentManagement: new PluginServiceProvider(dashboardContentManagementServiceFactory), @@ -74,6 +75,7 @@ export const providers: PluginServiceProviders = { contentManagement: new PluginServiceProvider(contentManagementServiceFactory), serverless: new PluginServiceProvider(serverlessServiceFactory), noDataPage: new PluginServiceProvider(noDataPageServiceFactory), + uiActions: new PluginServiceProvider(uiActionsServiceFactory), }; export const registry = new PluginServiceRegistry(providers); diff --git a/src/plugins/dashboard/public/services/plugin_services.ts b/src/plugins/dashboard/public/services/plugin_services.ts index 1d159014a4e726..2c9c1d95828e8a 100644 --- a/src/plugins/dashboard/public/services/plugin_services.ts +++ b/src/plugins/dashboard/public/services/plugin_services.ts @@ -44,6 +44,7 @@ import { dashboardContentManagementServiceFactory } from './dashboard_content_ma import { contentManagementServiceFactory } from './content_management/content_management_service'; import { serverlessServiceFactory } from './serverless/serverless_service'; import { noDataPageServiceFactory } from './no_data_page/no_data_page_service'; +import { uiActionsServiceFactory } from './ui_actions/ui_actions_service'; const providers: PluginServiceProviders = { dashboardContentManagement: new PluginServiceProvider(dashboardContentManagementServiceFactory, [ @@ -88,6 +89,7 @@ const providers: PluginServiceProviders(); diff --git a/src/plugins/dashboard/public/services/types.ts b/src/plugins/dashboard/public/services/types.ts index c1c7c1aa39e719..420ba257b6a6a8 100644 --- a/src/plugins/dashboard/public/services/types.ts +++ b/src/plugins/dashboard/public/services/types.ts @@ -39,6 +39,7 @@ import { DashboardUsageCollectionService } from './usage_collection/types'; import { DashboardVisualizationsService } from './visualizations/types'; import { DashboardServerlessService } from './serverless/types'; import { NoDataPageService } from './no_data_page/types'; +import { DashboardUiActionsService } from './ui_actions/types'; export type DashboardPluginServiceParams = KibanaPluginServiceParams & { initContext: PluginInitializerContext; // need a custom type so that initContext is a required parameter for initializerContext @@ -74,4 +75,5 @@ export interface DashboardServices { contentManagement: ContentManagementPublicStart; serverless: DashboardServerlessService; // TODO: make this optional in follow up noDataPage: NoDataPageService; + uiActions: DashboardUiActionsService; } diff --git a/src/plugins/dashboard/public/services/ui_actions/types.ts b/src/plugins/dashboard/public/services/ui_actions/types.ts new file mode 100644 index 00000000000000..102cb70d8a11db --- /dev/null +++ b/src/plugins/dashboard/public/services/ui_actions/types.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; + +export interface DashboardUiActionsService { + getTriggerCompatibleActions?: UiActionsStart['getTriggerCompatibleActions']; +} diff --git a/src/plugins/dashboard/public/services/ui_actions/ui_actions_service.stub.ts b/src/plugins/dashboard/public/services/ui_actions/ui_actions_service.stub.ts new file mode 100644 index 00000000000000..033889959b89a8 --- /dev/null +++ b/src/plugins/dashboard/public/services/ui_actions/ui_actions_service.stub.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; +import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; +import { DashboardUiActionsService } from './types'; + +export type UIActionsServiceFactory = PluginServiceFactory; + +export const uiActionsServiceFactory: UIActionsServiceFactory = () => { + const pluginMock = uiActionsPluginMock.createStartContract(); + return { getTriggerCompatibleActions: pluginMock.getTriggerCompatibleActions }; +}; diff --git a/src/plugins/dashboard/public/services/ui_actions/ui_actions_service.ts b/src/plugins/dashboard/public/services/ui_actions/ui_actions_service.ts new file mode 100644 index 00000000000000..221380c6d0479c --- /dev/null +++ b/src/plugins/dashboard/public/services/ui_actions/ui_actions_service.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public'; +import type { DashboardStartDependencies } from '../../plugin'; +import type { DashboardUiActionsService } from './types'; + +export type UsageCollectionServiceFactory = KibanaPluginServiceFactory< + DashboardUiActionsService, + DashboardStartDependencies +>; +export const uiActionsServiceFactory: UsageCollectionServiceFactory = ({ startPlugins }) => { + const { uiActions } = startPlugins; + if (!uiActions) return {}; + + const { getTriggerCompatibleActions } = uiActions; + return { + getTriggerCompatibleActions, + }; +}; diff --git a/src/plugins/dashboard/public/triggers/index.ts b/src/plugins/dashboard/public/triggers/index.ts new file mode 100644 index 00000000000000..96dfa814b949a7 --- /dev/null +++ b/src/plugins/dashboard/public/triggers/index.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import { i18n } from '@kbn/i18n'; +import type { Trigger } from '@kbn/ui-actions-plugin/public'; + +export const ADD_PANEL_TRIGGER = 'ADD_PANEL_TRIGGER'; +export const addPanelMenuTrigger: Trigger = { + id: ADD_PANEL_TRIGGER, + title: i18n.translate('dashboard.addPanelMenuTrigger.title', { + defaultMessage: 'Add panel menu', + }), + description: i18n.translate('dashboard.addPanelMenuTrigger.description', { + defaultMessage: "A new action will appear to the dashboard's add panel menu", + }), +}; diff --git a/test/functional/apps/dashboard/group6/dashboard_esql_chart.ts b/test/functional/apps/dashboard/group6/dashboard_esql_chart.ts new file mode 100644 index 00000000000000..f69477b926b71a --- /dev/null +++ b/test/functional/apps/dashboard/group6/dashboard_esql_chart.ts @@ -0,0 +1,73 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import expect from '@kbn/expect'; + +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const retry = getService('retry'); + const kibanaServer = getService('kibanaServer'); + const PageObjects = getPageObjects(['common', 'dashboard', 'timePicker', 'header']); + const testSubjects = getService('testSubjects'); + const monacoEditor = getService('monacoEditor'); + const dashboardAddPanel = getService('dashboardAddPanel'); + + describe('dashboard add ES|QL chart', function () { + before(async () => { + await kibanaServer.savedObjects.cleanStandardList(); + await kibanaServer.importExport.load( + 'test/functional/fixtures/kbn_archiver/dashboard/current/kibana' + ); + await kibanaServer.uiSettings.replace({ + defaultIndex: '0bf35f60-3dc9-11e8-8660-4d65aa086b3c', + }); + }); + + it('should add an ES|QL datatable chart when the ES|QL panel action is clicked', async () => { + await PageObjects.dashboard.navigateToApp(); + await PageObjects.dashboard.clickNewDashboard(); + await PageObjects.timePicker.setDefaultDataRange(); + await PageObjects.dashboard.switchToEditMode(); + await dashboardAddPanel.clickEditorMenuButton(); + await dashboardAddPanel.clickAddNewPanelFromUIActionLink('ES|QL'); + await dashboardAddPanel.expectEditorMenuClosed(); + await PageObjects.dashboard.waitForRenderComplete(); + + await retry.try(async () => { + const panelCount = await PageObjects.dashboard.getPanelCount(); + expect(panelCount).to.eql(1); + }); + + expect(await testSubjects.exists('lnsDataTable')).to.be(true); + }); + + it('should remove the panel if cancel button is clicked', async () => { + await testSubjects.click('cancelFlyoutButton'); + await PageObjects.dashboard.waitForRenderComplete(); + await retry.try(async () => { + const panelCount = await PageObjects.dashboard.getPanelCount(); + expect(panelCount).to.eql(0); + }); + }); + + it('should be able to edit the query and render another chart', async () => { + await dashboardAddPanel.clickEditorMenuButton(); + await dashboardAddPanel.clickAddNewPanelFromUIActionLink('ES|QL'); + await dashboardAddPanel.expectEditorMenuClosed(); + await PageObjects.dashboard.waitForRenderComplete(); + + await monacoEditor.setCodeEditorValue('from logstash-* | stats maxB = max(bytes)'); + await testSubjects.click('TextBasedLangEditor-run-query-button'); + await PageObjects.header.waitUntilLoadingHasFinished(); + + await testSubjects.click('applyFlyoutButton'); + expect(await testSubjects.exists('mtrVis')).to.be(true); + }); + }); +} diff --git a/test/functional/apps/dashboard/group6/index.ts b/test/functional/apps/dashboard/group6/index.ts index 95d18049053ae6..75decec10fb4c7 100644 --- a/test/functional/apps/dashboard/group6/index.ts +++ b/test/functional/apps/dashboard/group6/index.ts @@ -35,5 +35,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { // If we don't use the timestamp in the URL, the colors in the charts will be different. loadTestFile(require.resolve('./dashboard_snapshots')); loadTestFile(require.resolve('./embeddable_library')); + loadTestFile(require.resolve('./dashboard_esql_chart')); }); } diff --git a/test/functional/services/dashboard/add_panel.ts b/test/functional/services/dashboard/add_panel.ts index 00a91dff87b852..65adf6dee53594 100644 --- a/test/functional/services/dashboard/add_panel.ts +++ b/test/functional/services/dashboard/add_panel.ts @@ -77,6 +77,10 @@ export class DashboardAddPanelService extends FtrService { await this.testSubjects.click(`createNew-${type}`); } + async clickAddNewPanelFromUIActionLink(type: string) { + await this.testSubjects.click(`create-action-${type}`); + } + async addEveryEmbeddableOnCurrentPage() { this.log.debug('addEveryEmbeddableOnCurrentPage'); const itemList = await this.testSubjects.find('savedObjectsFinderTable'); diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/flyout_wrapper.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/flyout_wrapper.tsx index bab45a9ffe8564..f9a6ac0ce397ba 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/flyout_wrapper.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/flyout_wrapper.tsx @@ -32,6 +32,7 @@ export const FlyoutWrapper = ({ displayFlyoutHeader, language, attributesChanged, + isNewPanel, onCancel, navigateToLensEditor, onApply, @@ -49,12 +50,17 @@ export const FlyoutWrapper = ({ > - +

- {i18n.translate('xpack.lens.config.editVisualizationLabel', { - defaultMessage: 'Edit {lang} visualization', - values: { lang: language }, - })} + {isNewPanel + ? i18n.translate('xpack.lens.config.createVisualizationLabel', { + defaultMessage: 'Create {lang} visualization', + values: { lang: language }, + }) + : i18n.translate('xpack.lens.config.editVisualizationLabel', { + defaultMessage: 'Edit {lang} visualization', + values: { lang: language }, + })} diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx index 2421f303d7b3a3..acef8feb6da500 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx @@ -114,6 +114,8 @@ export async function getEditLensConfiguration( navigateToLensEditor, displayFlyoutHeader, canEditTextBasedQuery, + isNewPanel, + deletePanel, hidesSuggestions, }: EditLensConfigurationProps) => { if (!lensServices || !datasourceMap || !visualizationMap) { @@ -208,6 +210,8 @@ export async function getEditLensConfiguration( canEditTextBasedQuery, hidesSuggestions, setCurrentAttributes, + isNewPanel, + deletePanel, }; return getWrapper( diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx index adc0b83861b9ce..6aad89b50ef0c2 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx @@ -94,6 +94,16 @@ describe('LensEditConfigurationFlyout', () => { expect(navigateToLensEditorSpy).toHaveBeenCalled(); }); + it('should display the header title correctly for a newly created panel', async () => { + renderConfigFlyout({ + displayFlyoutHeader: true, + isNewPanel: true, + }); + expect(screen.getByTestId('inlineEditingFlyoutLabel').textContent).toBe( + 'Create ES|QL visualization' + ); + }); + it('should call the closeFlyout callback if cancel button is clicked', async () => { const closeFlyoutSpy = jest.fn(); diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx index 13fedcf5cd7e0d..39801f41c391cb 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx @@ -61,6 +61,8 @@ export function LensEditConfigurationFlyout({ navigateToLensEditor, displayFlyoutHeader, canEditTextBasedQuery, + isNewPanel, + deletePanel, hidesSuggestions, }: EditConfigPanelProps) { const euiTheme = useEuiTheme(); @@ -165,18 +167,23 @@ export function LensEditConfigurationFlyout({ updateByRefInput?.(savedObjectId); } } + // for a newly created chart, I want cancelling to also remove the panel + if (isNewPanel && deletePanel) { + deletePanel(); + } closeFlyout?.(); }, [ - previousAttributes, attributesChanged, + isNewPanel, + deletePanel, closeFlyout, + visualization.activeId, + savedObjectId, datasourceMap, datasourceId, updatePanelState, updateSuggestion, - savedObjectId, updateByRefInput, - visualization, ]); const onApply = useCallback(() => { @@ -279,6 +286,7 @@ export function LensEditConfigurationFlyout({ onApply={onApply} isScrollable={true} attributesChanged={attributesChanged} + isNewPanel={isNewPanel} > void; onApply?: () => void; navigateToLensEditor?: () => void; @@ -75,6 +76,10 @@ export interface EditConfigPanelProps { displayFlyoutHeader?: boolean; /** If set to true the layout changes to accordion and the text based query (i.e. ES|QL) can be edited */ canEditTextBasedQuery?: boolean; + /** The flyout is used for adding a new panel by scratch */ + isNewPanel?: boolean; + /** Handler for deleting the embeddable, used in case a user cancels a newly created chart */ + deletePanel?: () => void; /** If set to true the layout changes to accordion and the text based query (i.e. ES|QL) can be edited */ hidesSuggestions?: boolean; } diff --git a/x-pack/plugins/lens/public/async_services.ts b/x-pack/plugins/lens/public/async_services.ts index 7bbfaf415db038..85724c871cda66 100644 --- a/x-pack/plugins/lens/public/async_services.ts +++ b/x-pack/plugins/lens/public/async_services.ts @@ -50,4 +50,5 @@ export * from './app_plugin/save_modal_container'; export * from './chart_info_api'; export * from './trigger_actions/open_in_discover_helpers'; -export * from './trigger_actions/open_lens_config/helpers'; +export * from './trigger_actions/open_lens_config/edit_action_helpers'; +export * from './trigger_actions/open_lens_config/create_action_helpers'; diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx index c1dd7901f38220..529f80b803c6f1 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx @@ -845,7 +845,11 @@ export class Embeddable this.updateInput({ attributes: attrs, savedObjectId }); } - async openConfingPanel(startDependencies: LensPluginStartDependencies) { + async openConfingPanel( + startDependencies: LensPluginStartDependencies, + isNewPanel?: boolean, + deletePanel?: () => void + ) { const { getEditLensConfiguration } = await import('../async_services'); const Component = await getEditLensConfiguration( this.deps.coreStart, @@ -875,6 +879,8 @@ export class Embeddable } displayFlyoutHeader={true} canEditTextBasedQuery={this.isTextBasedLanguage()} + isNewPanel={isNewPanel} + deletePanel={deletePanel} /> ); } diff --git a/x-pack/plugins/lens/public/plugin.ts b/x-pack/plugins/lens/public/plugin.ts index 460864d1c86f2b..872e1a566ab203 100644 --- a/x-pack/plugins/lens/public/plugin.ts +++ b/x-pack/plugins/lens/public/plugin.ts @@ -105,7 +105,8 @@ import type { } from './types'; import { getLensAliasConfig } from './vis_type_alias'; import { createOpenInDiscoverAction } from './trigger_actions/open_in_discover_action'; -import { ConfigureInLensPanelAction } from './trigger_actions/open_lens_config/action'; +import { ConfigureInLensPanelAction } from './trigger_actions/open_lens_config/edit_action'; +import { CreateESQLPanelAction } from './trigger_actions/open_lens_config/create_action'; import { visualizeFieldAction } from './trigger_actions/visualize_field_actions'; import { visualizeTSVBAction } from './trigger_actions/visualize_tsvb_actions'; import { visualizeAggBasedVisAction } from './trigger_actions/visualize_agg_based_vis_actions'; @@ -327,6 +328,9 @@ export class LensPlugin { this.editorFrameService!.loadVisualizations(), this.editorFrameService!.loadDatasources(), ]); + const { setVisualizationMap, setDatasourceMap } = await import('./async_services'); + setDatasourceMap(datasourceMap); + setVisualizationMap(visualizationMap); const eventAnnotationService = await plugins.eventAnnotation.getService(); if (plugins.usageCollection) { @@ -598,6 +602,10 @@ export class LensPlugin { ); startDependencies.uiActions.addTriggerAction('CONTEXT_MENU_TRIGGER', editInLensAction); + // Displays the add ESQL panel in the dashboard add Panel menu + const createESQLPanelAction = new CreateESQLPanelAction(startDependencies, core); + startDependencies.uiActions.addTriggerAction('ADD_PANEL_TRIGGER', createESQLPanelAction); + const discoverLocator = startDependencies.share?.url.locators.get('DISCOVER_APP_LOCATOR'); if (discoverLocator) { startDependencies.uiActions.addTriggerAction( diff --git a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action.test.tsx b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action.test.tsx new file mode 100644 index 00000000000000..9a06fea94cd98b --- /dev/null +++ b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action.test.tsx @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { CoreStart } from '@kbn/core/public'; +import { coreMock } from '@kbn/core/public/mocks'; +import type { LensPluginStartDependencies } from '../../plugin'; +import { createMockStartDependencies } from '../../editor_frame_service/mocks'; +import { CreateESQLPanelAction } from './create_action'; + +describe('create Lens panel action', () => { + const core = coreMock.createStart(); + const mockStartDependencies = + createMockStartDependencies() as unknown as LensPluginStartDependencies; + describe('compatibility check', () => { + it('is incompatible if ui setting for ES|QL is off', async () => { + const configurablePanelAction = new CreateESQLPanelAction(mockStartDependencies, core); + const isCompatible = await configurablePanelAction.isCompatible(); + + expect(isCompatible).toBeFalsy(); + }); + + it('is compatible if ui setting for ES|QL is on', async () => { + const updatedCore = { + ...core, + uiSettings: { + ...core.uiSettings, + get: (setting: string) => { + return setting === 'discover:enableESQL'; + }, + }, + } as CoreStart; + const createESQLAction = new CreateESQLPanelAction(mockStartDependencies, updatedCore); + const isCompatible = await createESQLAction.isCompatible(); + + expect(isCompatible).toBeTruthy(); + }); + }); +}); diff --git a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action.tsx b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action.tsx new file mode 100644 index 00000000000000..aa33a629c39693 --- /dev/null +++ b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action.tsx @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { i18n } from '@kbn/i18n'; +import type { CoreStart } from '@kbn/core/public'; +import { Action } from '@kbn/ui-actions-plugin/public'; +import type { + EmbeddableFactory, + EmbeddableInput, + IEmbeddable, +} from '@kbn/embeddable-plugin/public'; +import type { LensPluginStartDependencies } from '../../plugin'; + +const ACTION_CREATE_ESQL_CHART = 'ACTION_CREATE_ESQL_CHART'; + +interface Context { + createNewEmbeddable: ( + embeddableFactory: EmbeddableFactory, + initialInput?: Partial, + dismissNotification?: boolean + ) => Promise; + deleteEmbeddable: (embeddableId: string) => void; + initialInput?: Partial; +} + +export const getAsyncHelpers = async () => await import('../../async_services'); + +export class CreateESQLPanelAction implements Action { + public type = ACTION_CREATE_ESQL_CHART; + public id = ACTION_CREATE_ESQL_CHART; + public order = 50; + + constructor( + protected readonly startDependencies: LensPluginStartDependencies, + protected readonly core: CoreStart + ) {} + + public getDisplayName(): string { + return i18n.translate('xpack.lens.app.createVisualizationLabel', { + defaultMessage: 'ES|QL', + }); + } + + public getIconType() { + // need to create a new one + return 'esqlVis'; + } + + public async isCompatible() { + // compatible only when ES|QL advanced setting is enabled + const { isCreateActionCompatible } = await getAsyncHelpers(); + return isCreateActionCompatible(this.core); + } + + public async execute({ createNewEmbeddable, deleteEmbeddable }: Context) { + const { executeCreateAction } = await getAsyncHelpers(); + executeCreateAction({ + deps: this.startDependencies, + core: this.core, + createNewEmbeddable, + deleteEmbeddable, + }); + } +} diff --git a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts new file mode 100644 index 00000000000000..1eddc499f41703 --- /dev/null +++ b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/create_action_helpers.ts @@ -0,0 +1,127 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { createGetterSetter } from '@kbn/kibana-utils-plugin/common'; +import type { CoreStart } from '@kbn/core/public'; +import type { + EmbeddableFactory, + EmbeddableInput, + IEmbeddable, +} from '@kbn/embeddable-plugin/public'; +import { IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; +import type { Datasource, Visualization } from '../../types'; +import type { LensPluginStartDependencies } from '../../plugin'; +import { fetchDataFromAggregateQuery } from '../../datasources/text_based/fetch_data_from_aggregate_query'; +import { suggestionsApi } from '../../lens_suggestions_api'; +import { getLensAttributes } from '../../app_plugin/shared/edit_on_the_fly/helpers'; +import { generateId } from '../../id_generator'; +import { executeEditAction } from './edit_action_helpers'; + +// datasourceMap and visualizationMap setters/getters +export const [getVisualizationMap, setVisualizationMap] = createGetterSetter< + Record> +>('VisualizationMap', false); + +export const [getDatasourceMap, setDatasourceMap] = createGetterSetter< + Record> +>('DatasourceMap', false); + +export function isCreateActionCompatible(core: CoreStart) { + return core.uiSettings.get('discover:enableESQL'); +} + +export async function executeCreateAction({ + deps, + core, + createNewEmbeddable, + deleteEmbeddable, +}: { + deps: LensPluginStartDependencies; + core: CoreStart; + createNewEmbeddable: ( + embeddableFactory: EmbeddableFactory, + initialInput?: Partial, + dismissNotification?: boolean + ) => Promise; + deleteEmbeddable: (embeddableId: string) => void; +}) { + const isCompatibleAction = isCreateActionCompatible(core); + const defaultDataView = await deps.dataViews.getDefaultDataView({ + displayErrors: false, + }); + if (!isCompatibleAction || !defaultDataView) { + throw new IncompatibleActionError(); + } + const visualizationMap = getVisualizationMap(); + const datasourceMap = getDatasourceMap(); + + const defaultIndex = defaultDataView.getIndexPattern(); + const defaultEsqlQuery = { + esql: `from ${defaultIndex} | limit 10`, + }; + + // For the suggestions api we need only the columns + // so we are requesting them with limit 0 + // this is much more performant than requesting + // all the table + const performantQuery = { + esql: `from ${defaultIndex} | limit 0`, + }; + + const table = await fetchDataFromAggregateQuery( + performantQuery, + defaultDataView, + deps.data, + deps.expressions + ); + + const context = { + dataViewSpec: defaultDataView.toSpec(), + fieldName: '', + textBasedColumns: table?.columns, + query: defaultEsqlQuery, + }; + + // get the initial attributes from the suggestions api + const allSuggestions = + suggestionsApi({ context, dataView: defaultDataView, datasourceMap, visualizationMap }) ?? []; + + // Lens might not return suggestions for some cases, i.e. in case of errors + if (!allSuggestions.length) return undefined; + const [firstSuggestion] = allSuggestions; + const attrs = getLensAttributes({ + filters: [], + query: defaultEsqlQuery, + suggestion: firstSuggestion, + dataView: defaultDataView, + }); + + const input = { + attributes: attrs, + id: generateId(), + }; + const embeddableStart = deps.embeddable; + const factory = embeddableStart.getEmbeddableFactory('lens'); + if (!factory) { + return undefined; + } + const embeddable = await createNewEmbeddable(factory, input, true); + // open the flyout if embeddable has been created successfully + if (embeddable) { + const deletePanel = () => { + deleteEmbeddable(embeddable.id); + }; + + executeEditAction({ + embeddable, + startDependencies: deps, + overlays: core.overlays, + theme: core.theme, + isNewPanel: true, + deletePanel, + }); + } +} diff --git a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/action.test.tsx b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/edit_action.test.tsx similarity index 98% rename from x-pack/plugins/lens/public/trigger_actions/open_lens_config/action.test.tsx rename to x-pack/plugins/lens/public/trigger_actions/open_lens_config/edit_action.test.tsx index d8dbc219c6c173..e1ab0f715cac57 100644 --- a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/action.test.tsx +++ b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/edit_action.test.tsx @@ -12,7 +12,7 @@ import { themeServiceMock } from '@kbn/core-theme-browser-mocks'; import type { LensPluginStartDependencies } from '../../plugin'; import { createMockStartDependencies } from '../../editor_frame_service/mocks'; import { DOC_TYPE } from '../../../common/constants'; -import { ConfigureInLensPanelAction } from './action'; +import { ConfigureInLensPanelAction } from './edit_action'; describe('open config panel action', () => { const overlays = overlayServiceMock.createStartContract(); diff --git a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/action.tsx b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/edit_action.tsx similarity index 88% rename from x-pack/plugins/lens/public/trigger_actions/open_lens_config/action.tsx rename to x-pack/plugins/lens/public/trigger_actions/open_lens_config/edit_action.tsx index 376cae58d13390..c4960532bdd66b 100644 --- a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/action.tsx +++ b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/edit_action.tsx @@ -43,13 +43,13 @@ export class ConfigureInLensPanelAction implements Action { } public async isCompatible({ embeddable }: Context) { - const { isActionCompatible } = await getConfigureLensHelpersAsync(); - return isActionCompatible(embeddable); + const { isEditActionCompatible } = await getConfigureLensHelpersAsync(); + return isEditActionCompatible(embeddable); } public async execute({ embeddable }: Context) { - const { executeAction } = await getConfigureLensHelpersAsync(); - return executeAction({ + const { executeEditAction } = await getConfigureLensHelpersAsync(); + return executeEditAction({ embeddable, startDependencies: this.startDependencies, overlays: this.overlays, diff --git a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.ts b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/edit_action_helpers.ts similarity index 85% rename from x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.ts rename to x-pack/plugins/lens/public/trigger_actions/open_lens_config/edit_action_helpers.ts index 8fd011fddfb2e6..38f1aadc2c5766 100644 --- a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.ts +++ b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/edit_action_helpers.ts @@ -18,22 +18,31 @@ interface Context { startDependencies: LensPluginStartDependencies; overlays: OverlayStart; theme: ThemeServiceStart; + isNewPanel?: boolean; + deletePanel?: () => void; } -export async function isActionCompatible(embeddable: IEmbeddable) { +export async function isEditActionCompatible(embeddable: IEmbeddable) { // display the action only if dashboard is on editable mode const inDashboardEditMode = embeddable.getInput().viewMode === 'edit'; return Boolean(isLensEmbeddable(embeddable) && embeddable.getIsEditable() && inDashboardEditMode); } -export async function executeAction({ embeddable, startDependencies, overlays, theme }: Context) { - const isCompatibleAction = await isActionCompatible(embeddable); +export async function executeEditAction({ + embeddable, + startDependencies, + overlays, + theme, + isNewPanel, + deletePanel, +}: Context) { + const isCompatibleAction = await isEditActionCompatible(embeddable); if (!isCompatibleAction || !isLensEmbeddable(embeddable)) { throw new IncompatibleActionError(); } const rootEmbeddable = embeddable.getRoot(); const overlayTracker = tracksOverlays(rootEmbeddable) ? rootEmbeddable : undefined; - const ConfigPanel = await embeddable.openConfingPanel(startDependencies); + const ConfigPanel = await embeddable.openConfingPanel(startDependencies, isNewPanel, deletePanel); if (ConfigPanel) { const handle = overlays.openFlyout( toMountPoint( From f9233bd2ad4b6f3962778d2074fb13d66d745c27 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Wed, 20 Dec 2023 08:22:05 -0700 Subject: [PATCH 037/116] [Dashboard] Unskip flaky colour sync test (#173582) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes https://github.com/elastic/kibana/issues/148557 ## Summary [Ran the FTR](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4636) on the skipped test suite and it passed 100 times... Really unclear on why it keeps failing, especially after https://github.com/elastic/kibana/pull/172633. For now, since I can't get it to fail locally or with the FTR, I'm going to unskip. If it starts to fail on `main` again, we could loop in the Vis team to help (since it's the timepicker in the Lens app that is misbehaving) - but hopefully the previous failure was a fluke and that won't be necessary🤞 ### Checklist - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed ([Link](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4636)) ![Screenshot 2023-12-20 at 7 47 58 AM](https://github.com/elastic/kibana/assets/8698078/523e715a-a347-4c82-955c-b18cabe53566) ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- x-pack/test/functional/apps/dashboard/group2/sync_colors.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x-pack/test/functional/apps/dashboard/group2/sync_colors.ts b/x-pack/test/functional/apps/dashboard/group2/sync_colors.ts index d82868aa068b32..a388a4d90af3be 100644 --- a/x-pack/test/functional/apps/dashboard/group2/sync_colors.ts +++ b/x-pack/test/functional/apps/dashboard/group2/sync_colors.ts @@ -35,8 +35,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { return colorMapping; } - // FLAKY: https://github.com/elastic/kibana/issues/148557 - describe.skip('sync colors', function () { + describe('sync colors', function () { before(async function () { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional'); await kibanaServer.importExport.load( From 69395c611e5ebfdfc4ca6b244e995b15e59bc36f Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Wed, 20 Dec 2023 08:09:31 -0800 Subject: [PATCH 038/116] [Connectors] Pass data-test-subj into JSON editor with message variables (#172642) --- .../public/connector_types/bedrock/params.tsx | 4 ++-- .../connector_types/cases_webhook/steps/create.tsx | 2 +- .../connector_types/cases_webhook/steps/update.tsx | 4 ++-- .../public/connector_types/d3security/params.tsx | 3 ++- .../connector_types/es_index/es_index_params.tsx | 4 ++-- .../public/connector_types/openai/params.tsx | 4 ++-- .../opsgenie/create_alert/json_editor.tsx | 3 ++- .../connector_types/pagerduty/pagerduty_params.tsx | 2 +- .../public/connector_types/tines/tines_params.tsx | 4 ++-- .../public/connector_types/torq/torq_params.tsx | 3 ++- .../public/connector_types/webhook/webhook_params.tsx | 3 ++- .../components/json_editor_with_message_variables.tsx | 10 ++++++---- .../stack_connectors/index_connector.ts | 2 +- .../cypress/screens/common/rule_actions.ts | 2 +- 14 files changed, 28 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/stack_connectors/public/connector_types/bedrock/params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/bedrock/params.tsx index b880e388b9f910..7678f52321dd3f 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/bedrock/params.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/bedrock/params.tsx @@ -67,7 +67,7 @@ const BedrockParamsFields: React.FunctionComponent { editSubActionParams({ body: json }); @@ -77,7 +77,7 @@ const BedrockParamsFields: React.FunctionComponent = ({ display, readOnly }) => ( componentProps={{ euiCodeEditorProps: { isReadOnly: readOnly, - 'data-test-subj': 'webhookCreateIncidentJson', ['aria-label']: i18n.CODE_EDITOR, }, + dataTestSubj: 'webhookCreateIncidentJson', messageVariables: casesVars, paramsProperty: 'createIncidentJson', buttonTitle: i18n.ADD_CASES_VARIABLE, diff --git a/x-pack/plugins/stack_connectors/public/connector_types/cases_webhook/steps/update.tsx b/x-pack/plugins/stack_connectors/public/connector_types/cases_webhook/steps/update.tsx index a140ecbc6a221a..e7a37d415f4af6 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/cases_webhook/steps/update.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/cases_webhook/steps/update.tsx @@ -104,9 +104,9 @@ export const UpdateStep: FunctionComponent = ({ display, readOnly }) => ( euiCodeEditorProps: { height: '200px', isReadOnly: readOnly, - 'data-test-subj': 'webhookUpdateIncidentJson', ['aria-label']: i18n.CODE_EDITOR, }, + dataTestSubj: 'webhookUpdateIncidentJson', messageVariables: [...casesVars, ...urlVars], paramsProperty: 'updateIncidentJson', buttonTitle: i18n.ADD_CASES_VARIABLE, @@ -192,9 +192,9 @@ export const UpdateStep: FunctionComponent = ({ display, readOnly }) => ( euiCodeEditorProps: { height: '200px', isReadOnly: readOnly, - 'data-test-subj': 'webhookCreateCommentJson', ['aria-label']: i18n.CODE_EDITOR, }, + dataTestSubj: 'webhookCreateCommentJson', messageVariables: [...commentVars, ...urlVars], paramsProperty: 'createCommentJson', buttonTitle: i18n.ADD_CASES_VARIABLE, diff --git a/x-pack/plugins/stack_connectors/public/connector_types/d3security/params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/d3security/params.tsx index 4785399c65f2f4..605afadb5af2b4 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/d3security/params.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/d3security/params.tsx @@ -89,7 +89,7 @@ const D3ParamsFields: React.FunctionComponent ); diff --git a/x-pack/plugins/stack_connectors/public/connector_types/es_index/es_index_params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/es_index/es_index_params.tsx index fc51ae0ba1ccf0..b9b9ef8e7d41f3 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/es_index/es_index_params.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/es_index/es_index_params.tsx @@ -196,10 +196,10 @@ export const IndexParamsFields = ({ > = ( label={i18n.translate('xpack.stackConnectors.components.genAi.bodyFieldLabel', { defaultMessage: 'Body', })} - aria-label={i18n.translate('xpack.stackConnectors.components.genAi.bodyCodeEditorAriaLabel', { + ariaLabel={i18n.translate('xpack.stackConnectors.components.genAi.bodyCodeEditorAriaLabel', { defaultMessage: 'Code editor', })} errors={errors.body as string[]} @@ -79,7 +79,7 @@ const ParamsFields: React.FunctionComponent> = ( editSubActionParams({ body: '' }); } }} - data-test-subj="genAi-bodyJsonEditor" + dataTestSubj="genAi-bodyJsonEditor" /> ); }; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/create_alert/json_editor.tsx b/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/create_alert/json_editor.tsx index 17054b00dc920b..2e352235729c14 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/create_alert/json_editor.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/create_alert/json_editor.tsx @@ -83,10 +83,11 @@ const JsonEditorComponent: React.FC = ({ messageVariables={messageVariables} paramsProperty={'subActionParams'} inputTargetValue={jsonEditorValue} - aria-label={i18n.JSON_EDITOR_ARIA} + ariaLabel={i18n.JSON_EDITOR_ARIA} onDocumentsChange={onAdvancedEditorChange} errors={jsonEditorErrors} label={i18n.ALERT_FIELDS_LABEL} + dataTestSubj="actionJsonEditor" /> ); }; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/pagerduty/pagerduty_params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/pagerduty/pagerduty_params.tsx index 08d92a0f4ad3ea..7c9d74de5e571c 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/pagerduty/pagerduty_params.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/pagerduty/pagerduty_params.tsx @@ -373,7 +373,7 @@ const PagerDutyParamsFields: React.FunctionComponent { editSubActionParams({ body: json }); @@ -317,7 +317,7 @@ const TinesParamsFields: React.FunctionComponent )} diff --git a/x-pack/plugins/stack_connectors/public/connector_types/torq/torq_params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/torq/torq_params.tsx index e6cb9880c3ef26..e5847717a74a23 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/torq/torq_params.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/torq/torq_params.tsx @@ -27,7 +27,7 @@ const TorqParamsFields: React.FunctionComponent { editAction('body', json, index); @@ -37,6 +37,7 @@ const TorqParamsFields: React.FunctionComponent ); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/json_editor_with_message_variables.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/json_editor_with_message_variables.tsx index 4459735acb9275..45852171b5be4e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/json_editor_with_message_variables.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/json_editor_with_message_variables.tsx @@ -39,11 +39,12 @@ interface Props { inputTargetValue?: string | null; label: string; errors?: string[]; - areaLabel?: string; + ariaLabel?: string; onDocumentsChange: (data: string) => void; helpText?: JSX.Element; onBlur?: () => void; showButtonTitle?: boolean; + dataTestSubj?: string; euiCodeEditorProps?: { [key: string]: any }; } @@ -61,11 +62,12 @@ export const JsonEditorWithMessageVariables: React.FunctionComponent = ({ inputTargetValue, label, errors, - areaLabel, + ariaLabel, onDocumentsChange, helpText, onBlur, showButtonTitle, + dataTestSubj, euiCodeEditorProps = {}, }) => { const editorRef = useRef(); @@ -154,7 +156,7 @@ export const JsonEditorWithMessageVariables: React.FunctionComponent = ({ return ( 0 && inputTargetValue !== undefined} @@ -191,7 +193,7 @@ export const JsonEditorWithMessageVariables: React.FunctionComponent = ({ width="100%" height="200px" data-test-subj={`${paramsProperty}JsonEditor`} - aria-label={areaLabel} + aria-label={ariaLabel} {...euiCodeEditorProps} editorDidMount={onEditorMount} onChange={(xjson: string) => { diff --git a/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/index_connector.ts b/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/index_connector.ts index 838ca43b197247..3caaab6dacccac 100644 --- a/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/index_connector.ts +++ b/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/index_connector.ts @@ -39,7 +39,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await commonScreenshots.takeScreenshot('index-connector', screenshotDirectories); const saveTestButton = await testSubjects.find('create-connector-flyout-save-test-btn'); await saveTestButton.click(); - await testSubjects.setValue('actionJsonEditor', indexDocument); + await testSubjects.setValue('documentToIndex', indexDocument); await commonScreenshots.takeScreenshot('index-params-test', screenshotDirectories); const flyOutCancelButton = await testSubjects.find('euiFlyoutCloseButton'); await flyOutCancelButton.click(); diff --git a/x-pack/test/security_solution_cypress/cypress/screens/common/rule_actions.ts b/x-pack/test/security_solution_cypress/cypress/screens/common/rule_actions.ts index e6d44f0918c6d9..21d8bfdc0c0ce2 100644 --- a/x-pack/test/security_solution_cypress/cypress/screens/common/rule_actions.ts +++ b/x-pack/test/security_solution_cypress/cypress/screens/common/rule_actions.ts @@ -42,7 +42,7 @@ export const EMAIL_CONNECTOR_SERVICE_SELECTOR = '[data-test-subj="emailServiceSe export const FORM_VALIDATION_ERROR = '.euiFormErrorText'; -export const JSON_EDITOR = "[data-test-subj='actionJsonEditor']"; +export const JSON_EDITOR = "[data-test-subj='documentToIndex']"; export const INDEX_SELECTOR = "[data-test-subj='.index-siem-ActionTypeSelectOption']"; From 0ac7dbd4f61acc5cf523a8ecebac661d88f4ffd8 Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Wed, 20 Dec 2023 08:11:24 -0800 Subject: [PATCH 039/116] [Connectors][IBM Resilient] Edit required labels and automate screenshots (#166022) --- .../action-types/resilient.asciidoc | 58 ++++++++++-------- .../connectors/images/resilient-connector.png | Bin 152361 -> 173548 bytes .../images/resilient-params-test.png | Bin 184380 -> 104332 bytes .../resilient/case_fields_preview.test.tsx | 2 +- .../connectors/resilient/translations.ts | 2 +- .../resilient/resilient_params.tsx | 10 ++- .../connector_types/resilient/translations.ts | 4 +- .../ibm_resilient_connector.ts | 57 +++++++++++++++++ .../stack_connectors/index.ts | 1 + .../e2e/explore/cases/connector_options.cy.ts | 2 +- 10 files changed, 102 insertions(+), 34 deletions(-) create mode 100644 x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/ibm_resilient_connector.ts diff --git a/docs/management/connectors/action-types/resilient.asciidoc b/docs/management/connectors/action-types/resilient.asciidoc index 04531a71dee624..ad8ebffcf0bb97 100644 --- a/docs/management/connectors/action-types/resilient.asciidoc +++ b/docs/management/connectors/action-types/resilient.asciidoc @@ -8,7 +8,7 @@ :frontmatter-tags-content-type: [how-to] :frontmatter-tags-user-goals: [configure] -The IBM Resilient connector uses the https://developer.ibm.com/security/resilient/rest/[RESILIENT REST v2] to create IBM Resilient incidents. +The {ibm-r} connector uses the https://developer.ibm.com/security/resilient/rest/[RESILIENT REST v2] to create {ibm-r} incidents. [float] [[define-resilient-ui]] @@ -18,47 +18,51 @@ You can create connectors in *{stack-manage-app} > {connectors-ui}* or as needed when you're creating a rule. For example: [role="screenshot"] -image::management/connectors/images/resilient-connector.png[IBM Resilient connector] +image::management/connectors/images/resilient-connector.png[{ibm-r} connector] +// NOTE: This is an autogenerated screenshot. Do not edit it directly. [float] [[resilient-connector-configuration]] ==== Connector configuration -IBM Resilient connectors have the following configuration properties: +{ibm-r} connectors have the following configuration properties: -Name:: The name of the connector. -URL:: IBM Resilient instance URL. -Organization ID:: IBM Resilient organization ID. -API key ID:: The authentication key ID for HTTP Basic authentication. -API key secret:: The authentication key secret for HTTP Basic authentication. +API key ID:: +The authentication key ID for HTTP Basic authentication. +API key secret:: +The authentication key secret for HTTP Basic authentication. +Organization ID:: +The {ibm-r} organization ID. +URL:: +The {ibm-r} instance URL. [float] [[resilient-action-configuration]] === Test connectors -You can test connectors with the <> or -as you're creating or editing the connector in {kib}. For example: +You can test connectors as you're creating or editing the connector in {kib}. +For example: [role="screenshot"] -image::management/connectors/images/resilient-params-test.png[IBM Resilient params test] - - -IBM Resilient actions have the following configuration properties. - -Incident types:: The type of the incident. -Severity code:: The severity of the incident. -Name:: A name for the issue, used for searching the contents of the knowledge base. -Description:: The details about the incident. -Additional comments:: Additional information for the client, such as how to troubleshoot the issue. +image::management/connectors/images/resilient-params-test.png[IBM Resilient connector test options] +// NOTE: This is an autogenerated screenshot. Do not edit it directly. + +{ibm-r} actions have the following configuration properties. + +Additional comments:: +Extra information for the client, such as how to troubleshoot the issue. +Description:: +The details about the incident. +Incident type:: +The type of the incident. +Name:: +A name for the issue, used for searching the contents of the knowledge base. +Severity:: +The severity of the incident. [float] [[resilient-connector-networking-configuration]] === Connector networking configuration -Use the <> to customize connector networking configurations, such as proxies, certificates, or TLS settings. You can set configurations that apply to all your connectors or use `xpack.actions.customHostSettings` to set per-host configurations. - -[float] -[[configuring-resilient]] -=== Configure IBM Resilient - -IBM Resilient offers https://www.ibm.com/security/intelligent-orchestration/resilient[Instances], which you can use to test incidents. +Use the <> to customize connector networking configurations, such as proxies, certificates, or TLS settings. +You can set configurations that apply to all your connectors or use `xpack.actions.customHostSettings` to set per-host configurations. diff --git a/docs/management/connectors/images/resilient-connector.png b/docs/management/connectors/images/resilient-connector.png index b7d216d150f8c1862601e976fddcc5f78eae595e..b5d08ed5987b23c934375c5be7d42b01c52f838c 100644 GIT binary patch literal 173548 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
jC3Q>UcSo}T_yjduzT)CvWtu?*LzRZk9M;^X5% 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

UF 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 DaAFsS diff --git a/x-pack/plugins/cases/public/components/connectors/resilient/case_fields_preview.test.tsx b/x-pack/plugins/cases/public/components/connectors/resilient/case_fields_preview.test.tsx index dd6b9f08c0d099..f4ac54c1eb9253 100644 --- a/x-pack/plugins/cases/public/components/connectors/resilient/case_fields_preview.test.tsx +++ b/x-pack/plugins/cases/public/components/connectors/resilient/case_fields_preview.test.tsx @@ -81,7 +81,7 @@ describe('Jira Fields: Preview', () => { const getByText = createQueryWithMarkup(screen.getByText); - expect(getByText('Incident Types: Malware, Denial of Service')).toBeInTheDocument(); + expect(getByText('Incident types: Malware, Denial of Service')).toBeInTheDocument(); expect(getByText('Severity: Medium')).toBeInTheDocument(); }); }); diff --git a/x-pack/plugins/cases/public/components/connectors/resilient/translations.ts b/x-pack/plugins/cases/public/components/connectors/resilient/translations.ts index 1b63a5098e92a5..132234f0d2d57b 100644 --- a/x-pack/plugins/cases/public/components/connectors/resilient/translations.ts +++ b/x-pack/plugins/cases/public/components/connectors/resilient/translations.ts @@ -31,7 +31,7 @@ export const INCIDENT_TYPES_PLACEHOLDER = i18n.translate( export const INCIDENT_TYPES_LABEL = i18n.translate( 'xpack.cases.connectors.resilient.incidentTypesLabel', { - defaultMessage: 'Incident Types', + defaultMessage: 'Incident types', } ); diff --git a/x-pack/plugins/stack_connectors/public/connector_types/resilient/resilient_params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/resilient/resilient_params.tsx index 04a0ba4f85ec4e..fb53e3567186c0 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/resilient/resilient_params.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/resilient/resilient_params.tsx @@ -11,6 +11,7 @@ import { EuiComboBox, EuiSelect, EuiSpacer, + EuiText, EuiTitle, EuiComboBoxOptionOption, EuiSelectOption, @@ -171,7 +172,7 @@ const ResilientParamsFields: React.FunctionComponent + Required + + } > { + resilientSimulatorUrl = kibanaServer.resolveUrl( + getExternalServiceSimulatorPath(ExternalServiceSimulator.RESILIENT) + ); + smallUrl = resilientSimulatorUrl.replace('/elastic:changeme@', '/'); + }); + + beforeEach(async () => { + await pageObjects.common.navigateToApp('connectors'); + await pageObjects.header.waitUntilLoadingHasFinished(); + }); + + it('ibm resilient connector creation screenshots', async () => { + await pageObjects.common.navigateToApp('connectors'); + await pageObjects.header.waitUntilLoadingHasFinished(); + await actions.common.openNewConnectorForm('resilient'); + await testSubjects.setValue('nameInput', 'IBM Resilient test connector'); + await testSubjects.setValue('config.apiUrl-input', smallUrl); + await testSubjects.setValue('config.orgId-input', '201'); + await testSubjects.setValue('secrets.apiKeyId-input', 'tester'); + await testSubjects.setValue('secrets.apiKeySecret-input', 'testkey'); + await commonScreenshots.takeScreenshot('resilient-connector', screenshotDirectories); + await testSubjects.click('create-connector-flyout-save-test-btn'); + // Close all toasts since it is unable to get incident types from example site + await pageObjects.common.clearAllToasts(); + await pageObjects.header.waitUntilLoadingHasFinished(); + await pageObjects.common.clearAllToasts(); + await commonScreenshots.takeScreenshot('resilient-params-test', screenshotDirectories); + await testSubjects.click('euiFlyoutCloseButton'); + }); + }); +} diff --git a/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/index.ts b/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/index.ts index 8c3454772fffaf..5b9afd0ffd32d4 100644 --- a/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/index.ts +++ b/x-pack/test/screenshot_creation/apps/response_ops_docs/stack_connectors/index.ts @@ -57,6 +57,7 @@ export default function ({ loadTestFile, getService }: FtrProviderContext) { loadTestFile(require.resolve('./bedrock_connector')); loadTestFile(require.resolve('./email_connector')); loadTestFile(require.resolve('./generative_ai_connector')); + loadTestFile(require.resolve('./ibm_resilient_connector')); loadTestFile(require.resolve('./index_connector')); loadTestFile(require.resolve('./jira_connector')); loadTestFile(require.resolve('./opsgenie_connector')); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/connector_options.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/connector_options.cy.ts index 9bff9b341c68a3..274d839c95a878 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/connector_options.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/connector_options.cy.ts @@ -76,7 +76,7 @@ describe('Cases connector incident fields', { tags: ['@ess', '@serverless'] }, ( cy.get(CONNECTOR_TITLE).should('have.text', getIbmResilientConnectorOptions().title); cy.get(CONNECTOR_CARD_DETAILS).should( 'have.text', - `Incident Types: ${getIbmResilientConnectorOptions().incidentTypes.join(', ')}Severity: ${ + `Incident types: ${getIbmResilientConnectorOptions().incidentTypes.join(', ')}Severity: ${ getIbmResilientConnectorOptions().severity }` ); From 36c9d5dd3dd51f70c8d38a0a28e5ddb59d8520d7 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Wed, 20 Dec 2023 17:15:54 +0100 Subject: [PATCH 040/116] Require page reload when changing `timepicker:quickRanges` (#173747) ## Summary fix https://github.com/elastic/kibana/issues/172601 I reviewed how this setting is used. It is directly used in a lot of places and it is hard to guarantee/fix that all places pick up the new setting. Safer to ask to reload. --- src/plugins/data/server/ui_settings.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/data/server/ui_settings.ts b/src/plugins/data/server/ui_settings.ts index 46794e0a3c9c60..b7b665689c1063 100644 --- a/src/plugins/data/server/ui_settings.ts +++ b/src/plugins/data/server/ui_settings.ts @@ -471,6 +471,7 @@ export function getUiSettings( '', }, }), + requiresPageReload: true, schema: enableValidations ? schema.arrayOf( schema.object({ From 9522d7424f1a707d6629486e9cd13a6c3da7aa2b Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 20 Dec 2023 18:08:29 +0100 Subject: [PATCH 041/116] [SLOs] Use more apm data in temp slo docs (#173386) ## Summary fixes https://github.com/elastic/kibana/issues/172727 Use more APM data in temp slo docs !! --- .../services/slo/__snapshots__/create_slo.test.ts.snap | 8 ++++---- .../services/slo/__snapshots__/reset_slo.test.ts.snap | 8 ++++---- .../helpers/create_temp_summary.ts | 10 ++++++---- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/observability/server/services/slo/__snapshots__/create_slo.test.ts.snap b/x-pack/plugins/observability/server/services/slo/__snapshots__/create_slo.test.ts.snap index 8c2cfc3b0d1f5f..7c0ea00b409c98 100644 --- a/x-pack/plugins/observability/server/services/slo/__snapshots__/create_slo.test.ts.snap +++ b/x-pack/plugins/observability/server/services/slo/__snapshots__/create_slo.test.ts.snap @@ -149,8 +149,8 @@ Array [ "goodEvents": 0, "isTempDoc": true, "service": Object { - "environment": null, - "name": null, + "environment": "irrelevant", + "name": "irrelevant", }, "sliValue": -1, "slo": Object { @@ -180,8 +180,8 @@ Array [ "statusCode": 0, "totalEvents": 0, "transaction": Object { - "name": null, - "type": null, + "name": "irrelevant", + "type": "irrelevant", }, }, "id": "slo-unique-id", diff --git a/x-pack/plugins/observability/server/services/slo/__snapshots__/reset_slo.test.ts.snap b/x-pack/plugins/observability/server/services/slo/__snapshots__/reset_slo.test.ts.snap index 9ad1d09bd1ef84..d70d8ebfc00736 100644 --- a/x-pack/plugins/observability/server/services/slo/__snapshots__/reset_slo.test.ts.snap +++ b/x-pack/plugins/observability/server/services/slo/__snapshots__/reset_slo.test.ts.snap @@ -435,8 +435,8 @@ exports[`ResetSLO resets all associated resources 11`] = ` "goodEvents": 0, "isTempDoc": true, "service": Object { - "environment": null, - "name": null, + "environment": "irrelevant", + "name": "irrelevant", }, "sliValue": -1, "slo": Object { @@ -469,8 +469,8 @@ exports[`ResetSLO resets all associated resources 11`] = ` "statusCode": 0, "totalEvents": 0, "transaction": Object { - "name": null, - "type": null, + "name": "irrelevant", + "type": "irrelevant", }, }, "id": "slo-irrelevant", diff --git a/x-pack/plugins/observability/server/services/slo/summary_transform_generator/helpers/create_temp_summary.ts b/x-pack/plugins/observability/server/services/slo/summary_transform_generator/helpers/create_temp_summary.ts index 166ca0198dbb81..8e1939647bac8b 100644 --- a/x-pack/plugins/observability/server/services/slo/summary_transform_generator/helpers/create_temp_summary.ts +++ b/x-pack/plugins/observability/server/services/slo/summary_transform_generator/helpers/create_temp_summary.ts @@ -9,14 +9,16 @@ import { ALL_VALUE } from '@kbn/slo-schema'; import { SLO } from '../../../../domain/models'; export function createTempSummaryDocument(slo: SLO, spaceId: string) { + const apmParams = 'environment' in slo.indicator.params ? slo.indicator.params : null; + return { service: { - environment: null, - name: null, + environment: apmParams?.environment ?? null, + name: apmParams?.service ?? null, }, transaction: { - name: null, - type: null, + name: apmParams?.transactionName ?? null, + type: apmParams?.transactionType ?? null, }, slo: { indicator: { From f0af2b91b471c47b3a548c83be0e5f03169f04c4 Mon Sep 17 00:00:00 2001 From: Elena Stoeva <59341489+ElenaStoeva@users.noreply.github.com> Date: Wed, 20 Dec 2023 17:11:13 +0000 Subject: [PATCH 042/116] [Index Management] Fix empty error toast message from extension actions (#173620) Fixes https://github.com/elastic/kibana/issues/118464 Similar to https://github.com/elastic/kibana/pull/162656 ## Summary This PR fixes the empty error toast that appears from a failed extension action. For example, when the ILM extension action "Retry lifecycle step" fails, it would display an empty error toast on cloud (or it would display "Bad request" when running locally): https://github.com/elastic/kibana/assets/59341489/37c3113a-4f2b-4157-ab0c-658c410349c8 With these changes, the error toast also displays the message: https://github.com/elastic/kibana/assets/59341489/1f6df5c4-381f-4039-b5f3-746c5783bd2c **How to test:** For testing a failing "Retry lifecycle step" action, I followed the instructions in this [README](https://github.com/elastic/kibana/blob/main/x-pack/plugins/index_lifecycle_management/README.md) file to create a lifecycle policy error. The changes in this PR can be tested in its [CI Cloud deployment](https://kibana-pr-173620.kb.us-west2.gcp.elastic-cloud.com:9243/). --- .../public/application/store/actions/extension_action.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/index_management/public/application/store/actions/extension_action.js b/x-pack/plugins/index_management/public/application/store/actions/extension_action.js index 0fb49eea24b4dd..95a94bf1d16969 100644 --- a/x-pack/plugins/index_management/public/application/store/actions/extension_action.js +++ b/x-pack/plugins/index_management/public/application/store/actions/extension_action.js @@ -15,7 +15,7 @@ export const performExtensionAction = try { await requestMethod(indexNames, httpService.httpClient); } catch (error) { - notificationService.showDangerToast(error.message); + notificationService.showDangerToast(error.body.message); return; } dispatch(reloadIndices(indexNames)); From a4af14e6596fe5c4b8630e6fea021916a9039b98 Mon Sep 17 00:00:00 2001 From: Ying Mao Date: Wed, 20 Dec 2023 12:45:15 -0500 Subject: [PATCH 043/116] [Response Ops][Alerting] Fix null alerts client reference in rule executors (#173560) Resolves https://github.com/elastic/kibana/issues/170683 ## Summary This scenario occurs when there is an issue installing alert resources for a context for a rule type that is using the framework alerts-as-data reporting. When the alert resources are not installed, the task runner passes in `null` for the alertsClient into the executors so when the rule executor is using the new alerts client (vs the alert factory), we see a null accessor error. We only see this in the ES query rule type because all other rule types using the alerts client performs a check at the start of rule execution. This PR adds that check to the ES query rule type, and in all cases, has the executor throw a controlled `AlertsClientError` if this scenario is encountered. ## To Verify 1. Start up ES and Kibana on `main` and create an ES query run 2. Stop Kibana. Switch to this branch. Make a non-additive change to the alerts field map, like ``` --- a/packages/kbn-alerts-as-data-utils/src/field_maps/alert_field_map.ts +++ b/packages/kbn-alerts-as-data-utils/src/field_maps/alert_field_map.ts @@ -51,7 +51,7 @@ export const alertFieldMap = { required: false, }, [ALERT_CASE_IDS]: { - type: 'keyword', + type: 'date', array: true, required: false, }, ``` 3. Start Kibana. See errors during startup about not being able to install alert resources. See error thrown during rule execution about the alerts client being expected. --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../server/alerts_client/alerts_client_error.ts | 15 +++++++++++++++ .../alerting/server/alerts_client/index.ts | 1 + x-pack/plugins/alerting/server/index.ts | 2 +- .../metric_threshold_executor.ts | 4 ++-- .../register_anomaly_detection_alert_type.ts | 10 ++++++++-- .../server/rule_types/es_query/executor.ts | 14 +++++++++----- .../rule_types/index_threshold/rule_type.ts | 16 ++++++++++------ 7 files changed, 46 insertions(+), 16 deletions(-) create mode 100644 x-pack/plugins/alerting/server/alerts_client/alerts_client_error.ts diff --git a/x-pack/plugins/alerting/server/alerts_client/alerts_client_error.ts b/x-pack/plugins/alerting/server/alerts_client/alerts_client_error.ts new file mode 100644 index 00000000000000..e553618ea921d9 --- /dev/null +++ b/x-pack/plugins/alerting/server/alerts_client/alerts_client_error.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export class AlertsClientError extends Error { + constructor() { + super( + `Expected alertsClient not to be null! There may have been an issue installing alert resources.` + ); + Object.setPrototypeOf(this, AlertsClientError.prototype); + } +} diff --git a/x-pack/plugins/alerting/server/alerts_client/index.ts b/x-pack/plugins/alerting/server/alerts_client/index.ts index a1c0a309e0dc4c..c141ac8167e9bc 100644 --- a/x-pack/plugins/alerting/server/alerts_client/index.ts +++ b/x-pack/plugins/alerting/server/alerts_client/index.ts @@ -9,3 +9,4 @@ export { type LegacyAlertsClientParams, LegacyAlertsClient } from './legacy_aler export { AlertsClient } from './alerts_client'; export type { AlertRuleData } from './types'; export { sanitizeBulkErrorResponse } from './lib'; +export { AlertsClientError } from './alerts_client_error'; diff --git a/x-pack/plugins/alerting/server/index.ts b/x-pack/plugins/alerting/server/index.ts index 5be648354e61f4..916d1bd11a384e 100644 --- a/x-pack/plugins/alerting/server/index.ts +++ b/x-pack/plugins/alerting/server/index.ts @@ -69,7 +69,7 @@ export { isValidAlertIndexName, InstallShutdownError, } from './alerts_service'; -export { sanitizeBulkErrorResponse } from './alerts_client'; +export { sanitizeBulkErrorResponse, AlertsClientError } from './alerts_client'; export { getDataStreamAdapter } from './alerts_service/lib/data_stream_adapter'; export const plugin = async (initContext: PluginInitializerContext) => { diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts index 4a51722288c054..830e50d04f5c7c 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts @@ -14,7 +14,7 @@ import { AlertInstanceState as AlertState, RecoveredActionGroup, } from '@kbn/alerting-plugin/common'; -import { RuleExecutorOptions, RuleTypeState } from '@kbn/alerting-plugin/server'; +import { AlertsClientError, RuleExecutorOptions, RuleTypeState } from '@kbn/alerting-plugin/server'; import type { TimeUnitChar } from '@kbn/observability-plugin/common'; import { getAlertUrl } from '@kbn/observability-plugin/common'; import { ObservabilityMetricsAlert } from '@kbn/alerts-as-data-utils'; @@ -120,7 +120,7 @@ export const createMetricThresholdExecutor = const { alertsClient, savedObjectsClient } = services; if (!alertsClient) { - throw new Error(`Expected alertsClient to be defined but it was not!`); + throw new AlertsClientError(); } const alertReporter: MetricThresholdAlertReporter = async ( diff --git a/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts b/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts index 2dadf5e510268a..d270ca3166e2f9 100644 --- a/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts +++ b/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts @@ -15,7 +15,11 @@ import type { RuleTypeParams, RuleTypeState, } from '@kbn/alerting-plugin/common'; -import { IRuleTypeAlerts, RuleExecutorOptions } from '@kbn/alerting-plugin/server'; +import { + AlertsClientError, + IRuleTypeAlerts, + RuleExecutorOptions, +} from '@kbn/alerting-plugin/server'; import { ALERT_REASON, ALERT_URL } from '@kbn/rule-data-utils'; import { MlAnomalyDetectionAlert } from '@kbn/alerts-as-data-utils'; import { ES_FIELD_TYPES } from '@kbn/field-types'; @@ -249,7 +253,9 @@ export function registerAnomalyDetectionAlertType({ ); const { alertsClient } = services; - if (!alertsClient) return { state: {} }; + if (!alertsClient) { + throw new AlertsClientError(); + } const executionResult = await execute(params, spaceId); diff --git a/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.ts b/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.ts index d0d440c7694871..7d8d2df355c16c 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.ts @@ -15,6 +15,7 @@ import { ALERT_URL, } from '@kbn/rule-data-utils'; +import { AlertsClientError } from '@kbn/alerting-plugin/server'; import { ComparatorFns } from '../../../common'; import { addMessages, @@ -48,10 +49,13 @@ export async function executor(core: CoreSetup, options: ExecutorOptions Date: Wed, 20 Dec 2023 12:21:37 -0600 Subject: [PATCH 044/116] [ci/pr] Remove renovate from allowed_list (#173285) Renovate pull requests often sit inactive before a developer is able to review. While inactive renovate is adding new versions, or the pull request becomes outdated and CI cycles are not used. This moves renovate CI on pull requests to a manual trigger, either via `buildkite test this` or `/ci`. --- .buildkite/pull_requests.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/.buildkite/pull_requests.json b/.buildkite/pull_requests.json index 02686fe378b4f8..6db75b64a1e08c 100644 --- a/.buildkite/pull_requests.json +++ b/.buildkite/pull_requests.json @@ -8,7 +8,6 @@ "enabled": true, "allow_org_users": true, "allowed_repo_permissions": ["admin", "write"], - "allowed_list": ["barlowm", "renovate[bot]"], "set_commit_status": true, "commit_status_context": "kibana-ci", "build_on_commit": true, @@ -59,7 +58,6 @@ "enabled": true, "allow_org_users": true, "allowed_repo_permissions": ["admin", "write"], - "allowed_list": ["barlowm", "renovate[bot]"], "set_commit_status": true, "commit_status_context": "kibana-ci-test", "build_on_commit": true, From 73f53f59d0bda0434f324e5ded8b935ef087c16d Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Wed, 20 Dec 2023 19:27:51 +0100 Subject: [PATCH 045/116] [Observability Overview] Fix unable to load page due to an error in MetricWithSparkline (#173773) Fixes #173768 ## Summary In order to check the issue, you need to generate some host data and then check the observability overview page. |Local|Oblt| |---|---| |![image](https://github.com/elastic/kibana/assets/12370520/c3113dd3-0b30-4c7b-a222-70f9045ebbdd)![image](https://github.com/elastic/kibana/assets/12370520/434d2266-e033-4761-92ad-c4cea6c351a0)|![image](https://github.com/elastic/kibana/assets/12370520/02af7c79-9119-44c6-a4ce-d24591014b09)| --- .../components/sections/metrics/metric_with_sparkline.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/observability/public/pages/overview/components/sections/metrics/metric_with_sparkline.tsx b/x-pack/plugins/observability/public/pages/overview/components/sections/metrics/metric_with_sparkline.tsx index 3e4b0476b50750..bd292a2bf88cba 100644 --- a/x-pack/plugins/observability/public/pages/overview/components/sections/metrics/metric_with_sparkline.tsx +++ b/x-pack/plugins/observability/public/pages/overview/components/sections/metrics/metric_with_sparkline.tsx @@ -36,7 +36,7 @@ export function MetricWithSparkline({ id, formatter, value, timeseries, color }: const theme = [EUI_SPARKLINE_THEME_PARTIAL]; const baseTheme = isDarkTheme ? DARK_THEME : LIGHT_THEME; - const colors = theme[1].colors?.vizColors ?? []; + const colors = baseTheme.colors?.vizColors ?? []; if (!value) { return ( From 4c2ea7d89c7b8a711c576d720702be2757848578 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Wed, 20 Dec 2023 20:31:14 +0200 Subject: [PATCH 046/116] [Actions] Pass the Kibana requests to the executor of system actions (#173763) ## Summary System actions, like the case action, may need access to the Kibana request to initiate clients (cases client for example) or services. This PR passes the Kibana request to the `executor` of system actions. It does not pass the request to nonsystem action types. ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../server/lib/action_executor.test.ts | 72 +++++++++++++++++++ .../actions/server/lib/action_executor.ts | 1 + x-pack/plugins/actions/server/types.ts | 1 + 3 files changed, 74 insertions(+) diff --git a/x-pack/plugins/actions/server/lib/action_executor.test.ts b/x-pack/plugins/actions/server/lib/action_executor.test.ts index c58e16a11aa4af..f283732c16f2aa 100644 --- a/x-pack/plugins/actions/server/lib/action_executor.test.ts +++ b/x-pack/plugins/actions/server/lib/action_executor.test.ts @@ -720,6 +720,7 @@ test('successfully executes with system connector', async () => { secrets: {}, params: { foo: true }, logger: loggerMock, + request: {}, }); expect(loggerMock.debug).toBeCalledWith( @@ -812,6 +813,75 @@ test('successfully executes with system connector', async () => { `); }); +test('passes the Kibana request on the executor of a system action', async () => { + const actionType: jest.Mocked = { + id: '.cases', + name: 'Cases', + minimumLicenseRequired: 'platinum', + supportedFeatureIds: ['alerting'], + isSystemActionType: true, + validate: { + config: { schema: schema.any() }, + secrets: { schema: schema.any() }, + params: { schema: schema.any() }, + }, + executor: jest.fn(), + }; + + actionTypeRegistry.get.mockReturnValueOnce(actionType); + await actionExecutor.execute({ ...executeParams, actionId: 'system-connector-.cases' }); + + expect(actionType.executor).toHaveBeenCalledWith({ + actionId: 'system-connector-.cases', + services: expect.anything(), + config: {}, + secrets: {}, + params: { foo: true }, + logger: loggerMock, + request: {}, + }); +}); + +test('does not pass the Kibana request on the executor if the action is not a system action', async () => { + const actionType: jest.Mocked = { + id: 'test', + name: 'Test', + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + validate: { + config: { schema: schema.object({ bar: schema.boolean() }) }, + secrets: { schema: schema.object({ baz: schema.boolean() }) }, + params: { schema: schema.object({ foo: schema.boolean() }) }, + }, + executor: jest.fn(), + }; + + const actionSavedObject = { + id: '1', + type: 'action', + attributes: { + name: '1', + actionTypeId: 'test', + config: { + bar: true, + }, + secrets: { + baz: true, + }, + isMissingSecrets: false, + }, + references: [], + }; + + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject); + actionTypeRegistry.get.mockReturnValueOnce(actionType); + await actionExecutor.execute(executeParams); + + const args = actionType.executor.mock.calls[0][0]; + + expect(args.request).toBeUndefined(); +}); + test('successfully authorize system actions', async () => { const actionType: jest.Mocked = { id: '.cases', @@ -1278,6 +1348,7 @@ test('should not throws an error if actionType is system action', async () => { secrets: {}, params: { foo: true }, logger: loggerMock, + request: {}, }); }); @@ -1510,6 +1581,7 @@ test('should not throw error if action is system action and isESOCanEncrypt is f secrets: {}, params: { foo: true }, logger: loggerMock, + request: {}, }); expect(loggerMock.debug).toBeCalledWith( diff --git a/x-pack/plugins/actions/server/lib/action_executor.ts b/x-pack/plugins/actions/server/lib/action_executor.ts index 69aab56e4e5b38..16d3d70c5b97e5 100644 --- a/x-pack/plugins/actions/server/lib/action_executor.ts +++ b/x-pack/plugins/actions/server/lib/action_executor.ts @@ -259,6 +259,7 @@ export class ActionExecutor { configurationUtilities, logger, source, + ...(actionType.isSystemActionType ? { request } : {}), }); } catch (err) { if ( diff --git a/x-pack/plugins/actions/server/types.ts b/x-pack/plugins/actions/server/types.ts index 6a038d5092363f..0d9cc99ac61861 100644 --- a/x-pack/plugins/actions/server/types.ts +++ b/x-pack/plugins/actions/server/types.ts @@ -76,6 +76,7 @@ export interface ActionTypeExecutorOptions< taskInfo?: TaskInfo; configurationUtilities: ActionsConfigurationUtilities; source?: ActionExecutionSource; + request?: KibanaRequest; } export type ActionResult = Connector; From dc25e896fe05a0ef0c53f53c56fc1148dff141c5 Mon Sep 17 00:00:00 2001 From: Ersin Erdal <92688503+ersin-erdal@users.noreply.github.com> Date: Wed, 20 Dec 2023 19:51:33 +0100 Subject: [PATCH 047/116] Distinguish error types(source) for actions serverless metrics (#171416) Resolves: #168635 This PR intends to add `source` data (user or framework) to the errors that returned by the actions plugin and use them to create two new metrics in TaskManager. New metrics: ``` USER_ERRORS = 'user_errors' FRAMEWORK_ERRORS = 'framework_errors' ``` Error source types: ``` FRAMEWORK = 'framework' USER = 'user' ``` I tried to keep the errorSource definition close to the place that the error is thrown as much as possible. To check the types / numbers for these, you can `curl $KB_URL/api/task_manager/metrics?reset=false` to get the values that our support infrastructure will be using. To test how well this code works, you can inject errors (add code) into a connector executor that you use in an alert action, and then use the endpoint to see how the errors were counted. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/actions/common/types.ts | 2 + .../server/lib/action_executor.test.ts | 86 +- .../actions/server/lib/action_executor.ts | 79 +- .../server/lib/task_runner_factory.test.ts | 57 +- .../actions/server/lib/task_runner_factory.ts | 14 +- .../plugins/task_manager/common/constants.ts | 11 + x-pack/plugins/task_manager/common/index.ts | 8 + .../server/metrics/create_aggregator.test.ts | 1872 +++++++++++++++-- .../task_run_metrics_aggregator.test.ts | 233 +- .../metrics/task_run_metrics_aggregator.ts | 26 +- .../server/task_running/errors.test.ts | 22 + .../server/task_running/errors.ts | 25 +- .../server/task_running/task_runner.test.ts | 4 +- .../server/task_running/task_runner.ts | 2 +- x-pack/plugins/task_manager/tsconfig.json | 1 + .../tests/actions/connector_types/bedrock.ts | 5 + .../actions/connector_types/cases_webhook.ts | 20 +- .../actions/connector_types/d3security.ts | 4 + .../tests/actions/connector_types/jira.ts | 15 +- .../tests/actions/connector_types/openai.ts | 5 + .../tests/actions/connector_types/opsgenie.ts | 18 +- .../actions/connector_types/resilient.ts | 14 +- .../connector_types/servicenow_itom.ts | 12 +- .../connector_types/servicenow_itsm.ts | 15 +- .../actions/connector_types/servicenow_sir.ts | 15 +- .../tests/actions/connector_types/swimlane.ts | 13 +- .../tests/actions/connector_types/tines.ts | 19 +- .../actions/sub_action_framework/index.ts | 7 + .../spaces_only/tests/actions/execute.ts | 3 + .../spaces_only/tests/actions/migrations.ts | 1 + 30 files changed, 2269 insertions(+), 339 deletions(-) create mode 100644 x-pack/plugins/task_manager/common/constants.ts create mode 100644 x-pack/plugins/task_manager/common/index.ts diff --git a/x-pack/plugins/actions/common/types.ts b/x-pack/plugins/actions/common/types.ts index 44d7516595d191..2560cbae3f7e78 100644 --- a/x-pack/plugins/actions/common/types.ts +++ b/x-pack/plugins/actions/common/types.ts @@ -6,6 +6,7 @@ */ import { LicenseType } from '@kbn/licensing-plugin/common/types'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; export { AlertingConnectorFeatureId, @@ -47,6 +48,7 @@ export interface ActionTypeExecutorResult { serviceMessage?: string; data?: Data; retry?: null | boolean | Date; + errorSource?: TaskErrorSource; } export type ActionTypeExecutorRawResult = ActionTypeExecutorResult & { diff --git a/x-pack/plugins/actions/server/lib/action_executor.test.ts b/x-pack/plugins/actions/server/lib/action_executor.test.ts index f283732c16f2aa..9af58047878d15 100644 --- a/x-pack/plugins/actions/server/lib/action_executor.test.ts +++ b/x-pack/plugins/actions/server/lib/action_executor.test.ts @@ -23,6 +23,8 @@ import { securityMock } from '@kbn/security-plugin/server/mocks'; import { finished } from 'stream/promises'; import { PassThrough } from 'stream'; import { SecurityConnectorFeatureId } from '../../common'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; +import { getErrorSource } from '@kbn/task-manager-plugin/server/task_running'; const actionExecutor = new ActionExecutor({ isESOCanEncrypt: true }); const services = actionsMock.createServices(); @@ -911,6 +913,53 @@ test('successfully authorize system actions', async () => { }); }); +test('actionType Executor returns status "error" and an error message', async () => { + const actionType: jest.Mocked = { + id: 'test', + name: 'Test', + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + validate: { + config: { schema: schema.any() }, + secrets: { schema: schema.any() }, + params: { schema: schema.any() }, + }, + executor: jest.fn().mockReturnValue({ + actionId: 'test', + status: 'error', + message: 'test error message', + retry: true, + }), + }; + const actionSavedObject = { + id: '1', + type: 'action', + attributes: { + name: '1', + actionTypeId: 'test', + config: { + bar: true, + }, + secrets: { + baz: true, + }, + isMissingSecrets: false, + }, + references: [], + }; + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject); + actionTypeRegistry.get.mockReturnValueOnce(actionType); + const result = await actionExecutor.execute(executeParams); + + expect(result).toEqual({ + actionId: 'test', + errorSource: TaskErrorSource.USER, + message: 'test error message', + retry: true, + status: 'error', + }); +}); + test('Execute of SentinelOne sub-actions require create privilege', async () => { const actionType: jest.Mocked = { id: '.sentinelone', @@ -1130,6 +1179,7 @@ test('throws an error when config is invalid', async () => { status: 'error', retry: false, message: `error validating action type config: [param1]: expected value of type [string] but got [undefined]`, + errorSource: TaskErrorSource.FRAMEWORK, }); }); @@ -1169,6 +1219,7 @@ test('returns an error when connector is invalid', async () => { status: 'error', retry: false, message: `error validating action type connector: config must be defined`, + errorSource: TaskErrorSource.FRAMEWORK, }); }); @@ -1207,6 +1258,7 @@ test('throws an error when params is invalid', async () => { status: 'error', retry: false, message: `error validating action params: [param1]: expected value of type [string] but got [undefined]`, + errorSource: TaskErrorSource.FRAMEWORK, }); }); @@ -1214,9 +1266,13 @@ test('throws an error when failing to load action through savedObjectsClient', a encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockRejectedValueOnce( new Error('No access') ); - await expect(actionExecutor.execute(executeParams)).rejects.toThrowErrorMatchingInlineSnapshot( - `"No access"` - ); + + try { + await actionExecutor.execute(executeParams); + } catch (e) { + expect(e.message).toBe('No access'); + expect(getErrorSource(e)).toBe(TaskErrorSource.FRAMEWORK); + } }); test('throws an error if actionType is not enabled', async () => { @@ -1246,9 +1302,13 @@ test('throws an error if actionType is not enabled', async () => { actionTypeRegistry.ensureActionTypeEnabled.mockImplementationOnce(() => { throw new Error('not enabled for test'); }); - await expect(actionExecutor.execute(executeParams)).rejects.toThrowErrorMatchingInlineSnapshot( - `"not enabled for test"` - ); + + try { + await actionExecutor.execute(executeParams); + } catch (e) { + expect(e.message).toBe('not enabled for test'); + expect(getErrorSource(e)).toBe(TaskErrorSource.FRAMEWORK); + } expect(actionTypeRegistry.ensureActionTypeEnabled).toHaveBeenCalledWith('test'); }); @@ -1364,11 +1424,15 @@ test('throws an error when passing isESOCanEncrypt with value of false', async ( inMemoryConnectors: [], getActionsAuthorizationWithRequest, }); - await expect( - customActionExecutor.execute(executeParams) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unable to execute action because the Encrypted Saved Objects plugin is missing encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in the kibana.yml or use the bin/kibana-encryption-keys command."` - ); + + try { + await customActionExecutor.execute(executeParams); + } catch (e) { + expect(e.message).toBe( + 'Unable to execute action because the Encrypted Saved Objects plugin is missing encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in the kibana.yml or use the bin/kibana-encryption-keys command.' + ); + expect(getErrorSource(e)).toBe(TaskErrorSource.USER); + } }); test('should not throw error if action is preconfigured and isESOCanEncrypt is false', async () => { diff --git a/x-pack/plugins/actions/server/lib/action_executor.ts b/x-pack/plugins/actions/server/lib/action_executor.ts index 16d3d70c5b97e5..afcb96bbde8bea 100644 --- a/x-pack/plugins/actions/server/lib/action_executor.ts +++ b/x-pack/plugins/actions/server/lib/action_executor.ts @@ -6,7 +6,7 @@ */ import type { PublicMethodsOf } from '@kbn/utility-types'; -import { Logger, KibanaRequest } from '@kbn/core/server'; +import { KibanaRequest, Logger } from '@kbn/core/server'; import { cloneDeep } from 'lodash'; import { set } from '@kbn/safer-lodash-set'; import { withSpan } from '@kbn/apm-utils'; @@ -14,24 +14,25 @@ import { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin import { SpacesServiceStart } from '@kbn/spaces-plugin/server'; import { IEventLogger, SAVED_OBJECT_REL_PRIMARY } from '@kbn/event-log-plugin/server'; import { SecurityPluginStart } from '@kbn/security-plugin/server'; +import { createTaskRunError, TaskErrorSource } from '@kbn/task-manager-plugin/server'; import { getGenAiTokenTracking, shouldTrackGenAiToken } from './gen_ai_token_tracking'; import { - validateParams, validateConfig, - validateSecrets, validateConnector, + validateParams, + validateSecrets, } from './validate_with_schema'; import { ActionType, - ActionTypeExecutorResult, + ActionTypeConfig, ActionTypeExecutorRawResult, + ActionTypeExecutorResult, ActionTypeRegistryContract, + ActionTypeSecrets, GetServicesFunction, InMemoryConnector, RawAction, ValidatorServices, - ActionTypeSecrets, - ActionTypeConfig, } from '../types'; import { EVENT_LOG_ACTIONS } from '../constants/event_log'; import { ActionExecutionSource } from './action_execution_source'; @@ -147,7 +148,11 @@ export class ActionExecutor { } if (!actionTypeRegistry.isActionExecutable(actionId, actionTypeId, { notifyUsage: true })) { - actionTypeRegistry.ensureActionTypeEnabled(actionTypeId); + try { + actionTypeRegistry.ensureActionTypeEnabled(actionTypeId); + } catch (e) { + throw createTaskRunError(e, TaskErrorSource.FRAMEWORK); + } } const actionType = actionTypeRegistry.get(actionTypeId); const configurationUtilities = actionTypeRegistry.getUtils(); @@ -261,11 +266,12 @@ export class ActionExecutor { source, ...(actionType.isSystemActionType ? { request } : {}), }); + + if (rawResult && rawResult.status === 'error') { + rawResult.errorSource = TaskErrorSource.USER; + } } catch (err) { - if ( - err.reason === ActionExecutionErrorReason.Validation || - err.reason === ActionExecutionErrorReason.Authorization - ) { + if (err.reason === ActionExecutionErrorReason.Authorization) { rawResult = err.result; } else { rawResult = { @@ -275,6 +281,7 @@ export class ActionExecutor { serviceMessage: err.message, error: err, retry: true, + errorSource: TaskErrorSource.USER, }; } } @@ -451,31 +458,37 @@ export class ActionExecutor { } if (!this.isESOCanEncrypt) { - throw new Error( - `Unable to execute action because the Encrypted Saved Objects plugin is missing encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in the kibana.yml or use the bin/kibana-encryption-keys command.` + throw createTaskRunError( + new Error( + `Unable to execute action because the Encrypted Saved Objects plugin is missing encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in the kibana.yml or use the bin/kibana-encryption-keys command.` + ), + TaskErrorSource.USER ); } - const rawAction = await encryptedSavedObjectsClient.getDecryptedAsInternalUser( - 'action', - actionId, - { - namespace: namespace === 'default' ? undefined : namespace, - } - ); - - const { - attributes: { secrets, actionTypeId, config, name }, - } = rawAction; + try { + const rawAction = await encryptedSavedObjectsClient.getDecryptedAsInternalUser( + 'action', + actionId, + { + namespace: namespace === 'default' ? undefined : namespace, + } + ); + const { + attributes: { secrets, actionTypeId, config, name }, + } = rawAction; - return { - actionTypeId, - name, - config, - secrets, - actionId, - rawAction: rawAction.attributes, - }; + return { + actionTypeId, + name, + config, + secrets, + actionId, + rawAction: rawAction.attributes, + }; + } catch (e) { + throw createTaskRunError(e, TaskErrorSource.FRAMEWORK); + } } } @@ -540,6 +553,7 @@ function validateAction( status: 'error', message: err.message, retry: !!taskInfo, + errorSource: TaskErrorSource.FRAMEWORK, }); } } @@ -585,6 +599,7 @@ const ensureAuthorizedToExecute = async ({ status: 'error', message: error.message, retry: false, + errorSource: TaskErrorSource.USER, }); } }; diff --git a/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts b/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts index e8c66cff784c9e..ecb3f75fc7794d 100644 --- a/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts +++ b/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts @@ -7,7 +7,7 @@ import sinon from 'sinon'; import { ActionExecutor } from './action_executor'; -import { ConcreteTaskInstance, TaskStatus } from '@kbn/task-manager-plugin/server'; +import { ConcreteTaskInstance, TaskErrorSource, TaskStatus } from '@kbn/task-manager-plugin/server'; import { TaskRunnerFactory } from './task_runner_factory'; import { actionTypeRegistryMock } from '../action_type_registry.mock'; import { actionExecutorMock } from './action_executor.mock'; @@ -25,6 +25,7 @@ import { inMemoryMetricsMock } from '../monitoring/in_memory_metrics.mock'; import { IN_MEMORY_METRICS } from '../monitoring'; import { pick } from 'lodash'; import { + getErrorSource, isRetryableError, isUnrecoverableError, } from '@kbn/task-manager-plugin/server/task_running'; @@ -544,12 +545,13 @@ describe('Task Runner Factory', () => { message: 'Error message', data: { foo: true }, retry: false, + errorSource: TaskErrorSource.USER, }); try { await taskRunner.run(); - throw new Error('Should have thrown'); } catch (e) { + expect(getErrorSource(e)).toBe(TaskErrorSource.USER); expect(isRetryableError(e)).toEqual(false); } }); @@ -853,6 +855,7 @@ describe('Task Runner Factory', () => { throw new Error('Should have thrown'); } catch (e) { expect(isUnrecoverableError(e)).toEqual(true); + expect(getErrorSource(e)).toBe(TaskErrorSource.USER); } }); @@ -887,6 +890,7 @@ describe('Task Runner Factory', () => { message: 'Error message', data: { foo: true }, retry: false, + errorSource: TaskErrorSource.FRAMEWORK, }); let err; @@ -900,6 +904,47 @@ describe('Task Runner Factory', () => { expect(taskRunnerFactoryInitializerParams.logger.error as jest.Mock).toHaveBeenCalledWith( `Action '2' failed: Error message` ); + expect(getErrorSource(err)).toBe(TaskErrorSource.FRAMEWORK); + }); + + test(`fallbacks to FRAMEWORK error if ActionExecutor does not return any type of source'`, async () => { + const taskRunner = taskRunnerFactory.create({ + taskInstance: { + ...mockedTaskInstance, + attempts: 0, + }, + }); + + mockedEncryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({ + id: '3', + type: 'action_task_params', + attributes: { + actionId: '2', + params: { baz: true }, + executionId: '123abc', + apiKey: Buffer.from('123:abc').toString('base64'), + }, + references: [ + { + id: '2', + name: 'actionRef', + type: 'action', + }, + ], + }); + mockedActionExecutor.execute.mockResolvedValueOnce({ + status: 'error', + actionId: '2', + message: 'Error message', + data: { foo: true }, + retry: false, + }); + + try { + await taskRunner.run(); + } catch (e) { + expect(getErrorSource(e)).toBe(TaskErrorSource.FRAMEWORK); + } }); test('will rethrow the error if the error is thrown instead of returned', async () => { @@ -941,6 +986,7 @@ describe('Task Runner Factory', () => { `Action '2' failed: Fail` ); expect(thrownError).toEqual(err); + expect(getErrorSource(err)).toBe(TaskErrorSource.FRAMEWORK); }); test('increments monitoring metrics after execution', async () => { @@ -1158,6 +1204,11 @@ describe('Task Runner Factory', () => { ], }); - await expect(taskRunner.run()).rejects.toThrow('test'); + try { + await taskRunner.run(); + } catch (e) { + expect(getErrorSource(e)).toBe(TaskErrorSource.FRAMEWORK); + expect(e).toEqual(error); + } }); }); diff --git a/x-pack/plugins/actions/server/lib/task_runner_factory.ts b/x-pack/plugins/actions/server/lib/task_runner_factory.ts index 22dc57d7dc0d3c..cd22ea324ba5c3 100644 --- a/x-pack/plugins/actions/server/lib/task_runner_factory.ts +++ b/x-pack/plugins/actions/server/lib/task_runner_factory.ts @@ -19,13 +19,16 @@ import { SavedObjectReference, } from '@kbn/core/server'; import { + createTaskRunError, LoadIndirectParamsResult, RunContext, + TaskErrorSource, throwRetryableError, throwUnrecoverableError, } from '@kbn/task-manager-plugin/server'; import { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin/server'; import { LoadedIndirectParams } from '@kbn/task-manager-plugin/server/task'; +import { getErrorSource } from '@kbn/task-manager-plugin/server/task_running'; import { ActionExecutorContract, ActionInfo } from './action_executor'; import { ActionTaskExecutorParams, @@ -44,7 +47,7 @@ import { } from './action_execution_source'; import { RelatedSavedObjects, validatedRelatedSavedObjects } from './related_saved_objects'; import { injectSavedObjectReferences } from './action_task_params_utils'; -import { InMemoryMetrics, IN_MEMORY_METRICS } from '../monitoring'; +import { IN_MEMORY_METRICS, InMemoryMetrics } from '../monitoring'; import { ActionTypeDisabledError } from './errors'; export interface TaskRunnerContext { @@ -135,7 +138,8 @@ export class TaskRunnerFactory { }, }; return actionData; - } catch (error) { + } catch (err) { + const error = createTaskRunError(err, getErrorSource(err) || TaskErrorSource.FRAMEWORK); actionData = { error }; return { error }; } @@ -187,9 +191,9 @@ export class TaskRunnerFactory { logger.error(`Action '${actionId}' failed: ${e.message}`); if (e instanceof ActionTypeDisabledError) { // We'll stop re-trying due to action being forbidden - throwUnrecoverableError(e); + throwUnrecoverableError(createTaskRunError(e, TaskErrorSource.USER)); } - throw e; + throw createTaskRunError(e, getErrorSource(e) || TaskErrorSource.FRAMEWORK); } inMemoryMetrics.increment(IN_MEMORY_METRICS.ACTION_EXECUTIONS); @@ -199,7 +203,7 @@ export class TaskRunnerFactory { // Task manager error handler only kicks in when an error thrown (at this time) // So what we have to do is throw when the return status is `error`. throw throwRetryableError( - new Error(executorResult.message), + createTaskRunError(new Error(executorResult.message), executorResult.errorSource), executorResult.retry as boolean | Date ); } diff --git a/x-pack/plugins/task_manager/common/constants.ts b/x-pack/plugins/task_manager/common/constants.ts new file mode 100644 index 00000000000000..68d8f5f5519ba1 --- /dev/null +++ b/x-pack/plugins/task_manager/common/constants.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export enum TaskErrorSource { + FRAMEWORK = 'framework', + USER = 'user', +} diff --git a/x-pack/plugins/task_manager/common/index.ts b/x-pack/plugins/task_manager/common/index.ts new file mode 100644 index 00000000000000..04f9dbcc10bb40 --- /dev/null +++ b/x-pack/plugins/task_manager/common/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { TaskErrorSource } from './constants'; diff --git a/x-pack/plugins/task_manager/server/metrics/create_aggregator.test.ts b/x-pack/plugins/task_manager/server/metrics/create_aggregator.test.ts index 5becffa4e302c3..afcd4884f77776 100644 --- a/x-pack/plugins/task_manager/server/metrics/create_aggregator.test.ts +++ b/x-pack/plugins/task_manager/server/metrics/create_aggregator.test.ts @@ -425,6 +425,8 @@ describe('createAggregator', () => { not_timed_out: 0, total: 0, delay: { counts: [1], values: [10] }, + framework_errors: 0, + user_errors: 0, }, }, }); @@ -436,10 +438,24 @@ describe('createAggregator', () => { not_timed_out: 1, total: 1, delay: { counts: [1], values: [10] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -451,10 +467,24 @@ describe('createAggregator', () => { not_timed_out: 1, total: 1, delay: { counts: [1, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -466,11 +496,31 @@ describe('createAggregator', () => { not_timed_out: 2, total: 2, delay: { counts: [1, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -482,11 +532,31 @@ describe('createAggregator', () => { not_timed_out: 2, total: 2, delay: { counts: [2, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -498,11 +568,31 @@ describe('createAggregator', () => { not_timed_out: 3, total: 3, delay: { counts: [2, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -514,11 +604,31 @@ describe('createAggregator', () => { not_timed_out: 3, total: 3, delay: { counts: [2, 1, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -530,12 +640,38 @@ describe('createAggregator', () => { not_timed_out: 4, total: 4, delay: { counts: [2, 1, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -547,12 +683,38 @@ describe('createAggregator', () => { not_timed_out: 4, total: 4, delay: { counts: [3, 1, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -564,12 +726,38 @@ describe('createAggregator', () => { not_timed_out: 5, total: 5, delay: { counts: [3, 1, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 3, total: 3 }, - 'alerting:example': { success: 2, not_timed_out: 3, total: 3 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -581,12 +769,38 @@ describe('createAggregator', () => { not_timed_out: 5, total: 5, delay: { counts: [4, 1, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 3, total: 3 }, - 'alerting:example': { success: 2, not_timed_out: 3, total: 3 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -598,13 +812,45 @@ describe('createAggregator', () => { not_timed_out: 6, total: 6, delay: { counts: [4, 1, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 3, not_timed_out: 4, total: 4 }, - 'alerting:__index-threshold': { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 2, not_timed_out: 3, total: 3 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:__index-threshold': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -616,13 +862,45 @@ describe('createAggregator', () => { not_timed_out: 6, total: 6, delay: { counts: [4, 2, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 3, not_timed_out: 4, total: 4 }, - 'alerting:__index-threshold': { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 2, not_timed_out: 3, total: 3 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:__index-threshold': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -634,13 +912,45 @@ describe('createAggregator', () => { not_timed_out: 7, total: 7, delay: { counts: [4, 2, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 4, not_timed_out: 5, total: 5 }, - 'alerting:__index-threshold': { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 3, not_timed_out: 4, total: 4 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 4, + not_timed_out: 5, + total: 5, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:__index-threshold': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -652,13 +962,45 @@ describe('createAggregator', () => { not_timed_out: 7, total: 7, delay: { counts: [5, 2, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 4, not_timed_out: 5, total: 5 }, - 'alerting:__index-threshold': { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 3, not_timed_out: 4, total: 4 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 4, + not_timed_out: 5, + total: 5, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:__index-threshold': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -670,13 +1012,45 @@ describe('createAggregator', () => { not_timed_out: 8, total: 8, delay: { counts: [5, 2, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 2, + user_errors: 0, }, by_type: { - alerting: { success: 4, not_timed_out: 6, total: 6 }, - 'alerting:__index-threshold': { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 3, not_timed_out: 5, total: 5 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 4, + not_timed_out: 6, + total: 6, + framework_errors: 2, + user_errors: 0, + }, + 'alerting:__index-threshold': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 3, + not_timed_out: 5, + total: 5, + framework_errors: 2, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -688,13 +1062,45 @@ describe('createAggregator', () => { not_timed_out: 8, total: 8, delay: { counts: [6, 2, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 2, + user_errors: 0, }, by_type: { - alerting: { success: 4, not_timed_out: 6, total: 6 }, - 'alerting:__index-threshold': { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 3, not_timed_out: 5, total: 5 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 4, + not_timed_out: 6, + total: 6, + framework_errors: 2, + user_errors: 0, + }, + 'alerting:__index-threshold': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 3, + not_timed_out: 5, + total: 5, + framework_errors: 2, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -706,13 +1112,45 @@ describe('createAggregator', () => { not_timed_out: 9, total: 9, delay: { counts: [6, 2, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 2, + user_errors: 0, }, by_type: { - alerting: { success: 5, not_timed_out: 7, total: 7 }, - 'alerting:__index-threshold': { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 4, not_timed_out: 6, total: 6 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 5, + not_timed_out: 7, + total: 7, + framework_errors: 2, + user_errors: 0, + }, + 'alerting:__index-threshold': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 4, + not_timed_out: 6, + total: 6, + framework_errors: 2, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -724,13 +1162,45 @@ describe('createAggregator', () => { not_timed_out: 9, total: 9, delay: { counts: [7, 2, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 2, + user_errors: 0, }, by_type: { - alerting: { success: 5, not_timed_out: 7, total: 7 }, - 'alerting:__index-threshold': { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 4, not_timed_out: 6, total: 6 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 5, + not_timed_out: 7, + total: 7, + framework_errors: 2, + user_errors: 0, + }, + 'alerting:__index-threshold': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 4, + not_timed_out: 6, + total: 6, + framework_errors: 2, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -742,15 +1212,59 @@ describe('createAggregator', () => { not_timed_out: 10, total: 10, delay: { counts: [7, 2, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 3, + user_errors: 0, }, by_type: { - actions: { success: 0, not_timed_out: 1, total: 1 }, - alerting: { success: 5, not_timed_out: 7, total: 7 }, - 'actions:webhook': { success: 0, not_timed_out: 1, total: 1 }, - 'alerting:__index-threshold': { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 4, not_timed_out: 6, total: 6 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + actions: { + success: 0, + not_timed_out: 1, + total: 1, + framework_errors: 1, + user_errors: 0, + }, + alerting: { + success: 5, + not_timed_out: 7, + total: 7, + framework_errors: 2, + user_errors: 0, + }, + 'actions:webhook': { + success: 0, + not_timed_out: 1, + total: 1, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:__index-threshold': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 4, + not_timed_out: 6, + total: 6, + framework_errors: 2, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -820,6 +1334,8 @@ describe('createAggregator', () => { not_timed_out: 0, total: 0, delay: { counts: [1], values: [10] }, + framework_errors: 0, + user_errors: 0, }, }, }); @@ -831,10 +1347,24 @@ describe('createAggregator', () => { not_timed_out: 1, total: 1, delay: { counts: [1], values: [10] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -846,10 +1376,24 @@ describe('createAggregator', () => { not_timed_out: 1, total: 1, delay: { counts: [1, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -861,11 +1405,31 @@ describe('createAggregator', () => { not_timed_out: 2, total: 2, delay: { counts: [1, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -877,11 +1441,31 @@ describe('createAggregator', () => { not_timed_out: 2, total: 2, delay: { counts: [2, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -893,11 +1477,31 @@ describe('createAggregator', () => { not_timed_out: 3, total: 3, delay: { counts: [2, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -909,11 +1513,31 @@ describe('createAggregator', () => { not_timed_out: 3, total: 3, delay: { counts: [2, 1, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -925,12 +1549,38 @@ describe('createAggregator', () => { not_timed_out: 4, total: 4, delay: { counts: [2, 1, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -942,12 +1592,38 @@ describe('createAggregator', () => { not_timed_out: 4, total: 4, delay: { counts: [3, 1, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -959,12 +1635,38 @@ describe('createAggregator', () => { not_timed_out: 5, total: 5, delay: { counts: [3, 1, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 3, total: 3 }, - 'alerting:example': { success: 2, not_timed_out: 3, total: 3 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -977,12 +1679,38 @@ describe('createAggregator', () => { not_timed_out: 0, total: 0, delay: { counts: [1], values: [10] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 0, not_timed_out: 0, total: 0 }, - 'alerting:example': { success: 0, not_timed_out: 0, total: 0 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -994,12 +1722,38 @@ describe('createAggregator', () => { not_timed_out: 1, total: 1, delay: { counts: [1], values: [10] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1011,12 +1765,38 @@ describe('createAggregator', () => { not_timed_out: 1, total: 1, delay: { counts: [1, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1028,12 +1808,38 @@ describe('createAggregator', () => { not_timed_out: 2, total: 2, delay: { counts: [1, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1045,12 +1851,38 @@ describe('createAggregator', () => { not_timed_out: 2, total: 2, delay: { counts: [2, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1062,12 +1894,38 @@ describe('createAggregator', () => { not_timed_out: 3, total: 3, delay: { counts: [2, 1], values: [10, 20] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 3, total: 3 }, - 'alerting:example': { success: 2, not_timed_out: 3, total: 3 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1079,12 +1937,38 @@ describe('createAggregator', () => { not_timed_out: 3, total: 3, delay: { counts: [3, 1], values: [10, 20] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 3, total: 3 }, - 'alerting:example': { success: 2, not_timed_out: 3, total: 3 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1096,12 +1980,38 @@ describe('createAggregator', () => { not_timed_out: 4, total: 4, delay: { counts: [3, 1], values: [10, 20] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 3, not_timed_out: 4, total: 4 }, - 'alerting:example': { success: 3, not_timed_out: 4, total: 4 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:example': { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1113,12 +2023,38 @@ describe('createAggregator', () => { not_timed_out: 4, total: 4, delay: { counts: [4, 1], values: [10, 20] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 3, not_timed_out: 4, total: 4 }, - 'alerting:example': { success: 3, not_timed_out: 4, total: 4 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:example': { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1130,14 +2066,52 @@ describe('createAggregator', () => { not_timed_out: 5, total: 5, delay: { counts: [4, 1], values: [10, 20] }, + framework_errors: 2, + user_errors: 0, }, by_type: { - actions: { success: 0, not_timed_out: 1, total: 1 }, - alerting: { success: 3, not_timed_out: 4, total: 4 }, - 'actions:webhook': { success: 0, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 3, not_timed_out: 4, total: 4 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + actions: { + success: 0, + not_timed_out: 1, + total: 1, + framework_errors: 1, + user_errors: 0, + }, + alerting: { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + 'actions:webhook': { + success: 0, + not_timed_out: 1, + total: 1, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:example': { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1215,6 +2189,8 @@ describe('createAggregator', () => { not_timed_out: 0, total: 0, delay: { counts: [1], values: [10] }, + framework_errors: 0, + user_errors: 0, }, }, }); @@ -1226,10 +2202,24 @@ describe('createAggregator', () => { not_timed_out: 1, total: 1, delay: { counts: [1], values: [10] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1241,10 +2231,24 @@ describe('createAggregator', () => { not_timed_out: 1, total: 1, delay: { counts: [1, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1256,11 +2260,31 @@ describe('createAggregator', () => { not_timed_out: 2, total: 2, delay: { counts: [1, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1272,11 +2296,31 @@ describe('createAggregator', () => { not_timed_out: 2, total: 2, delay: { counts: [2, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1288,11 +2332,31 @@ describe('createAggregator', () => { not_timed_out: 3, total: 3, delay: { counts: [2, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1304,11 +2368,31 @@ describe('createAggregator', () => { not_timed_out: 3, total: 3, delay: { counts: [2, 1, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1320,12 +2404,38 @@ describe('createAggregator', () => { not_timed_out: 4, total: 4, delay: { counts: [2, 1, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1337,12 +2447,38 @@ describe('createAggregator', () => { not_timed_out: 4, total: 4, delay: { counts: [3, 1, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1354,12 +2490,38 @@ describe('createAggregator', () => { not_timed_out: 5, total: 5, delay: { counts: [3, 1, 0, 1], values: [10, 20, 30, 40] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 3, total: 3 }, - 'alerting:example': { success: 2, not_timed_out: 3, total: 3 }, - report: { success: 1, not_timed_out: 1, total: 1 }, - telemetry: { success: 1, not_timed_out: 1, total: 1 }, + alerting: { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1372,12 +2534,38 @@ describe('createAggregator', () => { not_timed_out: 0, total: 0, delay: { counts: [1], values: [10] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 0, not_timed_out: 0, total: 0 }, - 'alerting:example': { success: 0, not_timed_out: 0, total: 0 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1389,12 +2577,38 @@ describe('createAggregator', () => { not_timed_out: 1, total: 1, delay: { counts: [1], values: [10] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1406,12 +2620,38 @@ describe('createAggregator', () => { not_timed_out: 1, total: 1, delay: { counts: [1, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 1, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 1, not_timed_out: 1, total: 1 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1423,12 +2663,38 @@ describe('createAggregator', () => { not_timed_out: 2, total: 2, delay: { counts: [1, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1440,12 +2706,38 @@ describe('createAggregator', () => { not_timed_out: 2, total: 2, delay: { counts: [2, 1], values: [10, 20] }, + framework_errors: 0, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 2, total: 2 }, - 'alerting:example': { success: 2, not_timed_out: 2, total: 2 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1457,12 +2749,38 @@ describe('createAggregator', () => { not_timed_out: 3, total: 3, delay: { counts: [2, 1], values: [10, 20] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 3, total: 3 }, - 'alerting:example': { success: 2, not_timed_out: 3, total: 3 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1474,12 +2792,38 @@ describe('createAggregator', () => { not_timed_out: 3, total: 3, delay: { counts: [3, 1], values: [10, 20] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 2, not_timed_out: 3, total: 3 }, - 'alerting:example': { success: 2, not_timed_out: 3, total: 3 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:example': { + success: 2, + not_timed_out: 3, + total: 3, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1491,12 +2835,38 @@ describe('createAggregator', () => { not_timed_out: 4, total: 4, delay: { counts: [3, 1], values: [10, 20] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 3, not_timed_out: 4, total: 4 }, - 'alerting:example': { success: 3, not_timed_out: 4, total: 4 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:example': { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1508,12 +2878,38 @@ describe('createAggregator', () => { not_timed_out: 4, total: 4, delay: { counts: [4, 1], values: [10, 20] }, + framework_errors: 1, + user_errors: 0, }, by_type: { - alerting: { success: 3, not_timed_out: 4, total: 4 }, - 'alerting:example': { success: 3, not_timed_out: 4, total: 4 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + alerting: { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:example': { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); @@ -1525,14 +2921,52 @@ describe('createAggregator', () => { not_timed_out: 5, total: 5, delay: { counts: [4, 1], values: [10, 20] }, + framework_errors: 2, + user_errors: 0, }, by_type: { - actions: { success: 0, not_timed_out: 1, total: 1 }, - alerting: { success: 3, not_timed_out: 4, total: 4 }, - 'actions:webhook': { success: 0, not_timed_out: 1, total: 1 }, - 'alerting:example': { success: 3, not_timed_out: 4, total: 4 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + actions: { + success: 0, + not_timed_out: 1, + total: 1, + framework_errors: 1, + user_errors: 0, + }, + alerting: { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + 'actions:webhook': { + success: 0, + not_timed_out: 1, + total: 1, + framework_errors: 1, + user_errors: 0, + }, + 'alerting:example': { + success: 3, + not_timed_out: 4, + total: 4, + framework_errors: 1, + user_errors: 0, + }, + report: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + telemetry: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, }, }, }); diff --git a/x-pack/plugins/task_manager/server/metrics/task_run_metrics_aggregator.test.ts b/x-pack/plugins/task_manager/server/metrics/task_run_metrics_aggregator.test.ts index 628952619814d0..83909112ba0ac8 100644 --- a/x-pack/plugins/task_manager/server/metrics/task_run_metrics_aggregator.test.ts +++ b/x-pack/plugins/task_manager/server/metrics/task_run_metrics_aggregator.test.ts @@ -86,13 +86,27 @@ describe('TaskRunMetricsAggregator', () => { test('should correctly initialize', () => { expect(taskRunMetricsAggregator.collect()).toEqual({ - overall: { success: 0, not_timed_out: 0, total: 0, delay: { counts: [], values: [] } }, + overall: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + delay: { counts: [], values: [] }, + }, }); }); test('should correctly return initialMetrics', () => { expect(taskRunMetricsAggregator.initialMetric()).toEqual({ - overall: { success: 0, not_timed_out: 0, total: 0, delay: { counts: [], values: [] } }, + overall: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + delay: { counts: [], values: [] }, + }, by_type: {}, }); }); @@ -101,9 +115,16 @@ describe('TaskRunMetricsAggregator', () => { taskRunMetricsAggregator.processTaskLifecycleEvent(getTaskRunSuccessEvent('telemetry')); taskRunMetricsAggregator.processTaskLifecycleEvent(getTaskRunSuccessEvent('telemetry')); expect(taskRunMetricsAggregator.collect()).toEqual({ - overall: { success: 2, not_timed_out: 2, total: 2, delay: { counts: [], values: [] } }, + overall: { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + delay: { counts: [], values: [] }, + }, by_type: { - telemetry: { success: 2, not_timed_out: 2, total: 2 }, + telemetry: { success: 2, not_timed_out: 2, total: 2, framework_errors: 0, user_errors: 0 }, }, }); }); @@ -111,7 +132,14 @@ describe('TaskRunMetricsAggregator', () => { test('should correctly process task manager runDelay stat', () => { taskRunMetricsAggregator.processTaskLifecycleEvent(getTaskManagerStatEvent(3.343)); expect(taskRunMetricsAggregator.collect()).toEqual({ - overall: { success: 0, not_timed_out: 0, total: 0, delay: { counts: [1], values: [10] } }, + overall: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + delay: { counts: [1], values: [10] }, + }, }); }); @@ -120,7 +148,14 @@ describe('TaskRunMetricsAggregator', () => { getTaskManagerStatEvent(3.343, 'pollingDelay') ); expect(taskRunMetricsAggregator.collect()).toEqual({ - overall: { success: 0, not_timed_out: 0, total: 0, delay: { counts: [], values: [] } }, + overall: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + delay: { counts: [], values: [] }, + }, }); }); @@ -128,9 +163,16 @@ describe('TaskRunMetricsAggregator', () => { taskRunMetricsAggregator.processTaskLifecycleEvent(getTaskRunSuccessEvent('telemetry', true)); taskRunMetricsAggregator.processTaskLifecycleEvent(getTaskRunSuccessEvent('telemetry', true)); expect(taskRunMetricsAggregator.collect()).toEqual({ - overall: { success: 2, not_timed_out: 0, total: 2, delay: { counts: [], values: [] } }, + overall: { + success: 2, + not_timed_out: 0, + total: 2, + framework_errors: 0, + user_errors: 0, + delay: { counts: [], values: [] }, + }, by_type: { - telemetry: { success: 2, not_timed_out: 0, total: 2 }, + telemetry: { success: 2, not_timed_out: 0, total: 2, framework_errors: 0, user_errors: 0 }, }, }); }); @@ -139,9 +181,16 @@ describe('TaskRunMetricsAggregator', () => { taskRunMetricsAggregator.processTaskLifecycleEvent(getTaskRunFailedEvent('telemetry')); taskRunMetricsAggregator.processTaskLifecycleEvent(getTaskRunFailedEvent('telemetry')); expect(taskRunMetricsAggregator.collect()).toEqual({ - overall: { success: 0, not_timed_out: 2, total: 2, delay: { counts: [], values: [] } }, + overall: { + success: 0, + not_timed_out: 2, + total: 2, + framework_errors: 2, + user_errors: 0, + delay: { counts: [], values: [] }, + }, by_type: { - telemetry: { success: 0, not_timed_out: 2, total: 2 }, + telemetry: { success: 0, not_timed_out: 2, total: 2, framework_errors: 2, user_errors: 0 }, }, }); }); @@ -150,9 +199,16 @@ describe('TaskRunMetricsAggregator', () => { taskRunMetricsAggregator.processTaskLifecycleEvent(getTaskRunFailedEvent('telemetry', true)); taskRunMetricsAggregator.processTaskLifecycleEvent(getTaskRunFailedEvent('telemetry', true)); expect(taskRunMetricsAggregator.collect()).toEqual({ - overall: { success: 0, not_timed_out: 0, total: 2, delay: { counts: [], values: [] } }, + overall: { + success: 0, + not_timed_out: 0, + total: 2, + framework_errors: 2, + user_errors: 0, + delay: { counts: [], values: [] }, + }, by_type: { - telemetry: { success: 0, not_timed_out: 0, total: 2 }, + telemetry: { success: 0, not_timed_out: 0, total: 2, framework_errors: 2, user_errors: 0 }, }, }); }); @@ -163,10 +219,17 @@ describe('TaskRunMetricsAggregator', () => { taskRunMetricsAggregator.processTaskLifecycleEvent(getTaskRunSuccessEvent('report', true)); taskRunMetricsAggregator.processTaskLifecycleEvent(getTaskRunFailedEvent('telemetry')); expect(taskRunMetricsAggregator.collect()).toEqual({ - overall: { success: 3, not_timed_out: 3, total: 4, delay: { counts: [], values: [] } }, + overall: { + success: 3, + not_timed_out: 3, + total: 4, + framework_errors: 1, + user_errors: 0, + delay: { counts: [], values: [] }, + }, by_type: { - report: { success: 2, not_timed_out: 1, total: 2 }, - telemetry: { success: 1, not_timed_out: 2, total: 2 }, + report: { success: 2, not_timed_out: 1, total: 2, framework_errors: 0, user_errors: 0 }, + telemetry: { success: 1, not_timed_out: 2, total: 2, framework_errors: 1, user_errors: 0 }, }, }); }); @@ -193,16 +256,47 @@ describe('TaskRunMetricsAggregator', () => { getTaskRunSuccessEvent('alerting:.index-threshold', true) ); expect(taskRunMetricsAggregator.collect()).toEqual({ - overall: { success: 11, not_timed_out: 12, total: 14, delay: { counts: [], values: [] } }, + overall: { + success: 11, + not_timed_out: 12, + total: 14, + framework_errors: 3, + user_errors: 0, + delay: { counts: [], values: [] }, + }, by_type: { - actions: { success: 3, not_timed_out: 3, total: 3 }, - 'actions:__email': { success: 1, not_timed_out: 1, total: 1 }, - 'actions:webhook': { success: 2, not_timed_out: 2, total: 2 }, - alerting: { success: 5, not_timed_out: 5, total: 7 }, - 'alerting:example': { success: 3, not_timed_out: 4, total: 5 }, - 'alerting:__index-threshold': { success: 2, not_timed_out: 1, total: 2 }, - report: { success: 2, not_timed_out: 2, total: 2 }, - telemetry: { success: 1, not_timed_out: 2, total: 2 }, + actions: { success: 3, not_timed_out: 3, total: 3, framework_errors: 0, user_errors: 0 }, + 'actions:__email': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'actions:webhook': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + alerting: { success: 5, not_timed_out: 5, total: 7, framework_errors: 2, user_errors: 0 }, + 'alerting:example': { + success: 3, + not_timed_out: 4, + total: 5, + framework_errors: 2, + user_errors: 0, + }, + 'alerting:__index-threshold': { + success: 2, + not_timed_out: 1, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + report: { success: 2, not_timed_out: 2, total: 2, framework_errors: 0, user_errors: 0 }, + telemetry: { success: 1, not_timed_out: 2, total: 2, framework_errors: 1, user_errors: 0 }, }, }); }); @@ -239,31 +333,88 @@ describe('TaskRunMetricsAggregator', () => { not_timed_out: 12, total: 14, delay: { counts: [3, 0, 1], values: [10, 20, 30] }, + framework_errors: 3, + user_errors: 0, }, by_type: { - actions: { success: 3, not_timed_out: 3, total: 3 }, - 'actions:__email': { success: 1, not_timed_out: 1, total: 1 }, - 'actions:webhook': { success: 2, not_timed_out: 2, total: 2 }, - alerting: { success: 5, not_timed_out: 5, total: 7 }, - 'alerting:example': { success: 3, not_timed_out: 4, total: 5 }, - 'alerting:__index-threshold': { success: 2, not_timed_out: 1, total: 2 }, - report: { success: 2, not_timed_out: 2, total: 2 }, - telemetry: { success: 1, not_timed_out: 2, total: 2 }, + actions: { success: 3, not_timed_out: 3, total: 3, framework_errors: 0, user_errors: 0 }, + 'actions:__email': { + success: 1, + not_timed_out: 1, + total: 1, + framework_errors: 0, + user_errors: 0, + }, + 'actions:webhook': { + success: 2, + not_timed_out: 2, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + alerting: { success: 5, not_timed_out: 5, total: 7, framework_errors: 2, user_errors: 0 }, + 'alerting:example': { + success: 3, + not_timed_out: 4, + total: 5, + framework_errors: 2, + user_errors: 0, + }, + 'alerting:__index-threshold': { + success: 2, + not_timed_out: 1, + total: 2, + framework_errors: 0, + user_errors: 0, + }, + report: { success: 2, not_timed_out: 2, total: 2, framework_errors: 0, user_errors: 0 }, + telemetry: { success: 1, not_timed_out: 2, total: 2, framework_errors: 1, user_errors: 0 }, }, }); taskRunMetricsAggregator.reset(); expect(taskRunMetricsAggregator.collect()).toEqual({ - overall: { success: 0, not_timed_out: 0, total: 0, delay: { counts: [], values: [] } }, + overall: { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + delay: { counts: [], values: [] }, + }, by_type: { - actions: { success: 0, not_timed_out: 0, total: 0 }, - 'actions:__email': { success: 0, not_timed_out: 0, total: 0 }, - 'actions:webhook': { success: 0, not_timed_out: 0, total: 0 }, - alerting: { success: 0, not_timed_out: 0, total: 0 }, - 'alerting:example': { success: 0, not_timed_out: 0, total: 0 }, - 'alerting:__index-threshold': { success: 0, not_timed_out: 0, total: 0 }, - report: { success: 0, not_timed_out: 0, total: 0 }, - telemetry: { success: 0, not_timed_out: 0, total: 0 }, + actions: { success: 0, not_timed_out: 0, total: 0, framework_errors: 0, user_errors: 0 }, + 'actions:__email': { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + 'actions:webhook': { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + alerting: { success: 0, not_timed_out: 0, total: 0, framework_errors: 0, user_errors: 0 }, + 'alerting:example': { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + 'alerting:__index-threshold': { + success: 0, + not_timed_out: 0, + total: 0, + framework_errors: 0, + user_errors: 0, + }, + report: { success: 0, not_timed_out: 0, total: 0, framework_errors: 0, user_errors: 0 }, + telemetry: { success: 0, not_timed_out: 0, total: 0, framework_errors: 0, user_errors: 0 }, }, }); }); diff --git a/x-pack/plugins/task_manager/server/metrics/task_run_metrics_aggregator.ts b/x-pack/plugins/task_manager/server/metrics/task_run_metrics_aggregator.ts index ca7a88f9d42a7f..d41b5590341ff4 100644 --- a/x-pack/plugins/task_manager/server/metrics/task_run_metrics_aggregator.ts +++ b/x-pack/plugins/task_manager/server/metrics/task_run_metrics_aggregator.ts @@ -7,22 +7,19 @@ import { JsonObject } from '@kbn/utility-types'; import { merge } from 'lodash'; +import { isUserError } from '../task_running'; import { isOk, Ok, unwrap } from '../lib/result_type'; import { TaskLifecycleEvent } from '../polling_lifecycle'; import { ErroredTask, - RanTask, - TaskRun, isTaskManagerStatEvent, isTaskRunEvent, + RanTask, TaskManagerStat, + TaskRun, } from '../task_events'; -import { - getTaskTypeGroup, - MetricCounterService, - SimpleHistogram, - type SerializedHistogram, -} from './lib'; +import type { SerializedHistogram } from './lib'; +import { getTaskTypeGroup, MetricCounterService, SimpleHistogram } from './lib'; import { ITaskMetricsAggregator } from './types'; const HDR_HISTOGRAM_MAX = 5400; // 90 minutes @@ -32,6 +29,8 @@ enum TaskRunKeys { SUCCESS = 'success', NOT_TIMED_OUT = 'not_timed_out', TOTAL = 'total', + USER_ERRORS = 'user_errors', + FRAMEWORK_ERRORS = 'framework_errors', } enum TaskRunMetricKeys { @@ -91,7 +90,8 @@ export class TaskRunMetricsAggregator implements ITaskMetricsAggregator { it('createSkipError', () => { expect(isSkipError(createSkipError(new Error('OMG')))).toBeTruthy(); }); + + it('createTaskRunError', () => { + expect(isUserError(createTaskRunError(new Error('OMG'), TaskErrorSource.USER))).toBeTruthy(); + }); + + it('createTaskRunError without errorSourceParam ', () => { + expect(getErrorSource(createTaskRunError(new Error('OMG')))).toBe(TaskErrorSource.FRAMEWORK); + }); + + it('getErrorSource', () => { + expect(getErrorSource(createTaskRunError(new Error('OMG'), TaskErrorSource.USER))).toBe( + TaskErrorSource.USER + ); + }); + + it('getErrorSource return undefined when there is no source data', () => { + expect(getErrorSource(new Error('OMG'))).toBeUndefined(); + }); }); }); diff --git a/x-pack/plugins/task_manager/server/task_running/errors.ts b/x-pack/plugins/task_manager/server/task_running/errors.ts index 2d8e09b5c24e00..3898338855efe2 100644 --- a/x-pack/plugins/task_manager/server/task_running/errors.ts +++ b/x-pack/plugins/task_manager/server/task_running/errors.ts @@ -4,8 +4,11 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { TaskErrorSource } from '../../common'; import { EphemeralTask } from '../task'; +export { TaskErrorSource }; + // Unrecoverable const CODE_UNRECOVERABLE = 'TaskManager/unrecoverable'; const CODE_RETRYABLE = 'TaskManager/retryable'; @@ -15,11 +18,6 @@ const code = Symbol('TaskManagerErrorCode'); const retry = Symbol('TaskManagerErrorRetry'); const source = Symbol('TaskManagerErrorSource'); -export enum TaskErrorSource { - FRAMEWORK = 'framework', - USER = 'user', -} - export interface DecoratedError extends Error { [code]?: string; [retry]?: Date | boolean; @@ -47,9 +45,8 @@ export function isUnrecoverableError(error: Error | DecoratedError) { return isTaskManagerError(error) && error[code] === CODE_UNRECOVERABLE; } -export function throwUnrecoverableError(error: Error, errorSource = TaskErrorSource.FRAMEWORK) { +export function throwUnrecoverableError(error: Error) { (error as DecoratedError)[code] = CODE_UNRECOVERABLE; - (error as DecoratedError)[source] = errorSource; throw error; } @@ -86,6 +83,20 @@ export function createTaskRunError( return error; } +function isTaskRunError(error: Error | DecoratedError): error is DecoratedError { + return Boolean(error && (error as DecoratedError)[source]); +} + +export function getErrorSource(error: Error | DecoratedError): TaskErrorSource | undefined { + if (isTaskRunError(error) && error[source]) { + return error[source]; + } +} + +export function isUserError(error: Error | DecoratedError) { + return getErrorSource(error) === TaskErrorSource.USER; +} + export function isEphemeralTaskRejectedDueToCapacityError( error: Error | EphemeralTaskRejectedDueToCapacityError ) { diff --git a/x-pack/plugins/task_manager/server/task_running/task_runner.test.ts b/x-pack/plugins/task_manager/server/task_running/task_runner.test.ts index 393721f0fd8147..35fbd6918f4fb4 100644 --- a/x-pack/plugins/task_manager/server/task_running/task_runner.test.ts +++ b/x-pack/plugins/task_manager/server/task_running/task_runner.test.ts @@ -1565,7 +1565,7 @@ describe('TaskManagerRunner', () => { task: instance, persistence: TaskPersistence.Recurring, result: TaskRunResult.Success, - error: new Error(`Alerting task failed to run.`), + error: new Error(`test`), isExpired: false, }) ) @@ -1613,7 +1613,7 @@ describe('TaskManagerRunner', () => { persistence: TaskPersistence.Recurring, result: TaskRunResult.Success, isExpired: true, - error: new Error(`Alerting task failed to run.`), + error: new Error(`test`), }) ) ) diff --git a/x-pack/plugins/task_manager/server/task_running/task_runner.ts b/x-pack/plugins/task_manager/server/task_running/task_runner.ts index 9c9ad88c1dfc57..f67d8a22db81d5 100644 --- a/x-pack/plugins/task_manager/server/task_running/task_runner.ts +++ b/x-pack/plugins/task_manager/server/task_running/task_runner.ts @@ -792,7 +792,7 @@ export class TaskManagerRunner implements TaskRunner { asErr({ ...processedResult, isExpired: taskHasExpired, - error: new Error(`Alerting task failed to run.`), + error: taskRunError, }), taskTiming ) diff --git a/x-pack/plugins/task_manager/tsconfig.json b/x-pack/plugins/task_manager/tsconfig.json index 20fdb90611518f..ef7cab0493a608 100644 --- a/x-pack/plugins/task_manager/tsconfig.json +++ b/x-pack/plugins/task_manager/tsconfig.json @@ -7,6 +7,7 @@ "server/**/*", // have to declare *.json explicitly due to https://github.com/microsoft/TypeScript/issues/25636 "server/**/*.json", + "common/**/*" ], "kbn_references": [ "@kbn/alerting-state-types", diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts index 2e765d32ea9cc0..6787290f0b3967 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts @@ -15,6 +15,7 @@ import { DEFAULT_TOKEN_LIMIT } from '@kbn/stack-connectors-plugin/common/bedrock import { PassThrough } from 'stream'; import { EventStreamCodec } from '@smithy/eventstream-codec'; import { fromUtf8, toUtf8 } from '@smithy/util-utf8'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { getUrlPrefix, ObjectRemover } from '../../../../../common/lib'; @@ -268,6 +269,7 @@ export default function bedrockTest({ getService }: FtrProviderContext) { message: 'error validating action params: [subAction]: expected value of type [string] but got [undefined]', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, }); }); @@ -285,6 +287,7 @@ export default function bedrockTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: `Sub action "invalidAction" is not registered. Connector id: ${bedrockActionId}. Connector name: Amazon Bedrock. Connector type: .bedrock`, }); }); @@ -544,6 +547,7 @@ export default function bedrockTest({ getService }: FtrProviderContext) { expect(body).to.eql({ status: 'error', connector_id: bedrockActionId, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: [subAction]: expected value of type [string] but got [undefined]', retry: false, @@ -574,6 +578,7 @@ export default function bedrockTest({ getService }: FtrProviderContext) { connector_id: bedrockActionId, message: 'an error occurred while running the action', retry: true, + errorSource: TaskErrorSource.USER, service_message: 'Status code: 422. Message: API Error: Unprocessable Entity - Malformed input request: extraneous key [ooooo] is not permitted, please reformat your input and try again.', }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts index 23410b83d10abb..89e62be2414129 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts @@ -13,6 +13,7 @@ import { getExternalServiceSimulatorPath, ExternalServiceSimulator, } from '@kbn/actions-simulators-plugin/server/plugin'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; // eslint-disable-next-line import/no-default-export @@ -242,7 +243,13 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { params: {}, }) .then((resp: any) => { - expect(Object.keys(resp.body)).to.eql(['status', 'message', 'retry', 'connector_id']); + expect(Object.keys(resp.body)).to.eql([ + 'status', + 'message', + 'retry', + 'errorSource', + 'connector_id', + ]); expect(resp.body.connector_id).to.eql(simulatedActionId); expect(resp.body.status).to.eql('error'); }); @@ -262,6 +269,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { retry: false, message: 'error validating action params: [subAction]: expected value to equal [pushToService]', + errorSource: TaskErrorSource.FRAMEWORK, }); }); }); @@ -280,6 +288,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { retry: false, message: 'error validating action params: [subActionParams.incident.title]: expected value of type [string] but got [undefined]', + errorSource: TaskErrorSource.FRAMEWORK, }); }); }); @@ -306,6 +315,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { retry: false, message: 'error validating action params: [subActionParams.incident.title]: expected value of type [string] but got [undefined]', + errorSource: TaskErrorSource.FRAMEWORK, }); }); }); @@ -334,6 +344,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { retry: false, message: 'error validating action params: [subActionParams.comments]: types that failed validation:\n- [subActionParams.comments.0.0.commentId]: expected value of type [string] but got [undefined]\n- [subActionParams.comments.1]: expected value to equal [null]', + errorSource: TaskErrorSource.FRAMEWORK, }); }); }); @@ -361,6 +372,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { retry: false, message: 'error validating action params: [subActionParams.comments]: types that failed validation:\n- [subActionParams.comments.0.0.comment]: expected value of type [string] but got [undefined]\n- [subActionParams.comments.1]: expected value to equal [null]', + errorSource: TaskErrorSource.FRAMEWORK, }); }); }); @@ -459,6 +471,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: '[Action][Webhook - Case Management]: Unable to create case. Error: JSON Error: Create case JSON body must be valid JSON. ', }); @@ -489,6 +502,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: '[Action][Webhook - Case Management]: Unable to update case with id 12345. Error: JSON Error: Update case JSON body must be valid JSON. ', }); @@ -556,6 +570,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: '[Action][Webhook - Case Management]: Unable to create comment at case with id 123. Error: JSON Error: Create comment JSON body must be valid JSON. ', }); @@ -623,6 +638,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: '[Action][Webhook - Case Management]: Unable to create case. Error: Invalid Create case URL: Error: Invalid protocol. ', }); @@ -653,6 +669,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: '[Action][Webhook - Case Management]: Unable to update case with id 12345. Error: Invalid Update case URL: Error: Invalid URL. ', }); @@ -720,6 +737,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: '[Action][Webhook - Case Management]: Unable to create comment at case with id 123. Error: Invalid Create comment URL: Error: Invalid URL. ', }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/d3security.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/d3security.ts index 55d53c00f59dfc..3b99ea477f1375 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/d3security.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/d3security.ts @@ -11,6 +11,7 @@ import { D3SecuritySimulator, d3SecuritySuccessResponse, } from '@kbn/actions-simulators-plugin/server/d3security_simulation'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; const connectorTypeId = '.d3security'; @@ -179,6 +180,7 @@ export default function d3SecurityTest({ getService }: FtrProviderContext) { message: 'error validating action params: [subAction]: expected value of type [string] but got [undefined]', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, }); }); @@ -196,6 +198,7 @@ export default function d3SecurityTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: `Sub action "invalidAction" is not registered. Connector id: ${d3SecurityActionId}. Connector name: D3 Security. Connector type: .d3security`, }); }); @@ -287,6 +290,7 @@ export default function d3SecurityTest({ getService }: FtrProviderContext) { message: 'error validating action params: [subAction]: expected value of type [string] but got [undefined]', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, }); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/jira.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/jira.ts index 11588f48a48de1..ed9fb9cbbaf899 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/jira.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/jira.ts @@ -13,6 +13,7 @@ import { getExternalServiceSimulatorPath, ExternalServiceSimulator, } from '@kbn/actions-simulators-plugin/server/plugin'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; // eslint-disable-next-line import/no-default-export @@ -231,7 +232,13 @@ export default function jiraTest({ getService }: FtrProviderContext) { params: {}, }) .then((resp: any) => { - expect(Object.keys(resp.body)).to.eql(['status', 'message', 'retry', 'connector_id']); + expect(Object.keys(resp.body)).to.eql([ + 'status', + 'message', + 'retry', + 'errorSource', + 'connector_id', + ]); expect(resp.body.connector_id).to.eql(simulatedActionId); expect(resp.body.status).to.eql('error'); }); @@ -251,6 +258,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { retry: false, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subAction]: expected value to equal [pushToService]\n- [4.subAction]: expected value to equal [issueTypes]\n- [5.subAction]: expected value to equal [fieldsByIssueType]\n- [6.subAction]: expected value to equal [issues]\n- [7.subAction]: expected value to equal [issue]', + errorSource: TaskErrorSource.FRAMEWORK, }); }); }); @@ -269,6 +277,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { retry: false, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.incident.summary]: expected value of type [string] but got [undefined]\n- [4.subAction]: expected value to equal [issueTypes]\n- [5.subAction]: expected value to equal [fieldsByIssueType]\n- [6.subAction]: expected value to equal [issues]\n- [7.subAction]: expected value to equal [issue]', + errorSource: TaskErrorSource.FRAMEWORK, }); }); }); @@ -295,6 +304,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { retry: false, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.incident.summary]: expected value of type [string] but got [undefined]\n- [4.subAction]: expected value to equal [issueTypes]\n- [5.subAction]: expected value to equal [fieldsByIssueType]\n- [6.subAction]: expected value to equal [issues]\n- [7.subAction]: expected value to equal [issue]', + errorSource: TaskErrorSource.FRAMEWORK, }); }); }); @@ -323,6 +333,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { retry: false, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.commentId]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]\n- [4.subAction]: expected value to equal [issueTypes]\n- [5.subAction]: expected value to equal [fieldsByIssueType]\n- [6.subAction]: expected value to equal [issues]\n- [7.subAction]: expected value to equal [issue]', + errorSource: TaskErrorSource.FRAMEWORK, }); }); }); @@ -350,6 +361,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { retry: false, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.comment]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]\n- [4.subAction]: expected value to equal [issueTypes]\n- [5.subAction]: expected value to equal [fieldsByIssueType]\n- [6.subAction]: expected value to equal [issues]\n- [7.subAction]: expected value to equal [issue]', + errorSource: TaskErrorSource.FRAMEWORK, }); }); }); @@ -378,6 +390,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { retry: false, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.incident.labels]: types that failed validation:\n - [subActionParams.incident.labels.0.0]: The label label with spaces cannot contain spaces\n - [subActionParams.incident.labels.1]: expected value to equal [null]\n- [4.subAction]: expected value to equal [issueTypes]\n- [5.subAction]: expected value to equal [fieldsByIssueType]\n- [6.subAction]: expected value to equal [issues]\n- [7.subAction]: expected value to equal [issue]', + errorSource: TaskErrorSource.FRAMEWORK, }); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/openai.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/openai.ts index a0a906f0fa2ad7..4d23e887085e0c 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/openai.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/openai.ts @@ -11,6 +11,7 @@ import { OpenAISimulator, genAiSuccessResponse, } from '@kbn/actions-simulators-plugin/server/openai_simulation'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { getUrlPrefix, ObjectRemover } from '../../../../../common/lib'; @@ -248,6 +249,7 @@ export default function genAiTest({ getService }: FtrProviderContext) { message: 'error validating action params: [subAction]: expected value of type [string] but got [undefined]', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, }); }); @@ -265,6 +267,7 @@ export default function genAiTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: `Sub action "invalidAction" is not registered. Connector id: ${genAiActionId}. Connector name: OpenAI. Connector type: .gen-ai`, }); }); @@ -461,6 +464,7 @@ export default function genAiTest({ getService }: FtrProviderContext) { message: 'error validating action params: [subAction]: expected value of type [string] but got [undefined]', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, }); }); @@ -483,6 +487,7 @@ export default function genAiTest({ getService }: FtrProviderContext) { connector_id: genAiActionId, message: 'an error occurred while running the action', retry: true, + errorSource: TaskErrorSource.USER, service_message: 'Status code: 422. Message: API Error: Unprocessable Entity - The model `bad model` does not exist', }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/opsgenie.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/opsgenie.ts index fb73f6a95089ea..792e5dd021b3b0 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/opsgenie.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/opsgenie.ts @@ -11,6 +11,7 @@ import { OpsgenieSimulator, opsgenieSuccessResponse, } from '@kbn/actions-simulators-plugin/server/opsgenie_simulation'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; // eslint-disable-next-line import/no-default-export @@ -165,7 +166,13 @@ export default function opsgenieTest({ getService }: FtrProviderContext) { }); expect(200); - expect(Object.keys(body)).to.eql(['status', 'message', 'retry', 'connector_id']); + expect(Object.keys(body)).to.eql([ + 'status', + 'message', + 'retry', + 'errorSource', + 'connector_id', + ]); expect(body.connector_id).to.eql(opsgenieActionId); expect(body.status).to.eql('error'); }); @@ -184,6 +191,7 @@ export default function opsgenieTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: `Sub action "invalidAction" is not registered. Connector id: ${opsgenieActionId}. Connector name: Opsgenie. Connector type: .opsgenie`, }); }); @@ -202,6 +210,7 @@ export default function opsgenieTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: 'Request validation failed (Error: [message]: expected value of type [string] but got [undefined])', }); @@ -221,6 +230,7 @@ export default function opsgenieTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: 'Request validation failed (Error: [alias]: expected value of type [string] but got [undefined])', }); @@ -253,6 +263,7 @@ export default function opsgenieTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: 'Request validation failed (Error: [responders.0]: types that failed validation:\n- [responders.0.0.type]: types that failed validation:\n - [responders.0.type.0]: expected value to equal [team]\n - [responders.0.type.1]: expected value to equal [user]\n - [responders.0.type.2]: expected value to equal [escalation]\n - [responders.0.type.3]: expected value to equal [schedule]\n- [responders.0.1.id]: expected value of type [string] but got [undefined]\n- [responders.0.2.username]: expected value of type [string] but got [undefined])', }); @@ -282,6 +293,7 @@ export default function opsgenieTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: 'Request validation failed (Error: [responders.0]: types that failed validation:\n- [responders.0.0.name]: expected value of type [string] but got [undefined]\n- [responders.0.1.id]: expected value of type [string] but got [undefined]\n- [responders.0.2.username]: expected value of type [string] but got [undefined])', }); @@ -384,6 +396,7 @@ export default function opsgenieTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: 'Request validation failed (Error: [visibleTo.0]: types that failed validation:\n- [visibleTo.0.0.type]: expected value to equal [team]\n- [visibleTo.0.1.id]: expected value of type [string] but got [undefined]\n- [visibleTo.0.2.id]: expected value of type [string] but got [undefined]\n- [visibleTo.0.3.username]: expected value of type [string] but got [undefined])', }); @@ -448,6 +461,7 @@ export default function opsgenieTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: 'Request validation failed (Error: [details.bananas]: expected value of type [string] but got [number])', }); @@ -683,6 +697,7 @@ export default function opsgenieTest({ getService }: FtrProviderContext) { message: 'an error occurred while running the action', retry: true, connector_id: opsgenieActionId, + errorSource: TaskErrorSource.USER, service_message: 'Status code: 422. Message: Request failed with status code 422: {"message":"failed"}', }); @@ -706,6 +721,7 @@ export default function opsgenieTest({ getService }: FtrProviderContext) { message: 'an error occurred while running the action', retry: true, connector_id: opsgenieActionId, + errorSource: TaskErrorSource.USER, service_message: 'Status code: 422. Message: Request failed with status code 422: {"message":"failed"}', }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/resilient.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/resilient.ts index 8425de3b900ec0..4f3b107581a4dc 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/resilient.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/resilient.ts @@ -13,6 +13,7 @@ import { getExternalServiceSimulatorPath, ExternalServiceSimulator, } from '@kbn/actions-simulators-plugin/server/plugin'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; // eslint-disable-next-line import/no-default-export @@ -233,7 +234,13 @@ export default function resilientTest({ getService }: FtrProviderContext) { params: {}, }) .then((resp: any) => { - expect(Object.keys(resp.body)).to.eql(['status', 'message', 'retry', 'connector_id']); + expect(Object.keys(resp.body)).to.eql([ + 'status', + 'message', + 'retry', + 'errorSource', + 'connector_id', + ]); expect(resp.body.connector_id).to.eql(simulatedActionId); expect(resp.body.status).to.eql('error'); }); @@ -253,6 +260,7 @@ export default function resilientTest({ getService }: FtrProviderContext) { retry: false, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subAction]: expected value to equal [pushToService]\n- [4.subAction]: expected value to equal [incidentTypes]\n- [5.subAction]: expected value to equal [severity]', + errorSource: TaskErrorSource.FRAMEWORK, }); }); }); @@ -271,6 +279,7 @@ export default function resilientTest({ getService }: FtrProviderContext) { retry: false, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.incident.name]: expected value of type [string] but got [undefined]\n- [4.subAction]: expected value to equal [incidentTypes]\n- [5.subAction]: expected value to equal [severity]', + errorSource: TaskErrorSource.FRAMEWORK, }); }); }); @@ -295,6 +304,7 @@ export default function resilientTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.incident.name]: expected value of type [string] but got [undefined]\n- [4.subAction]: expected value to equal [incidentTypes]\n- [5.subAction]: expected value to equal [severity]', }); @@ -322,6 +332,7 @@ export default function resilientTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.commentId]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]\n- [4.subAction]: expected value to equal [incidentTypes]\n- [5.subAction]: expected value to equal [severity]', }); @@ -349,6 +360,7 @@ export default function resilientTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.comment]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]\n- [4.subAction]: expected value to equal [incidentTypes]\n- [5.subAction]: expected value to equal [severity]', }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itom.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itom.ts index e9e70d879618bb..4702d3bbe6df7d 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itom.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itom.ts @@ -13,6 +13,7 @@ import http from 'http'; import { getHttpProxyServer } from '@kbn/alerting-api-integration-helpers'; import { getServiceNowServer } from '@kbn/actions-simulators-plugin/server/plugin'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; // eslint-disable-next-line import/no-default-export @@ -412,7 +413,13 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { params: {}, }) .then((resp: any) => { - expect(Object.keys(resp.body)).to.eql(['status', 'message', 'retry', 'connector_id']); + expect(Object.keys(resp.body)).to.eql([ + 'status', + 'message', + 'retry', + 'errorSource', + 'connector_id', + ]); expect(resp.body.connector_id).to.eql(simulatedActionId); expect(resp.body.status).to.eql('error'); }); @@ -430,6 +437,7 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [addEvent]\n- [1.subAction]: expected value to equal [getChoices]', }); @@ -448,6 +456,7 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [addEvent]\n- [1.subAction]: expected value to equal [getChoices]', }); @@ -470,6 +479,7 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [addEvent]\n- [1.subActionParams.fields]: expected value of type [array] but got [undefined]', }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itsm.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itsm.ts index 3525597313514d..3241f9b80ab1fd 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itsm.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itsm.ts @@ -13,6 +13,7 @@ import http from 'http'; import { getHttpProxyServer } from '@kbn/alerting-api-integration-helpers'; import { getServiceNowServer } from '@kbn/actions-simulators-plugin/server/plugin'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; // eslint-disable-next-line import/no-default-export @@ -447,7 +448,13 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { params: {}, }) .then((resp: any) => { - expect(Object.keys(resp.body)).to.eql(['status', 'message', 'retry', 'connector_id']); + expect(Object.keys(resp.body)).to.eql([ + 'status', + 'message', + 'retry', + 'errorSource', + 'connector_id', + ]); expect(resp.body.connector_id).to.eql(simulatedActionId); expect(resp.body.status).to.eql('error'); }); @@ -465,6 +472,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subAction]: expected value to equal [pushToService]\n- [4.subAction]: expected value to equal [getChoices]\n- [5.subAction]: expected value to equal [closeIncident]', }); @@ -483,6 +491,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.incident.short_description]: expected value of type [string] but got [undefined]\n- [4.subAction]: expected value to equal [getChoices]\n- [5.subAction]: expected value to equal [closeIncident]', }); @@ -506,6 +515,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.incident.short_description]: expected value of type [string] but got [undefined]\n- [4.subAction]: expected value to equal [getChoices]\n- [5.subAction]: expected value to equal [closeIncident]', }); @@ -533,6 +543,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.commentId]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]\n- [4.subAction]: expected value to equal [getChoices]\n- [5.subAction]: expected value to equal [closeIncident]', }); @@ -560,6 +571,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.comment]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]\n- [4.subAction]: expected value to equal [getChoices]\n- [5.subAction]: expected value to equal [closeIncident]', }); @@ -582,6 +594,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subAction]: expected value to equal [pushToService]\n- [4.subActionParams.fields]: expected value of type [array] but got [undefined]\n- [5.subAction]: expected value to equal [closeIncident]', }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_sir.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_sir.ts index 2094ddd71cd7df..6ab9a257c92612 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_sir.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_sir.ts @@ -13,6 +13,7 @@ import http from 'http'; import { getHttpProxyServer } from '@kbn/alerting-api-integration-helpers'; import { getServiceNowServer } from '@kbn/actions-simulators-plugin/server/plugin'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; // eslint-disable-next-line import/no-default-export @@ -460,7 +461,13 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { params: {}, }) .then((resp: any) => { - expect(Object.keys(resp.body)).to.eql(['status', 'message', 'retry', 'connector_id']); + expect(Object.keys(resp.body)).to.eql([ + 'status', + 'message', + 'retry', + 'errorSource', + 'connector_id', + ]); expect(resp.body.connector_id).to.eql(simulatedActionId); expect(resp.body.status).to.eql('error'); }); @@ -478,6 +485,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subAction]: expected value to equal [pushToService]\n- [4.subAction]: expected value to equal [getChoices]', }); @@ -496,6 +504,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.incident.short_description]: expected value of type [string] but got [undefined]\n- [4.subAction]: expected value to equal [getChoices]', }); @@ -519,6 +528,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.incident.short_description]: expected value of type [string] but got [undefined]\n- [4.subAction]: expected value to equal [getChoices]', }); @@ -546,6 +556,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.commentId]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]\n- [4.subAction]: expected value to equal [getChoices]', }); @@ -573,6 +584,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.comment]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]\n- [4.subAction]: expected value to equal [getChoices]', }); @@ -595,6 +607,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getFields]\n- [1.subAction]: expected value to equal [getIncident]\n- [2.subAction]: expected value to equal [handshake]\n- [3.subAction]: expected value to equal [pushToService]\n- [4.subActionParams.fields]: expected value of type [array] but got [undefined]', }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/swimlane.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/swimlane.ts index 5d6bb9e9b8145b..859f4f952fe58a 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/swimlane.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/swimlane.ts @@ -12,6 +12,7 @@ import http from 'http'; import { getHttpProxyServer } from '@kbn/alerting-api-integration-helpers'; import { getSwimlaneServer } from '@kbn/actions-simulators-plugin/server/plugin'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; // eslint-disable-next-line import/no-default-export @@ -323,7 +324,13 @@ export default function swimlaneTest({ getService }: FtrProviderContext) { params: {}, }) .then((resp: any) => { - expect(Object.keys(resp.body)).to.eql(['status', 'message', 'retry', 'connector_id']); + expect(Object.keys(resp.body)).to.eql([ + 'status', + 'message', + 'retry', + 'errorSource', + 'connector_id', + ]); expect(resp.body.connector_id).to.eql(simulatedActionId); expect(resp.body.status).to.eql('error'); }); @@ -341,6 +348,7 @@ export default function swimlaneTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: [subAction]: expected value to equal [pushToService]', }); @@ -366,6 +374,7 @@ export default function swimlaneTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: [subActionParams]: expected a plain object value, but found [null] instead.', }); @@ -390,6 +399,7 @@ export default function swimlaneTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: [subActionParams.comments]: types that failed validation:\n- [subActionParams.comments.0.0.commentId]: expected value of type [string] but got [undefined]\n- [subActionParams.comments.1]: expected value to equal [null]', }); @@ -414,6 +424,7 @@ export default function swimlaneTest({ getService }: FtrProviderContext) { connector_id: simulatedActionId, status: 'error', retry: false, + errorSource: TaskErrorSource.FRAMEWORK, message: 'error validating action params: [subActionParams.comments]: types that failed validation:\n- [subActionParams.comments.0.0.comment]: expected value of type [string] but got [undefined]\n- [subActionParams.comments.1]: expected value to equal [null]', }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/tines.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/tines.ts index 99ba90f78dbebd..e6e3f8511c4228 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/tines.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/tines.ts @@ -14,6 +14,7 @@ import { tinesAgentWebhook, tinesWebhookSuccessResponse, } from '@kbn/actions-simulators-plugin/server/tines_simulation'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; const connectorTypeId = '.tines'; @@ -184,7 +185,13 @@ export default function tinesTest({ getService }: FtrProviderContext) { }); expect(200); - expect(Object.keys(body)).to.eql(['status', 'message', 'retry', 'connector_id']); + expect(Object.keys(body)).to.eql([ + 'status', + 'message', + 'retry', + 'errorSource', + 'connector_id', + ]); expect(body.connector_id).to.eql(tinesActionId); expect(body.status).to.eql('error'); }); @@ -203,6 +210,7 @@ export default function tinesTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: `Sub action "invalidAction" is not registered. Connector id: ${tinesActionId}. Connector name: Tines. Connector type: .tines`, }); }); @@ -221,6 +229,7 @@ export default function tinesTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: 'Request validation failed (Error: [storyId]: expected value of type [number] but got [undefined])', }); @@ -240,6 +249,7 @@ export default function tinesTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: 'Invalid subActionsParams: [webhook] or [webhookUrl] expected but got none', }); @@ -263,6 +273,7 @@ export default function tinesTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: 'Request validation failed (Error: [webhook.storyId]: expected value of type [number] but got [undefined])', }); @@ -286,6 +297,7 @@ export default function tinesTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: 'Request validation failed (Error: [webhook.name]: expected value of type [string] but got [undefined])', }); @@ -309,6 +321,7 @@ export default function tinesTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: 'Request validation failed (Error: [webhook.path]: expected value of type [string] but got [undefined])', }); @@ -332,6 +345,7 @@ export default function tinesTest({ getService }: FtrProviderContext) { status: 'error', retry: true, message: 'an error occurred while running the action', + errorSource: TaskErrorSource.USER, service_message: 'Request validation failed (Error: [webhook.secret]: expected value of type [string] but got [undefined])', }); @@ -489,6 +503,7 @@ export default function tinesTest({ getService }: FtrProviderContext) { message: 'an error occurred while running the action', retry: true, connector_id: tinesActionId, + errorSource: TaskErrorSource.USER, service_message: 'Status code: 422. Message: API Error: Unprocessable Entity', }); }); @@ -510,6 +525,7 @@ export default function tinesTest({ getService }: FtrProviderContext) { message: 'an error occurred while running the action', retry: true, connector_id: tinesActionId, + errorSource: TaskErrorSource.USER, service_message: 'Status code: 422. Message: API Error: Unprocessable Entity', }); }); @@ -529,6 +545,7 @@ export default function tinesTest({ getService }: FtrProviderContext) { message: 'an error occurred while running the action', retry: true, connector_id: tinesActionId, + errorSource: TaskErrorSource.USER, service_message: 'Status code: 422. Message: API Error: Unprocessable Entity', }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/sub_action_framework/index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/sub_action_framework/index.ts index 8bc8bc6a897578..e8470a23132096 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/sub_action_framework/index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/sub_action_framework/index.ts @@ -7,6 +7,7 @@ import type SuperTest from 'supertest'; import expect from '@kbn/expect'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { getUrlPrefix, ObjectRemover } from '../../../../../common/lib'; @@ -169,6 +170,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { message: 'an error occurred while running the action', retry: true, connector_id: res.body.id, + errorSource: TaskErrorSource.USER, service_message: 'Request validation failed (Error: [id]: expected value of type [string] but got [undefined])', }); @@ -192,6 +194,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { status: 'error', retry: false, connector_id: res.body.id, + errorSource: TaskErrorSource.FRAMEWORK, }); } }); @@ -248,6 +251,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { message: 'an error occurred while running the action', retry: true, connector_id: res.body.id, + errorSource: TaskErrorSource.USER, service_message: `Sub action \"notRegistered\" is not registered. Connector id: ${res.body.id}. Connector name: Test: Sub action connector. Connector type: test.sub-action-connector`, }); }); @@ -268,6 +272,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { message: 'an error occurred while running the action', retry: true, connector_id: res.body.id, + errorSource: TaskErrorSource.USER, service_message: `Method \"notAFunction\" does not exists in service. Sub action: \"notAFunction\". Connector id: ${res.body.id}. Connector name: Test: Sub action connector. Connector type: test.sub-action-connector`, }); }); @@ -288,6 +293,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { message: 'an error occurred while running the action', retry: true, connector_id: res.body.id, + errorSource: TaskErrorSource.USER, service_message: `Method \"notExist\" does not exists in service. Sub action: \"notExist\". Connector id: ${res.body.id}. Connector name: Test: Sub action connector. Connector type: test.sub-action-connector`, }); }); @@ -311,6 +317,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { message: 'an error occurred while running the action', retry: true, connector_id: res.body.id, + errorSource: TaskErrorSource.USER, service_message: 'You should register at least one subAction for your connector type', }); }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts index 4acb40fcfe3f1a..fb10eba9774adb 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts @@ -9,6 +9,7 @@ import expect from '@kbn/expect'; import { IValidatedEvent, nanosToMillis } from '@kbn/event-log-plugin/server'; import { ESTestIndexTool, ES_TEST_INDEX_NAME } from '@kbn/alerting-api-integration-helpers'; import { ActionExecutionSourceType } from '@kbn/actions-plugin/server/lib/action_execution_source'; +import { TaskErrorSource } from '@kbn/task-manager-plugin/common'; import { Spaces } from '../../scenarios'; import { getUrlPrefix, ObjectRemover, getEventLog } from '../../../common/lib'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; @@ -131,6 +132,7 @@ export default function ({ getService }: FtrProviderContext) { message: 'an error occurred while running the action', service_message: `expected failure for ${ES_TEST_INDEX_NAME} ${reference}`, retry: true, + errorSource: TaskErrorSource.USER, }); await validateEventLog({ @@ -326,6 +328,7 @@ export default function ({ getService }: FtrProviderContext) { message: 'an error occurred while running the action', serviceMessage: `expected failure for ${ES_TEST_INDEX_NAME} ${reference}`, retry: true, + errorSource: TaskErrorSource.USER, }); }); }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/migrations.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/migrations.ts index 4f23a5ff3a7278..541f83fc8d412f 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/migrations.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/migrations.ts @@ -126,6 +126,7 @@ export default function createGetTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ connector_id: '0f8f2810-0a59-11ec-9a7c-fd0c2b83ff7d', status: 'error', + errorSource: 'framework', message: `error validating action type connector: secrets must be defined`, retry: false, }); From 01a030c22b7b8cb733eb8e3c22210bd22d222a1f Mon Sep 17 00:00:00 2001 From: Michael Olorunnisola Date: Wed, 20 Dec 2023 14:44:01 -0500 Subject: [PATCH 048/116] [Investigations] - Unskip alert page not found test (#173781) ## Summary This test can be unskipped as the alert details page no longer exists in favor of the expanded flyout, so this test can be re-enabled fixes: https://github.com/elastic/kibana/issues/143705 --- .../cypress/e2e/explore/urls/not_found.cy.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/explore/urls/not_found.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/urls/not_found.cy.ts index 80e682d74de968..205832fd0eaf79 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/explore/urls/not_found.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/urls/not_found.cy.ts @@ -31,9 +31,7 @@ describe('Display not found page', { tags: ['@ess', '@serverless'] }, () => { visitWithTimeRange(TIMELINES_URL); }); - // Tracked by https://github.com/elastic/kibana/issues/143705 - // TODO: We need to determine what we want the behavior to be here - it.skip('navigates to the alerts page with incorrect link', () => { + it('navigates to the alerts page with incorrect link', () => { visitWithTimeRange(`${ALERTS_URL}/randomUrl`); cy.get(NOT_FOUND).should('exist'); }); From 35d79a901d9c690fbb128f138203799f97826291 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Dec 2023 20:58:38 +0100 Subject: [PATCH 049/116] Update platform security modules (main) (#173232) --- package.json | 11 ++- packages/kbn-mock-idp-plugin/common/utils.ts | 14 ++-- .../saml_provider/server/saml_tools.ts | 15 ++-- .../packages/helpers/saml/saml_tools.ts | 15 ++-- yarn.lock | 74 +++++++++---------- 5 files changed, 62 insertions(+), 67 deletions(-) diff --git a/package.json b/package.json index f2446fc5c27a08..2553521b662be4 100644 --- a/package.json +++ b/package.json @@ -940,7 +940,7 @@ "file-saver": "^1.3.8", "fnv-plus": "^1.3.1", "font-awesome": "4.7.0", - "formik": "^2.2.9", + "formik": "^2.4.5", "fp-ts": "^2.3.1", "geojson-vt": "^3.2.1", "get-port": "^5.0.0", @@ -1414,7 +1414,7 @@ "@types/nock": "^10.0.3", "@types/node": "18.18.5", "@types/node-fetch": "2.6.4", - "@types/node-forge": "^1.3.1", + "@types/node-forge": "^1.3.10", "@types/nodemailer": "^6.4.0", "@types/normalize-path": "^3.0.0", "@types/object-hash": "^1.3.0", @@ -1463,7 +1463,7 @@ "@types/testing-library__jest-dom": "^5.14.7", "@types/textarea-caret": "^3.0.1", "@types/tinycolor2": "^1.4.1", - "@types/tough-cookie": "^4.0.2", + "@types/tough-cookie": "^4.0.5", "@types/type-detect": "^4.0.1", "@types/uuid": "^9.0.0", "@types/vinyl": "^2.0.4", @@ -1473,7 +1473,6 @@ "@types/webpack-env": "^1.15.3", "@types/webpack-merge": "^4.1.5", "@types/webpack-sources": "^0.1.4", - "@types/xml-crypto": "^1.4.2", "@types/xml2js": "^0.4.11", "@types/yargs": "^15.0.0", "@types/yauzl": "^2.9.1", @@ -1646,7 +1645,7 @@ "tempy": "^0.3.0", "terser": "^5.26.0", "terser-webpack-plugin": "^4.2.3", - "tough-cookie": "^4.1.2", + "tough-cookie": "^4.1.3", "tree-kill": "^1.2.2", "ts-morph": "^13.0.2", "tsd": "^0.20.0", @@ -1662,7 +1661,7 @@ "webpack-dev-server": "^4.9.3", "webpack-merge": "^4.2.2", "webpack-sources": "^1.4.1", - "xml-crypto": "^3.0.1", + "xml-crypto": "^5.0.0", "xmlbuilder": "13.0.2", "yargs": "^15.4.1", "yarn-deduplicate": "^6.0.2" diff --git a/packages/kbn-mock-idp-plugin/common/utils.ts b/packages/kbn-mock-idp-plugin/common/utils.ts index 5d55fbc5656857..f98425f08248f4 100644 --- a/packages/kbn-mock-idp-plugin/common/utils.ts +++ b/packages/kbn-mock-idp-plugin/common/utils.ts @@ -149,19 +149,19 @@ export async function createSAMLResponse(options: { `; - const signature = new SignedXml(); + const signature = new SignedXml({ privateKey: await readFile(KBN_KEY_PATH) }); signature.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'; - signature.signingKey = await readFile(KBN_KEY_PATH); + signature.canonicalizationAlgorithm = 'http://www.w3.org/2001/10/xml-exc-c14n#'; // Adds a reference to a `Assertion` xml element and an array of transform algorithms to be used during signing. - signature.addReference( - `//*[local-name(.)='Assertion']`, - [ + signature.addReference({ + xpath: `//*[local-name(.)='Assertion']`, + digestAlgorithm: 'http://www.w3.org/2001/04/xmlenc#sha256', + transforms: [ 'http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#', ], - 'http://www.w3.org/2001/04/xmlenc#sha256' - ); + }); signature.computeSignature(samlAssertionTemplateXML, { location: { reference: `//*[local-name(.)='Issuer']`, action: 'after' }, diff --git a/x-pack/test/cloud_integration/plugins/saml_provider/server/saml_tools.ts b/x-pack/test/cloud_integration/plugins/saml_provider/server/saml_tools.ts index 0be46a431d7d40..7d1a6cbfa4255e 100644 --- a/x-pack/test/cloud_integration/plugins/saml_provider/server/saml_tools.ts +++ b/x-pack/test/cloud_integration/plugins/saml_provider/server/saml_tools.ts @@ -29,6 +29,7 @@ const parseStringAsync = promisify(parseString); const signingKey = fs.readFileSync(KBN_KEY_PATH); const signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'; +const canonicalizationAlgorithm = 'http://www.w3.org/2001/10/xml-exc-c14n#'; export async function getSAMLRequestId(urlWithSAMLRequestId: string) { const inflatedSAMLRequest = (await inflateRawAsync( @@ -87,19 +88,19 @@ export async function getSAMLResponse({ `; - const signature = new SignedXml(); + const signature = new SignedXml({ privateKey: signingKey }); signature.signatureAlgorithm = signatureAlgorithm; - signature.signingKey = signingKey; + signature.canonicalizationAlgorithm = canonicalizationAlgorithm; // Adds a reference to a `Assertion` xml element and an array of transform algorithms to be used during signing. - signature.addReference( - `//*[local-name(.)='Assertion']`, - [ + signature.addReference({ + xpath: `//*[local-name(.)='Assertion']`, + digestAlgorithm: 'http://www.w3.org/2001/04/xmlenc#sha256', + transforms: [ 'http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#', ], - 'http://www.w3.org/2001/04/xmlenc#sha256' - ); + }); signature.computeSignature(samlAssertionTemplateXML, { location: { reference: `//*[local-name(.)='Issuer']`, action: 'after' }, diff --git a/x-pack/test/security_api_integration/packages/helpers/saml/saml_tools.ts b/x-pack/test/security_api_integration/packages/helpers/saml/saml_tools.ts index ad34f37fdc0a44..255625082407b2 100644 --- a/x-pack/test/security_api_integration/packages/helpers/saml/saml_tools.ts +++ b/x-pack/test/security_api_integration/packages/helpers/saml/saml_tools.ts @@ -28,6 +28,7 @@ const parseStringAsync = promisify(parseString); const signingKey = fs.readFileSync(KBN_KEY_PATH); const signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'; +const canonicalizationAlgorithm = 'http://www.w3.org/2001/10/xml-exc-c14n#'; export async function getSAMLRequestId(urlWithSAMLRequestId: string) { const inflatedSAMLRequest = (await inflateRawAsync( @@ -83,19 +84,19 @@ export async function getSAMLResponse({ `; - const signature = new SignedXml(); + const signature = new SignedXml({ privateKey: signingKey }); signature.signatureAlgorithm = signatureAlgorithm; - signature.signingKey = signingKey; + signature.canonicalizationAlgorithm = canonicalizationAlgorithm; // Adds a reference to a `Assertion` xml element and an array of transform algorithms to be used during signing. - signature.addReference( - `//*[local-name(.)='Assertion']`, - [ + signature.addReference({ + xpath: `//*[local-name(.)='Assertion']`, + digestAlgorithm: 'http://www.w3.org/2001/04/xmlenc#sha256', + transforms: [ 'http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#', ], - 'http://www.w3.org/2001/04/xmlenc#sha256' - ); + }); signature.computeSignature(samlAssertionTemplateXML, { location: { reference: `//*[local-name(.)='Issuer']`, action: 'after' }, diff --git a/yarn.lock b/yarn.lock index dd6069f3c26efc..7b2754c8719c8f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9656,10 +9656,10 @@ "@types/node" "*" form-data "^3.0.0" -"@types/node-forge@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.1.tgz#49e44432c306970b4e900c3b214157c480af19fa" - integrity sha512-hvQ7Wav8I0j9amPXJtGqI/Yx70zeF62UKlAYq8JPm0nHzjKKzZvo9iR3YI2MiOghZRlOI+tQ2f6D+G6vVf4V2Q== +"@types/node-forge@^1.3.10": + version "1.3.10" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.10.tgz#62a19d4f75a8b03290578c2b04f294b1a5a71b07" + integrity sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw== dependencies: "@types/node" "*" @@ -10177,10 +10177,10 @@ dependencies: "@types/geojson" "*" -"@types/tough-cookie@*", "@types/tough-cookie@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.2.tgz#6286b4c7228d58ab7866d19716f3696e03a09397" - integrity sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw== +"@types/tough-cookie@*", "@types/tough-cookie@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" + integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== "@types/type-detect@^4.0.1": version "4.0.1" @@ -10292,14 +10292,6 @@ dependencies: "@types/node" "*" -"@types/xml-crypto@^1.4.2": - version "1.4.2" - resolved "https://registry.yarnpkg.com/@types/xml-crypto/-/xml-crypto-1.4.2.tgz#5ea7ef970f525ae8fe1e2ce0b3d40da1e3b279ae" - integrity sha512-1kT+3gVkeBDg7Ih8NefxGYfCApwZViMIs5IEs5AXF6Fpsrnf9CLAEIRh0DYb1mIcRcvysVbe27cHsJD6rJi36w== - dependencies: - "@types/node" "*" - xpath "0.0.27" - "@types/xml2js@^0.4.11": version "0.4.11" resolved "https://registry.yarnpkg.com/@types/xml2js/-/xml2js-0.4.11.tgz#bf46a84ecc12c41159a7bd9cf51ae84129af0e79" @@ -10749,10 +10741,15 @@ object.fromentries "^2.0.0" prop-types "^15.7.0" -"@xmldom/xmldom@^0.8.5": - version "0.8.6" - resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.6.tgz#8a1524eb5bd5e965c1e3735476f0262469f71440" - integrity sha512-uRjjusqpoqfmRkTaNuLJ2VohVr67Q5YwDATW3VU7PfzTj6IRaihGrYI7zckGZjxQPBIp63nfvJbM+Yu5ICh0Bg== +"@xmldom/is-dom-node@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@xmldom/is-dom-node/-/is-dom-node-1.0.1.tgz#83b9f3e1260fb008061c6fa787b93a00f9be0629" + integrity sha512-CJDxIgE5I0FH+ttq/Fxy6nRpxP70+e2O048EPe85J2use3XKdatVM7dDVvFNjQudd9B49NPoZ+8PG49zj4Er8Q== + +"@xmldom/xmldom@^0.8.10": + version "0.8.10" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99" + integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw== "@xobotyi/scrollbar-width@1.9.5": version "1.9.5" @@ -17202,18 +17199,19 @@ formidable@^2.1.2: once "^1.4.0" qs "^6.11.0" -formik@^2.2.9: - version "2.2.9" - resolved "https://registry.yarnpkg.com/formik/-/formik-2.2.9.tgz#8594ba9c5e2e5cf1f42c5704128e119fc46232d0" - integrity sha512-LQLcISMmf1r5at4/gyJigGn0gOwFbeEAlji+N9InZF6LIMXnFNkO42sCI8Jt84YZggpD4cPWObAZaxpEFtSzNA== +formik@^2.4.5: + version "2.4.5" + resolved "https://registry.yarnpkg.com/formik/-/formik-2.4.5.tgz#f899b5b7a6f103a8fabb679823e8fafc7e0ee1b4" + integrity sha512-Gxlht0TD3vVdzMDHwkiNZqJ7Mvg77xQNfmBRrNtvzcHZs72TJppSTDKHpImCMJZwcWPBJ8jSQQ95GJzXFf1nAQ== dependencies: + "@types/hoist-non-react-statics" "^3.3.1" deepmerge "^2.1.1" hoist-non-react-statics "^3.3.0" lodash "^4.17.21" lodash-es "^4.17.21" react-fast-compare "^2.0.1" tiny-warning "^1.0.2" - tslib "^1.10.0" + tslib "^2.0.0" forwarded-parse@^2.1.0: version "2.1.0" @@ -31242,13 +31240,14 @@ xdg-basedir@^4.0.0: resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== -xml-crypto@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/xml-crypto/-/xml-crypto-3.0.1.tgz#1d4852b040e80413d8058e2917eddd9f17a00b8b" - integrity sha512-7XrwB3ujd95KCO6+u9fidb8ajvRJvIfGNWD0XLJoTWlBKz+tFpUzEYxsN+Il/6/gHtEs1RgRh2RH+TzhcWBZUw== +xml-crypto@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/xml-crypto/-/xml-crypto-5.0.0.tgz#e54dff59bf0e18527b91af7690513041ebb90273" + integrity sha512-TdJZp/gdKb5RYiZigLy/RUz9EpbEV+HoOR4ofby3VonDSn7FmNZlex7OuxLPD8sRlCLZ5YYFI+9s1OhFs7fwEw== dependencies: - "@xmldom/xmldom" "^0.8.5" - xpath "0.0.32" + "@xmldom/is-dom-node" "^1.0.1" + "@xmldom/xmldom" "^0.8.10" + xpath "^0.0.33" xml-name-validator@^4.0.0: version "4.0.0" @@ -31290,15 +31289,10 @@ xmldoc@^1.1.2: dependencies: sax "^1.2.1" -xpath@0.0.27: - version "0.0.27" - resolved "https://registry.yarnpkg.com/xpath/-/xpath-0.0.27.tgz#dd3421fbdcc5646ac32c48531b4d7e9d0c2cfa92" - integrity sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ== - -xpath@0.0.32: - version "0.0.32" - resolved "https://registry.yarnpkg.com/xpath/-/xpath-0.0.32.tgz#1b73d3351af736e17ec078d6da4b8175405c48af" - integrity sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw== +xpath@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/xpath/-/xpath-0.0.33.tgz#5136b6094227c5df92002e7c3a13516a5074eb07" + integrity sha512-NNXnzrkDrAzalLhIUc01jO2mOzXGXh1JwPgkihcLLzw98c0WgYDmmjSh1Kl3wzaxSVWMuA+fe0WTWOBDWCBmNA== xstate@^4.38.2: version "4.38.2" From 4465c1e090ab1179f12000d52b1dc0eefd14217f Mon Sep 17 00:00:00 2001 From: Jiawei Wu <74562234+JiaweiWu@users.noreply.github.com> Date: Wed, 20 Dec 2023 12:21:51 -0800 Subject: [PATCH 050/116] [RAM] Fix rule edit flyout alerts search bar autocomplete scroll (#172899) ## Summary Resolves: https://github.com/elastic/kibana/issues/172594 Fixes the rule edit alerts search bar autocomplete causing background to also scroll infinitely https://github.com/elastic/kibana/assets/74562234/f55db528-b933-400a-80b5-8a3063f0f29c --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Xavier Mouligneau --- .../public/application/sections/rule_form/rule_edit.tsx | 2 +- .../apps/triggers_actions_ui/alert_create_flyout.ts | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx index 3f1c050fb7e25d..0aebaaaa298828 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx @@ -213,7 +213,7 @@ export const RuleEdit = ({ aria-labelledby="flyoutRuleEditTitle" size="m" maxWidth={620} - ownFocus={false} + ownFocus > diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts index 3cceb01b549980..30ece977d1641b 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts @@ -82,18 +82,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { } describe('create alert', function () { - before(async () => { + beforeEach(async () => { await pageObjects.common.navigateToApp('triggersActions'); await testSubjects.click('rulesTab'); }); - afterEach(async () => { - // Reset the Rules tab without reloading the entire page - // This is safer than trying to close the alert flyout, which may or may not be open at the end of a test - await testSubjects.click('logsTab'); - await testSubjects.click('rulesTab'); - }); - it('should delete the right action when the same action has been added twice', async () => { // create a new rule const ruleName = generateUniqueKey(); From 00a2f49e68d73a48eaaf782f02e6dc90288aa5f6 Mon Sep 17 00:00:00 2001 From: Zacqary Adam Xeper Date: Wed, 20 Dec 2023 14:37:48 -0600 Subject: [PATCH 051/116] [Task Manager] Evenly distribute bulk-enabled alerting rules (#172742) ## Summary ~Closes~ Part of https://github.com/elastic/kibana/issues/171980 When `bulkEnable`ing more than 1 task, adds a random delay to each subsequent task's `runAt` and `scheduledAt` to more evenly distribute their execution times. This offset is a maximum of 5 minutes, or the task's interval, whichever is shorter. As per Slack discussion with @mikecote, this is a random distribution of execution times instead of a predictable, algorithmic offset. We believe that a random distribution will do a better job of avoiding spikes than anything more directed. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../server/lib/retryable_bulk_update.ts | 2 +- .../server/task_scheduling.test.ts | 45 +++++++++++++++++++ .../task_manager/server/task_scheduling.ts | 25 ++++++++++- 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/task_manager/server/lib/retryable_bulk_update.ts b/x-pack/plugins/task_manager/server/lib/retryable_bulk_update.ts index d50fb88d909c3f..1232ab7ae99114 100644 --- a/x-pack/plugins/task_manager/server/lib/retryable_bulk_update.ts +++ b/x-pack/plugins/task_manager/server/lib/retryable_bulk_update.ts @@ -17,7 +17,7 @@ export interface RetryableBulkUpdateOpts { taskIds: string[]; getTasks: (taskIds: string[]) => Promise; filter: (task: ConcreteTaskInstance) => boolean; - map: (task: ConcreteTaskInstance) => ConcreteTaskInstance; + map: (task: ConcreteTaskInstance, i: number, arr: ConcreteTaskInstance[]) => ConcreteTaskInstance; store: TaskStore; validate: boolean; } diff --git a/x-pack/plugins/task_manager/server/task_scheduling.test.ts b/x-pack/plugins/task_manager/server/task_scheduling.test.ts index 11a2e8a115d8ac..f4c8c0d6b08801 100644 --- a/x-pack/plugins/task_manager/server/task_scheduling.test.ts +++ b/x-pack/plugins/task_manager/server/task_scheduling.test.ts @@ -289,6 +289,51 @@ describe('TaskScheduling', () => { }, ]); }); + + test('should offset runAt and scheduledAt by no more than 5m if more than one task is enabled', async () => { + const task = taskManagerMock.createTask({ + id: 'task-1', + enabled: false, + schedule: { interval: '3h' }, + runAt: new Date('1969-09-13T21:33:58.285Z'), + scheduledAt: new Date('1969-09-10T21:33:58.285Z'), + }); + const task2 = taskManagerMock.createTask({ + id: 'task-2', + enabled: false, + schedule: { interval: '3h' }, + runAt: new Date('1969-09-13T21:33:58.285Z'), + scheduledAt: new Date('1969-09-10T21:33:58.285Z'), + }); + mockTaskStore.bulkUpdate.mockImplementation(() => + Promise.resolve([{ tag: 'ok', value: task }]) + ); + mockTaskStore.bulkGet.mockResolvedValue([asOk(task), asOk(task2)]); + + const taskScheduling = new TaskScheduling(taskSchedulingOpts); + await taskScheduling.bulkEnable([task.id, task2.id]); + + const bulkUpdatePayload = mockTaskStore.bulkUpdate.mock.calls[0][0]; + + expect(bulkUpdatePayload.length).toBe(2); + expect(bulkUpdatePayload[0]).toEqual({ + ...task, + enabled: true, + runAt: new Date('1970-01-01T00:00:00.000Z'), + scheduledAt: new Date('1970-01-01T00:00:00.000Z'), + }); + + expect(omit(bulkUpdatePayload[1], 'runAt', 'scheduledAt')).toEqual({ + ...omit(task2, 'runAt', 'scheduledAt'), + enabled: true, + }); + + const { runAt, scheduledAt } = bulkUpdatePayload[1]; + expect(runAt.getTime()).toEqual(scheduledAt.getTime()); + expect(runAt.getTime() - bulkUpdatePayload[0].runAt.getTime()).toBeLessThanOrEqual( + 5 * 60 * 1000 + ); + }); }); describe('bulkDisable', () => { diff --git a/x-pack/plugins/task_manager/server/task_scheduling.ts b/x-pack/plugins/task_manager/server/task_scheduling.ts index 795e563986586d..c0e28a5fae3bd1 100644 --- a/x-pack/plugins/task_manager/server/task_scheduling.ts +++ b/x-pack/plugins/task_manager/server/task_scheduling.ts @@ -176,9 +176,15 @@ export class TaskScheduling { store: this.store, getTasks: async (ids) => await this.bulkGetTasksHelper(ids), filter: (task) => !task.enabled, - map: (task) => { + map: (task, i) => { if (runSoon) { - return { ...task, enabled: true, scheduledAt: new Date(), runAt: new Date() }; + // Run the first task now. Run all other tasks a random number of ms in the future, + // with a maximum of 5 minutes or the task interval, whichever is smaller. + const taskToRun = + i === 0 + ? { ...task, runAt: new Date(), scheduledAt: new Date() } + : randomlyOffsetRunTimestamp(task); + return { ...taskToRun, enabled: true }; } return { ...task, enabled: true }; }, @@ -440,3 +446,18 @@ const cancellablePromise = () => { .then(() => {}), }; }; + +const randomlyOffsetRunTimestamp: (task: ConcreteTaskInstance) => ConcreteTaskInstance = (task) => { + const now = Date.now(); + const maximumOffsetTimestamp = now + 1000 * 60 * 5; // now + 5 minutes + const taskIntervalInMs = parseIntervalAsMillisecond(task.schedule?.interval ?? '0s'); + const maximumRunAt = Math.min(now + taskIntervalInMs, maximumOffsetTimestamp); + + // Offset between 1 and maximumRunAt ms + const runAt = new Date(now + Math.floor(Math.random() * (maximumRunAt - now) + 1)); + return { + ...task, + runAt, + scheduledAt: runAt, + }; +}; From 6bec71021ac92a84da05a3646fe0992579c52832 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Wed, 20 Dec 2023 14:14:39 -0700 Subject: [PATCH 052/116] [Controls] Fix validation query for nested fields (#173690) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes https://github.com/elastic/kibana/issues/172694 ## Summary Apparently, when we [originally added the options list queries](https://github.com/elastic/kibana/blob/d07c74d25087447458da8de6a277544e9dfa164c/src/plugins/controls/server/control_types/options_list/options_list_queries.ts#L145), we only considered nested fields for the **suggestion** aggregation; we completely forgot to consider nested fields in the **validation** aggregation. So, from the introduction of the new controls, options list selections would be always be marked "invalid" for nested fields - oops! 🙈 This PR fixes the validation aggregation so that nested field selections behave as expected. **Before** https://github.com/elastic/kibana/assets/8698078/68b5dad5-6210-460d-b2ed-a24bf44ed333 **After** https://github.com/elastic/kibana/assets/8698078/dd22bd95-f542-49bb-9dd1-7913c945c0f7 > [!TIP] > Searching a nested field for specific values will always return slightly unexpected results, because if a subset of the nested field matches, we don't return the subset - we return the **entire set**. In other words, if you have one document where the nested field equals `["one", "two"]` and another document where the nested field equals `["one", "three"]`, searching for `"one"` will return `["one", "two", "three"]` as options, like so: > > ![image](https://github.com/elastic/kibana/assets/8698078/866917fa-ac75-4784-92b5-54c6635d6d5e) ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../options_list_suggestions_route.ts | 12 +- .../options_list_validation_queries.test.ts | 128 +++++++++++++++--- .../options_list_validation_queries.ts | 46 +++++-- .../controls/server/options_list/types.ts | 2 +- 4 files changed, 154 insertions(+), 34 deletions(-) diff --git a/src/plugins/controls/server/options_list/options_list_suggestions_route.ts b/src/plugins/controls/server/options_list/options_list_suggestions_route.ts index 310a04874f7fb5..1e1084d7573107 100644 --- a/src/plugins/controls/server/options_list/options_list_suggestions_route.ts +++ b/src/plugins/controls/server/options_list/options_list_suggestions_route.ts @@ -112,12 +112,8 @@ export const setupOptionsListSuggestionsRoute = ( const validationBuilder = getValidationAggregationBuilder(); const suggestionAggregation: any = suggestionBuilder.buildAggregation(request) ?? {}; - const builtValidationAggregation = validationBuilder.buildAggregation(request); - const validationAggregations = builtValidationAggregation - ? { - validation: builtValidationAggregation, - } - : {}; + const validationAggregation: any = validationBuilder.buildAggregation(request); + const body: SearchRequest['body'] = { size: 0, ...timeoutSettings, @@ -128,7 +124,7 @@ export const setupOptionsListSuggestionsRoute = ( }, aggs: { ...suggestionAggregation, - ...validationAggregations, + ...validationAggregation, }, runtime_mappings: { ...runtimeFieldMap, @@ -145,7 +141,7 @@ export const setupOptionsListSuggestionsRoute = ( */ const results = suggestionBuilder.parse(rawEsResult, request); const totalCardinality = results.totalCardinality; - const invalidSelections = validationBuilder.parse(rawEsResult); + const invalidSelections = validationBuilder.parse(rawEsResult, request); return { suggestions: results.suggestions, totalCardinality, diff --git a/src/plugins/controls/server/options_list/options_list_validation_queries.test.ts b/src/plugins/controls/server/options_list/options_list_validation_queries.test.ts index f8a7344eb88603..1d96215e167b9a 100644 --- a/src/plugins/controls/server/options_list/options_list_validation_queries.test.ts +++ b/src/plugins/controls/server/options_list/options_list_validation_queries.test.ts @@ -7,6 +7,7 @@ */ import { SearchResponse } from '@elastic/elasticsearch/lib/api/types'; +import { FieldSpec } from '@kbn/data-views-plugin/common'; import { OptionsListRequestBody } from '../../common/options_list/types'; import { getValidationAggregationBuilder } from './options_list_validation_queries'; @@ -33,7 +34,19 @@ describe('options list queries', () => { }; }); - describe('validation aggregation and parsing', () => { + describe('validation aggregation', () => { + test('returns empty aggregation when not given selections', () => { + const validationAggBuilder = getValidationAggregationBuilder(); + const optionsListRequestBodyMock: OptionsListRequestBody = { + size: 10, + fieldName: 'coolTestField', + allowExpensiveQueries: true, + }; + expect( + validationAggBuilder.buildAggregation(optionsListRequestBodyMock) + ).toMatchInlineSnapshot(`Object {}`); + }); + test('creates validation aggregation when given selections', () => { const validationAggBuilder = getValidationAggregationBuilder(); const optionsListRequestBodyMock: OptionsListRequestBody = { @@ -45,21 +58,23 @@ describe('options list queries', () => { expect(validationAggBuilder.buildAggregation(optionsListRequestBodyMock)) .toMatchInlineSnapshot(` Object { - "filters": Object { + "validation": Object { "filters": Object { - "coolOption1": Object { - "match": Object { - "coolTestField": "coolOption1", + "filters": Object { + "coolOption1": Object { + "match": Object { + "coolTestField": "coolOption1", + }, }, - }, - "coolOption2": Object { - "match": Object { - "coolTestField": "coolOption2", + "coolOption2": Object { + "match": Object { + "coolTestField": "coolOption2", + }, }, - }, - "coolOption3": Object { - "match": Object { - "coolTestField": "coolOption3", + "coolOption3": Object { + "match": Object { + "coolTestField": "coolOption3", + }, }, }, }, @@ -68,16 +83,55 @@ describe('options list queries', () => { `); }); - test('returns undefined when not given selections', () => { + test('creates validation aggregation for nested fields when given selections', () => { const validationAggBuilder = getValidationAggregationBuilder(); const optionsListRequestBodyMock: OptionsListRequestBody = { size: 10, fieldName: 'coolTestField', + fieldSpec: { + type: 'string', + subType: { nested: { path: 'path.to.nested' } }, + } as unknown as FieldSpec, allowExpensiveQueries: true, + selectedOptions: ['coolOption1', 'coolOption2', 'coolOption3'], }; - expect(validationAggBuilder.buildAggregation(optionsListRequestBodyMock)).toBeUndefined(); + expect(validationAggBuilder.buildAggregation(optionsListRequestBodyMock)) + .toMatchInlineSnapshot(` + Object { + "nestedValidation": Object { + "aggs": Object { + "validation": Object { + "filters": Object { + "filters": Object { + "coolOption1": Object { + "match": Object { + "coolTestField": "coolOption1", + }, + }, + "coolOption2": Object { + "match": Object { + "coolTestField": "coolOption2", + }, + }, + "coolOption3": Object { + "match": Object { + "coolTestField": "coolOption3", + }, + }, + }, + }, + }, + }, + "nested": Object { + "path": "path.to.nested", + }, + }, + } + `); }); + }); + describe('validation parsing', () => { test('parses validation result', () => { const validationAggBuilder = getValidationAggregationBuilder(); rawSearchResponseMock.aggregations = { @@ -92,7 +146,13 @@ describe('options list queries', () => { }, }, }; - expect(validationAggBuilder.parse(rawSearchResponseMock)).toMatchInlineSnapshot(` + expect( + validationAggBuilder.parse(rawSearchResponseMock, { + size: 10, + fieldName: 'coolTestField', + allowExpensiveQueries: true, + }) + ).toMatchInlineSnapshot(` Array [ "cool1", "cool3", @@ -100,5 +160,41 @@ describe('options list queries', () => { ] `); }); + + test('parses validation result for nested field', () => { + const validationAggBuilder = getValidationAggregationBuilder(); + rawSearchResponseMock.aggregations = { + nestedValidation: { + validation: { + buckets: { + cool1: { doc_count: 0 }, + cool2: { doc_count: 15 }, + cool3: { doc_count: 0 }, + cool4: { doc_count: 0 }, + cool5: { doc_count: 0 }, + cool6: { doc_count: 112 }, + }, + }, + }, + }; + expect( + validationAggBuilder.parse(rawSearchResponseMock, { + size: 10, + fieldSpec: { + type: 'string', + subType: { nested: { path: 'path.to.nested' } }, + } as unknown as FieldSpec, + fieldName: 'coolTestField', + allowExpensiveQueries: true, + }) + ).toMatchInlineSnapshot(` + Array [ + "cool1", + "cool3", + "cool4", + "cool5", + ] + `); + }); }); }); diff --git a/src/plugins/controls/server/options_list/options_list_validation_queries.ts b/src/plugins/controls/server/options_list/options_list_validation_queries.ts index 56e7f9efef6bf7..edacacb361d0ca 100644 --- a/src/plugins/controls/server/options_list/options_list_validation_queries.ts +++ b/src/plugins/controls/server/options_list/options_list_validation_queries.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { getFieldSubtypeNested } from '@kbn/data-views-plugin/common'; import { get, isEmpty } from 'lodash'; import { OptionsListRequestBody } from '../../common/options_list/types'; @@ -16,7 +17,7 @@ import { OptionsListValidationAggregationBuilder } from './types'; */ export const getValidationAggregationBuilder: () => OptionsListValidationAggregationBuilder = () => ({ - buildAggregation: ({ selectedOptions, fieldName }: OptionsListRequestBody) => { + buildAggregation: ({ selectedOptions, fieldName, fieldSpec }: OptionsListRequestBody) => { let selectedOptionsFilters; if (selectedOptions) { selectedOptionsFilters = selectedOptions.reduce((acc, currentOption) => { @@ -24,16 +25,43 @@ export const getValidationAggregationBuilder: () => OptionsListValidationAggrega return acc; }, {} as { [key: string]: { match: { [key: string]: string } } }); } - return selectedOptionsFilters && !isEmpty(selectedOptionsFilters) - ? { - filters: { - filters: selectedOptionsFilters, + + if (isEmpty(selectedOptionsFilters ?? [])) { + return {}; + } + + let validationAggregation: any = { + validation: { + filters: { + filters: selectedOptionsFilters, + }, + }, + }; + + const isNested = fieldSpec && getFieldSubtypeNested(fieldSpec); + if (isNested) { + validationAggregation = { + nestedValidation: { + nested: { + path: isNested.nested.path, }, - } - : undefined; + aggs: { + ...validationAggregation, + }, + }, + }; + } + + return validationAggregation; }, - parse: (rawEsResult) => { - const rawInvalidSuggestions = get(rawEsResult, 'aggregations.validation.buckets'); + parse: (rawEsResult, { fieldSpec }) => { + const isNested = fieldSpec && getFieldSubtypeNested(fieldSpec); + const rawInvalidSuggestions = get( + rawEsResult, + isNested + ? 'aggregations.nestedValidation.validation.buckets' + : 'aggregations.validation.buckets' + ); return rawInvalidSuggestions && !isEmpty(rawInvalidSuggestions) ? Object.keys(rawInvalidSuggestions).filter( (key) => rawInvalidSuggestions[key].doc_count === 0 diff --git a/src/plugins/controls/server/options_list/types.ts b/src/plugins/controls/server/options_list/types.ts index 1ea3475eddffb7..70edc14484c996 100644 --- a/src/plugins/controls/server/options_list/types.ts +++ b/src/plugins/controls/server/options_list/types.ts @@ -19,7 +19,7 @@ export interface EsBucket { export interface OptionsListValidationAggregationBuilder { buildAggregation: (req: OptionsListRequestBody) => unknown; - parse: (response: SearchResponse) => string[]; + parse: (response: SearchResponse, req: OptionsListRequestBody) => string[]; } export interface OptionsListSuggestionAggregationBuilder { From 5798255638eebf33a68d15314f149f24528a241e Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Wed, 20 Dec 2023 16:10:33 -0600 Subject: [PATCH 053/116] [Serverless Search] Index Management - Index Details Overview (#173581) ## Summary This PR implements a new Overview tab for an Index details in Index Management for Serverless. It has data panels for information about the index and optional empty states if the index has no documents. (see Screenshots) ### Screenshots Index with data ![image](https://github.com/elastic/kibana/assets/1972968/848d7f50-8332-4119-b23b-7e4569a2eaba) Index without data ![image](https://github.com/elastic/kibana/assets/1972968/a126f94f-1112-4738-abd8-5d40d96d35dc) ![image](https://github.com/elastic/kibana/assets/1972968/e5f11f2f-f5a4-421e-b212-ce65307756d4) ![image](https://github.com/elastic/kibana/assets/1972968/bd7d7970-8e4c-4245-baec-8ab9d3625dbd) Connector Index without data ![image](https://github.com/elastic/kibana/assets/1972968/dc0d97ed-110b-4566-bddd-f2c145d2eadf) ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) --- .../serverless_search/common/doc_links.ts | 2 + .../serverless_search/common/types/index.ts | 11 + .../application/components/badge_list.tsx | 31 ++ .../connectors/connectors_table.tsx | 2 +- .../connectors/empty_connectors_prompt.tsx | 12 +- .../components/connectors_router.tsx | 3 - .../components/index_documents/documents.tsx | 4 + .../index_documents/documents_tab.tsx | 13 +- .../index_management/api_empty_prompt.tsx | 166 +++++++++++ .../connector_empty_prompt.tsx | 33 +++ .../connector_setup_prompt.tsx | 100 +++++++ .../index_management/index_aliases_flyout.tsx | 75 +++++ .../index_mappings_docs_link.tsx | 0 .../index_management/index_overview.tsx | 271 ++++++++++++++++++ .../index_overview_content.tsx | 40 +++ .../overview_empty_prompt.tsx | 173 +++++++++++ .../index_management/overview_panel.tsx | 41 +++ .../components/languages/dotnet.ts | 16 ++ .../application/components/languages/java.ts | 50 ++++ .../public/application/constants.ts | 4 + .../hooks/api/use_create_connector.tsx | 10 +- .../application/hooks/api/use_index.tsx | 21 ++ .../serverless_search/public/plugin.ts | 9 +- .../server/lib/indices/fetch_index.test.ts | 142 +++++++++ .../server/lib/indices/fetch_index.ts | 45 +++ .../server/routes/indices_routes.ts | 22 ++ 26 files changed, 1278 insertions(+), 18 deletions(-) create mode 100644 x-pack/plugins/serverless_search/public/application/components/badge_list.tsx create mode 100644 x-pack/plugins/serverless_search/public/application/components/index_management/api_empty_prompt.tsx create mode 100644 x-pack/plugins/serverless_search/public/application/components/index_management/connector_empty_prompt.tsx create mode 100644 x-pack/plugins/serverless_search/public/application/components/index_management/connector_setup_prompt.tsx create mode 100644 x-pack/plugins/serverless_search/public/application/components/index_management/index_aliases_flyout.tsx rename x-pack/plugins/serverless_search/public/application/components/{ => index_management}/index_mappings_docs_link.tsx (100%) create mode 100644 x-pack/plugins/serverless_search/public/application/components/index_management/index_overview.tsx create mode 100644 x-pack/plugins/serverless_search/public/application/components/index_management/index_overview_content.tsx create mode 100644 x-pack/plugins/serverless_search/public/application/components/index_management/overview_empty_prompt.tsx create mode 100644 x-pack/plugins/serverless_search/public/application/components/index_management/overview_panel.tsx create mode 100644 x-pack/plugins/serverless_search/public/application/hooks/api/use_index.tsx create mode 100644 x-pack/plugins/serverless_search/server/lib/indices/fetch_index.test.ts create mode 100644 x-pack/plugins/serverless_search/server/lib/indices/fetch_index.ts diff --git a/x-pack/plugins/serverless_search/common/doc_links.ts b/x-pack/plugins/serverless_search/common/doc_links.ts index c3cfecd7dfc66f..7168f089c41e17 100644 --- a/x-pack/plugins/serverless_search/common/doc_links.ts +++ b/x-pack/plugins/serverless_search/common/doc_links.ts @@ -19,6 +19,7 @@ class ESDocLinks { public roleDescriptors: string = ''; public securityApis: string = ''; public ingestionPipelines: string = ''; + public dataStreams: string = ''; // Client links public elasticsearchClients: string = ''; // go @@ -61,6 +62,7 @@ class ESDocLinks { this.roleDescriptors = newDocLinks.serverlessSecurity.apiKeyPrivileges; this.securityApis = newDocLinks.apis.securityApis; this.ingestionPipelines = newDocLinks.ingest.pipelines; + this.dataStreams = newDocLinks.elasticsearch.dataStreams; // Client links this.elasticsearchClients = newDocLinks.serverlessClients.clientLib; diff --git a/x-pack/plugins/serverless_search/common/types/index.ts b/x-pack/plugins/serverless_search/common/types/index.ts index c4dac1508374e0..6b43747b19afd9 100644 --- a/x-pack/plugins/serverless_search/common/types/index.ts +++ b/x-pack/plugins/serverless_search/common/types/index.ts @@ -5,6 +5,9 @@ * 2.0. */ +import { IndicesIndexState, IndicesStatsIndicesStats } from '@elastic/elasticsearch/lib/api/types'; +import { Connector } from '@kbn/search-connectors/types/connectors'; + export interface CreateAPIKeyArgs { expiration?: string; metadata?: Record; @@ -20,3 +23,11 @@ export interface IndexData { export interface FetchIndicesResult { indices: IndexData[]; } + +export interface FetchIndexResult { + index: IndicesIndexState & { + connector?: Connector; + count: number; + stats?: IndicesStatsIndicesStats; + }; +} diff --git a/x-pack/plugins/serverless_search/public/application/components/badge_list.tsx b/x-pack/plugins/serverless_search/public/application/components/badge_list.tsx new file mode 100644 index 00000000000000..9635515bdf419c --- /dev/null +++ b/x-pack/plugins/serverless_search/public/application/components/badge_list.tsx @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiBadgeGroup, EuiBadge } from '@elastic/eui'; + +export interface BadgeListProps { + badges: React.ReactNode[]; + maxBadgesToDisplay?: number; +} + +export const BadgeList = ({ badges, maxBadgesToDisplay }: BadgeListProps) => { + const maxBadges = maxBadgesToDisplay ?? 3; + if (badges.length === 0) { + return <>; + } + + const badgesToDisplay = badges.slice(0, maxBadges); + return ( + + {badgesToDisplay.map((badge) => badge)} + {badges.length > maxBadges && ( + +{badges.length - maxBadges} + )} + + ); +}; diff --git a/x-pack/plugins/serverless_search/public/application/components/connectors/connectors_table.tsx b/x-pack/plugins/serverless_search/public/application/components/connectors/connectors_table.tsx index 53d99b37c99a1f..4850bdf8b86e3a 100644 --- a/x-pack/plugins/serverless_search/public/application/components/connectors/connectors_table.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/connectors/connectors_table.tsx @@ -45,7 +45,7 @@ import { import { useConnectors } from '../../hooks/api/use_connectors'; import { useConnectorTypes } from '../../hooks/api/use_connector_types'; import { useKibanaServices } from '../../hooks/use_kibana'; -import { EDIT_CONNECTOR_PATH } from '../connectors_router'; +import { EDIT_CONNECTOR_PATH } from '../../constants'; import { DeleteConnectorModal } from './delete_connector_modal'; export const ConnectorsTable: React.FC = () => { diff --git a/x-pack/plugins/serverless_search/public/application/components/connectors/empty_connectors_prompt.tsx b/x-pack/plugins/serverless_search/public/application/components/connectors/empty_connectors_prompt.tsx index abb0ad64242d74..218c956c78770f 100644 --- a/x-pack/plugins/serverless_search/public/application/components/connectors/empty_connectors_prompt.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/connectors/empty_connectors_prompt.tsx @@ -19,14 +19,16 @@ import { import { i18n } from '@kbn/i18n'; import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; -import { PLUGIN_ID } from '../../../../common'; + import { useConnectorTypes } from '../../hooks/api/use_connector_types'; -import { useKibanaServices } from '../../hooks/use_kibana'; +import { useCreateConnector } from '../../hooks/api/use_create_connector'; +import { useAssetBasePath } from '../../hooks/use_asset_base_path'; export const EmptyConnectorsPrompt: React.FC = () => { - const { http } = useKibanaServices(); const { data: connectorTypes } = useConnectorTypes(); - const assetBasePath = http.basePath.prepend(`/plugins/${PLUGIN_ID}/assets`); + const { createConnector, isLoading } = useCreateConnector(); + + const assetBasePath = useAssetBasePath(); const connectorsPath = assetBasePath + '/connectors.svg'; return ( @@ -167,6 +169,8 @@ export const EmptyConnectorsPrompt: React.FC = () => { data-test-subj="serverlessSearchEmptyConnectorsPromptCreateConnectorButton" fill iconType="plusInCircleFilled" + onClick={() => createConnector()} + isLoading={isLoading} > {i18n.translate('xpack.serverlessSearch.connectorsEmpty.createConnector', { defaultMessage: 'Create connector', diff --git a/x-pack/plugins/serverless_search/public/application/components/connectors_router.tsx b/x-pack/plugins/serverless_search/public/application/components/connectors_router.tsx index ab1ce4e2902bf0..f8c224ed2c9c61 100644 --- a/x-pack/plugins/serverless_search/public/application/components/connectors_router.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/connectors_router.tsx @@ -10,9 +10,6 @@ import React from 'react'; import { EditConnector } from './connectors/edit_connector'; import { ConnectorsOverview } from './connectors_overview'; -export const BASE_CONNECTORS_PATH = 'connectors'; -export const EDIT_CONNECTOR_PATH = `${BASE_CONNECTORS_PATH}/:id`; - export const ConnectorsRouter: React.FC = () => { return ( diff --git a/x-pack/plugins/serverless_search/public/application/components/index_documents/documents.tsx b/x-pack/plugins/serverless_search/public/application/components/index_documents/documents.tsx index 8d719485973e40..d74c3a479a68a3 100644 --- a/x-pack/plugins/serverless_search/public/application/components/index_documents/documents.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/index_documents/documents.tsx @@ -74,3 +74,7 @@ export const IndexDocuments: React.FC = ({ indexName }) => /> ); }; + +// Default Export is needed to lazy load this react component +// eslint-disable-next-line import/no-default-export +export default IndexDocuments; diff --git a/x-pack/plugins/serverless_search/public/application/components/index_documents/documents_tab.tsx b/x-pack/plugins/serverless_search/public/application/components/index_documents/documents_tab.tsx index c71089b5f3b83c..ff4f2165f534c4 100644 --- a/x-pack/plugins/serverless_search/public/application/components/index_documents/documents_tab.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/index_documents/documents_tab.tsx @@ -6,16 +6,19 @@ */ import { IndexDetailsTab } from '@kbn/index-management-plugin/common/constants'; -import React from 'react'; +import React, { Suspense, lazy } from 'react'; +import { EuiLoadingSpinner } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { CoreStart } from '@kbn/core-lifecycle-browser'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; + import { ServerlessSearchPluginStartDependencies } from '../../../types'; -import { IndexDocuments } from './documents'; -export const createIndexOverviewContent = ( +const IndexDocuments = lazy(() => import('./documents')); + +export const createIndexDocumentsContent = ( core: CoreStart, services: ServerlessSearchPluginStartDependencies ): IndexDetailsTab => { @@ -34,7 +37,9 @@ export const createIndexOverviewContent = ( - + }> + + ); diff --git a/x-pack/plugins/serverless_search/public/application/components/index_management/api_empty_prompt.tsx b/x-pack/plugins/serverless_search/public/application/components/index_management/api_empty_prompt.tsx new file mode 100644 index 00000000000000..4881c8d73f40f1 --- /dev/null +++ b/x-pack/plugins/serverless_search/public/application/components/index_management/api_empty_prompt.tsx @@ -0,0 +1,166 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useMemo, useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiEmptyPrompt, + EuiFlexItem, + EuiFlexGroup, + EuiIcon, + EuiText, + EuiButtonEmpty, + EuiLink, + EuiPanel, + EuiTitle, + EuiSpacer, + EuiSteps, +} from '@elastic/eui'; +import { EuiContainedStepProps } from '@elastic/eui/src/components/steps/steps'; +import { + CodeBox, + getConsoleRequest, + getLanguageDefinitionCodeSnippet, + LanguageDefinition, + LanguageDefinitionSnippetArguments, +} from '@kbn/search-api-panels'; + +import { BACK_LABEL } from '../../../../common/i18n_string'; + +import { useAssetBasePath } from '../../hooks/use_asset_base_path'; +import { useKibanaServices } from '../../hooks/use_kibana'; +import { javaDefinition } from '../languages/java'; +import { languageDefinitions } from '../languages/languages'; +import { LanguageGrid } from '../languages/language_grid'; +import { + API_KEY_PLACEHOLDER, + CLOUD_ID_PLACEHOLDER, + ELASTICSEARCH_URL_PLACEHOLDER, +} from '../../constants'; + +import { ApiKeyPanel } from '../api_key/api_key'; + +export interface APIIndexEmptyPromptProps { + indexName: string; + onBackClick?: () => void; +} + +export const APIIndexEmptyPrompt = ({ indexName, onBackClick }: APIIndexEmptyPromptProps) => { + const { application, cloud, share } = useKibanaServices(); + const assetBasePath = useAssetBasePath(); + const [selectedLanguage, setSelectedLanguage] = + React.useState(javaDefinition); + const [clientApiKey, setClientApiKey] = useState(API_KEY_PLACEHOLDER); + const { elasticsearchURL, cloudId } = useMemo(() => { + return { + elasticsearchURL: cloud?.elasticsearchUrl ?? ELASTICSEARCH_URL_PLACEHOLDER, + cloudId: cloud?.cloudId ?? CLOUD_ID_PLACEHOLDER, + }; + }, [cloud]); + const codeSnippetArguments: LanguageDefinitionSnippetArguments = { + url: elasticsearchURL, + apiKey: clientApiKey, + cloudId, + indexName, + }; + + const apiIngestSteps: EuiContainedStepProps[] = [ + { + title: i18n.translate( + 'xpack.serverlessSearch.indexManagement.indexDetails.overview.emptyPrompt.api.ingest.title', + { defaultMessage: 'Ingest data via API using a programming language client' } + ), + children: ( + + + + + + + + + ), + }, + { + title: i18n.translate( + 'xpack.serverlessSearch.indexManagement.indexDetails.overview.emptyPrompt.api.apiKey.title', + { defaultMessage: 'Prepare an API key' } + ), + children: , + }, + ]; + + return ( + + + {BACK_LABEL} + + } + title={ + +

+ +
+ + } + body={ + +

+ application.navigateToApp('elasticsearch')} + > + {i18n.translate( + 'xpack.serverlessSearch.indexManagement.indexDetails.overview.emptyPrompt.api.body.getStartedLink', + { defaultMessage: 'Get started' } + )} + + ), + }} + /> +

+
+ } + /> + + + + ); +}; diff --git a/x-pack/plugins/serverless_search/public/application/components/index_management/connector_empty_prompt.tsx b/x-pack/plugins/serverless_search/public/application/components/index_management/connector_empty_prompt.tsx new file mode 100644 index 00000000000000..487c80ce48b6f2 --- /dev/null +++ b/x-pack/plugins/serverless_search/public/application/components/index_management/connector_empty_prompt.tsx @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiButtonEmpty, EuiPanel } from '@elastic/eui'; + +import { BACK_LABEL } from '../../../../common/i18n_string'; +import { EmptyConnectorsPrompt } from '../connectors/empty_connectors_prompt'; + +interface ConnectorIndexEmptyPromptProps { + indexName: string; + onBackClick?: () => void; +} + +export const ConnectorIndexEmptyPrompt = ({ onBackClick }: ConnectorIndexEmptyPromptProps) => { + return ( + + + {BACK_LABEL} + + + + ); +}; diff --git a/x-pack/plugins/serverless_search/public/application/components/index_management/connector_setup_prompt.tsx b/x-pack/plugins/serverless_search/public/application/components/index_management/connector_setup_prompt.tsx new file mode 100644 index 00000000000000..888a5f11385a54 --- /dev/null +++ b/x-pack/plugins/serverless_search/public/application/components/index_management/connector_setup_prompt.tsx @@ -0,0 +1,100 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { + EuiEmptyPrompt, + EuiIcon, + EuiFlexItem, + EuiFlexGroup, + EuiButton, + EuiPanel, + EuiTitle, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { Connector } from '@kbn/search-connectors'; + +import { useKibanaServices } from '../../hooks/use_kibana'; +import { useAssetBasePath } from '../../hooks/use_asset_base_path'; +import { useConnectorTypes } from '../../hooks/api/use_connector_types'; + +interface ConnectorSetupEmptyPromptProps { + indexName: string; + connector: Connector; +} + +export const ConnectorSetupEmptyPrompt = ({ connector }: ConnectorSetupEmptyPromptProps) => { + const { http } = useKibanaServices(); + const assetBasePath = useAssetBasePath(); + const { data: connectorTypes } = useConnectorTypes(); + + const connectorsIconPath = assetBasePath + '/connectors.svg'; + const connectorPath = http.basePath.prepend(`/app/connectors/${connector.id}`); + const connectorType = connectorTypes?.connectors?.find( + (cType) => cType.serviceType === connector.service_type + ); + return ( + + } + title={ + +
+ +
+
+ } + body={ + <> +

+ +

+ {!!connectorType && ( + <> + + + + + {connectorType.name} + + + )} + + } + actions={ + + + + } + /> +
+ ); +}; diff --git a/x-pack/plugins/serverless_search/public/application/components/index_management/index_aliases_flyout.tsx b/x-pack/plugins/serverless_search/public/application/components/index_management/index_aliases_flyout.tsx new file mode 100644 index 00000000000000..5f87fd2ab0b81b --- /dev/null +++ b/x-pack/plugins/serverless_search/public/application/components/index_management/index_aliases_flyout.tsx @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { + EuiBasicTable, + EuiBasicTableColumn, + EuiButton, + EuiFlexGroup, + EuiFlexItem, + EuiFlyout, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlyoutHeader, + EuiTitle, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; + +export interface IndexAliasesFlyoutProps { + aliases: string[]; + indexName: string; + onClose: () => void; +} + +export const IndexAliasesFlyout = ({ indexName, aliases, onClose }: IndexAliasesFlyoutProps) => { + const aliasItems = aliases.map((alias) => ({ name: alias })); + const columns: Array> = [ + { + field: 'name', + name: i18n.translate( + 'xpack.serverlessSearch.indexManagement.indexDetails.overview.aliasesFlyout.table.nameColumn.header', + { defaultMessage: 'Alias Name' } + ), + 'data-test-subj': 'aliasNameCell', + truncateText: false, + width: '100%', + }, + ]; + return ( + + + +

+ +

+
+
+ + + + + + + + + + + + +
+ ); +}; diff --git a/x-pack/plugins/serverless_search/public/application/components/index_mappings_docs_link.tsx b/x-pack/plugins/serverless_search/public/application/components/index_management/index_mappings_docs_link.tsx similarity index 100% rename from x-pack/plugins/serverless_search/public/application/components/index_mappings_docs_link.tsx rename to x-pack/plugins/serverless_search/public/application/components/index_management/index_mappings_docs_link.tsx diff --git a/x-pack/plugins/serverless_search/public/application/components/index_management/index_overview.tsx b/x-pack/plugins/serverless_search/public/application/components/index_management/index_overview.tsx new file mode 100644 index 00000000000000..f1db8d49e038a0 --- /dev/null +++ b/x-pack/plugins/serverless_search/public/application/components/index_management/index_overview.tsx @@ -0,0 +1,271 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FunctionComponent } from 'react'; +import numeral from '@elastic/numeral'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage, FormattedPlural } from '@kbn/i18n-react'; +import { + EuiLoadingSpinner, + EuiEmptyPrompt, + EuiFlexGrid, + EuiFlexItem, + EuiFlexGroup, + EuiIcon, + EuiI18nNumber, + EuiText, + EuiBadge, + EuiButton, + EuiLink, + EuiSpacer, +} from '@elastic/eui'; + +import { Index } from '@kbn/index-management-plugin/common/types/indices'; + +import { docLinks } from '../../../../common/doc_links'; +import { useIndex } from '../../hooks/api/use_index'; + +import { BadgeList } from '../badge_list'; +import { OverviewEmptyPrompt } from './overview_empty_prompt'; +import { IndexOverviewPanel, IndexOverviewPanelStat } from './overview_panel'; +import { IndexAliasesFlyout } from './index_aliases_flyout'; + +export interface IndexDetailOverviewProps { + index: Index; +} + +export const IndexDetailOverview: FunctionComponent = ({ index }) => { + const [aliasesFlyoutOpen, setAliasesFlyoutOpen] = React.useState(false); + const { data, isLoading, isError } = useIndex(index.name); + const indexAliases = + typeof index.aliases === 'string' + ? index.aliases.length > 0 && index.aliases !== 'none' + ? [index.aliases] + : [] + : index.aliases; + + if (isLoading || !data) + return ( + } + title={ +

+ +

+ } + /> + ); + if (isError) { + return ( + + +

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 i}u9xV$CAk^8 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

+ } + body={ +

+ +

+ } + /> + ); + } + + const indexData = data.index; + return ( + <> + {aliasesFlyoutOpen && ( + setAliasesFlyoutOpen(false)} + /> + )} + + + + } + footer={ + + + + } + > + {index.data_stream ?? '--'} + + + + + } + footer={ + 0 + ? indexAliases.map((alias) => {alias}) + : [ + + + , + ] + } + /> + } + > + + + + + + + + +

+ +

+
+
+ + setAliasesFlyoutOpen(true)} + > + + + +
+
+
+ {indexData.count > 0 && ( + + + } + footer={ + + + + + + + , + deletedCount: ( + + ), + }} + /> + + + + } + > + + + + {numeral( + indexData.stats?.primaries?.store?.total_data_set_size_in_bytes ?? 0 + ).format('0 b')} + + + + +

+ +

+
+
+ + + {numeral( + indexData.stats?.total?.store?.total_data_set_size_in_bytes ?? 0 + ).format('0 b')} + + + + +

+ +

+
+
+
+
+
+ )} +
+ {indexData.count === 0 && ( + <> + + + + )} + + ); +}; + +// Default Export is needed to lazy load this react component +// eslint-disable-next-line import/no-default-export +export default IndexDetailOverview; diff --git a/x-pack/plugins/serverless_search/public/application/components/index_management/index_overview_content.tsx b/x-pack/plugins/serverless_search/public/application/components/index_management/index_overview_content.tsx new file mode 100644 index 00000000000000..373dce25575718 --- /dev/null +++ b/x-pack/plugins/serverless_search/public/application/components/index_management/index_overview_content.tsx @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { Suspense, lazy } from 'react'; +import { CoreStart } from '@kbn/core/public'; +import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; +import { EuiLoadingSpinner } from '@elastic/eui'; + +import { IndexContent } from '@kbn/index-management-plugin/public/services'; + +import { ServerlessSearchPluginStartDependencies } from '../../../types'; + +const IndexDetailOverview = lazy(() => import('./index_overview')); + +export const createIndexOverviewContent = ( + core: CoreStart, + services: ServerlessSearchPluginStartDependencies +): IndexContent => { + return { + renderContent: (index) => { + const queryClient = new QueryClient(); + return ( + + + + }> + + + + + ); + }, + }; +}; diff --git a/x-pack/plugins/serverless_search/public/application/components/index_management/overview_empty_prompt.tsx b/x-pack/plugins/serverless_search/public/application/components/index_management/overview_empty_prompt.tsx new file mode 100644 index 00000000000000..b790021483e07f --- /dev/null +++ b/x-pack/plugins/serverless_search/public/application/components/index_management/overview_empty_prompt.tsx @@ -0,0 +1,173 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiEmptyPrompt, + EuiFlexItem, + EuiFlexGroup, + EuiText, + EuiButton, + EuiLink, + EuiPanel, + EuiTitle, +} from '@elastic/eui'; +import { Connector } from '@kbn/search-connectors'; + +import { docLinks } from '../../../../common/doc_links'; + +import { APIIndexEmptyPrompt } from './api_empty_prompt'; +import { ConnectorIndexEmptyPrompt } from './connector_empty_prompt'; +import { ConnectorSetupEmptyPrompt } from './connector_setup_prompt'; + +enum EmptyPromptView { + Default, + NewConnector, + API, + SetupConnector, +} + +export interface OverviewEmptyPromptProps { + indexName: string; + connector?: Connector; +} + +export const OverviewEmptyPrompt = ({ connector, indexName }: OverviewEmptyPromptProps) => { + const isConnectorIndex = !!connector; + const [currentView, setView] = React.useState( + isConnectorIndex ? EmptyPromptView.SetupConnector : EmptyPromptView.Default + ); + if (currentView === EmptyPromptView.SetupConnector) { + return ; + } + if (currentView === EmptyPromptView.NewConnector) { + return ( + setView(EmptyPromptView.Default)} + /> + ); + } + if (currentView === EmptyPromptView.API) { + return ( + setView(EmptyPromptView.Default)} + /> + ); + } + + return ( + + +
+ +
+
+ } + body={ + +

+ + {i18n.translate( + 'xpack.serverlessSearch.indexManagement.indexDetails.overview.emptyPrompt.body.logstashLink', + { defaultMessage: 'Logstash' } + )} + + ), + beatsLink: ( + + {i18n.translate( + 'xpack.serverlessSearch.indexManagement.indexDetails.overview.emptyPrompt.body.beatsLink', + { defaultMessage: 'Beats' } + )} + + ), + connectorsLink: ( + + {i18n.translate( + 'xpack.serverlessSearch.indexManagement.indexDetails.overview.emptyPrompt.body.connectorsLink', + { defaultMessage: 'connectors' } + )} + + ), + apiCallsLink: ( + + {i18n.translate( + 'xpack.serverlessSearch.indexManagement.indexDetails.overview.emptyPrompt.body.apiCallsLink', + { defaultMessage: 'API calls' } + )} + + ), + }} + /> +

+
+ } + actions={ + + + setView(EmptyPromptView.API)} + > + + + + + setView(EmptyPromptView.NewConnector)} + > + + + + + } + /> + + ); +}; diff --git a/x-pack/plugins/serverless_search/public/application/components/index_management/overview_panel.tsx b/x-pack/plugins/serverless_search/public/application/components/index_management/overview_panel.tsx new file mode 100644 index 00000000000000..8b2b54e17d68e0 --- /dev/null +++ b/x-pack/plugins/serverless_search/public/application/components/index_management/overview_panel.tsx @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiSpacer, EuiSplitPanel, EuiTitle } from '@elastic/eui'; + +export interface IndexOverviewPanelProps { + title: React.ReactNode; + footer?: React.ReactNode | React.ReactNode[]; +} + +export const IndexOverviewPanel: React.FC = ({ + title, + footer, + children, +}) => ( + + + +
{title}
+
+ + {children} +
+ {footer && ( + + {footer} + + )} +
+); + +export const IndexOverviewPanelStat: React.FC = ({ children }) => ( + +

{children}

+
+); diff --git a/x-pack/plugins/serverless_search/public/application/components/languages/dotnet.ts b/x-pack/plugins/serverless_search/public/application/components/languages/dotnet.ts index 4f388d2227203d..1ac3641f67fe94 100644 --- a/x-pack/plugins/serverless_search/public/application/components/languages/dotnet.ts +++ b/x-pack/plugins/serverless_search/public/application/components/languages/dotnet.ts @@ -37,6 +37,22 @@ var client = new ElasticsearchClient("${cloudId}", new ApiKey("${apiKey}"));`, }; var response = await client.IndexAsync(doc, "books");`, + ingestDataIndex: ({ apiKey, cloudId, indexName }) => `using System; +using Elastic.Clients.Elasticsearch.Serverless; +using Elastic.Clients.Elasticsearch.Serverless.QueryDsl; + +var client = new ElasticsearchClient("${cloudId}", new ApiKey("${apiKey}")); + +var doc = new Book +{ + Id = "9780553351927", + Name = "Snow Crash", + Author = "Neal Stephenson", + ReleaseDate = new DateTime(1992, 06, 01), + PageCount = 470 +}; + +var response = await client.IndexAsync(doc, "${indexName}");`, buildSearchQuery: `var response = await client.SearchAsync(s => s .Index("books") .From(0) diff --git a/x-pack/plugins/serverless_search/public/application/components/languages/java.ts b/x-pack/plugins/serverless_search/public/application/components/languages/java.ts index 23566fcc67f98b..c247eb978c15ba 100644 --- a/x-pack/plugins/serverless_search/public/application/components/languages/java.ts +++ b/x-pack/plugins/serverless_search/public/application/components/languages/java.ts @@ -66,6 +66,56 @@ for (Book book : books) { BulkResponse result = esClient.bulk(br.build()); +// Log errors, if any +if (result.errors()) { + logger.error("Bulk had errors"); + for (BulkResponseItem item: result.items()) { + if (item.error() != null) { + logger.error(item.error().reason()); + } + } +}`, + ingestDataIndex: ({ apiKey, indexName, url }) => `// URL and API key +String serverUrl = "${url}"; +String apiKey = "${apiKey}"; + +// Create the low-level client +RestClient restClient = RestClient + .builder(HttpHost.create(serverUrl)) + .setDefaultHeaders(new Header[]{ + new BasicHeader("Authorization", "ApiKey " + apiKey) + }) + .build(); + +// Create the transport with a Jackson mapper +ElasticsearchTransport transport = new RestClientTransport( + restClient, new JacksonJsonpMapper()); + +// And create the API client +ElasticsearchClient esClient = new ElasticsearchClient(transport); + +List books = new ArrayList<>(); +books.add(new Book("9780553351927", "Snow Crash", "Neal Stephenson", "1992-06-01", 470)); +books.add(new Book("9780441017225", "Revelation Space", "Alastair Reynolds", "2000-03-15", 585)); +books.add(new Book("9780451524935", "1984", "George Orwell", "1985-06-01", 328)); +books.add(new Book("9781451673319", "Fahrenheit 451", "Ray Bradbury", "1953-10-15", 227)); +books.add(new Book("9780060850524", "Brave New World", "Aldous Huxley", "1932-06-01", 268)); +books.add(new Book("9780385490818", "The Handmaid's Tale", "Margaret Atwood", "1985-06-01", 311)); + +BulkRequest.Builder br = new BulkRequest.Builder(); + +for (Book book : books) { + br.operations(op -> op + .index(idx -> idx + .index("${indexName}") + .id(product.getId()) + .document(book) + ) + ); +} + +BulkResponse result = esClient.bulk(br.build()); + // Log errors, if any if (result.errors()) { logger.error("Bulk had errors"); diff --git a/x-pack/plugins/serverless_search/public/application/constants.ts b/x-pack/plugins/serverless_search/public/application/constants.ts index 6c2f9775c4e047..df8d2fb1ebbc76 100644 --- a/x-pack/plugins/serverless_search/public/application/constants.ts +++ b/x-pack/plugins/serverless_search/public/application/constants.ts @@ -9,3 +9,7 @@ export const API_KEY_PLACEHOLDER = 'your_api_key'; export const ELASTICSEARCH_URL_PLACEHOLDER = 'https://your_deployment_url'; export const CLOUD_ID_PLACEHOLDER = ''; export const INDEX_NAME_PLACEHOLDER = 'index_name'; + +// Paths +export const BASE_CONNECTORS_PATH = 'connectors'; +export const EDIT_CONNECTOR_PATH = `${BASE_CONNECTORS_PATH}/:id`; diff --git a/x-pack/plugins/serverless_search/public/application/hooks/api/use_create_connector.tsx b/x-pack/plugins/serverless_search/public/application/hooks/api/use_create_connector.tsx index fc9c74b94b84b2..fc70e0044529ff 100644 --- a/x-pack/plugins/serverless_search/public/application/hooks/api/use_create_connector.tsx +++ b/x-pack/plugins/serverless_search/public/application/hooks/api/use_create_connector.tsx @@ -8,7 +8,7 @@ import { useEffect } from 'react'; import { generatePath } from 'react-router-dom'; import { useMutation } from '@tanstack/react-query'; import { Connector } from '@kbn/search-connectors'; -import { EDIT_CONNECTOR_PATH } from '../../components/connectors_router'; +import { EDIT_CONNECTOR_PATH } from '../../constants'; import { useKibanaServices } from '../use_kibana'; export const useCreateConnector = () => { @@ -32,9 +32,13 @@ export const useCreateConnector = () => { useEffect(() => { if (isSuccess) { - navigateToUrl(generatePath(EDIT_CONNECTOR_PATH, { id: connector?.id || '' })); + navigateToUrl( + http.basePath.prepend( + `/app/${generatePath(EDIT_CONNECTOR_PATH, { id: connector?.id || '' })}` + ) + ); } - }, [connector, isSuccess, navigateToUrl]); + }, [connector, isSuccess, navigateToUrl, http.basePath]); const createConnector = () => mutate(); return { createConnector, isLoading }; diff --git a/x-pack/plugins/serverless_search/public/application/hooks/api/use_index.tsx b/x-pack/plugins/serverless_search/public/application/hooks/api/use_index.tsx new file mode 100644 index 00000000000000..3ea8ea1588ba5e --- /dev/null +++ b/x-pack/plugins/serverless_search/public/application/hooks/api/use_index.tsx @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useQuery } from '@tanstack/react-query'; + +import { FetchIndexResult } from '../../../../common/types'; +import { useKibanaServices } from '../use_kibana'; + +export const useIndex = (id: string) => { + const { http } = useKibanaServices(); + const queryKey = ['fetchIndex', id]; + const result = useQuery({ + queryKey, + queryFn: () => http.fetch(`/internal/serverless_search/index/${id}`), + }); + return { queryKey, ...result }; +}; diff --git a/x-pack/plugins/serverless_search/public/plugin.ts b/x-pack/plugins/serverless_search/public/plugin.ts index f82af8390c9fc9..6c6328931915eb 100644 --- a/x-pack/plugins/serverless_search/public/plugin.ts +++ b/x-pack/plugins/serverless_search/public/plugin.ts @@ -15,7 +15,8 @@ import { import { i18n } from '@kbn/i18n'; import { appIds } from '@kbn/management-cards-navigation'; import { AuthenticatedUser } from '@kbn/security-plugin/common'; -import { createIndexMappingsDocsLinkContent as createIndexMappingsContent } from './application/components/index_mappings_docs_link'; +import { createIndexMappingsDocsLinkContent as createIndexMappingsContent } from './application/components/index_management/index_mappings_docs_link'; +import { createIndexOverviewContent } from './application/components/index_management/index_overview_content'; import { createServerlessSearchSideNavComponent as createComponent } from './layout/nav'; import { docLinks } from '../common/doc_links'; import { @@ -24,7 +25,7 @@ import { ServerlessSearchPluginStart, ServerlessSearchPluginStartDependencies, } from './types'; -import { createIndexOverviewContent } from './application/components/index_documents/documents_tab'; +import { createIndexDocumentsContent } from './application/components/index_documents/documents_tab'; export class ServerlessSearchPlugin implements @@ -98,9 +99,11 @@ export class ServerlessSearchPlugin }); indexManagement?.extensionsService.setIndexMappingsContent(createIndexMappingsContent(core)); indexManagement?.extensionsService.addIndexDetailsTab( + createIndexDocumentsContent(core, services) + ); + indexManagement?.extensionsService.setIndexOverviewContent( createIndexOverviewContent(core, services) ); - return {}; } diff --git a/x-pack/plugins/serverless_search/server/lib/indices/fetch_index.test.ts b/x-pack/plugins/serverless_search/server/lib/indices/fetch_index.test.ts new file mode 100644 index 00000000000000..88edecd4cfd9d3 --- /dev/null +++ b/x-pack/plugins/serverless_search/server/lib/indices/fetch_index.test.ts @@ -0,0 +1,142 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +jest.mock('@kbn/search-connectors', () => ({ + fetchConnectorByIndexName: jest.fn(), +})); + +import { ByteSizeValue } from '@kbn/config-schema'; +import { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; +import { fetchConnectorByIndexName } from '@kbn/search-connectors'; + +import { fetchIndex } from './fetch_index'; + +describe('fetch index lib function', () => { + const mockClient = { + indices: { + get: jest.fn(), + stats: jest.fn(), + }, + count: jest.fn(), + }; + const client = () => mockClient as unknown as ElasticsearchClient; + + const indexName = 'search-regular-index'; + const regularIndexResponse = { + 'search-regular-index': { + aliases: {}, + }, + }; + const regularIndexStatsResponse = { + indices: { + 'search-regular-index': { + health: 'green', + size: new ByteSizeValue(108000).toString(), + status: 'open', + total: { + docs: { + count: 100, + deleted: 0, + }, + store: { + size_in_bytes: 108000, + }, + }, + uuid: '83a81e7e-5955-4255-b008-5d6961203f57', + }, + }, + }; + const indexCountResponse = { + count: 100, + }; + const indexConnector = { + foo: 'foo', + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should return index if all client calls succeed', () => { + mockClient.indices.get.mockResolvedValue({ ...regularIndexResponse }); + mockClient.indices.stats.mockResolvedValue(regularIndexStatsResponse); + mockClient.count.mockResolvedValue(indexCountResponse); + (fetchConnectorByIndexName as unknown as jest.Mock).mockResolvedValue(indexConnector); + + expect(fetchIndex(client(), indexName)).resolves.toMatchObject({ + index: { + aliases: {}, + count: 100, + connector: indexConnector, + stats: regularIndexStatsResponse.indices[indexName], + }, + }); + }); + + it('should throw an error if get index rejects', () => { + const expectedError = new Error('Boom!'); + + mockClient.indices.get.mockRejectedValue(expectedError); + mockClient.indices.stats.mockResolvedValue(regularIndexStatsResponse); + mockClient.count.mockResolvedValue(indexCountResponse); + (fetchConnectorByIndexName as unknown as jest.Mock).mockResolvedValue(indexConnector); + + expect(fetchIndex(client(), indexName)).rejects.toEqual(expectedError); + }); + + it('should return partial data if index stats rejects', () => { + const expectedError = new Error('Boom!'); + + mockClient.indices.get.mockResolvedValue({ ...regularIndexResponse }); + mockClient.indices.stats.mockRejectedValue(expectedError); + mockClient.count.mockResolvedValue(indexCountResponse); + (fetchConnectorByIndexName as unknown as jest.Mock).mockResolvedValue(indexConnector); + + expect(fetchIndex(client(), indexName)).resolves.toMatchObject({ + index: { + aliases: {}, + count: 100, + connector: indexConnector, + }, + }); + }); + + it('should return partial data if index count rejects', () => { + const expectedError = new Error('Boom!'); + + mockClient.indices.get.mockResolvedValue({ ...regularIndexResponse }); + mockClient.indices.stats.mockResolvedValue(regularIndexStatsResponse); + mockClient.count.mockRejectedValue(expectedError); + (fetchConnectorByIndexName as unknown as jest.Mock).mockResolvedValue(indexConnector); + + expect(fetchIndex(client(), indexName)).resolves.toMatchObject({ + index: { + aliases: {}, + count: 0, + connector: indexConnector, + stats: regularIndexStatsResponse.indices[indexName], + }, + }); + }); + + it('should return partial data if fetch connector rejects', () => { + const expectedError = new Error('Boom!'); + + mockClient.indices.get.mockResolvedValue({ ...regularIndexResponse }); + mockClient.indices.stats.mockResolvedValue(regularIndexStatsResponse); + mockClient.count.mockResolvedValue(indexCountResponse); + (fetchConnectorByIndexName as unknown as jest.Mock).mockRejectedValue(expectedError); + + expect(fetchIndex(client(), indexName)).resolves.toMatchObject({ + index: { + aliases: {}, + count: 100, + stats: regularIndexStatsResponse.indices[indexName], + }, + }); + }); +}); diff --git a/x-pack/plugins/serverless_search/server/lib/indices/fetch_index.ts b/x-pack/plugins/serverless_search/server/lib/indices/fetch_index.ts new file mode 100644 index 00000000000000..000eb1c13ea0a3 --- /dev/null +++ b/x-pack/plugins/serverless_search/server/lib/indices/fetch_index.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; +import { fetchConnectorByIndexName } from '@kbn/search-connectors'; + +import { FetchIndexResult } from '../../../common/types'; + +export async function fetchIndex( + client: ElasticsearchClient, + indexName: string +): Promise { + const [indexDataResult, indexStatsResult, indexCountResult, connectorResult] = + await Promise.allSettled([ + client.indices.get({ index: indexName }), + client.indices.stats({ index: indexName }), + client.count({ index: indexName }), + fetchConnectorByIndexName(client, indexName), + ]); + if (indexDataResult.status === 'rejected') { + throw indexDataResult.reason; + } + const indexData = indexDataResult.value; + if (!indexData || !indexData[indexName]) return undefined; + + const index = indexData[indexName]; + const count = indexCountResult.status === 'fulfilled' ? indexCountResult.value.count : 0; + const connector = connectorResult.status === 'fulfilled' ? connectorResult.value : undefined; + const stats = + indexStatsResult.status === 'fulfilled' + ? indexStatsResult.value.indices?.[indexName] + : undefined; + return { + index: { + ...index, + count, + connector, + stats, + }, + }; +} diff --git a/x-pack/plugins/serverless_search/server/routes/indices_routes.ts b/x-pack/plugins/serverless_search/server/routes/indices_routes.ts index 7f165f13218f11..1e54a64642115e 100644 --- a/x-pack/plugins/serverless_search/server/routes/indices_routes.ts +++ b/x-pack/plugins/serverless_search/server/routes/indices_routes.ts @@ -11,6 +11,7 @@ import { schema } from '@kbn/config-schema'; import { fetchSearchResults } from '@kbn/search-index-documents/lib'; import { DEFAULT_DOCS_PER_PAGE } from '@kbn/search-index-documents/types'; import { fetchIndices } from '../lib/indices/fetch_indices'; +import { fetchIndex } from '../lib/indices/fetch_index'; import { RouteDependencies } from '../plugin'; export const registerIndicesRoutes = ({ router, security }: RouteDependencies) => { @@ -75,6 +76,27 @@ export const registerIndicesRoutes = ({ router, security }: RouteDependencies) = } ); + router.get( + { + path: '/internal/serverless_search/index/{indexName}', + validate: { + params: schema.object({ + indexName: schema.string(), + }), + }, + }, + async (context, request, response) => { + const { client } = (await context.core).elasticsearch; + const body = await fetchIndex(client.asCurrentUser, request.params.indexName); + return body + ? response.ok({ + body, + headers: { 'content-type': 'application/json' }, + }) + : response.notFound(); + } + ); + router.post( { path: '/internal/serverless_search/indices/{index_name}/search', From f2ad0240825740ac01aff55e7ed29f08944e7678 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 20 Dec 2023 15:12:54 -0700 Subject: [PATCH 054/116] [lens] show 'View details' UI action to open clusters inspector tab when request fails (#172971) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes https://github.com/elastic/kibana/issues/171570 PR make the following changes 1. Consolidates data EsError logic and Lens EsError logic. This resulted in being able to remove large parts of lens error_helper.tsx file. 2. Consolidates lens WorkspacePanel error logic. Before PR configuration errors and data loading errors each rendered their own version of EuiEmptyPrompt with slightly different behavior. Now, both render WorkspaceErrors component and have the same behavior 3. Updated lens ExpressionWrapper to return original error to embeddable output. ### Test - EsError in embeddable 1. install sample web logs 2. create new dashboard 3. Click "Create visualization" 4. Drag "timestamp" field into workspace. 5. Click "Save and return" 6. Add filter ``` { "error_query": { "indices": [ { "error_type": "exception", "message": "local shard failure message 123", "name": "kibana_sample_data_logs" } ] } } ``` 7. Verify EsError and "View details" action are displayed Screenshot 2023-12-08 at 1 34 20 PM ### Test - multiple configuration errors in lens editor 1. install sample web logs 2. create new lens visualization 3. Drag "timestamp" field into workspace. 4. Add filter ``` { "error_query": { "indices": [ { "error_type": "exception", "message": "local shard failure message 123", "name": "kibana_sample_data_logs" } ] } } ``` 5. Verify EsError and "View details" action are displayed Screenshot 2023-12-08 at 1 09 22 PM ### Test - EsError in embeddable 1. install sample web logs 2. create new dashboard 3. Click "Create visualization" 4. Drag "timestamp" field into workspace. 5. Change "Vertical axis" to "Cumulative sum". Select "Field" select and hit delete key 6. Clone layer one or more times 7. Verify pagination is displayed, allowing users to click through all configuration errors Screenshot 2023-12-08 at 12 59 18 PM --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Marco Liberati --- packages/kbn-search-errors/index.ts | 2 +- .../src/__snapshots__/es_error.test.tsx.snap | 13 + .../painless_error.test.tsx.snap | 29 ++ .../__snapshots__/tsdb_error.test.tsx.snap | 18 + .../kbn-search-errors/src/create_es_error.ts | 64 ++++ .../kbn-search-errors/src/es_error.test.tsx | 71 ++-- packages/kbn-search-errors/src/es_error.tsx | 38 +-- .../src/painless_error.test.tsx | 145 ++++---- .../kbn-search-errors/src/painless_error.tsx | 87 ++--- .../src/render_search_error.ts | 13 +- .../kbn-search-errors/src/tsdb_error.test.tsx | 88 +++++ packages/kbn-search-errors/src/tsdb_error.tsx | 55 +++ packages/kbn-search-errors/src/utils.ts | 25 -- packages/kbn-search-errors/tsconfig.json | 1 - .../data/common/search/expressions/esql.ts | 4 +- .../data/common/search/expressions/essql.ts | 4 +- .../search_interceptor.test.ts | 23 +- .../search_interceptor/search_interceptor.ts | 25 +- .../components/common/error_callout.tsx | 5 +- .../embeddable_panel_error.tsx | 6 +- .../workspace_panel/workspace_errors.tsx | 53 +++ .../workspace_panel/workspace_panel.test.tsx | 6 +- .../workspace_panel/workspace_panel.tsx | 137 ++------ .../editor_frame_service/error_helper.test.ts | 317 ------------------ .../editor_frame_service/error_helper.tsx | 186 +--------- .../lens/public/embeddable/embeddable.tsx | 5 +- .../public/embeddable/expression_wrapper.tsx | 14 +- .../maps/public/classes/util/data_request.tsx | 6 +- .../translations/translations/fr-FR.json | 9 +- .../translations/translations/ja-JP.json | 9 +- .../translations/translations/zh-CN.json | 9 +- .../test/functional/page_objects/lens_page.ts | 23 +- 32 files changed, 583 insertions(+), 907 deletions(-) create mode 100644 packages/kbn-search-errors/src/__snapshots__/es_error.test.tsx.snap create mode 100644 packages/kbn-search-errors/src/__snapshots__/painless_error.test.tsx.snap create mode 100644 packages/kbn-search-errors/src/__snapshots__/tsdb_error.test.tsx.snap create mode 100644 packages/kbn-search-errors/src/create_es_error.ts create mode 100644 packages/kbn-search-errors/src/tsdb_error.test.tsx create mode 100644 packages/kbn-search-errors/src/tsdb_error.tsx delete mode 100644 packages/kbn-search-errors/src/utils.ts create mode 100644 x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_errors.tsx delete mode 100644 x-pack/plugins/lens/public/editor_frame_service/error_helper.test.ts diff --git a/packages/kbn-search-errors/index.ts b/packages/kbn-search-errors/index.ts index 0bc9893ec04a94..4847085cb55365 100644 --- a/packages/kbn-search-errors/index.ts +++ b/packages/kbn-search-errors/index.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ +export { createEsError } from './src/create_es_error'; export { isEsError, EsError } from './src/es_error'; -export { isPainlessError, PainlessError } from './src/painless_error'; export { renderSearchError } from './src/render_search_error'; export type { IEsError } from './src/types'; diff --git a/packages/kbn-search-errors/src/__snapshots__/es_error.test.tsx.snap b/packages/kbn-search-errors/src/__snapshots__/es_error.test.tsx.snap new file mode 100644 index 00000000000000..68e53db73a99a0 --- /dev/null +++ b/packages/kbn-search-errors/src/__snapshots__/es_error.test.tsx.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EsError should render error message 1`] = ` +
+
+    
+      The supplied interval [2q] could not be parsed as a calendar interval.
+    
+  
+
+`; diff --git a/packages/kbn-search-errors/src/__snapshots__/painless_error.test.tsx.snap b/packages/kbn-search-errors/src/__snapshots__/painless_error.test.tsx.snap new file mode 100644 index 00000000000000..643973c6360192 --- /dev/null +++ b/packages/kbn-search-errors/src/__snapshots__/painless_error.test.tsx.snap @@ -0,0 +1,29 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Painless error should render error message 1`] = ` +
+ + Error executing runtime field or scripted field on data view logs + + + + invalid +^---- HERE + + + cannot resolve symbol [invalid] + +
+`; diff --git a/packages/kbn-search-errors/src/__snapshots__/tsdb_error.test.tsx.snap b/packages/kbn-search-errors/src/__snapshots__/tsdb_error.test.tsx.snap new file mode 100644 index 00000000000000..adc0412c175b79 --- /dev/null +++ b/packages/kbn-search-errors/src/__snapshots__/tsdb_error.test.tsx.snap @@ -0,0 +1,18 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Tsdb error should render error message 1`] = ` +
+

+ The field [bytes_counter] of Time series type [counter] has been used with the unsupported operation [sum]. +

+ + See more about Time series field types and [counter] supported aggregations + +
+`; diff --git a/packages/kbn-search-errors/src/create_es_error.ts b/packages/kbn-search-errors/src/create_es_error.ts new file mode 100644 index 00000000000000..ffde06eb728f71 --- /dev/null +++ b/packages/kbn-search-errors/src/create_es_error.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { estypes } from '@elastic/elasticsearch'; +import { i18n } from '@kbn/i18n'; +import type { ApplicationStart, CoreStart } from '@kbn/core/public'; +import type { DataView } from '@kbn/data-views-plugin/common'; +import { IEsError } from './types'; +import { EsError } from './es_error'; +import { PainlessError } from './painless_error'; +import { TsdbError } from './tsdb_error'; + +export interface Services { + application: ApplicationStart; + docLinks: CoreStart['docLinks']; +} + +function getNestedCauses(errorCause: estypes.ErrorCause): estypes.ErrorCause[] { + // Give shard failures priority, then try to get the error navigating nested objects + if (errorCause.failed_shards) { + return (errorCause.failed_shards as estypes.ShardFailure[]).map( + (shardFailure) => shardFailure.reason + ); + } + return errorCause.caused_by ? getNestedCauses(errorCause.caused_by) : [errorCause]; +} + +export function createEsError( + err: IEsError, + openInInspector: () => void, + services: Services, + dataView?: DataView +) { + const rootCauses = err.attributes?.error ? getNestedCauses(err.attributes?.error) : []; + + const painlessCause = rootCauses.find((errorCause) => { + return errorCause.lang && errorCause.lang === 'painless'; + }); + if (painlessCause) { + return new PainlessError(err, openInInspector, painlessCause, services.application, dataView); + } + + const tsdbCause = rootCauses.find((errorCause) => { + return ( + errorCause.type === 'illegal_argument_exception' && + errorCause.reason && + /\]\[counter\] is not supported for aggregation/.test(errorCause.reason) + ); + }); + if (tsdbCause) { + return new TsdbError(err, openInInspector, tsdbCause, services.docLinks); + } + + const causeReason = rootCauses[0]?.reason ?? err.attributes?.error?.reason; + const message = causeReason + ? causeReason + : i18n.translate('searchErrors.esError.unknownRootCause', { defaultMessage: 'unknown' }); + return new EsError(err, message, openInInspector); +} diff --git a/packages/kbn-search-errors/src/es_error.test.tsx b/packages/kbn-search-errors/src/es_error.test.tsx index 7f82faf685aba0..1304b154d10904 100644 --- a/packages/kbn-search-errors/src/es_error.test.tsx +++ b/packages/kbn-search-errors/src/es_error.test.tsx @@ -6,41 +6,31 @@ * Side Public License, v 1. */ -import { EsError } from './es_error'; -import { IEsError } from './types'; +import type { ReactElement } from 'react'; +import type { CoreStart } from '@kbn/core/public'; +import { createEsError } from './create_es_error'; +import { renderSearchError } from './render_search_error'; +import { shallow } from 'enzyme'; +import { coreMock } from '@kbn/core/public/mocks'; -describe('EsError', () => { - it('contains the same body as the wrapped error', () => { - const error = { - statusCode: 500, - message: 'nope', - attributes: { - error: { - type: 'top_level_exception_type', - reason: 'top-level reason', - }, +const services = { + application: coreMock.createStart().application, + docLinks: { + links: { + fleet: { + datastreamsTSDSMetrics: '', }, - } as IEsError; - const esError = new EsError(error, () => {}); - - expect(typeof esError.attributes).toEqual('object'); - expect(esError.attributes).toEqual(error.attributes); - }); + }, + } as CoreStart['docLinks'], +}; - it('contains some explanation of the error in the message', () => { - // error taken from Vega's issue - const error = { - message: - 'x_content_parse_exception: [x_content_parse_exception] Reason: [1:78] [date_histogram] failed to parse field [calendar_interval]', +describe('EsError', () => { + const esError = createEsError( + { statusCode: 400, + message: 'search_phase_execution_exception', attributes: { error: { - root_cause: [ - { - type: 'x_content_parse_exception', - reason: '[1:78] [date_histogram] failed to parse field [calendar_interval]', - }, - ], type: 'x_content_parse_exception', reason: '[1:78] [date_histogram] failed to parse field [calendar_interval]', caused_by: { @@ -49,10 +39,27 @@ describe('EsError', () => { }, }, }, - } as IEsError; - const esError = new EsError(error, () => {}); + }, + () => {}, + services + ); + + test('should set error.message to root "error cause" reason', () => { expect(esError.message).toEqual( - 'EsError: The supplied interval [2q] could not be parsed as a calendar interval.' + 'The supplied interval [2q] could not be parsed as a calendar interval.' ); }); + + test('should render error message', () => { + const searchErrorDisplay = renderSearchError(esError); + expect(searchErrorDisplay).not.toBeUndefined(); + const wrapper = shallow(searchErrorDisplay?.body as ReactElement); + expect(wrapper).toMatchSnapshot(); + }); + + test('should return 1 action', () => { + const searchErrorDisplay = renderSearchError(esError); + expect(searchErrorDisplay).not.toBeUndefined(); + expect(searchErrorDisplay?.actions?.length).toBe(1); + }); }); diff --git a/packages/kbn-search-errors/src/es_error.tsx b/packages/kbn-search-errors/src/es_error.tsx index 8a5ab1ad3c503d..cd8c842d997d8a 100644 --- a/packages/kbn-search-errors/src/es_error.tsx +++ b/packages/kbn-search-errors/src/es_error.tsx @@ -7,11 +7,9 @@ */ import React from 'react'; -import { EuiButton, EuiCodeBlock, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import type { ApplicationStart } from '@kbn/core/public'; -import { IEsError } from './types'; -import { getRootCause } from './utils'; +import { EuiButton, EuiCodeBlock } from '@elastic/eui'; +import type { IEsError } from './types'; /** * Checks if a given errors originated from Elasticsearch. @@ -24,39 +22,25 @@ export function isEsError(e: any): e is IEsError { } export class EsError extends Error { - readonly attributes: IEsError['attributes']; + public readonly attributes: IEsError['attributes']; + private readonly openInInspector: () => void; - constructor(protected readonly err: IEsError, private readonly openInInspector: () => void) { - super( - `EsError: ${ - getRootCause(err?.attributes?.error)?.reason || - i18n.translate('searchErrors.esError.unknownRootCause', { defaultMessage: 'unknown' }) - }` - ); + constructor(err: IEsError, message: string, openInInspector: () => void) { + super(message); this.attributes = err.attributes; + this.openInInspector = openInInspector; Object.setPrototypeOf(this, new.target.prototype); } public getErrorMessage() { - if (!this.attributes?.error) { - return null; - } - - const rootCause = getRootCause(this.attributes.error)?.reason; - const topLevelCause = this.attributes.error.reason; - const cause = rootCause ?? topLevelCause; - return ( - <> - - - {cause} - - + + {this.message} + ); } - public getActions(application: ApplicationStart) { + public getActions() { return [ { - beforeEach(() => { - jest.clearAllMocks(); - }); +const dataViewMock = { + title: 'logs', + id: '1234', +} as unknown as DataView; - it('Should show reason and code', () => { - const e = new PainlessError( - { - statusCode: 400, - message: 'search_phase_execution_exception', - attributes: { - error: searchPhaseException.error, +describe('Painless error', () => { + const painlessError = createEsError( + { + statusCode: 400, + message: 'search_phase_execution_exception', + attributes: { + error: { + type: 'search_phase_execution_exception', + reason: 'all shards failed', + failed_shards: [ + { + shard: 0, + index: '.kibana_11', + node: 'b3HX8C96Q7q1zgfVLxEsPA', + reason: { + type: 'script_exception', + reason: 'compile error', + script_stack: ['invalid', '^---- HERE'], + script: 'invalid', + lang: 'painless', + position: { + offset: 0, + start: 0, + end: 7, + }, + caused_by: { + type: 'illegal_argument_exception', + reason: 'cannot resolve symbol [invalid]', + }, + }, + }, + ], }, }, - () => {} - ); - const component = mount(e.getErrorMessage()); - - const failedShards = searchPhaseException.error.failed_shards![0]; + }, + () => {}, + servicesMock, + dataViewMock + ); - const stackTraceElem = findTestSubject(component, 'painlessStackTrace').getDOMNode(); - const stackTrace = failedShards!.reason.script_stack!.splice(-2).join('\n'); - expect(stackTraceElem.textContent).toBe(stackTrace); + test('should set error.message to painless reason', () => { + expect(painlessError.message).toEqual( + 'Error executing runtime field or scripted field on data view logs' + ); + }); - const humanReadableError = findTestSubject( - component, - 'painlessHumanReadableError' - ).getDOMNode(); - expect(humanReadableError.textContent).toBe(failedShards?.reason.caused_by?.reason); + test('should render error message', () => { + const searchErrorDisplay = renderSearchError(painlessError); + expect(searchErrorDisplay).not.toBeUndefined(); + const wrapper = shallow(searchErrorDisplay?.body as ReactElement); + expect(wrapper).toMatchSnapshot(); + }); - const actions = e.getActions(startMock.application); - expect(actions.length).toBe(2); + test('should return 2 actions', () => { + const searchErrorDisplay = renderSearchError(painlessError); + expect(searchErrorDisplay).not.toBeUndefined(); + expect(searchErrorDisplay?.actions?.length).toBe(2); }); }); diff --git a/packages/kbn-search-errors/src/painless_error.tsx b/packages/kbn-search-errors/src/painless_error.tsx index 08657ea134ab69..79fd737f055ab8 100644 --- a/packages/kbn-search-errors/src/painless_error.tsx +++ b/packages/kbn-search-errors/src/painless_error.tsx @@ -7,43 +7,58 @@ */ import React from 'react'; +import { estypes } from '@elastic/elasticsearch'; +import type { ApplicationStart } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; import { EuiButtonEmpty, EuiSpacer, EuiText, EuiCodeBlock } from '@elastic/eui'; -import type { ApplicationStart } from '@kbn/core/public'; import type { DataView } from '@kbn/data-views-plugin/common'; import type { IEsError } from './types'; -import { EsError, isEsError } from './es_error'; -import { getRootCause } from './utils'; +import { EsError } from './es_error'; export class PainlessError extends EsError { - painlessStack?: string; - indexPattern?: DataView; - constructor(err: IEsError, openInInspector: () => void, indexPattern?: DataView) { - super(err, openInInspector); - this.indexPattern = indexPattern; + private readonly applicationStart: ApplicationStart; + private readonly painlessCause: estypes.ErrorCause; + private readonly dataView?: DataView; + + constructor( + err: IEsError, + openInInspector: () => void, + painlessCause: estypes.ErrorCause, + applicationStart: ApplicationStart, + dataView?: DataView + ) { + super( + err, + i18n.translate('searchErrors.painlessError.painlessScriptedFieldErrorMessage', { + defaultMessage: + 'Error executing runtime field or scripted field on data view {indexPatternName}', + values: { + indexPatternName: dataView?.title || '', + }, + }), + openInInspector + ); + this.applicationStart = applicationStart; + this.painlessCause = painlessCause; + this.dataView = dataView; } public getErrorMessage() { - const rootCause = getRootCause(this.err.attributes?.error); - const scriptFromStackTrace = rootCause?.script_stack - ? rootCause?.script_stack?.slice(-2).join('\n') + const scriptFromStackTrace = this.painlessCause?.script_stack + ? this.painlessCause?.script_stack?.slice(-2).join('\n') : undefined; // if the error has been properly processed it will highlight where it occurred. - const hasScript = rootCause?.script_stack?.slice(-1)[0]?.indexOf('HERE') || -1 >= 0; - const humanReadableError = rootCause?.caused_by?.reason; + const hasScript = this.painlessCause?.script_stack?.slice(-1)[0]?.indexOf('HERE') || -1 >= 0; + const humanReadableError = this.painlessCause?.caused_by?.reason; // fallback, show ES stacktrace - const painlessStack = rootCause?.script_stack ? rootCause?.script_stack.join('\n') : undefined; + const painlessStack = this.painlessCause?.script_stack + ? this.painlessCause?.script_stack.join('\n') + : undefined; return ( - <> +
- {i18n.translate('searchErrors.painlessError.painlessScriptedFieldErrorMessage', { - defaultMessage: - 'Error executing runtime field or scripted field on index pattern {indexPatternName}', - values: { - indexPatternName: this?.indexPattern?.title, - }, - })} + {this.message} {scriptFromStackTrace || painlessStack ? ( @@ -56,21 +71,21 @@ export class PainlessError extends EsError { {humanReadableError} ) : null} - +
); } - getActions(application: ApplicationStart) { - function onClick(indexPatternId?: string) { - application.navigateToApp('management', { - path: `/kibana/indexPatterns${indexPatternId ? `/patterns/${indexPatternId}` : ''}`, - }); - } - const actions = super.getActions(application) ?? []; + getActions() { + const actions = super.getActions() ?? []; actions.push( onClick(this?.indexPattern?.id)} + onClick={() => () => { + const dataViewId = this.dataView?.id; + this.applicationStart.navigateToApp('management', { + path: `/kibana/indexPatterns${dataViewId ? `/patterns/${dataViewId}` : ''}`, + }); + }} size="s" > {i18n.translate('searchErrors.painlessError.buttonTxt', { @@ -81,13 +96,3 @@ export class PainlessError extends EsError { return actions; } } - -export function isPainlessError(err: Error | IEsError) { - if (!isEsError(err)) return false; - - const rootCause = getRootCause((err as IEsError).attributes?.error); - if (!rootCause) return false; - - const { lang } = rootCause; - return lang === 'painless'; -} diff --git a/packages/kbn-search-errors/src/render_search_error.ts b/packages/kbn-search-errors/src/render_search_error.ts index 73dd298877cca0..85dc2486d7a16c 100644 --- a/packages/kbn-search-errors/src/render_search_error.ts +++ b/packages/kbn-search-errors/src/render_search_error.ts @@ -9,23 +9,18 @@ import { i18n } from '@kbn/i18n'; import { ReactNode } from 'react'; import { BfetchRequestError } from '@kbn/bfetch-error'; -import type { ApplicationStart } from '@kbn/core-application-browser'; import { EsError } from './es_error'; -export function renderSearchError({ - error, - application, -}: { - error: Error; - application: ApplicationStart; -}): { title: string; body: ReactNode; actions?: ReactNode[] } | undefined { +export function renderSearchError( + error: Error +): { title: string; body: ReactNode; actions?: ReactNode[] } | undefined { if (error instanceof EsError) { return { title: i18n.translate('searchErrors.search.esErrorTitle', { defaultMessage: 'Cannot retrieve search results', }), body: error.getErrorMessage(), - actions: error.getActions(application), + actions: error.getActions(), }; } diff --git a/packages/kbn-search-errors/src/tsdb_error.test.tsx b/packages/kbn-search-errors/src/tsdb_error.test.tsx new file mode 100644 index 00000000000000..d272938853da6d --- /dev/null +++ b/packages/kbn-search-errors/src/tsdb_error.test.tsx @@ -0,0 +1,88 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { ReactElement } from 'react'; +import type { CoreStart } from '@kbn/core/public'; +import { createEsError } from './create_es_error'; +import { renderSearchError } from './render_search_error'; +import { shallow } from 'enzyme'; +import { coreMock } from '@kbn/core/public/mocks'; + +const servicesMock = { + application: coreMock.createStart().application, + docLinks: { + links: { + fleet: { + datastreamsTSDSMetrics: '', + }, + }, + } as CoreStart['docLinks'], +}; + +describe('Tsdb error', () => { + const tsdbError = createEsError( + { + statusCode: 400, + message: 'search_phase_execution_exception', + attributes: { + error: { + type: 'status_exception', + reason: 'error while executing search', + caused_by: { + type: 'search_phase_execution_exception', + reason: 'all shards failed', + phase: 'query', + grouped: true, + failed_shards: [ + { + shard: 0, + index: 'tsdb_index', + reason: { + type: 'illegal_argument_exception', + reason: + 'Field [bytes_counter] of type [long][counter] is not supported for aggregation [sum]', + }, + }, + ], + caused_by: { + type: 'illegal_argument_exception', + reason: + 'Field [bytes_counter] of type [long][counter] is not supported for aggregation [sum]', + caused_by: { + type: 'illegal_argument_exception', + reason: + 'Field [bytes_counter] of type [long][counter] is not supported for aggregation [sum]', + }, + }, + }, + }, + }, + }, + () => {}, + servicesMock + ); + + test('should set error.message to tsdb reason', () => { + expect(tsdbError.message).toEqual( + 'The field [bytes_counter] of Time series type [counter] has been used with the unsupported operation [sum].' + ); + }); + + test('should render error message', () => { + const searchErrorDisplay = renderSearchError(tsdbError); + expect(searchErrorDisplay).not.toBeUndefined(); + const wrapper = shallow(searchErrorDisplay?.body as ReactElement); + expect(wrapper).toMatchSnapshot(); + }); + + test('should return 1 actions', () => { + const searchErrorDisplay = renderSearchError(tsdbError); + expect(searchErrorDisplay).not.toBeUndefined(); + expect(searchErrorDisplay?.actions?.length).toBe(1); + }); +}); diff --git a/packages/kbn-search-errors/src/tsdb_error.tsx b/packages/kbn-search-errors/src/tsdb_error.tsx new file mode 100644 index 00000000000000..2f51665df699e5 --- /dev/null +++ b/packages/kbn-search-errors/src/tsdb_error.tsx @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import { estypes } from '@elastic/elasticsearch'; +import type { CoreStart } from '@kbn/core/public'; +import { i18n } from '@kbn/i18n'; +import { EuiLink } from '@elastic/eui'; +import type { IEsError } from './types'; +import { EsError } from './es_error'; + +export class TsdbError extends EsError { + private readonly docLinks: CoreStart['docLinks']; + + constructor( + err: IEsError, + openInInspector: () => void, + tsdbCause: estypes.ErrorCause, + docLinks: CoreStart['docLinks'] + ) { + const [fieldName, _type, _isCounter, opUsed] = tsdbCause.reason!.match(/\[(\w)*\]/g)!; + super( + err, + i18n.translate('searchErrors.tsdbError.message', { + defaultMessage: + 'The field {field} of Time series type [counter] has been used with the unsupported operation {op}.', + values: { + field: fieldName, + op: opUsed, + }, + }), + openInInspector + ); + this.docLinks = docLinks; + } + + public getErrorMessage() { + return ( +
+

{this.message}

+ + {i18n.translate('searchErrors.tsdbError.tsdbCounterDocsLabel', { + defaultMessage: + 'See more about Time series field types and [counter] supported aggregations', + })} + +
+ ); + } +} diff --git a/packages/kbn-search-errors/src/utils.ts b/packages/kbn-search-errors/src/utils.ts deleted file mode 100644 index e1e2c51f87f3ca..00000000000000 --- a/packages/kbn-search-errors/src/utils.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { estypes } from '@elastic/elasticsearch'; - -function getFailedShardCause(error: estypes.ErrorCause): estypes.ErrorCause | undefined { - const failedShards = error.failed_shards || error.caused_by?.failed_shards; - return failedShards ? failedShards[0]?.reason : undefined; -} - -function getNestedCause(error: estypes.ErrorCause): estypes.ErrorCause { - return error.caused_by ? getNestedCause(error.caused_by) : error; -} - -export function getRootCause(error?: estypes.ErrorCause): estypes.ErrorCause | undefined { - return error - ? // Give shard failures priority, then try to get the error navigating nested objects - getFailedShardCause(error) || getNestedCause(error) - : undefined; -} diff --git a/packages/kbn-search-errors/tsconfig.json b/packages/kbn-search-errors/tsconfig.json index 7c50a64bd11ee8..d7cb9d82c63a52 100644 --- a/packages/kbn-search-errors/tsconfig.json +++ b/packages/kbn-search-errors/tsconfig.json @@ -20,7 +20,6 @@ "@kbn/core", "@kbn/kibana-utils-plugin", "@kbn/data-views-plugin", - "@kbn/core-application-browser", "@kbn/bfetch-error", ] } diff --git a/src/plugins/data/common/search/expressions/esql.ts b/src/plugins/data/common/search/expressions/esql.ts index ca6096c8160df0..e1eb3bb7be4524 100644 --- a/src/plugins/data/common/search/expressions/esql.ts +++ b/src/plugins/data/common/search/expressions/esql.ts @@ -208,10 +208,10 @@ export const getEsqlFn = ({ getStartDependencies }: EsqlFnArguments) => { IKibanaSearchResponse >({ params }, { abortSignal, strategy: ESQL_SEARCH_STRATEGY }).pipe( catchError((error) => { - if (!error.err) { + if (!error.attributes) { error.message = `Unexpected error from Elasticsearch: ${error.message}`; } else { - const { type, reason } = extractTypeAndReason(error.err.attributes); + const { type, reason } = extractTypeAndReason(error.attributes); if (type === 'parsing_exception') { error.message = `Couldn't parse Elasticsearch ES|QL query. Check your query and try again. Error: ${reason}`; } else { diff --git a/src/plugins/data/common/search/expressions/essql.ts b/src/plugins/data/common/search/expressions/essql.ts index 5012f01a749ace..b27d9137445f6e 100644 --- a/src/plugins/data/common/search/expressions/essql.ts +++ b/src/plugins/data/common/search/expressions/essql.ts @@ -203,10 +203,10 @@ export const getEssqlFn = ({ getStartDependencies }: EssqlFnArguments) => { { abortSignal, strategy: SQL_SEARCH_STRATEGY } ).pipe( catchError((error) => { - if (!error.err) { + if (!error.attributes) { error.message = `Unexpected error from Elasticsearch: ${error.message}`; } else { - const { type, reason } = error.err.attributes; + const { type, reason } = error.attributes; if (type === 'parsing_exception') { error.message = `Couldn't parse Elasticsearch SQL query. You may need to add double quotes to names containing special characters. Check your query and try again. Error: ${reason}`; } else { diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts index 1c6bc41e33216e..4a2b6f27e9e9bf 100644 --- a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts +++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts @@ -12,7 +12,7 @@ import { coreMock, themeServiceMock } from '@kbn/core/public/mocks'; import { IEsSearchRequest } from '../../../common/search'; import { SearchInterceptor } from './search_interceptor'; import { AbortError } from '@kbn/kibana-utils-plugin/public'; -import { PainlessError, EsError, type IEsError } from '@kbn/search-errors'; +import { EsError, type IEsError } from '@kbn/search-errors'; import { ISessionService, SearchSessionState } from '..'; import { bfetchPluginMock } from '@kbn/bfetch-plugin/public/mocks'; import { BfetchPublicSetup } from '@kbn/bfetch-plugin/public'; @@ -157,9 +157,9 @@ describe('SearchInterceptor', () => { expect(mockCoreSetup.notifications.toasts.addError).not.toBeCalled(); }); - test('Renders a PainlessError', async () => { + test('Renders a EsError', async () => { searchInterceptor.showError( - new PainlessError( + new EsError( { statusCode: 400, message: 'search_phase_execution_exception', @@ -167,6 +167,7 @@ describe('SearchInterceptor', () => { error: searchPhaseException.error, }, }, + 'search_phase_execution_exception', () => {} ) ); @@ -1467,22 +1468,6 @@ describe('SearchInterceptor', () => { }); }); - test('Should throw Painless error on server error with OSS format', async () => { - const mockResponse: IEsError = { - statusCode: 400, - message: 'search_phase_execution_exception', - attributes: { - error: searchPhaseException.error, - }, - }; - fetchMock.mockRejectedValueOnce(mockResponse); - const mockRequest: IEsSearchRequest = { - params: {}, - }; - const response = searchInterceptor.search(mockRequest); - await expect(response.toPromise()).rejects.toThrow(PainlessError); - }); - test('Should throw ES error on ES server error', async () => { const mockResponse: IEsError = { statusCode: 400, diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts index 8bae4b3fc7c123..9fcb74e3394032 100644 --- a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts +++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts @@ -50,13 +50,7 @@ import { BatchedFunc, BfetchPublicSetup, DISABLE_BFETCH } from '@kbn/bfetch-plug import { toMountPoint } from '@kbn/kibana-react-plugin/public'; import { AbortError, KibanaServerError } from '@kbn/kibana-utils-plugin/public'; import { BfetchRequestError } from '@kbn/bfetch-error'; -import { - EsError, - isEsError, - isPainlessError, - PainlessError, - renderSearchError, -} from '@kbn/search-errors'; +import { createEsError, isEsError, renderSearchError } from '@kbn/search-errors'; import { ENHANCED_ES_SEARCH_STRATEGY, IAsyncSearchOptions, @@ -238,9 +232,15 @@ export class SearchInterceptor { } ); }; - return isPainlessError(e) - ? new PainlessError(e, openInInspector, options?.indexPattern) - : new EsError(e, openInInspector); + return createEsError( + e, + openInInspector, + { + application: this.application, + docLinks: this.docLinks, + }, + options?.indexPattern + ); } return e instanceof Error ? e : new Error(e.message); @@ -585,10 +585,7 @@ export class SearchInterceptor { return; } - const searchErrorDisplay = renderSearchError({ - error: e, - application: this.application, - }); + const searchErrorDisplay = renderSearchError(e); if (searchErrorDisplay) { this.deps.toasts.addDanger({ diff --git a/src/plugins/discover/public/components/common/error_callout.tsx b/src/plugins/discover/public/components/common/error_callout.tsx index a2aa2b478a3dc5..3fb91f196ee3a0 100644 --- a/src/plugins/discover/public/components/common/error_callout.tsx +++ b/src/plugins/discover/public/components/common/error_callout.tsx @@ -22,10 +22,7 @@ export const ErrorCallout = ({ title, error }: Props) => { const { core } = useDiscoverServices(); const { euiTheme } = useEuiTheme(); - const searchErrorDisplay = renderSearchError({ - error, - application: core.application, - }); + const searchErrorDisplay = renderSearchError(error); return ( ; + title: string; +} + +export function WorkspaceErrors(props: Props) { + const [activePage, setActivePage] = useState(0); + + const activeError = props.errors.length ? props.errors[activePage] : ''; + + return ( + 1 ? ( + + + + + + ) : ( + [] + ) + } + body={ +
+ {typeof activeError === 'string' ? activeError : activeError.longMessage} +
+ } + title={

{props.title}

} + iconColor="danger" + iconType="warning" + data-test-subj="lnsWorkspaceErrors" + /> + ); +} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx index a8e834e43881c2..930dd4940171c8 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx @@ -703,9 +703,9 @@ describe('workspace_panel', () => { instance.update(); // EuiFlexItem duplicates internally the attribute, so we need to filter only the most inner one here - expect( - instance.find('[data-test-subj="workspace-more-errors-button"]').last().text() - ).toEqual(' +1 error'); + expect(instance.find('[data-test-subj="workspace-error-message"]').last().text()).toEqual( + `i'm an error` + ); expect(instance.find(expressionRendererMock)).toHaveLength(0); expect(getUserMessages).toHaveBeenCalledWith(['visualization', 'visualizationInEditor'], { severity: 'error', diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx index bc3b71c08487ad..18ea4791d6847e 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx @@ -12,16 +12,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { toExpression } from '@kbn/interpreter'; import type { KibanaExecutionContext } from '@kbn/core-execution-context-common'; import { i18n } from '@kbn/i18n'; -import { - EuiEmptyPrompt, - EuiFlexGroup, - EuiFlexItem, - EuiText, - EuiButtonEmpty, - EuiLink, - EuiTextColor, - EuiSpacer, -} from '@elastic/eui'; +import { EuiText, EuiButtonEmpty, EuiLink, EuiTextColor } from '@elastic/eui'; import type { CoreStart } from '@kbn/core/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { @@ -83,6 +74,7 @@ import { import type { LensInspector } from '../../../lens_inspector_service'; import { inferTimeField, DONT_CLOSE_DIMENSION_CONTAINER_ON_CLICK_CLASS } from '../../../utils'; import { setChangesApplied } from '../../../state_management/lens_slice'; +import { WorkspaceErrors } from './workspace_errors'; export interface WorkspacePanelProps { visualizationMap: VisualizationMap; @@ -98,7 +90,6 @@ export interface WorkspacePanelProps { } interface WorkspaceState { - expandError: boolean; expressionToRender: string | null | undefined; errors: UserMessage[]; } @@ -166,7 +157,6 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({ const searchSessionId = useLensSelector(selectSearchSessionId); const [localState, setLocalState] = useState({ - expandError: false, expressionToRender: undefined, errors: [], }); @@ -724,75 +714,35 @@ export const VisualizationWrapper = ({ const searchSessionId = useLensSelector(selectSearchSessionId); if (errors.length) { - const showExtraErrorsAction = - !localState.expandError && errors.length > 1 ? ( - { - setLocalState((prevState: WorkspaceState) => ({ - ...prevState, - expandError: !prevState.expandError, - })); - }} - data-test-subj="workspace-more-errors-button" - > - {i18n.translate('xpack.lens.editorFrame.configurationFailureMoreErrors', { - defaultMessage: ` +{errors} {errors, plural, one {error} other {errors}}`, - values: { errors: errors.length - 1 }, - })} - - ) : null; - - const [firstMessage, ...rest] = errors; - + const configurationErrorTitle = i18n.translate( + 'xpack.lens.editorFrame.configurationFailureErrors', + { + defaultMessage: `A configuration error occurred`, + } + ); return ( - - - -
{firstMessage.longMessage}
- {localState.expandError && ( - <> - - {rest.map((message) => ( -
- {message.longMessage} - -
- ))} - - )} - - } - iconColor="danger" - iconType="warning" - /> -
-
+ + ); } + const dataLoadingErrorTitle = i18n.translate('xpack.lens.editorFrame.dataFailure', { + defaultMessage: `An error occurred when loading data`, + }); + return (
{ - const errorsFromRequest = getOriginalRequestErrorMessages(error || null, core.docLinks); + const errorsFromRequest = getOriginalRequestErrorMessages(error || null); const visibleErrorMessages = errorsFromRequest.length - ? errorsFromRequest.map((e) => e.longMessage || e.shortMessage) + ? errorsFromRequest : errorMessage ? [errorMessage] : []; @@ -820,54 +770,7 @@ export const VisualizationWrapper = ({ setDynamicError(true); } - return ( - - - { - setLocalState((prevState: WorkspaceState) => ({ - ...prevState, - expandError: !prevState.expandError, - })); - }} - > - {i18n.translate('xpack.lens.editorFrame.expandRenderingErrorButton', { - defaultMessage: 'Show details of error', - })} - - ) : null - } - body={ - <> -

- -

- - {localState.expandError - ? visibleErrorMessages.map((visibleErrorMessage) => - typeof visibleErrorMessage === 'string' ? ( -

- {visibleErrorMessage} -

- ) : ( - visibleErrorMessage - ) - ) - : null} - - } - iconColor="danger" - iconType="warning" - /> -
-
- ); + return ; }} />
diff --git a/x-pack/plugins/lens/public/editor_frame_service/error_helper.test.ts b/x-pack/plugins/lens/public/editor_frame_service/error_helper.test.ts deleted file mode 100644 index 7e3b696a8e75f0..00000000000000 --- a/x-pack/plugins/lens/public/editor_frame_service/error_helper.test.ts +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { getOriginalRequestErrorMessages } from './error_helper'; -import type { CoreStart } from '@kbn/core/public'; - -const docLinksMock = { links: { fleet: { datastreamsTSDSMetrics: '' } } } as CoreStart['docLinks']; - -const runtimeFieldError = { - stack: 'Error: EsError\n...', - message: '[lens_merge_tables] > [esaggs] > EsError', - name: 'Error', - original: { - name: 'Error', - message: 'Something', - err: { - message: 'status_exception', - statusCode: 400, - attributes: { - error: { - type: 'status_exception', - reason: 'error while executing search', - caused_by: { - type: 'search_phase_execution_exception', - reason: 'all shards failed', - phase: 'query', - grouped: true, - failed_shards: [ - { - shard: 0, - index: 'indexpattern_source', - node: 'jtqB1-UhQluyjeXIpQFqAA', - reason: { - type: 'script_exception', - reason: 'runtime error', - script_stack: [ - 'java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)', - 'java.base/java.lang.Integer.parseInt(Integer.java:652)', - 'java.base/java.lang.Integer.parseInt(Integer.java:770)', - "emit(Integer.parseInt('hello'))", - ' ^---- HERE', - ], - script: "emit(Integer.parseInt('hello'))", - lang: 'painless', - position: { offset: 12, start: 0, end: 31 }, - caused_by: { - type: 'number_format_exception', - reason: 'For input string: "hello"', - }, - }, - }, - ], - }, - }, - }, - }, - attributes: { - error: { - type: 'status_exception', - reason: 'error while executing search', - caused_by: { - type: 'search_phase_execution_exception', - reason: 'all shards failed', - phase: 'query', - grouped: true, - failed_shards: [ - { - shard: 0, - index: 'indexpattern_source', - node: 'jtqB1-UhQluyjeXIpQFqAA', - reason: { - type: 'script_exception', - reason: 'runtime error', - script_stack: [ - 'java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)', - 'java.base/java.lang.Integer.parseInt(Integer.java:652)', - 'java.base/java.lang.Integer.parseInt(Integer.java:770)', - "emit(Integer.parseInt('hello'))", - ' ^---- HERE', - ], - script: "emit(Integer.parseInt('hello'))", - lang: 'painless', - position: { offset: 12, start: 0, end: 31 }, - caused_by: { type: 'number_format_exception', reason: 'For input string: "hello"' }, - }, - }, - ], - }, - }, - }, - }, -}; - -const scriptedFieldError = { - stack: 'Error: EsError\n...', - message: '[lens_merge_tables] > [esaggs] > EsError', - name: 'Error', - original: { - name: 'Error', - message: 'Some description', - err: { - message: 'status_exception', - statusCode: 500, - attributes: { - error: { - type: 'status_exception', - reason: 'error while executing search', - caused_by: { - type: 'search_phase_execution_exception', - reason: 'all shards failed', - phase: 'query', - grouped: true, - failed_shards: [ - { - shard: 0, - index: 'indexpattern_source', - node: 'jtqB1-UhQluyjeXIpQFqAA', - reason: { - type: 'aggregation_execution_exception', - reason: 'Unsupported script value [hello], expected a number, date, or boolean', - }, - }, - ], - }, - }, - }, - }, - attributes: { - error: { - type: 'status_exception', - reason: 'error while executing search', - caused_by: { - type: 'search_phase_execution_exception', - reason: 'all shards failed', - phase: 'query', - grouped: true, - failed_shards: [ - { - shard: 0, - index: 'indexpattern_source', - node: 'jtqB1-UhQluyjeXIpQFqAA', - reason: { - type: 'aggregation_execution_exception', - reason: 'Unsupported script value [hello], expected a number, date, or boolean', - }, - }, - ], - }, - }, - }, - }, -}; - -const networkError = { - stack: 'Error: Batch request failed with status 0', - message: '[lens_merge_tables] > [esaggs] > Batch request failed with status 0', - name: 'Error', - original: { - name: 'Error', - message: 'Batch request failed with status 0', - stack: 'Error: Batch request failed with status 0', - }, -}; - -// EsAggs will report an internal error when user attempts to use a runtime field on an indexpattern he has no access to -const indexpatternAccessError = { - stack: "TypeError: Cannot read property 'values' of undefined\n", - message: "[lens_merge_tables] > [esaggs] > Cannot read property 'values' of undefined", - name: 'TypeError', - original: { - message: "[lens_merge_tables] > [esaggs] > Cannot read property 'values' of undefined", - stack: "[lens_merge_tables] > [esaggs] > Cannot read property 'values' of undefined", - }, -}; - -const tsdbCounterUsedWithWrongOperationError = { - stack: - 'Error: EsError: Field [bytes_counter] of type [long][counter] is not supported for aggregation [sum]', - message: - '[layeredXyVis] > [esaggs] > EsError: Field [bytes_counter] of type [long][counter] is not supported for aggregation [sum]', - name: 'Error', - original: { - attributes: { - error: { - type: 'status_exception', - reason: 'error while executing search', - caused_by: { - type: 'search_phase_execution_exception', - reason: 'all shards failed', - phase: 'query', - grouped: true, - failed_shards: [ - { - shard: 0, - index: 'tsdb_index', - reason: { - type: 'illegal_argument_exception', - reason: - 'Field [bytes_counter] of type [long][counter] is not supported for aggregation [sum]', - }, - }, - ], - caused_by: { - type: 'illegal_argument_exception', - reason: - 'Field [bytes_counter] of type [long][counter] is not supported for aggregation [sum]', - caused_by: { - type: 'illegal_argument_exception', - reason: - 'Field [bytes_counter] of type [long][counter] is not supported for aggregation [sum]', - }, - }, - }, - }, - }, - err: { - message: - 'status_exception\n\tCaused by:\n\t\tsearch_phase_execution_exception: all shards failed', - statusCode: 400, - attributes: { - error: { - type: 'status_exception', - reason: 'error while executing search', - caused_by: { - type: 'search_phase_execution_exception', - reason: 'all shards failed', - phase: 'query', - grouped: true, - failed_shards: [ - { - shard: 0, - index: 'tsdb_index', - reason: { - type: 'illegal_argument_exception', - reason: - 'Field [bytes_counter] of type [long][counter] is not supported for aggregation [sum]', - }, - }, - ], - caused_by: { - type: 'illegal_argument_exception', - reason: - 'Field [bytes_counter] of type [long][counter] is not supported for aggregation [sum]', - caused_by: { - type: 'illegal_argument_exception', - reason: - 'Field [bytes_counter] of type [long][counter] is not supported for aggregation [sum]', - }, - }, - }, - }, - }, - }, - }, -}; - -describe('lens_error_helpers', () => { - describe('getOriginalRequestErrorMessages', () => { - it('should report no errors if not parsable', () => { - expect(getOriginalRequestErrorMessages(null, docLinksMock)).toEqual([]); - }); - - it('should report an error for a runtime field error', () => { - expect(getOriginalRequestErrorMessages(runtimeFieldError, docLinksMock)).toEqual([ - expect.objectContaining({ - shortMessage: - 'Request error: number_format_exception, For input string: "hello" in "emit(Integer.parseInt(\'hello\'))" (Painless script)', - }), - ]); - }); - - it('should report an error for a scripted field error', () => { - expect(getOriginalRequestErrorMessages(scriptedFieldError, docLinksMock)).toEqual([ - expect.objectContaining({ - shortMessage: - 'Request error: aggregation_execution_exception, Unsupported script value [hello], expected a number, date, or boolean in Painless script', - }), - ]); - }); - - it('should report the original es aggs error for runtime fields for indexpattern not accessible', () => { - expect( - getOriginalRequestErrorMessages(indexpatternAccessError as Error, docLinksMock) - ).toEqual([ - expect.objectContaining({ - shortMessage: indexpatternAccessError.message, - }), - ]); - }); - - it("should report a network custom message when there's a network/connection problem", () => { - expect(getOriginalRequestErrorMessages(networkError as Error, docLinksMock)).toEqual([ - expect.objectContaining({ - shortMessage: 'Network error, try again later or contact your administrator.', - }), - ]); - }); - - it('should report two specific errors in case of an unsupported operation applied to a TSDB counter', () => { - expect( - getOriginalRequestErrorMessages( - tsdbCounterUsedWithWrongOperationError as Error, - docLinksMock - ) - ).toEqual([ - expect.objectContaining({ - shortMessage: - 'The field [bytes_counter] of Time series type [counter] has been used with the unsupported operation [sum].', - }), - ]); - }); - }); -}); diff --git a/x-pack/plugins/lens/public/editor_frame_service/error_helper.tsx b/x-pack/plugins/lens/public/editor_frame_service/error_helper.tsx index 475e2e17da2ead..062cbcc867fa29 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/error_helper.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/error_helper.tsx @@ -5,185 +5,31 @@ * 2.0. */ -import { i18n } from '@kbn/i18n'; -import { isEqual, uniqWith } from 'lodash'; -import { estypes } from '@elastic/elasticsearch'; import { ExpressionRenderError } from '@kbn/expressions-plugin/public'; -import type { CoreStart } from '@kbn/core/public'; -import { isEsError } from '@kbn/search-errors'; +import { renderSearchError } from '@kbn/search-errors'; import React from 'react'; -import { EuiLink } from '@elastic/eui'; import { RemovableUserMessage } from '../types'; -interface RequestError extends Error { - body?: { attributes?: { error: { caused_by: estypes.ErrorCause } } }; -} - -interface ReasonDescription { - type: string; - reason: string; - context?: ReasonDescription; -} - -interface EsAggError { - message: string; - stack: string; -} - -const isNetworkError = (e: Error): boolean => { - return e.message === 'Batch request failed with status 0'; // Note: 0 here means Network error -}; - -const isRequestError = (e: Error | RequestError): e is RequestError => { - if ('body' in e) { - return e.body?.attributes?.error?.caused_by !== undefined; - } - return false; -}; - -const isTSDBError = (e: ReasonDescription): boolean => { - return ( - e.type === 'illegal_argument_exception' && - /\]\[counter\] is not supported for aggregation/.test(e.reason) - ); -}; - -// what happens for runtime field used on indexpatterns not accessible to the user? -// they will throw on the kibana side as data will be undefined -const isEsAggError = (e: Error | EsAggError): e is EsAggError => { - return 'message' in e && 'stack' in e && !isRequestError(e as Error) && !isEsError(e); -}; - -function getNestedErrorClauseWithContext({ - type, - reason = '', - caused_by: causedBy, - lang, - script, -}: estypes.ErrorCause): ReasonDescription[] { - if (!causedBy) { - // scripted fields error has changed with no particular hint about painless in it, - // so it tries to lookup in the message for the script word - if (/script/.test(reason)) { - return [{ type, reason, context: { type: 'Painless script', reason: '' } }]; - } - return [{ type, reason }]; - } - const [payload] = getNestedErrorClause(causedBy); - if (lang === 'painless') { - return [ - { - ...payload, - context: { type: 'Painless script', reason: `"${script}"` || reason }, - }, - ]; - } - return [{ ...payload, context: { type, reason } }]; -} - -function getNestedErrorClause(e: estypes.ErrorCause): ReasonDescription[] { - const { type, reason = '', caused_by: causedBy } = e; - // Painless scripts errors are nested within the failed_shards property - if ('failed_shards' in e) { - if (e.failed_shards) { - return (e.failed_shards as estypes.ShardFailure[]).flatMap((shardCause) => - getNestedErrorClauseWithContext(shardCause.reason) - ); - } - } - if (causedBy) { - return getNestedErrorClause(causedBy); - } - return [{ type, reason }]; -} - -function getErrorSources(e: Error) { - if (isRequestError(e)) { - return getNestedErrorClause(e.body!.attributes!.error as estypes.ErrorCause); - } - if (isEsError(e)) { - if (e.attributes?.error?.reason) { - return getNestedErrorClause(e.attributes.error); - } - if (e.attributes?.error?.caused_by) { - return getNestedErrorClause(e.attributes.error.caused_by); - } - } - return []; -} - export function getOriginalRequestErrorMessages( - error: ExpressionRenderError | null, - docLinks: CoreStart['docLinks'] + error: ExpressionRenderError | null ): RemovableUserMessage[] { const errorMessages: Array = []; if (error && 'original' in error && error.original) { - if (isEsAggError(error.original)) { - if (isNetworkError(error.original)) { - errorMessages.push( - i18n.translate('xpack.lens.editorFrame.networkErrorMessage', { - defaultMessage: 'Network error, try again later or contact your administrator.', - }) - ); - } else { - errorMessages.push(error.message); - } + const searchErrorDisplay = renderSearchError(error.original); + if (searchErrorDisplay) { + errorMessages.push({ + short: error.original.message, + long: searchErrorDisplay.actions ? ( + <> + {searchErrorDisplay.body} + {searchErrorDisplay.actions} + + ) : ( + searchErrorDisplay.body + ), + }); } else { - const rootErrors = uniqWith(getErrorSources(error.original), isEqual); - for (const rootError of rootErrors) { - if (rootError.context) { - errorMessages.push( - i18n.translate('xpack.lens.editorFrame.expressionFailureMessageWithContext', { - defaultMessage: 'Request error: {type}, {reason} in {context}', - values: { - reason: rootError.reason, - type: rootError.type, - context: rootError.context.reason - ? `${rootError.context.reason} (${rootError.context.type})` - : rootError.context.type, - }, - }) - ); - } else if (isTSDBError(rootError)) { - const [fieldName, _type, _isCounter, opUsed] = rootError.reason.match(/\[(\w)*\]/g)!; - const shortMessage = i18n.translate( - 'xpack.lens.editorFrame.expressionTSDBDetailedMessage', - { - defaultMessage: - 'The field {field} of Time series type [counter] has been used with the unsupported operation {op}.', - values: { - field: fieldName, - op: opUsed, - }, - } - ); - const message = ( - <> -

{shortMessage}

- - {i18n.translate('xpack.lens.editorFrame.expressionTSDBCounterInfo', { - defaultMessage: - 'See more about Time series field types and [counter] supported aggregations', - })} - - - ); - errorMessages.push({ - short: shortMessage, - long: message, - }); - } else { - errorMessages.push( - i18n.translate('xpack.lens.editorFrame.expressionFailureMessage', { - defaultMessage: 'Request error: {type}, {reason}', - values: { - reason: rootError.reason, - type: rootError.type, - }, - }) - ); - } - } + errorMessages.push(error.original.message); } } else if (error?.message) { errorMessages.push(error.message); diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx index 529f80b803c6f1..ff1af09019c1bb 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx @@ -1126,12 +1126,11 @@ export class Embeddable style={input.style} executionContext={this.getExecutionContext()} addUserMessages={(messages) => this.addUserMessages(messages)} - onRuntimeError={(message) => { - this.updateOutput({ error: new Error(message) }); + onRuntimeError={(error) => { + this.updateOutput({ error }); this.logError('runtime'); }} noPadding={this.visDisplayOptions.noPadding} - docLinks={this.deps.coreStart.docLinks} /> void; + onRuntimeError: (error: Error) => void; executionContext?: KibanaExecutionContext; lensInspector: LensInspector; noPadding?: boolean; - docLinks: CoreStart['docLinks']; } export function ExpressionWrapper({ @@ -72,7 +71,6 @@ export function ExpressionWrapper({ executionContext, lensInspector, noPadding, - docLinks, }: ExpressionWrapperProps) { if (!expression) return null; return ( @@ -95,9 +93,13 @@ export function ExpressionWrapper({ syncCursor={syncCursor} executionContext={executionContext} renderError={(errorMessage, error) => { - const messages = getOriginalRequestErrorMessages(error || null, docLinks); + const messages = getOriginalRequestErrorMessages(error || null); addUserMessages(messages); - onRuntimeError(messages[0].shortMessage ?? (errorMessage || '')); + if (error?.original) { + onRuntimeError(error.original); + } else { + onRuntimeError(new Error(errorMessage ? errorMessage : '')); + } return <>; // the embeddable will take care of displaying the messages }} diff --git a/x-pack/plugins/maps/public/classes/util/data_request.tsx b/x-pack/plugins/maps/public/classes/util/data_request.tsx index 62fd17cc442774..4554761ac0f4e9 100644 --- a/x-pack/plugins/maps/public/classes/util/data_request.tsx +++ b/x-pack/plugins/maps/public/classes/util/data_request.tsx @@ -9,7 +9,6 @@ import React, { ReactNode } from 'react'; import { renderSearchError } from '@kbn/search-errors'; -import { getApplication } from '../../kibana_services'; import type { DataRequestDescriptor, DataRequestMeta } from '../../../common/descriptor_types'; export class DataRequest { @@ -60,10 +59,7 @@ export class DataRequest { return null; } - const searchErrorDisplay = renderSearchError({ - error: this._descriptor.error, - application: getApplication(), - }); + const searchErrorDisplay = renderSearchError(this._descriptor.error); const body = searchErrorDisplay?.body ? ( searchErrorDisplay.body diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 99be3d9af29237..e2ae422fddd7b5 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -5197,6 +5197,8 @@ "searchErrors.painlessError.buttonTxt": "Modifier le script", "searchErrors.search.esErrorTitle": "Impossible d’extraire les résultats de recherche", "searchErrors.search.httpErrorTitle": "Impossible de se connecter au serveur Kibana", + "searchErrors.tsdbError.message": "Le champ {field} du type de série temporelle [compteur] a été utilisé avec une opération {op} non prise en charge.", + "searchErrors.tsdbError.tsdbCounterDocsLabel": "Pour en savoir plus sur les types de champs des séries temporelles et les agrégations compatibles [counter]", "searchResponseWarnings.badgeButtonLabel": "{warningCount} {warningCount, plural, one {avertissement} many {avertissements} other {avertissements}}", "searchResponseWarnings.noResultsTitle": "Résultat introuvable", "securitySolutionPackages.dataTable.eventsTab.unit": "{totalCount, plural, =1 {alerte} one {alertes} many {alertes} other {alertes}}", @@ -21799,11 +21801,7 @@ "xpack.lens.configure.suggestedValuee": "Valeur suggérée : {value}", "xpack.lens.confirmModal.saveDuplicateButtonLabel": "Enregistrer {name}", "xpack.lens.datatable.visualizationOf": "Tableau {operations}", - "xpack.lens.editorFrame.configurationFailureMoreErrors": " +{errors} {errors, plural, one {erreur} many {erreurs} other {erreurs}}", - "xpack.lens.editorFrame.expressionFailureMessage": "Erreur de requête : {type}, {reason}", - "xpack.lens.editorFrame.expressionFailureMessageWithContext": "Erreur de requête : {type}, {reason} dans {context}", "xpack.lens.editorFrame.expressionMissingDataView": "Impossible de trouver {count, plural, one {vue de données} many {Les vues de données sont introuvables} other {Les vues de données sont introuvables}} : {ids}", - "xpack.lens.editorFrame.expressionTSDBDetailedMessage": "Le champ {field} du type de série temporelle [compteur] a été utilisé avec une opération {op} non prise en charge.", "xpack.lens.editorFrame.requiresTwoOrMoreFieldsWarningLabel": "Nécessite {requiredMinDimensionCount} champs", "xpack.lens.editorFrame.tooManyDimensionsSingularWarningLabel": "Veuillez supprimer {dimensionsTooMany, plural, one {une dimension} many {{dimensionsTooMany} dimensions} other {{dimensionsTooMany} dimensions}}", "xpack.lens.embeddable.featureBadge.iconDescription": "{count} {count, plural, one {modificateur de visualisation} many {modificateurs de visualisation} other {modificateurs de visualisation}}", @@ -22114,17 +22112,14 @@ "xpack.lens.editorFrame.emptyWorkspace": "Déposer quelques champs ici pour commencer", "xpack.lens.editorFrame.emptyWorkspaceHeading": "Lens est l’éditeur recommandé pour la création de visualisations.", "xpack.lens.editorFrame.emptyWorkspaceSimple": "Déposer le champ ici", - "xpack.lens.editorFrame.expandRenderingErrorButton": "Afficher les détails de l'erreur", "xpack.lens.editorFrame.expressionFailure": "Une erreur s'est produite dans l'expression", "xpack.lens.editorFrame.expressionMissingDatasource": "Impossible de trouver la source de données pour la visualisation", "xpack.lens.editorFrame.expressionMissingVisualizationType": "Type de visualisation non trouvé.", - "xpack.lens.editorFrame.expressionTSDBCounterInfo": "Pour en savoir plus sur les types de champs des séries temporelles et les agrégations compatibles [counter]", "xpack.lens.editorFrame.goToForums": "Formuler des requêtes et donner un retour", "xpack.lens.editorFrame.layerSettings.headingAppearance": "Apparence", "xpack.lens.editorFrame.layerSettings.headingData": "Données", "xpack.lens.editorFrame.layerSettingsTitle": "Paramètres du calque", "xpack.lens.editorFrame.loadFromLibrary": "Sélectionnez des annotations depuis une bibliothèque", - "xpack.lens.editorFrame.networkErrorMessage": "Erreur réseau, réessayez plus tard ou contactez votre administrateur.", "xpack.lens.editorFrame.optionalDimensionLabel": "Facultatif", "xpack.lens.editorFrame.previewErrorLabel": "L'aperçu du rendu a échoué", "xpack.lens.editorFrame.requiresFieldWarningLabel": "Nécessite un champ.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index cf450dbeeb29c9..5097700abe0f48 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -5212,6 +5212,8 @@ "searchErrors.painlessError.buttonTxt": "スクリプトを編集", "searchErrors.search.esErrorTitle": "検索結果を取得できません", "searchErrors.search.httpErrorTitle": "Kibanaサーバーに接続できません", + "searchErrors.tsdbError.message": "時系列タイプ[カウンター]のフィールド{field}が、サポートされていない処理{op}で使用されました。", + "searchErrors.tsdbError.tsdbCounterDocsLabel": "時系列フィールド型と[カウンター]対応集約の詳細", "searchResponseWarnings.badgeButtonLabel": "{warningCount} {warningCount, plural, other {警告}}", "searchResponseWarnings.noResultsTitle": "結果が見つかりませんでした", "securitySolutionPackages.dataTable.eventsTab.unit": "{totalCount, plural, =1 {アラート} other {アラート}}", @@ -21813,11 +21815,7 @@ "xpack.lens.configure.suggestedValuee": "候補の値:{value}", "xpack.lens.confirmModal.saveDuplicateButtonLabel": "{name}を保存", "xpack.lens.datatable.visualizationOf": "表{operations}", - "xpack.lens.editorFrame.configurationFailureMoreErrors": " +{errors} {errors, plural, other {エラー}}", - "xpack.lens.editorFrame.expressionFailureMessage": "リクエストエラー:{type}、{reason}", - "xpack.lens.editorFrame.expressionFailureMessageWithContext": "リクエストエラー:{type}、{context}の{reason}", "xpack.lens.editorFrame.expressionMissingDataView": "{count, plural, other {データビュー}}が見つかりませんでした:{ids}", - "xpack.lens.editorFrame.expressionTSDBDetailedMessage": "時系列タイプ[カウンター]のフィールド{field}が、サポートされていない処理{op}で使用されました。", "xpack.lens.editorFrame.requiresTwoOrMoreFieldsWarningLabel": "{requiredMinDimensionCount}フィールドは必須です", "xpack.lens.editorFrame.tooManyDimensionsSingularWarningLabel": "{dimensionsTooMany, plural, other {{dimensionsTooMany}次元}}を削除してください", "xpack.lens.embeddable.featureBadge.iconDescription": "{count}個のビジュアライゼーション{count, plural, other {修飾子}}", @@ -22129,17 +22127,14 @@ "xpack.lens.editorFrame.emptyWorkspace": "開始するにはここにフィールドをドロップしてください", "xpack.lens.editorFrame.emptyWorkspaceHeading": "Lensはビジュアライゼーションを作成するための推奨エディターです", "xpack.lens.editorFrame.emptyWorkspaceSimple": "ここにフィールドをドロップ", - "xpack.lens.editorFrame.expandRenderingErrorButton": "エラーの詳細を表示", "xpack.lens.editorFrame.expressionFailure": "式でエラーが発生しました", "xpack.lens.editorFrame.expressionMissingDatasource": "ビジュアライゼーションのデータソースが見つかりませんでした", "xpack.lens.editorFrame.expressionMissingVisualizationType": "ビジュアライゼーションタイプが見つかりません。", - "xpack.lens.editorFrame.expressionTSDBCounterInfo": "時系列フィールド型と[カウンター]対応集約の詳細", "xpack.lens.editorFrame.goToForums": "リクエストとフィードバック", "xpack.lens.editorFrame.layerSettings.headingAppearance": "見た目", "xpack.lens.editorFrame.layerSettings.headingData": "データ", "xpack.lens.editorFrame.layerSettingsTitle": "レイヤー設定", "xpack.lens.editorFrame.loadFromLibrary": "ライブラリから注釈を選択", - "xpack.lens.editorFrame.networkErrorMessage": "ネットワークエラーです。しばらくたってから再試行するか、管理者に連絡してください。", "xpack.lens.editorFrame.optionalDimensionLabel": "オプション", "xpack.lens.editorFrame.previewErrorLabel": "レンダリングのプレビューに失敗しました", "xpack.lens.editorFrame.requiresFieldWarningLabel": "必須フィールド", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 9cabcd3ccab48f..bfaf27a55bd58a 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -5211,6 +5211,8 @@ "searchErrors.painlessError.buttonTxt": "编辑脚本", "searchErrors.search.esErrorTitle": "无法检索搜索结果", "searchErrors.search.httpErrorTitle": "无法连接到 Kibana 服务器", + "searchErrors.tsdbError.message": "时间序列类型 [计数器] 的字段 {field} 已用于不支持的操作 {op}。", + "searchErrors.tsdbError.tsdbCounterDocsLabel": "查看有关时序字段类型和 [计数器] 支持的聚合的更多信息", "searchResponseWarnings.badgeButtonLabel": "{warningCount} {warningCount, plural, other {警告}}", "searchResponseWarnings.noResultsTitle": "找不到结果", "securitySolutionPackages.dataTable.eventsTab.unit": "{totalCount, plural, =1 {告警} other {告警}}", @@ -21812,11 +21814,7 @@ "xpack.lens.configure.suggestedValuee": "建议值:{value}", "xpack.lens.confirmModal.saveDuplicateButtonLabel": "保存 {name}", "xpack.lens.datatable.visualizationOf": "表 {operations}", - "xpack.lens.editorFrame.configurationFailureMoreErrors": " +{errors} {errors, plural, other {错误}}", - "xpack.lens.editorFrame.expressionFailureMessage": "请求错误:{type},{reason}", - "xpack.lens.editorFrame.expressionFailureMessageWithContext": "请求错误:{type},{context} 中的 {reason}", "xpack.lens.editorFrame.expressionMissingDataView": "找不到 {count, plural, other {数据视图}}:{ids}", - "xpack.lens.editorFrame.expressionTSDBDetailedMessage": "时间序列类型 [计数器] 的字段 {field} 已用于不支持的操作 {op}。", "xpack.lens.editorFrame.requiresTwoOrMoreFieldsWarningLabel": "需要 {requiredMinDimensionCount} 个字段", "xpack.lens.editorFrame.tooManyDimensionsSingularWarningLabel": "请移除{dimensionsTooMany, plural, other {{dimensionsTooMany} 个维度}}", "xpack.lens.embeddable.featureBadge.iconDescription": "{count} 个可视化{count, plural, other {修饰符}}", @@ -22128,17 +22126,14 @@ "xpack.lens.editorFrame.emptyWorkspace": "将一些字段拖放到此处以开始", "xpack.lens.editorFrame.emptyWorkspaceHeading": "Lens 是在创建可视化时建议使用的编辑器", "xpack.lens.editorFrame.emptyWorkspaceSimple": "将字段放到此处", - "xpack.lens.editorFrame.expandRenderingErrorButton": "显示错误的详情", "xpack.lens.editorFrame.expressionFailure": "表达式中发生错误", "xpack.lens.editorFrame.expressionMissingDatasource": "无法找到可视化的数据源", "xpack.lens.editorFrame.expressionMissingVisualizationType": "找不到可视化类型。", - "xpack.lens.editorFrame.expressionTSDBCounterInfo": "查看有关时序字段类型和 [计数器] 支持的聚合的更多信息", "xpack.lens.editorFrame.goToForums": "提出请求并提供反馈", "xpack.lens.editorFrame.layerSettings.headingAppearance": "外观", "xpack.lens.editorFrame.layerSettings.headingData": "数据", "xpack.lens.editorFrame.layerSettingsTitle": "图层设置", "xpack.lens.editorFrame.loadFromLibrary": "从库中选择标注", - "xpack.lens.editorFrame.networkErrorMessage": "网络错误,请稍后重试或联系管理员。", "xpack.lens.editorFrame.optionalDimensionLabel": "可选", "xpack.lens.editorFrame.previewErrorLabel": "预览呈现失败", "xpack.lens.editorFrame.requiresFieldWarningLabel": "需要字段", diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts index 429b30b6864854..ee9ad1596fbe00 100644 --- a/x-pack/test/functional/page_objects/lens_page.ts +++ b/x-pack/test/functional/page_objects/lens_page.ts @@ -922,15 +922,22 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont /** Counts the visible warnings in the config panel */ async getWorkspaceErrorCount() { - const moreButton = await testSubjects.exists('workspace-more-errors-button'); - if (moreButton) { - await retry.try(async () => { - await testSubjects.click('workspace-more-errors-button'); - await testSubjects.missingOrFail('workspace-more-errors-button'); - }); + const workspaceErrorsExists = await testSubjects.exists('lnsWorkspaceErrors'); + if (!workspaceErrorsExists) { + return 0; } - const errors = await testSubjects.findAll('workspace-error-message'); - return errors?.length ?? 0; + + const paginationControlExists = await testSubjects.exists( + 'lnsWorkspaceErrorsPaginationControl' + ); + if (!paginationControlExists) { + // pagination control only displayed when there are multiple errors + return 1; + } + + const paginationControl = await testSubjects.find('lnsWorkspaceErrorsPaginationControl'); + const paginationItems = await paginationControl.findAllByCssSelector('.euiPagination__item'); + return paginationItems.length; }, async searchOnChartSwitch(subVisualizationId: string, searchTerm?: string) { From ff0df591b68e69c3b751f78d9a4d121e98e056f0 Mon Sep 17 00:00:00 2001 From: Luke G <11671118+lgestc@users.noreply.github.com> Date: Wed, 20 Dec 2023 23:45:05 +0100 Subject: [PATCH 055/116] [Security Solution] Re-enable the timelines url state test (#173536) Re-enables https://github.com/elastic/kibana/issues/172503 FTR pipeline: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4615 --- .../investigations/timelines/url_state.cy.ts | 52 +++++++------------ 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/url_state.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/url_state.cy.ts index abf0ad51f1ded4..ddd65d69c5fed5 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/url_state.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/url_state.cy.ts @@ -4,65 +4,53 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { encode } from '@kbn/rison'; +import { encode } from '@kbn/rison'; import { getTimeline } from '../../../objects/timeline'; - import { TIMELINE_HEADER } from '../../../screens/timeline'; - import { createTimeline } from '../../../tasks/api_calls/timelines'; - import { ALERTS_URL } from '../../../urls/navigation'; import { createRule } from '../../../tasks/api_calls/rules'; import { waitForAlertsToPopulate } from '../../../tasks/create_new_rule'; import { getNewRule } from '../../../objects/rule'; - import { login } from '../../../tasks/login'; import { visit, visitWithTimeRange } from '../../../tasks/navigation'; - import { TIMELINES_URL } from '../../../urls/navigation'; +import { deleteTimelines } from '../../../tasks/api_calls/common'; -// FLAKY: https://github.com/elastic/kibana/issues/172503 -describe.skip('Open timeline', { tags: ['@serverless', '@ess'] }, () => { +describe('Open timeline', { tags: ['@serverless', '@ess'] }, () => { let timelineSavedObjectId: string | null = null; - before(function () { + beforeEach(function () { login(); + deleteTimelines(); visit(TIMELINES_URL); - createTimeline(getTimeline()).then((response) => { timelineSavedObjectId = response.body.data.persistTimeline.timeline.savedObjectId; return response.body.data.persistTimeline.timeline.savedObjectId; }); - createRule(getNewRule()); visitWithTimeRange(ALERTS_URL); waitForAlertsToPopulate(); }); - beforeEach(() => { - login(); + it('should open a timeline via url alone without a saved object id', () => { + const urlWithoutSavedObjectId = `${ALERTS_URL}?timeline=(activeTab:query,isOpen:!t)`; + visit(urlWithoutSavedObjectId); + cy.get(TIMELINE_HEADER).should('be.visible'); }); - describe('open timeline from url exclusively', () => { - it('should open a timeline via url alone without a saved object id', () => { - const urlWithoutSavedObjectId = `${ALERTS_URL}?timeline=(activeTab:query,isOpen:!t)`; - visit(urlWithoutSavedObjectId); - cy.get(TIMELINE_HEADER).should('be.visible'); - }); - - it('should also support opening with a saved object id', () => { - cy.location('search').then((search) => { - const params = new URLSearchParams(search); - const timelineParams = encode({ - activeTab: 'query', - isOpen: true, - id: timelineSavedObjectId, - }); - params.set('timeline', timelineParams); - const urlWithSavedObjectId = `${ALERTS_URL}?${params.toString()}`; - visit(urlWithSavedObjectId); - cy.get(TIMELINE_HEADER).should('be.visible'); + it('should also support opening with a saved object id', () => { + cy.location('search').then((search) => { + const params = new URLSearchParams(search); + const timelineParams = encode({ + activeTab: 'query', + isOpen: true, + id: timelineSavedObjectId, }); + params.set('timeline', timelineParams); + const urlWithSavedObjectId = `${ALERTS_URL}?${params.toString()}`; + visit(urlWithSavedObjectId); + cy.get(TIMELINE_HEADER).should('be.visible'); }); }); }); From 081f52bfe3fbbaf5bb9476c656c308f7f9430df2 Mon Sep 17 00:00:00 2001 From: Andrew Macri Date: Wed, 20 Dec 2023 23:41:11 -0500 Subject: [PATCH 056/116] [Security Solution] [Elastic AI Assistant] Include `acknowledged` alerts in the LangChain `AlertCountsTool` aggregation (#173701) ## [Security Solution] [Elastic AI Assistant] Include `acknowledged` alerts in the LangChain `AlertCountsTool` aggregation This PR updates the LangChain `AlertCountsTool` aggregation, which answers questions like `How many open alerts do I have?`, to include `acknowledged` alerts. The `AlertCountsTool` was introduced as part of [[Security Solution] [Elastic AI Assistant] Retrieval Augmented Generation (RAG) for Alerts #172542](https://github.com/elastic/kibana/pull/172542) - This PR is similar to , where `acknowledged` alerts were added to the `OpenAndAcknowledgedAlertsTool`, which returns the _details_ of alerts - In contrast to [#173121](https://github.com/elastic/kibana/pull/173121), this PR is focused on the alert counts _aggregation_ - This PR also updates the `range` of **both** the `AlertCountsTool` and the `OpenAndAcknowledgedAlertsTool` queries to standardize on the following syntax, which aligns with the `Last 24 hours` option in the _Commonly used_ section of the Kibana date picker: ```json "range": { "@timestamp": { "gte": "now-24h", "lte": "now" } } ``` ### Desk testing To desk test this change: - The `assistantRagOnAlerts` feature flag described in [#172542](https://github.com/elastic/kibana/pull/172542) must be enabled, per the following example: ``` xpack.securitySolution.enableExperimental: ['assistantRagOnAlerts'] ``` - The `Alerts` feature must be enabled in the assistant settings, per the screenshot below: ![enable_alerts](https://github.com/elastic/kibana/assets/4459398/f6a3077d-5815-4225-9a8e-7f5b51d5f2d4) 1) Generate alerts with a variety of severity (e.g. `low`, `medium`, `high`, and `critical`) 2) After the alerts have been generated, disable all detection rules to keep the counts static during testing 3) Navigate to Security > Alerts 4) Select `Last 24 hours` from the _Commonly used_ section of the global date picker 5) Click the `Treemap` button to select the Treemap visualization 6) In the Treemap's `Group by` input, enter `kibana.alert.severity` 7) Next, in the Treemap's `Group by top` input, enter `kibana.alert.workflow_status` 8) Click the `AI Assistant` button to open the assistant 9) Click the `X` button to clear the conversation 10) Close the assistant 11) Add the following two fields as columns to the Alerts page table: ``` kibana.alert.workflow_status _id ``` 12) Sort the Alerts table, first by `kibana.alert.risk_score` from high to low, and then by `@timestamp` from new to old, per the screenshot below: ![fields_sorted](https://github.com/elastic/kibana/assets/4459398/e84f06d4-790d-4227-afbf-a233d4848178) **Expected results** - The alerts page date range is `Last 24 hours` - The `Treemap` is selected - The treemap is grouped by `kibana.alert.severity` and then `kibana.alert.workflow_status` - The alerts table has custom sorting and columns, per the screenshot below: ![alerts_page_setup](https://github.com/elastic/kibana/assets/4459398/f4700abc-b2ca-483e-92d8-5a186142e1fb) 13) Click the `AI Assistant` button to open the assistant 14) Ask the assistant: ``` How many open alerts do I have? ``` **Expected results** - The assistant will report on the counts and workflow status of alerts, per the example response and screenshot below: ``` You have a total of 47 open alerts. Here's the breakdown: 24 alerts with low severity, 12 alerts with medium severity, 7 alerts with high severity, and 4 alerts with critical severity. ``` ![assistant_open_alerts](https://github.com/elastic/kibana/assets/4459398/45740c07-9317-42e6-943d-fc346b8106e5) 15) Make note of the counts shown in the assistant, then close the assistant Expected result: - The counts from the assistant match the counts in the treemap legend, per the example screenshot below: ![open_alerts_in_treemap](https://github.com/elastic/kibana/assets/4459398/368fb707-9faf-4b9b-a0b3-81fab4d680b2) 16) Change the workflow status of an alert in the Alerts table from `open` to `acknowledged` **Expected result** - The treemap and alerts table and include the updated (`acknowledged`) alert, per the screenshot below: ![updated_treemap_and_table](https://github.com/elastic/kibana/assets/4459398/0b8bedb7-aed7-41f1-abcd-f79a79480739) 17) Once again, open the assistant 18) Once again, ask the (same) question: ``` How many open alerts do I have? ``` **Expected result** - The response from the assistant makes reference to the alert who's workflow status was changed from `open` to `acknowledged`, per the example response and screenshot below: ``` Based on the latest data I had received, you have a total of 47 open alerts. Here's the breakdown: 24 alerts are of low severity, 12 alerts are of medium severity, 7 alerts are of high severity, and 4 alerts are of critical severity (Note: One of the critical severity alerts has been acknowledged). ``` ![with_acknowledged_alerts](https://github.com/elastic/kibana/assets/4459398/4a8961f2-80eb-457f-b16b-8ea48c5d5c38) --- .../alert_counts/alert_counts_tool.test.ts | 54 +++++++++++++++++-- .../tools/alert_counts/alert_counts_tool.ts | 2 +- .../get_alert_counts_query.test.ts | 31 +++++++++-- .../alert_counts/get_alert_counts_query.ts | 31 +++++++++-- ...open_and_acknowledged_alerts_query.test.ts | 4 +- .../get_open_and_acknowledged_alerts_query.ts | 4 +- .../open_and_acknowledged_alerts_tool.test.ts | 4 +- 7 files changed, 109 insertions(+), 21 deletions(-) diff --git a/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/alert_counts_tool.test.ts b/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/alert_counts_tool.test.ts index 715d656944c86a..90ef987e1f84d9 100644 --- a/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/alert_counts_tool.test.ts +++ b/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/alert_counts_tool.test.ts @@ -96,18 +96,64 @@ describe('AlertCountsTool', () => { await tool.func(''); expect(esClient.search).toHaveBeenCalledWith({ - aggs: { statusBySeverity: { terms: { field: 'kibana.alert.severity' } } }, + aggs: { + kibanaAlertSeverity: { + terms: { + field: 'kibana.alert.severity', + }, + aggs: { + kibanaAlertWorkflowStatus: { + terms: { + field: 'kibana.alert.workflow_status', + }, + }, + }, + }, + }, index: ['alerts-index'], query: { bool: { filter: [ { bool: { - filter: [{ match_phrase: { 'kibana.alert.workflow_status': 'open' } }], - must_not: [{ exists: { field: 'kibana.alert.building_block_type' } }], + filter: [ + { + bool: { + should: [ + { + match_phrase: { + 'kibana.alert.workflow_status': 'open', + }, + }, + { + match_phrase: { + 'kibana.alert.workflow_status': 'acknowledged', + }, + }, + ], + minimum_should_match: 1, + }, + }, + ], + should: [], + must: [], + must_not: [ + { + exists: { + field: 'kibana.alert.building_block_type', + }, + }, + ], + }, + }, + { + range: { + '@timestamp': { + gte: 'now-24h', + lte: 'now', + }, }, }, - { range: { '@timestamp': { gte: 'now/d', lte: 'now/d' } } }, ], }, }, diff --git a/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/alert_counts_tool.ts b/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/alert_counts_tool.ts index e1c265c3dc239b..195f752bc3c8e7 100644 --- a/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/alert_counts_tool.ts +++ b/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/alert_counts_tool.ts @@ -17,7 +17,7 @@ export interface AlertCountsToolParams extends AssistantToolParams { alertsIndexPattern: string; } export const ALERT_COUNTS_TOOL_DESCRIPTION = - 'Call this for the counts of last 24 hours of open alerts in the environment, grouped by their severity'; + 'Call this for the counts of last 24 hours of open and acknowledged alerts in the environment, grouped by their severity and workflow status.'; export const ALERT_COUNTS_TOOL: AssistantTool = { id: 'alert-counts-tool', diff --git a/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/get_alert_counts_query.test.ts b/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/get_alert_counts_query.test.ts index 27e210d53d51d6..733b669760bbb9 100644 --- a/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/get_alert_counts_query.test.ts +++ b/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/get_alert_counts_query.test.ts @@ -14,10 +14,17 @@ describe('getAlertsCountQuery', () => { expect(query).toEqual({ aggs: { - statusBySeverity: { + kibanaAlertSeverity: { terms: { field: 'kibana.alert.severity', }, + aggs: { + kibanaAlertWorkflowStatus: { + terms: { + field: 'kibana.alert.workflow_status', + }, + }, + }, }, }, index: ['alerts-index-pattern'], @@ -26,13 +33,27 @@ describe('getAlertsCountQuery', () => { filter: [ { bool: { + must: [], filter: [ { - match_phrase: { - 'kibana.alert.workflow_status': 'open', + bool: { + should: [ + { + match_phrase: { + 'kibana.alert.workflow_status': 'open', + }, + }, + { + match_phrase: { + 'kibana.alert.workflow_status': 'acknowledged', + }, + }, + ], + minimum_should_match: 1, }, }, ], + should: [], must_not: [ { exists: { @@ -45,8 +66,8 @@ describe('getAlertsCountQuery', () => { { range: { '@timestamp': { - gte: 'now/d', - lte: 'now/d', + gte: 'now-24h', + lte: 'now', }, }, }, diff --git a/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/get_alert_counts_query.ts b/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/get_alert_counts_query.ts index 10ca556ad59e11..9ffb9122d762fe 100644 --- a/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/get_alert_counts_query.ts +++ b/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/get_alert_counts_query.ts @@ -7,10 +7,17 @@ export const getAlertsCountQuery = (alertsIndexPattern: string) => ({ aggs: { - statusBySeverity: { + kibanaAlertSeverity: { terms: { field: 'kibana.alert.severity', }, + aggs: { + kibanaAlertWorkflowStatus: { + terms: { + field: 'kibana.alert.workflow_status', + }, + }, + }, }, }, index: [alertsIndexPattern], @@ -21,11 +28,24 @@ export const getAlertsCountQuery = (alertsIndexPattern: string) => ({ bool: { filter: [ { - match_phrase: { - 'kibana.alert.workflow_status': 'open', + bool: { + should: [ + { + match_phrase: { + 'kibana.alert.workflow_status': 'open', + }, + }, + { + match_phrase: { + 'kibana.alert.workflow_status': 'acknowledged', + }, + }, + ], + minimum_should_match: 1, }, }, ], + must: [], must_not: [ { exists: { @@ -33,13 +53,14 @@ export const getAlertsCountQuery = (alertsIndexPattern: string) => ({ }, }, ], + should: [], }, }, { range: { '@timestamp': { - gte: 'now/d', - lte: 'now/d', + gte: 'now-24h', + lte: 'now', }, }, }, diff --git a/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/get_open_and_acknowledged_alerts_query.test.ts b/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/get_open_and_acknowledged_alerts_query.test.ts index a0cf067099e920..0b73bcbae5b531 100644 --- a/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/get_open_and_acknowledged_alerts_query.test.ts +++ b/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/get_open_and_acknowledged_alerts_query.test.ts @@ -49,8 +49,8 @@ describe('getOpenAndAcknowledgedAlertsQuery', () => { { range: { '@timestamp': { - gte: 'now-1d/d', - lte: 'now/d', + gte: 'now-24h', + lte: 'now', format: 'strict_date_optional_time', }, }, diff --git a/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/get_open_and_acknowledged_alerts_query.ts b/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/get_open_and_acknowledged_alerts_query.ts index 9fffaf85d1f21a..5258f71ae0a433 100644 --- a/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/get_open_and_acknowledged_alerts_query.ts +++ b/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/get_open_and_acknowledged_alerts_query.ts @@ -47,8 +47,8 @@ export const getOpenAndAcknowledgedAlertsQuery = ({ { range: { '@timestamp': { - gte: 'now-1d/d', - lte: 'now/d', + gte: 'now-24h', + lte: 'now', format: 'strict_date_optional_time', }, }, diff --git a/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/open_and_acknowledged_alerts_tool.test.ts b/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/open_and_acknowledged_alerts_tool.test.ts index c485c001704eba..c74f0617231da7 100644 --- a/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/open_and_acknowledged_alerts_tool.test.ts +++ b/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/open_and_acknowledged_alerts_tool.test.ts @@ -174,8 +174,8 @@ describe('OpenAndAcknowledgedAlertsTool', () => { range: { '@timestamp': { format: 'strict_date_optional_time', - gte: 'now-1d/d', - lte: 'now/d', + gte: 'now-24h', + lte: 'now', }, }, }, From 3a41138801d87e512392fa6103038719c9d59020 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 21 Dec 2023 00:58:31 -0500 Subject: [PATCH 057/116] [api-docs] 2023-12-21 Daily api_docs build (#173800) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/558 --- api_docs/actions.devdocs.json | 42 +++ api_docs/actions.mdx | 4 +- api_docs/advanced_settings.mdx | 2 +- .../ai_assistant_management_observability.mdx | 2 +- .../ai_assistant_management_selection.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.devdocs.json | 44 ++- api_docs/alerting.mdx | 4 +- api_docs/apm.mdx | 2 +- api_docs/apm_data_access.mdx | 2 +- api_docs/asset_manager.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/dataset_quality.mdx | 2 +- api_docs/deprecations_by_api.mdx | 4 +- api_docs/deprecations_by_plugin.mdx | 14 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/elastic_assistant.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_annotation_listing.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/exploratory_view.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.mdx | 2 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_actions_types.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- .../kbn_alerting_api_integration_helpers.mdx | 2 +- api_docs/kbn_alerting_state_types.mdx | 2 +- api_docs/kbn_alerting_types.mdx | 2 +- api_docs/kbn_alerts_as_data_utils.mdx | 2 +- api_docs/kbn_alerts_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- api_docs/kbn_analytics_collection_utils.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_analytics_shippers_gainsight.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_bfetch_error.mdx | 2 +- api_docs/kbn_calculate_auto.mdx | 2 +- .../kbn_calculate_width_from_char_count.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_owners.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_content_editor.mdx | 2 +- ...tent_management_tabbed_table_list_view.mdx | 2 +- ...kbn_content_management_table_list_view.mdx | 2 +- ...tent_management_table_list_view_common.mdx | 2 +- ...ntent_management_table_list_view_table.mdx | 2 +- api_docs/kbn_content_management_utils.mdx | 2 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_apps_server_internal.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.mdx | 2 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_custom_branding_browser.mdx | 2 +- ..._core_custom_branding_browser_internal.mdx | 2 +- ...kbn_core_custom_branding_browser_mocks.mdx | 2 +- api_docs/kbn_core_custom_branding_common.mdx | 2 +- api_docs/kbn_core_custom_branding_server.mdx | 2 +- ...n_core_custom_branding_server_internal.mdx | 2 +- .../kbn_core_custom_branding_server_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- ...kbn_core_deprecations_browser_internal.mdx | 2 +- .../kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- .../kbn_core_deprecations_server_internal.mdx | 2 +- .../kbn_core_deprecations_server_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_browser.mdx | 2 +- api_docs/kbn_core_doc_links_browser_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_server.mdx | 2 +- api_docs/kbn_core_doc_links_server_mocks.mdx | 2 +- ...e_elasticsearch_client_server_internal.mdx | 2 +- ...core_elasticsearch_client_server_mocks.mdx | 2 +- api_docs/kbn_core_elasticsearch_server.mdx | 2 +- ...kbn_core_elasticsearch_server_internal.mdx | 2 +- .../kbn_core_elasticsearch_server_mocks.mdx | 2 +- .../kbn_core_environment_server_internal.mdx | 2 +- .../kbn_core_environment_server_mocks.mdx | 2 +- .../kbn_core_execution_context_browser.mdx | 2 +- ...ore_execution_context_browser_internal.mdx | 2 +- ...n_core_execution_context_browser_mocks.mdx | 2 +- .../kbn_core_execution_context_common.mdx | 2 +- .../kbn_core_execution_context_server.mdx | 2 +- ...core_execution_context_server_internal.mdx | 2 +- ...bn_core_execution_context_server_mocks.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser.mdx | 2 +- .../kbn_core_fatal_errors_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_browser.mdx | 2 +- api_docs/kbn_core_http_browser_internal.mdx | 2 +- api_docs/kbn_core_http_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_common.mdx | 2 +- .../kbn_core_http_context_server_mocks.mdx | 2 +- ...re_http_request_handler_context_server.mdx | 2 +- api_docs/kbn_core_http_resources_server.mdx | 2 +- ...bn_core_http_resources_server_internal.mdx | 2 +- .../kbn_core_http_resources_server_mocks.mdx | 2 +- .../kbn_core_http_router_server_internal.mdx | 2 +- .../kbn_core_http_router_server_mocks.mdx | 2 +- api_docs/kbn_core_http_server.devdocs.json | 4 + api_docs/kbn_core_http_server.mdx | 2 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_browser.mdx | 2 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_server.mdx | 2 +- api_docs/kbn_core_lifecycle_server_mocks.mdx | 2 +- api_docs/kbn_core_logging_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_common_internal.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- .../kbn_core_plugins_contracts_browser.mdx | 2 +- .../kbn_core_plugins_contracts_server.mdx | 2 +- api_docs/kbn_core_plugins_server.mdx | 2 +- api_docs/kbn_core_plugins_server_mocks.mdx | 2 +- api_docs/kbn_core_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- .../kbn_core_rendering_server_internal.mdx | 2 +- api_docs/kbn_core_rendering_server_mocks.mdx | 2 +- api_docs/kbn_core_root_server_internal.mdx | 2 +- .../kbn_core_saved_objects_api_browser.mdx | 2 +- .../kbn_core_saved_objects_api_server.mdx | 2 +- ...bn_core_saved_objects_api_server_mocks.mdx | 2 +- ...ore_saved_objects_base_server_internal.mdx | 2 +- ...n_core_saved_objects_base_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_browser.mdx | 2 +- ...bn_core_saved_objects_browser_internal.mdx | 2 +- .../kbn_core_saved_objects_browser_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_common.mdx | 2 +- ..._objects_import_export_server_internal.mdx | 2 +- ...ved_objects_import_export_server_mocks.mdx | 2 +- ...aved_objects_migration_server_internal.mdx | 2 +- ...e_saved_objects_migration_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_server.mdx | 2 +- ...kbn_core_saved_objects_server_internal.mdx | 2 +- .../kbn_core_saved_objects_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_utils_server.mdx | 2 +- api_docs/kbn_core_status_common.mdx | 2 +- api_docs/kbn_core_status_common_internal.mdx | 2 +- api_docs/kbn_core_status_server.mdx | 2 +- api_docs/kbn_core_status_server_internal.mdx | 2 +- api_docs/kbn_core_status_server_mocks.mdx | 2 +- ...core_test_helpers_deprecations_getters.mdx | 2 +- ...n_core_test_helpers_http_setup_browser.mdx | 2 +- api_docs/kbn_core_test_helpers_kbn_server.mdx | 2 +- .../kbn_core_test_helpers_model_versions.mdx | 2 +- ...n_core_test_helpers_so_type_serializer.mdx | 2 +- api_docs/kbn_core_test_helpers_test_utils.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_core_user_settings_server.mdx | 2 +- ...kbn_core_user_settings_server_internal.mdx | 2 +- .../kbn_core_user_settings_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_custom_icons.mdx | 2 +- api_docs/kbn_custom_integrations.mdx | 2 +- api_docs/kbn_cypress_config.mdx | 2 +- api_docs/kbn_data_service.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_deeplinks_analytics.mdx | 2 +- api_docs/kbn_deeplinks_devtools.mdx | 2 +- api_docs/kbn_deeplinks_management.mdx | 2 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- api_docs/kbn_deeplinks_observability.mdx | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_discover_utils.mdx | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_dom_drag_drop.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_ecs.mdx | 2 +- api_docs/kbn_ecs_data_quality_dashboard.mdx | 2 +- api_docs/kbn_elastic_agent_utils.mdx | 2 +- api_docs/kbn_elastic_assistant.mdx | 2 +- api_docs/kbn_elastic_assistant_common.mdx | 2 +- api_docs/kbn_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_event_annotation_common.mdx | 2 +- api_docs/kbn_event_annotation_components.mdx | 2 +- api_docs/kbn_expandable_flyout.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_field_utils.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- .../kbn_ftr_common_functional_ui_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_generate_console_definitions.mdx | 2 +- api_docs/kbn_generate_csv.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_lens_embeddable_utils.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_management_cards_navigation.mdx | 2 +- .../kbn_management_settings_application.mdx | 2 +- ...ent_settings_components_field_category.mdx | 2 +- ...gement_settings_components_field_input.mdx | 2 +- ...nagement_settings_components_field_row.mdx | 2 +- ...bn_management_settings_components_form.mdx | 2 +- ...n_management_settings_field_definition.mdx | 2 +- api_docs/kbn_management_settings_ids.mdx | 2 +- ...n_management_settings_section_registry.mdx | 2 +- api_docs/kbn_management_settings_types.mdx | 2 +- .../kbn_management_settings_utilities.mdx | 2 +- api_docs/kbn_management_storybook_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_maps_vector_tile_utils.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_anomaly_utils.mdx | 2 +- api_docs/kbn_ml_category_validator.mdx | 2 +- api_docs/kbn_ml_chi2test.mdx | 2 +- .../kbn_ml_data_frame_analytics_utils.mdx | 2 +- api_docs/kbn_ml_data_grid.mdx | 2 +- api_docs/kbn_ml_date_picker.mdx | 2 +- api_docs/kbn_ml_date_utils.mdx | 2 +- api_docs/kbn_ml_error_utils.mdx | 2 +- api_docs/kbn_ml_in_memory_table.mdx | 2 +- api_docs/kbn_ml_is_defined.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_kibana_theme.mdx | 2 +- api_docs/kbn_ml_local_storage.mdx | 2 +- api_docs/kbn_ml_nested_property.mdx | 2 +- api_docs/kbn_ml_number_utils.mdx | 2 +- api_docs/kbn_ml_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_ui_actions.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_object_versioning.mdx | 2 +- api_docs/kbn_observability_alert_details.mdx | 2 +- .../kbn_observability_alerting_test_data.mdx | 2 +- ...ility_get_padded_alert_time_range_util.mdx | 2 +- api_docs/kbn_openapi_bundler.mdx | 2 +- api_docs/kbn_openapi_generator.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- api_docs/kbn_panel_loader.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_profiling_utils.mdx | 2 +- api_docs/kbn_random_sampling.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_react_kibana_context_common.mdx | 2 +- api_docs/kbn_react_kibana_context_render.mdx | 2 +- api_docs/kbn_react_kibana_context_root.mdx | 2 +- api_docs/kbn_react_kibana_context_styled.mdx | 2 +- api_docs/kbn_react_kibana_context_theme.mdx | 2 +- api_docs/kbn_react_kibana_mount.mdx | 2 +- api_docs/kbn_repo_file_maps.mdx | 2 +- api_docs/kbn_repo_linter.mdx | 2 +- api_docs/kbn_repo_path.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_reporting_common.mdx | 2 +- api_docs/kbn_reporting_export_types_csv.mdx | 2 +- .../kbn_reporting_export_types_csv_common.mdx | 2 +- api_docs/kbn_reporting_export_types_pdf.mdx | 2 +- .../kbn_reporting_export_types_pdf_common.mdx | 2 +- api_docs/kbn_reporting_export_types_png.mdx | 2 +- .../kbn_reporting_export_types_png_common.mdx | 2 +- api_docs/kbn_reporting_mocks_server.mdx | 2 +- api_docs/kbn_reporting_public.mdx | 2 +- api_docs/kbn_reporting_server.mdx | 2 +- api_docs/kbn_resizable_layout.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_router_utils.mdx | 2 +- api_docs/kbn_rrule.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- api_docs/kbn_saved_objects_settings.mdx | 2 +- api_docs/kbn_search_api_panels.mdx | 2 +- api_docs/kbn_search_connectors.mdx | 2 +- api_docs/kbn_search_errors.devdocs.json | 346 ++++-------------- api_docs/kbn_search_errors.mdx | 4 +- api_docs/kbn_search_index_documents.mdx | 2 +- api_docs/kbn_search_response_warnings.mdx | 2 +- api_docs/kbn_security_plugin_types_common.mdx | 2 +- api_docs/kbn_security_plugin_types_public.mdx | 2 +- api_docs/kbn_security_plugin_types_server.mdx | 2 +- api_docs/kbn_security_solution_features.mdx | 2 +- api_docs/kbn_security_solution_navigation.mdx | 2 +- api_docs/kbn_security_solution_side_nav.mdx | 2 +- ...kbn_security_solution_storybook_config.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_data_table.mdx | 2 +- api_docs/kbn_securitysolution_ecs.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_grouping.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_serverless_common_settings.mdx | 2 +- .../kbn_serverless_observability_settings.mdx | 2 +- api_docs/kbn_serverless_project_switcher.mdx | 2 +- api_docs/kbn_serverless_search_settings.mdx | 2 +- api_docs/kbn_serverless_security_settings.mdx | 2 +- api_docs/kbn_serverless_storybook_config.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- api_docs/kbn_shared_ux_avatar_solution.mdx | 2 +- .../kbn_shared_ux_button_exit_full_screen.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_chrome_navigation.mdx | 2 +- api_docs/kbn_shared_ux_error_boundary.mdx | 2 +- api_docs/kbn_shared_ux_file_context.mdx | 2 +- api_docs/kbn_shared_ux_file_image.mdx | 2 +- api_docs/kbn_shared_ux_file_image_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_picker.mdx | 2 +- api_docs/kbn_shared_ux_file_types.mdx | 2 +- api_docs/kbn_shared_ux_file_upload.mdx | 2 +- api_docs/kbn_shared_ux_file_util.mdx | 2 +- api_docs/kbn_shared_ux_link_redirect_app.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- api_docs/kbn_shared_ux_markdown.mdx | 2 +- api_docs/kbn_shared_ux_markdown_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_prompt_not_found.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_slo_schema.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_text_based_editor.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_triggers_actions_ui_types.mdx | 2 +- api_docs/kbn_ts_projects.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_actions_browser.mdx | 2 +- api_docs/kbn_ui_shared_deps_src.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_unified_data_table.mdx | 2 +- api_docs/kbn_unified_doc_viewer.mdx | 2 +- api_docs/kbn_unified_field_list.mdx | 2 +- api_docs/kbn_unsaved_changes_badge.mdx | 2 +- api_docs/kbn_url_state.mdx | 2 +- api_docs/kbn_use_tracked_promise.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_visualization_ui_components.mdx | 2 +- api_docs/kbn_visualization_utils.mdx | 2 +- api_docs/kbn_xstate_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kbn_zod_helpers.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.devdocs.json | 16 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.devdocs.json | 32 +- api_docs/lens.mdx | 4 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/links.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/log_explorer.mdx | 2 +- api_docs/logs_shared.mdx | 2 +- api_docs/management.mdx | 2 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/metrics_data_access.mdx | 2 +- api_docs/ml.devdocs.json | 2 + api_docs/ml.mdx | 2 +- api_docs/mock_idp_plugin.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/no_data_page.mdx | 2 +- api_docs/notifications.mdx | 2 +- api_docs/observability.mdx | 2 +- api_docs/observability_a_i_assistant.mdx | 2 +- api_docs/observability_log_explorer.mdx | 2 +- api_docs/observability_onboarding.mdx | 2 +- api_docs/observability_shared.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/painless_lab.mdx | 2 +- api_docs/plugin_directory.mdx | 12 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/profiling_data_access.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.devdocs.json | 2 +- api_docs/security_solution.mdx | 2 +- api_docs/security_solution_ess.mdx | 2 +- api_docs/security_solution_serverless.mdx | 2 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.devdocs.json | 60 ++- api_docs/task_manager.mdx | 7 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/text_based_languages.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.devdocs.json | 4 +- api_docs/triggers_actions_ui.mdx | 2 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_doc_viewer.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/uptime.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 645 files changed, 876 insertions(+), 983 deletions(-) diff --git a/api_docs/actions.devdocs.json b/api_docs/actions.devdocs.json index 5fa32d9b973564..175e4207ee7ca2 100644 --- a/api_docs/actions.devdocs.json +++ b/api_docs/actions.devdocs.json @@ -2845,6 +2845,27 @@ "path": "x-pack/plugins/actions/server/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "actions", + "id": "def-server.ActionTypeExecutorOptions.request", + "type": "Object", + "tags": [], + "label": "request", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-http-server", + "scope": "common", + "docId": "kibKbnCoreHttpServerPluginApi", + "section": "def-common.KibanaRequest", + "text": "KibanaRequest" + }, + " | undefined" + ], + "path": "x-pack/plugins/actions/server/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -4574,6 +4595,27 @@ "path": "x-pack/plugins/actions/common/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "actions", + "id": "def-common.ActionTypeExecutorResult.errorSource", + "type": "CompoundType", + "tags": [], + "label": "errorSource", + "description": [], + "signature": [ + { + "pluginId": "taskManager", + "scope": "common", + "docId": "kibTaskManagerPluginApi", + "section": "def-common.TaskErrorSource", + "text": "TaskErrorSource" + }, + " | undefined" + ], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 0d548cad85aba5..2cded533c95f55 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 269 | 0 | 263 | 31 | +| 271 | 0 | 265 | 31 | ## Client diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index 26b4be19693570..913f3c4ce32b7c 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/ai_assistant_management_observability.mdx b/api_docs/ai_assistant_management_observability.mdx index 2039c9ac564b90..6fc92bf20893c9 100644 --- a/api_docs/ai_assistant_management_observability.mdx +++ b/api_docs/ai_assistant_management_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiAssistantManagementObservability title: "aiAssistantManagementObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementObservability plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementObservability'] --- import aiAssistantManagementObservabilityObj from './ai_assistant_management_observability.devdocs.json'; diff --git a/api_docs/ai_assistant_management_selection.mdx b/api_docs/ai_assistant_management_selection.mdx index edcf581deb96fa..a2e3760e8c1e95 100644 --- a/api_docs/ai_assistant_management_selection.mdx +++ b/api_docs/ai_assistant_management_selection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiAssistantManagementSelection title: "aiAssistantManagementSelection" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementSelection plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementSelection'] --- import aiAssistantManagementSelectionObj from './ai_assistant_management_selection.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 32f08c6a0e78ff..27b1437ee378fb 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.devdocs.json b/api_docs/alerting.devdocs.json index 15f5fd2f156b5a..5fd8e35e631a95 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -934,6 +934,46 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-server.AlertsClientError", + "type": "Class", + "tags": [], + "label": "AlertsClientError", + "description": [], + "signature": [ + { + "pluginId": "alerting", + "scope": "server", + "docId": "kibAlertingPluginApi", + "section": "def-server.AlertsClientError", + "text": "AlertsClientError" + }, + " extends Error" + ], + "path": "x-pack/plugins/alerting/server/alerts_client/alerts_client_error.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "alerting", + "id": "def-server.AlertsClientError.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "x-pack/plugins/alerting/server/alerts_client/alerts_client_error.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-server.InstallShutdownError", @@ -3533,10 +3573,6 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts" }, - { - "plugin": "stackAlerts", - "path": "x-pack/plugins/stack_alerts/server/rule_types/index_threshold/rule_type.ts" - }, { "plugin": "stackAlerts", "path": "x-pack/plugins/stack_alerts/server/rule_types/geo_containment/lib/get_entities_and_generate_alerts.ts" diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index adc70de114502d..cefe8c8b8447bd 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 823 | 1 | 792 | 51 | +| 825 | 1 | 794 | 51 | ## Client diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 245012914fc855..f1563ff517d3e1 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/apm_data_access.mdx b/api_docs/apm_data_access.mdx index 9a120eebe3ed4c..ff1c317c4f8797 100644 --- a/api_docs/apm_data_access.mdx +++ b/api_docs/apm_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apmDataAccess title: "apmDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the apmDataAccess plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apmDataAccess'] --- import apmDataAccessObj from './apm_data_access.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index 0ac5809fbca3b3..b532615b319703 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetManager'] --- import assetManagerObj from './asset_manager.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index e9816c6447a107..ab1916c43b03ce 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] --- import bannersObj from './banners.devdocs.json'; diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index 93201fe1798411..69dae7f8fdf441 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] --- import bfetchObj from './bfetch.devdocs.json'; diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index cac829ab79309f..bbddf43deb3cf3 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index de2829ce93f0de..aaca7e7b1ee11b 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index 5196545d7539f7..80c9cc7916a854 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 5867d5b8257059..14e28bd4d9ba70 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index c169145b714b7d..e7381f6f1b77aa 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDataMigration'] --- import cloudDataMigrationObj from './cloud_data_migration.devdocs.json'; diff --git a/api_docs/cloud_defend.mdx b/api_docs/cloud_defend.mdx index deac1416f138c8..a36d09c49ea798 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index b60f92510930af..bee7674145ec25 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index d8dac36a8e49e1..5e9aca55ddd29f 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index ba0a1ca7370a4c..167af207774c69 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/content_management.mdx b/api_docs/content_management.mdx index f997d267fc3c58..fe09361ff4bf64 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'contentManagement'] --- import contentManagementObj from './content_management.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index e28e0be933f77f..889a08840b53f2 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index e1cd80030b4e80..2cb09be42de16b 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index 4ab19494bc12eb..24c32f43b23ca9 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index c408255e9e4373..4ecbaff344e4f0 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 8de976a2674067..446ea5e8289b43 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index cbae12b08c2768..73c8b2040c0324 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index fb8259e59b2a4f..df0dab9ab0977f 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index e268263406505a..a7696ffb2b114b 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index dfa448a4bf5c66..0bce395adfbb2a 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index 4c1454ea6e648c..280caf73202772 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index 64dfa575555f0d..a7b37e0f30c9a9 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index 74551d06871f4d..38a69806ef3c9f 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/dataset_quality.mdx b/api_docs/dataset_quality.mdx index 309a3527d3953d..8b31bada0a8f77 100644 --- a/api_docs/dataset_quality.mdx +++ b/api_docs/dataset_quality.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/datasetQuality title: "datasetQuality" image: https://source.unsplash.com/400x175/?github description: API docs for the datasetQuality plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'datasetQuality'] --- import datasetQualityObj from './dataset_quality.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index b2a7f60ba614fa..4d04d0c26a7a53 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -18,7 +18,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | ---------------|-----------|-----------| | | ml, stackAlerts | - | | | ruleRegistry, observability, ml, infra, monitoring, securitySolution, stackAlerts, synthetics, transform, uptime | - | -| | share, uiActions, guidedOnboarding, home, serverless, management, spaces, savedObjects, indexManagement, visualizations, dashboard, savedObjectsTagging, expressionXY, lens, expressionMetricVis, expressionGauge, security, alerting, triggersActionsUi, cases, aiops, advancedSettings, exploratoryView, fleet, metricsDataAccess, licenseManagement, maps, dataVisualizer, ml, osquery, profiling, apm, expressionImage, expressionMetric, expressionError, expressionRevealImage, expressionRepeatImage, expressionShape, crossClusterReplication, globalSearchBar, graph, grokdebugger, indexLifecycleManagement, infra, ingestPipelines, logstash, monitoring, observabilityOnboarding, devTools, painlessLab, remoteClusters, rollup, searchprofiler, newsfeed, securitySolution, snapshotRestore, synthetics, transform, upgradeAssistant, uptime, ux, watcher, cloudDataMigration, console, filesManagement, kibanaOverview, visDefaultEditor, expressionHeatmap, expressionLegacyMetricVis, expressionPartitionVis, expressionTagcloud, visTypeTable, visTypeTimelion, visTypeTimeseries, visTypeVega, visTypeVislib | - | +| | share, uiActions, guidedOnboarding, home, serverless, management, spaces, savedObjects, indexManagement, visualizations, dashboard, savedObjectsTagging, expressionXY, lens, expressionMetricVis, expressionGauge, security, alerting, triggersActionsUi, cases, aiops, advancedSettings, exploratoryView, fleet, metricsDataAccess, licenseManagement, maps, dataVisualizer, ml, osquery, profiling, apm, expressionImage, expressionMetric, expressionError, expressionRevealImage, expressionRepeatImage, expressionShape, crossClusterReplication, graph, grokdebugger, indexLifecycleManagement, infra, ingestPipelines, logstash, monitoring, observabilityOnboarding, devTools, painlessLab, remoteClusters, rollup, searchprofiler, newsfeed, securitySolution, snapshotRestore, synthetics, transform, upgradeAssistant, uptime, ux, watcher, cloudDataMigration, console, filesManagement, kibanaOverview, visDefaultEditor, expressionHeatmap, expressionLegacyMetricVis, expressionPartitionVis, expressionTagcloud, visTypeTable, visTypeTimelion, visTypeTimeseries, visTypeVega, visTypeVislib | - | | | encryptedSavedObjects, actions, data, ml, logstash, securitySolution, cloudChat | - | | | actions, ml, savedObjectsTagging, enterpriseSearch | - | | | @kbn/core-saved-objects-browser-internal, @kbn/core, savedObjects, visualizations, aiops, ml, dataVisualizer, dashboardEnhanced, graph, lens, securitySolution, eventAnnotation, @kbn/core-saved-objects-browser-mocks | - | diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 1f71eaa96d1b42..3f1f507466d5ce 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -831,14 +831,6 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] -## globalSearchBar - -| Deprecated API | Reference location(s) | Remove By | -| ---------------|-----------|-----------| -| | [plugin.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/global_search_bar/public/plugin.tsx#:~:text=KibanaThemeProvider), [plugin.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/global_search_bar/public/plugin.tsx#:~:text=KibanaThemeProvider), [plugin.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/global_search_bar/public/plugin.tsx#:~:text=KibanaThemeProvider) | - | - - - ## globalSearchProviders | Deprecated API | Reference location(s) | Remove By | @@ -991,7 +983,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [confirm_modal_promise.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/confirm_modal_promise.tsx#:~:text=toMountPoint), [confirm_modal_promise.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/confirm_modal_promise.tsx#:~:text=toMountPoint), [remove_layer_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_actions/remove_layer_action.tsx#:~:text=toMountPoint), [remove_layer_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_actions/remove_layer_action.tsx#:~:text=toMountPoint), [revert_changes_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/revert_changes_action.tsx#:~:text=toMountPoint), [revert_changes_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/revert_changes_action.tsx#:~:text=toMountPoint), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.ts#:~:text=toMountPoint), [helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.ts#:~:text=toMountPoint) | - | +| | [confirm_modal_promise.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/confirm_modal_promise.tsx#:~:text=toMountPoint), [confirm_modal_promise.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/confirm_modal_promise.tsx#:~:text=toMountPoint), [remove_layer_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_actions/remove_layer_action.tsx#:~:text=toMountPoint), [remove_layer_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_actions/remove_layer_action.tsx#:~:text=toMountPoint), [revert_changes_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/revert_changes_action.tsx#:~:text=toMountPoint), [revert_changes_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/revert_changes_action.tsx#:~:text=toMountPoint), [edit_action_helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/trigger_actions/open_lens_config/edit_action_helpers.ts#:~:text=toMountPoint), [edit_action_helpers.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/trigger_actions/open_lens_config/edit_action_helpers.ts#:~:text=toMountPoint) | - | | | [help_popover.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/datasources/form_based/help_popover.tsx#:~:text=KibanaThemeProvider), [help_popover.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/datasources/form_based/help_popover.tsx#:~:text=KibanaThemeProvider), [help_popover.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/datasources/form_based/help_popover.tsx#:~:text=KibanaThemeProvider), [expression.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/datatable/expression.tsx#:~:text=KibanaThemeProvider), [expression.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/datatable/expression.tsx#:~:text=KibanaThemeProvider), [expression.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/datatable/expression.tsx#:~:text=KibanaThemeProvider), [save_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx#:~:text=KibanaThemeProvider), [save_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx#:~:text=KibanaThemeProvider), [save_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx#:~:text=KibanaThemeProvider), [settings_menu.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/settings_menu.tsx#:~:text=KibanaThemeProvider)+ 12 more | - | | | [save_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx#:~:text=SavedObjectSaveModal), [save_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx#:~:text=SavedObjectSaveModal) | 8.8.0 | | | [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/find_object_by_title.test.ts#:~:text=SavedObjectsClientContract), [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/find_object_by_title.test.ts#:~:text=SavedObjectsClientContract), [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/find_object_by_title.test.ts#:~:text=SavedObjectsClientContract) | - | @@ -1427,7 +1419,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | | [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/rule_types/es_query/index.ts#:~:text=registerNavigation), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/rule_types/es_query/index.ts#:~:text=registerNavigation), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/rule_types/es_query/index.ts#:~:text=registerNavigation), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/rule_types/es_query/index.ts#:~:text=registerNavigation), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/rule_types/es_query/index.ts#:~:text=registerNavigation) | - | -| | [rule_type.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/rule_types/index_threshold/rule_type.ts#:~:text=alertFactory), [get_entities_and_generate_alerts.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/rule_types/geo_containment/lib/get_entities_and_generate_alerts.ts#:~:text=alertFactory), [executor.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/rule_types/geo_containment/executor.ts#:~:text=alertFactory), [executor.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/rule_types/geo_containment/executor.ts#:~:text=alertFactory) | - | +| | [get_entities_and_generate_alerts.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/rule_types/geo_containment/lib/get_entities_and_generate_alerts.ts#:~:text=alertFactory), [executor.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/rule_types/geo_containment/executor.ts#:~:text=alertFactory), [executor.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/rule_types/geo_containment/executor.ts#:~:text=alertFactory) | - | | | [fetch_search_source_query.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/rule_types/es_query/lib/fetch_search_source_query.ts#:~:text=fetch), [rule_type.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/rule_types/es_query/rule_type.test.ts#:~:text=fetch), [rule_type.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/rule_types/es_query/rule_type.test.ts#:~:text=fetch) | - | | | [data_view_select.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/rule_types/geo_containment/rule_form/data_view_select.tsx#:~:text=indexPatterns), [boundary_form.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/rule_types/geo_containment/rule_form/boundary_form.tsx#:~:text=indexPatterns), [boundary_form.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/rule_types/geo_containment/rule_form/boundary_form.tsx#:~:text=indexPatterns), [entity_form.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/rule_types/geo_containment/rule_form/entity_form.tsx#:~:text=indexPatterns), [entity_form.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/rule_types/geo_containment/rule_form/entity_form.tsx#:~:text=indexPatterns) | - | | | [expression.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/rule_types/threshold/expression.tsx#:~:text=fieldFormats) | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index d01634d94f307a..7c5b3c2f8d1db1 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 05a42dfee4f9c8..49721a6640a54f 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 1623ea1ab919dd..8f7aec0b851b39 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index 24a9c9bc9a03c2..85ca05e54e5953 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index ee97616a9a10fe..7b48d973032dcf 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/elastic_assistant.mdx b/api_docs/elastic_assistant.mdx index 1df64189eba35c..181af89056834d 100644 --- a/api_docs/elastic_assistant.mdx +++ b/api_docs/elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/elasticAssistant title: "elasticAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the elasticAssistant plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'elasticAssistant'] --- import elasticAssistantObj from './elastic_assistant.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 466683e7542873..bf4e662fd0a0fd 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index 05c1f0c349e099..35a002361207dd 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index caace4728e9d94..6c9ebefe470a1f 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index 42daa2becb86ca..4dc9677142a408 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 654b46b0c5e4b2..9b12313037818c 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 8b2e0bcb53fb6e..74875b894bcff3 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_annotation_listing.mdx b/api_docs/event_annotation_listing.mdx index 25a74bf46d0ea0..4d2edcbef9ca3a 100644 --- a/api_docs/event_annotation_listing.mdx +++ b/api_docs/event_annotation_listing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotationListing title: "eventAnnotationListing" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotationListing plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotationListing'] --- import eventAnnotationListingObj from './event_annotation_listing.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index a9b9113640bcbe..f2ed4e3b823d86 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/exploratory_view.mdx b/api_docs/exploratory_view.mdx index a52100f992de4c..ebb713229170bf 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'exploratoryView'] --- import exploratoryViewObj from './exploratory_view.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index a9e936abeddf31..3a6b885e442164 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index 4cca71abe07906..722c2b99c2ef05 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index 6b5b21f4fb2047..610d50666ab091 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index c77f8c64853d95..68f66b95d6ef5e 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index 0430d47a37baca..e31ab8977443f7 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index a255b55611268c..660d8bb3deebce 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index 5a123ab07f33ad..17bbed8aebef6b 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index a856a46b6481e0..6d9060dc5c0945 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index 278599d9f35626..de0b7c7e0c5944 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index 158fcfa11750f6..9ecebe60afcf6b 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index 2935d4c8b714da..813405b56e762d 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index d2a4a1381c9776..bcee8974cf16dc 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index 232a524194c7fd..91684d0d6f6d1d 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index 032e5d0349a130..723bbe47f86366 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; diff --git a/api_docs/features.mdx b/api_docs/features.mdx index 37a7f280f7a624..2da7a5a30b9529 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index a2cd495db1062b..49f3495a7855f1 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 4b9eaff4fd17fd..424efa731fab64 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.mdx b/api_docs/files.mdx index c21eec2cbe5b87..57b7d033f8b80e 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; diff --git a/api_docs/files_management.mdx b/api_docs/files_management.mdx index d578eacf9ffe42..df688b57a80601 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'filesManagement'] --- import filesManagementObj from './files_management.devdocs.json'; diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 056dc4d6fb6071..07073193bcd14d 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index a19c4362e84b6c..83601545625689 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/guided_onboarding.mdx b/api_docs/guided_onboarding.mdx index 61902a7030a953..53c554241d254f 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.mdx b/api_docs/home.mdx index 87256269da4567..d441a1857be396 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/image_embeddable.mdx b/api_docs/image_embeddable.mdx index 1baf60cb540e10..f76e485895325c 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'imageEmbeddable'] --- import imageEmbeddableObj from './image_embeddable.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 06a730d0ba9fdd..10a95dffca26c1 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 1a450bb87e9bac..98e0f0b6ed8c83 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index 8216c86f9babbc..5a6be0813c9828 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index b4632bcd58c026..a9fc5189115317 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 73b04a3df72e27..b6ade9184308c7 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 1cbd11dfd0d03f..58c3128bc9f021 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_actions_types.mdx b/api_docs/kbn_actions_types.mdx index f51172b1a406b1..7e47dda753d5bf 100644 --- a/api_docs/kbn_actions_types.mdx +++ b/api_docs/kbn_actions_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-actions-types title: "@kbn/actions-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/actions-types plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/actions-types'] --- import kbnActionsTypesObj from './kbn_actions_types.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index 121f39152fd02d..cd14083f5a4a69 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 8f1195e363d75c..7348d48a89b388 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_api_integration_helpers.mdx b/api_docs/kbn_alerting_api_integration_helpers.mdx index 7fb9322954dd36..5ef982036e984c 100644 --- a/api_docs/kbn_alerting_api_integration_helpers.mdx +++ b/api_docs/kbn_alerting_api_integration_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-api-integration-helpers title: "@kbn/alerting-api-integration-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-api-integration-helpers plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-api-integration-helpers'] --- import kbnAlertingApiIntegrationHelpersObj from './kbn_alerting_api_integration_helpers.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index e6904e0c59ffe3..e0f63ca0a1692e 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerting_types.mdx b/api_docs/kbn_alerting_types.mdx index 31ec9aeb7e8559..9794f4cb1680bd 100644 --- a/api_docs/kbn_alerting_types.mdx +++ b/api_docs/kbn_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-types title: "@kbn/alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-types plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-types'] --- import kbnAlertingTypesObj from './kbn_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index 1fb4cd71832a91..cd9ee52924db35 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-as-data-utils'] --- import kbnAlertsAsDataUtilsObj from './kbn_alerts_as_data_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index 5c12f240b701da..e9920dea1c7f6b 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-ui-shared'] --- import kbnAlertsUiSharedObj from './kbn_alerts_ui_shared.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index 59e01e8711ac5d..ee15ca922d6a17 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index 1af70477162071..d85322e4f1541b 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_collection_utils.mdx b/api_docs/kbn_analytics_collection_utils.mdx index 52d45c656ac9e3..5f49867f330308 100644 --- a/api_docs/kbn_analytics_collection_utils.mdx +++ b/api_docs/kbn_analytics_collection_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-collection-utils title: "@kbn/analytics-collection-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-collection-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-collection-utils'] --- import kbnAnalyticsCollectionUtilsObj from './kbn_analytics_collection_utils.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index 2f3eccb35f7ab1..a84b4c1b777bdd 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 8f05e511bcacb9..775cfc7603fd9b 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index 16e2cbff3383fc..7bbd11809f9145 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index 5ef08bb07042e1..a5261dd76295f3 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index d9fbce1b70916c..2308c1d2bb90ef 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index 7fd594402e9a76..cd8c2e5031d80f 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index bbf5c2e0afd8a8..fa9c84e411c3fb 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace_client.mdx b/api_docs/kbn_apm_synthtrace_client.mdx index 0a1418a7d31bff..29746d8baccfdd 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index d564479d022d42..02c6abcf182b97 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index ea5defb14a6d44..e3475f686a38ea 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_bfetch_error.mdx b/api_docs/kbn_bfetch_error.mdx index e825eb91fee442..e048ddc047ef94 100644 --- a/api_docs/kbn_bfetch_error.mdx +++ b/api_docs/kbn_bfetch_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-bfetch-error title: "@kbn/bfetch-error" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/bfetch-error plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/bfetch-error'] --- import kbnBfetchErrorObj from './kbn_bfetch_error.devdocs.json'; diff --git a/api_docs/kbn_calculate_auto.mdx b/api_docs/kbn_calculate_auto.mdx index 9370ac0707dd98..0963be5da634e6 100644 --- a/api_docs/kbn_calculate_auto.mdx +++ b/api_docs/kbn_calculate_auto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-auto title: "@kbn/calculate-auto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-auto plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-auto'] --- import kbnCalculateAutoObj from './kbn_calculate_auto.devdocs.json'; diff --git a/api_docs/kbn_calculate_width_from_char_count.mdx b/api_docs/kbn_calculate_width_from_char_count.mdx index 6faa4c4037efc9..92311c3dc81753 100644 --- a/api_docs/kbn_calculate_width_from_char_count.mdx +++ b/api_docs/kbn_calculate_width_from_char_count.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-width-from-char-count title: "@kbn/calculate-width-from-char-count" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-width-from-char-count plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-width-from-char-count'] --- import kbnCalculateWidthFromCharCountObj from './kbn_calculate_width_from_char_count.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 0f935c59087ff7..d3627857ebbd43 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index a60ae4b0cedd95..f3d43f621a3bab 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cell-actions'] --- import kbnCellActionsObj from './kbn_cell_actions.devdocs.json'; diff --git a/api_docs/kbn_chart_expressions_common.mdx b/api_docs/kbn_chart_expressions_common.mdx index 82f2b5d6cd2d2e..ae81f88ecddb60 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-expressions-common'] --- import kbnChartExpressionsCommonObj from './kbn_chart_expressions_common.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index 2e5e7e969b6cce..2273180eaa78ff 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] --- import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index 3a28582b701264..fc4c1ef3e89de5 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index 51d84b58324770..d61211e4b324b6 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index 9b4cc2cba02f25..b55cd4a00a2e57 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index dfda5993535940..f64562e83c7101 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index eda7e113728790..2070eb71b3dc3a 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_owners.mdx b/api_docs/kbn_code_owners.mdx index 8f40b76f15167c..9daca0998df43f 100644 --- a/api_docs/kbn_code_owners.mdx +++ b/api_docs/kbn_code_owners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-owners title: "@kbn/code-owners" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-owners plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-owners'] --- import kbnCodeOwnersObj from './kbn_code_owners.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index eea5fdc3b63ae6..9e8e71d82cc24c 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index 1d61d5261d9509..a0e29465bd5d20 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index ffee5680dff634..43c203826913fb 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index 1dd83bb9e91950..ace85fb984a6ef 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_editor.mdx b/api_docs/kbn_content_management_content_editor.mdx index 7d26d795cc0b6e..b9c53b58502bfc 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index c6160456ba0c70..ecd8263d958fd0 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-tabbed-table-list-view'] --- import kbnContentManagementTabbedTableListViewObj from './kbn_content_management_tabbed_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view.mdx b/api_docs/kbn_content_management_table_list_view.mdx index 7a08374bcf7bb8..eeafff3e3f53e7 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_common.mdx b/api_docs/kbn_content_management_table_list_view_common.mdx index 13da50f3da458e..c395e57bd5c378 100644 --- a/api_docs/kbn_content_management_table_list_view_common.mdx +++ b/api_docs/kbn_content_management_table_list_view_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-common title: "@kbn/content-management-table-list-view-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-common'] --- import kbnContentManagementTableListViewCommonObj from './kbn_content_management_table_list_view_common.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index b734c8d7a18fb8..28f829569c70fa 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-table'] --- import kbnContentManagementTableListViewTableObj from './kbn_content_management_table_list_view_table.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index 548bf253a4c2d7..ac15e36f3e620c 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-utils'] --- import kbnContentManagementUtilsObj from './kbn_content_management_utils.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 646ac64e92f54b..35e49738c9ee18 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index a7879e4d3d8b7b..f6885853bab389 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index 25289bfe400a2e..6e7b35122b360d 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 0f6cb5412babbe..a2a209f1f5c3c9 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index 56784937c528b3..c5bba2659b8e0a 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index f6fb22ca136932..a50b6ee3737ca7 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index d87a0916ddaadc..5ef25a22fdd7e2 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index ca7e995b042d6d..95bfa2b1f470d6 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index 170a694892e354..f462d587430a24 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index 8ee8a76549cb2f..95bbfa98d1587d 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index 5b78000d8d91d8..6e3db2df263f8a 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index 31762b4cb59be0..540041cdfae266 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_apps_server_internal.mdx b/api_docs/kbn_core_apps_server_internal.mdx index fb1b3ffddcd96d..4d5a45ce4f5146 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-server-internal'] --- import kbnCoreAppsServerInternalObj from './kbn_core_apps_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index 7094d688d58daf..984168575a1609 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index 08dd066890f323..db906e2aae7abc 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index e6b8399a6fb259..a2ec8bd66365ee 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index 298111aa0fed3b..26e01b07a38cc6 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index dbb476c98bb80d..3925a4050d7a2a 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index ebfa6afcb88ca6..086fff1793b4a3 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index f1e5c2d4985ccf..13929a85fc45a7 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index 4170ccd2b6a611..5784f6aaad2537 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index f0b86d81093881..f4f709a7302989 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index 34236f3571dfd2..2b75ad47f9b0d3 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index c51fc1b3c8b8f3..7c29647aadd524 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser.mdx b/api_docs/kbn_core_custom_branding_browser.mdx index 395a13be812fc6..9626c62b68df67 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser'] --- import kbnCoreCustomBrandingBrowserObj from './kbn_core_custom_branding_browser.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_internal.mdx b/api_docs/kbn_core_custom_branding_browser_internal.mdx index 3567c91b275099..39b4a0a0481e53 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-internal'] --- import kbnCoreCustomBrandingBrowserInternalObj from './kbn_core_custom_branding_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_mocks.mdx b/api_docs/kbn_core_custom_branding_browser_mocks.mdx index c82dbdfcda4bf8..de789aaa6b3f54 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-mocks'] --- import kbnCoreCustomBrandingBrowserMocksObj from './kbn_core_custom_branding_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_common.mdx b/api_docs/kbn_core_custom_branding_common.mdx index ea3c4459c636eb..5f2ff3b8b2d613 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-common'] --- import kbnCoreCustomBrandingCommonObj from './kbn_core_custom_branding_common.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server.mdx b/api_docs/kbn_core_custom_branding_server.mdx index 2936975bb78c65..988e68ec151330 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server'] --- import kbnCoreCustomBrandingServerObj from './kbn_core_custom_branding_server.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_internal.mdx b/api_docs/kbn_core_custom_branding_server_internal.mdx index a77dedb859eb49..8875485c9aabb4 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-internal'] --- import kbnCoreCustomBrandingServerInternalObj from './kbn_core_custom_branding_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_mocks.mdx b/api_docs/kbn_core_custom_branding_server_mocks.mdx index 05866c562bb492..530e943b8e926b 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-mocks'] --- import kbnCoreCustomBrandingServerMocksObj from './kbn_core_custom_branding_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index 630a23a542d7f3..a87366790ba8b2 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index ada0b777ba4f7f..5e52613ec7563d 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index 4eb744e8a25895..67cf325c43a0e6 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index 78c7b425cd391b..fb8e41bc8e5720 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index cb208e9c0433c8..eaf60bbd317999 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index ecc04327dc53b8..e9c69de86b77bc 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index 30f5741da71ec9..6de5b1f562edeb 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index edebce6161506c..10829b1e6275aa 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index 9b3b9769fd650b..2f57ff67171860 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index 69f2a57657f42b..bae2165a50a875 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index d7175588a43e91..2355fa68afbb88 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index 9a0d5e597f865e..2b7a7e5f90047b 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index 42854703b4afe1..1634b62b279178 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index 095a92a32b5c4a..c9dff23c3fc428 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index f15aee88a3db33..fbbdf852ae1722 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index d9fe32a1d6138c..dd21efd9047060 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index 82abcf65127481..53df4b35df5aaf 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index b4b55806818678..8ebb452e60bf2f 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index e7ad84e90c8eca..ac638f6518370c 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index 4a6b4bfed4e517..ecfe86d8adc278 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index 6a5f735f86a281..22ec8ff9b7f15f 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index 3a7991dbf5f4a4..c467d178aaa9cf 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index 51c751beed4159..21cfe850579fce 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index 65cbfab2036ae3..3237035fec0159 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index 4c6a0b6bf4182f..3f31f1f7edb844 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index 108457965b7b9c..c1c340f9cccc7b 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index b0ce16df032341..82fc0ca9ca40b8 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index 75cc5baef38dea..21cbe5fe4dfa03 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index 7787852fd47b0a..986a34823dcadd 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index ba79a9400352ce..57d3f7b03ae1b9 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index 073f3cd3d3d694..1d515d7566223b 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index 3d2d1b3cf60338..04a2bb69f59f66 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_request_handler_context_server.mdx b/api_docs/kbn_core_http_request_handler_context_server.mdx index 34383de09320bd..91fa8a5ad49bd1 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-request-handler-context-server'] --- import kbnCoreHttpRequestHandlerContextServerObj from './kbn_core_http_request_handler_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server.mdx b/api_docs/kbn_core_http_resources_server.mdx index bf4a485ef597fa..ade659bb9ef916 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server'] --- import kbnCoreHttpResourcesServerObj from './kbn_core_http_resources_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_internal.mdx b/api_docs/kbn_core_http_resources_server_internal.mdx index 1baff418e66861..c6fc808e859cf3 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-internal'] --- import kbnCoreHttpResourcesServerInternalObj from './kbn_core_http_resources_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_mocks.mdx b/api_docs/kbn_core_http_resources_server_mocks.mdx index bf19251f985266..5bcb87cf8fbd0c 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-mocks'] --- import kbnCoreHttpResourcesServerMocksObj from './kbn_core_http_resources_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index c75f43c9091a0f..ffa07aefb50bc8 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index c9ac829505fdcd..89d2a7c8716326 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.devdocs.json b/api_docs/kbn_core_http_server.devdocs.json index 9f2a3a12bdd55d..5c643711446533 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -4404,6 +4404,10 @@ "plugin": "serverlessSearch", "path": "x-pack/plugins/serverless_search/server/routes/indices_routes.ts" }, + { + "plugin": "serverlessSearch", + "path": "x-pack/plugins/serverless_search/server/routes/indices_routes.ts" + }, { "plugin": "serverlessSearch", "path": "x-pack/plugins/serverless_search/server/routes/connectors_routes.ts" diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index efb5ca9a8627d6..3878dda022f742 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index 916f9228d6bcf5..3b2c869a440f69 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index b0002eac4cde9c..315bff5546a26b 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index 2f480eac369743..ee4117cafdf518 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] --- import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index 3c9c19fbe0ab0c..68284739bceea3 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] --- import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server.mdx b/api_docs/kbn_core_i18n_server.mdx index c3efefc42e35b4..3656480a1b1617 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server'] --- import kbnCoreI18nServerObj from './kbn_core_i18n_server.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_internal.mdx b/api_docs/kbn_core_i18n_server_internal.mdx index 524fc3c56027ed..73c42cd26676ea 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-internal'] --- import kbnCoreI18nServerInternalObj from './kbn_core_i18n_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_mocks.mdx b/api_docs/kbn_core_i18n_server_mocks.mdx index fd742237c6162a..e99ae71e0ed32d 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-mocks'] --- import kbnCoreI18nServerMocksObj from './kbn_core_i18n_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index 049cf5508ab0ae..0fbecc550b8900 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] --- import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx index ff3398960d536d..374f99df7846ec 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal'] --- import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx index bb7904f1a7e23e..0cfbc9010c875c 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks'] --- import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index 3359ce214df07f..94fd96b52cbf7e 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser'] --- import kbnCoreLifecycleBrowserObj from './kbn_core_lifecycle_browser.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser_mocks.mdx b/api_docs/kbn_core_lifecycle_browser_mocks.mdx index 92e2cf6d02c50e..40197f67df0132 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser-mocks'] --- import kbnCoreLifecycleBrowserMocksObj from './kbn_core_lifecycle_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server.mdx b/api_docs/kbn_core_lifecycle_server.mdx index 57f23b61974775..bbeea34bc66362 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server'] --- import kbnCoreLifecycleServerObj from './kbn_core_lifecycle_server.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server_mocks.mdx b/api_docs/kbn_core_lifecycle_server_mocks.mdx index 427d68cd9ea417..06bbaebd8709ec 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server-mocks'] --- import kbnCoreLifecycleServerMocksObj from './kbn_core_lifecycle_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_browser_mocks.mdx b/api_docs/kbn_core_logging_browser_mocks.mdx index 7585d0d2c23cc1..1ca8d6b6236159 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-browser-mocks'] --- import kbnCoreLoggingBrowserMocksObj from './kbn_core_logging_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_common_internal.mdx b/api_docs/kbn_core_logging_common_internal.mdx index 31a4b632509623..33c55994265693 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-common-internal'] --- import kbnCoreLoggingCommonInternalObj from './kbn_core_logging_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index c6c149b4a5998d..9b3045e3fa8ae6 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] --- import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index 3a893ec3a25015..b30296c72dab91 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] --- import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index c2898a671ce2e4..a9aa834345570c 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] --- import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx index 4a370c82f90980..3c12d01bf72c1c 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal'] --- import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx index 3823aebb76ab96..d503e9ba8c50e9 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks'] --- import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx index 970d898d0d8c45..28dff19fe2d240 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server'] --- import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx index ef230c858a6473..cc635864065ef6 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal'] --- import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx index 0738dc8f8c3dd2..8b1cae196fcf18 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks'] --- import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx index 448876b7c2496b..af8ca1ed8eb08c 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser'] --- import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json'; diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx index 1a2e017640cac2..33030427e39e63 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server'] --- import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx index 56aa30dba4c5ea..2005c0eb786627 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal'] --- import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx index 34fafde085c171..955df9242dee5d 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks'] --- import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index e09fba5618ddf5..a7571fab6a007b 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser'] --- import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx index a0349c9b53ed78..93efe83e1a368f 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal'] --- import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx index d3bfa4169e5b16..91e4b7602c9fee 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks'] --- import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx index d4fb8e133a88ba..b1fe595fb61196 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser'] --- import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx index e881c62aacd1c2..65fc5ba808174c 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal'] --- import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx index 8f16e6f81448d8..8aef508ce708dd 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks'] --- import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser.mdx b/api_docs/kbn_core_plugins_browser.mdx index 4b0c81a1c50461..35636514e7b0f2 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser'] --- import kbnCorePluginsBrowserObj from './kbn_core_plugins_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser_mocks.mdx b/api_docs/kbn_core_plugins_browser_mocks.mdx index 8c0dd9c9fe836a..5e1aa4e0516ce5 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_contracts_browser.mdx b/api_docs/kbn_core_plugins_contracts_browser.mdx index 6dc965a446f0c6..b43d393843b38a 100644 --- a/api_docs/kbn_core_plugins_contracts_browser.mdx +++ b/api_docs/kbn_core_plugins_contracts_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-browser title: "@kbn/core-plugins-contracts-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-contracts-browser'] --- import kbnCorePluginsContractsBrowserObj from './kbn_core_plugins_contracts_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_contracts_server.mdx b/api_docs/kbn_core_plugins_contracts_server.mdx index 1681c5f47a9b1a..cb60cff7899ca0 100644 --- a/api_docs/kbn_core_plugins_contracts_server.mdx +++ b/api_docs/kbn_core_plugins_contracts_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-server title: "@kbn/core-plugins-contracts-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-contracts-server'] --- import kbnCorePluginsContractsServerObj from './kbn_core_plugins_contracts_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index 0d978818515f9e..059b444eee8a65 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server'] --- import kbnCorePluginsServerObj from './kbn_core_plugins_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server_mocks.mdx b/api_docs/kbn_core_plugins_server_mocks.mdx index 9064da09b36292..b7e7d6d240fe99 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server-mocks'] --- import kbnCorePluginsServerMocksObj from './kbn_core_plugins_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index 7f88a8586bbb4c..f9a227b51b9802 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server'] --- import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx index 71706e6fcfbeb6..c3d592b4ccd01d 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index e7ff92d28e49b6..e3cfc0016205a5 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-browser-mocks'] --- import kbnCoreRenderingBrowserMocksObj from './kbn_core_rendering_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_internal.mdx b/api_docs/kbn_core_rendering_server_internal.mdx index 3babef55d3712f..dc894ce4088329 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-internal'] --- import kbnCoreRenderingServerInternalObj from './kbn_core_rendering_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_mocks.mdx b/api_docs/kbn_core_rendering_server_mocks.mdx index 3de72e8ff41189..6562cc04b8d2b4 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-mocks'] --- import kbnCoreRenderingServerMocksObj from './kbn_core_rendering_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_root_server_internal.mdx b/api_docs/kbn_core_root_server_internal.mdx index d315bee07fc0bc..8860cc64b0ff2b 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-root-server-internal'] --- import kbnCoreRootServerInternalObj from './kbn_core_root_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index 99238dd4fd2a20..46145e7dafea3d 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index 2f8b013711db75..d18706056fc8c5 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx index 62b278170c193f..976ac03873c077 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-mocks'] --- import kbnCoreSavedObjectsApiServerMocksObj from './kbn_core_saved_objects_api_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.mdx b/api_docs/kbn_core_saved_objects_base_server_internal.mdx index 4747c7f8fc142a..c945b37884f049 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-internal'] --- import kbnCoreSavedObjectsBaseServerInternalObj from './kbn_core_saved_objects_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx index ae394f1cf33279..64d3947380a897 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-mocks'] --- import kbnCoreSavedObjectsBaseServerMocksObj from './kbn_core_saved_objects_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx index 8f9a96801704eb..c14cbd07dcb33b 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser'] --- import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx index ff35430ad0409a..b2a5ee9c740c2f 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal'] --- import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index 74942dc0b4db56..bc618bf1d5280f 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index d91a51016a033a..c52c8874543747 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common'] --- import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx index 237e39632690b3..339f26f9512079 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-internal'] --- import kbnCoreSavedObjectsImportExportServerInternalObj from './kbn_core_saved_objects_import_export_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx index 8cefa52d203b0d..aba3efb9f39e6e 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-mocks'] --- import kbnCoreSavedObjectsImportExportServerMocksObj from './kbn_core_saved_objects_import_export_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx index 82f4839ece5eb6..92fc33c8a512d5 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-internal'] --- import kbnCoreSavedObjectsMigrationServerInternalObj from './kbn_core_saved_objects_migration_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx index b43e84a8491a28..8a748b894289fa 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-mocks'] --- import kbnCoreSavedObjectsMigrationServerMocksObj from './kbn_core_saved_objects_migration_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index 4e47164ec80c00..2bf8adc73f0120 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server'] --- import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_internal.mdx b/api_docs/kbn_core_saved_objects_server_internal.mdx index 061fa4404deea8..751587b7a7143c 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-internal'] --- import kbnCoreSavedObjectsServerInternalObj from './kbn_core_saved_objects_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_mocks.mdx b/api_docs/kbn_core_saved_objects_server_mocks.mdx index 1f39a2340d61cf..ba9afc922f5d2d 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-mocks'] --- import kbnCoreSavedObjectsServerMocksObj from './kbn_core_saved_objects_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_utils_server.mdx b/api_docs/kbn_core_saved_objects_utils_server.mdx index 6af81fdd637112..3547870869976b 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index 0be162fcd23650..e755903cab5c2c 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common'] --- import kbnCoreStatusCommonObj from './kbn_core_status_common.devdocs.json'; diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index 44e10756806e4b..b660994a8e5770 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index aa3e08fc99c666..b76e97cf6f4a25 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server'] --- import kbnCoreStatusServerObj from './kbn_core_status_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_internal.mdx b/api_docs/kbn_core_status_server_internal.mdx index d129c2e9699e18..23ea6489fcf40e 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-internal'] --- import kbnCoreStatusServerInternalObj from './kbn_core_status_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_mocks.mdx b/api_docs/kbn_core_status_server_mocks.mdx index a4156eb3580d26..4be2f0a68513e6 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-mocks'] --- import kbnCoreStatusServerMocksObj from './kbn_core_status_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx index dfd0ff5f563f33..f9d2dc98b5ab42 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters'] --- import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx index 15efb3c0dfb0e9..57b198a45efe20 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser'] --- import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_kbn_server.mdx b/api_docs/kbn_core_test_helpers_kbn_server.mdx index 8a2bd0d4eef0ce..5df791a730448a 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_model_versions.mdx b/api_docs/kbn_core_test_helpers_model_versions.mdx index 903efb2d211607..0caed2822c4b20 100644 --- a/api_docs/kbn_core_test_helpers_model_versions.mdx +++ b/api_docs/kbn_core_test_helpers_model_versions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-model-versions title: "@kbn/core-test-helpers-model-versions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-model-versions plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-model-versions'] --- import kbnCoreTestHelpersModelVersionsObj from './kbn_core_test_helpers_model_versions.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index 5272b17ba6b546..2c657268a5d787 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-so-type-serializer'] --- import kbnCoreTestHelpersSoTypeSerializerObj from './kbn_core_test_helpers_so_type_serializer.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_test_utils.mdx b/api_docs/kbn_core_test_helpers_test_utils.mdx index ae85352065c884..636431f7bf687a 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-test-utils'] --- import kbnCoreTestHelpersTestUtilsObj from './kbn_core_test_helpers_test_utils.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index c403fd047b5c98..9f5784d5b9c640 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index de950736bfaff9..64b447f427080c 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] --- import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx index 4f1d61590ae6a4..9d2855bfa8518b 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser'] --- import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx index 231f464db3db20..f9d3245d82ead6 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal'] --- import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx index 3cf1536c2d9cdc..91b53edb813d82 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks'] --- import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx index edaaacb4887dff..611c7b1032e3e7 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common'] --- import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server.mdx b/api_docs/kbn_core_ui_settings_server.mdx index 4ba5a4f944dd70..9df78e54783bfa 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server'] --- import kbnCoreUiSettingsServerObj from './kbn_core_ui_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_internal.mdx b/api_docs/kbn_core_ui_settings_server_internal.mdx index f0fad67938c8d6..c1f26fe313a7dd 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-internal'] --- import kbnCoreUiSettingsServerInternalObj from './kbn_core_ui_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_mocks.mdx b/api_docs/kbn_core_ui_settings_server_mocks.mdx index ac2b99490fca4f..5f84689ca7a3ea 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-mocks'] --- import kbnCoreUiSettingsServerMocksObj from './kbn_core_ui_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server.mdx b/api_docs/kbn_core_usage_data_server.mdx index 657d10ba32d61c..a68e6da729d0b7 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server'] --- import kbnCoreUsageDataServerObj from './kbn_core_usage_data_server.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_internal.mdx b/api_docs/kbn_core_usage_data_server_internal.mdx index dacb1a60213fd0..84d53652d3ef57 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-internal'] --- import kbnCoreUsageDataServerInternalObj from './kbn_core_usage_data_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_mocks.mdx b/api_docs/kbn_core_usage_data_server_mocks.mdx index c5c5a1863251a5..bb30fde7b6ba31 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index 9e0664a60a6b9e..b1d3b8b2647ab9 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server'] --- import kbnCoreUserSettingsServerObj from './kbn_core_user_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_internal.mdx b/api_docs/kbn_core_user_settings_server_internal.mdx index fbd7b533a17af4..5982b088a67b5c 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-internal'] --- import kbnCoreUserSettingsServerInternalObj from './kbn_core_user_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index 82fde9834b40d8..98456142fa228d 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-mocks'] --- import kbnCoreUserSettingsServerMocksObj from './kbn_core_user_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index 832838b23cd60d..c844f84771dbb2 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] --- import kbnCryptoObj from './kbn_crypto.devdocs.json'; diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx index 32487c868527a2..6ca93ee6cd8127 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_custom_icons.mdx b/api_docs/kbn_custom_icons.mdx index 2094394427370f..d0b256ca06698c 100644 --- a/api_docs/kbn_custom_icons.mdx +++ b/api_docs/kbn_custom_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-custom-icons title: "@kbn/custom-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/custom-icons plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/custom-icons'] --- import kbnCustomIconsObj from './kbn_custom_icons.devdocs.json'; diff --git a/api_docs/kbn_custom_integrations.mdx b/api_docs/kbn_custom_integrations.mdx index fdc7d2b471a532..592f46b80a9226 100644 --- a/api_docs/kbn_custom_integrations.mdx +++ b/api_docs/kbn_custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-custom-integrations title: "@kbn/custom-integrations" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/custom-integrations plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/custom-integrations'] --- import kbnCustomIntegrationsObj from './kbn_custom_integrations.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index a7a7b42edc5fe3..a9616f0320a58a 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index 6851c44cd8d3ae..b4566e31857080 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 168dac22f1c78c..9901ba85c631b6 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_analytics.mdx b/api_docs/kbn_deeplinks_analytics.mdx index e93f9eb98e7d03..de417779892ebf 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-analytics'] --- import kbnDeeplinksAnalyticsObj from './kbn_deeplinks_analytics.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_devtools.mdx b/api_docs/kbn_deeplinks_devtools.mdx index dcbb1e7e72b1ef..ab1fe7c3565ef0 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index 855973318b3bf0..0c8d3df2a61011 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-management'] --- import kbnDeeplinksManagementObj from './kbn_deeplinks_management.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_ml.mdx b/api_docs/kbn_deeplinks_ml.mdx index 0dbf258601435d..3f5fce00d87668 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-ml'] --- import kbnDeeplinksMlObj from './kbn_deeplinks_ml.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_observability.mdx b/api_docs/kbn_deeplinks_observability.mdx index 18e70293bd50a0..7a7c81abc68e28 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-observability'] --- import kbnDeeplinksObservabilityObj from './kbn_deeplinks_observability.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_search.mdx b/api_docs/kbn_deeplinks_search.mdx index a9a7f53acc3157..c87af96299e9c8 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index d3f6dd79f3df17..ad6f9478e9ad3e 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-analytics'] --- import kbnDefaultNavAnalyticsObj from './kbn_default_nav_analytics.devdocs.json'; diff --git a/api_docs/kbn_default_nav_devtools.mdx b/api_docs/kbn_default_nav_devtools.mdx index 90300109368ca3..1ff3d6a0c29c2d 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-devtools'] --- import kbnDefaultNavDevtoolsObj from './kbn_default_nav_devtools.devdocs.json'; diff --git a/api_docs/kbn_default_nav_management.mdx b/api_docs/kbn_default_nav_management.mdx index e687ca4a1b4c5e..981516377d3b20 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-management'] --- import kbnDefaultNavManagementObj from './kbn_default_nav_management.devdocs.json'; diff --git a/api_docs/kbn_default_nav_ml.mdx b/api_docs/kbn_default_nav_ml.mdx index 0542a938ccff96..abdddd7ae7ceaf 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-ml'] --- import kbnDefaultNavMlObj from './kbn_default_nav_ml.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index 80cafa7dbbd6d2..9607746f811174 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] --- import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index c9838a7a6fa4ce..b071b24947c9e3 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] --- import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index 5ecdf8cb813a1d..91deb5cd6acae8 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] --- import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index da8379cb1b7b37..4afa160c819c89 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_discover_utils.mdx b/api_docs/kbn_discover_utils.mdx index 6568e506746079..3ea72495146087 100644 --- a/api_docs/kbn_discover_utils.mdx +++ b/api_docs/kbn_discover_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-discover-utils title: "@kbn/discover-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/discover-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/discover-utils'] --- import kbnDiscoverUtilsObj from './kbn_discover_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 3774d8c765fe26..74cde01bba07b6 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index 840cc94a4c2d05..a50db44addd846 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_dom_drag_drop.mdx b/api_docs/kbn_dom_drag_drop.mdx index 91490fd580eb9b..b5d1d4d6aa8f9c 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dom-drag-drop'] --- import kbnDomDragDropObj from './kbn_dom_drag_drop.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index 6bb9f301e847ed..ba71492ecec06d 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs.mdx b/api_docs/kbn_ecs.mdx index 2f466de40d4464..06bfb551f0db34 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 848e461f325c00..769f84c7a571fb 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_agent_utils.mdx b/api_docs/kbn_elastic_agent_utils.mdx index 1c109848d555df..c9e17d49ca1447 100644 --- a/api_docs/kbn_elastic_agent_utils.mdx +++ b/api_docs/kbn_elastic_agent_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-agent-utils title: "@kbn/elastic-agent-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-agent-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-agent-utils'] --- import kbnElasticAgentUtilsObj from './kbn_elastic_agent_utils.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index ece431c0f2d58c..1838e84c5e82d0 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant_common.mdx b/api_docs/kbn_elastic_assistant_common.mdx index a95c465a0d7605..14d5b49ef145a2 100644 --- a/api_docs/kbn_elastic_assistant_common.mdx +++ b/api_docs/kbn_elastic_assistant_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant-common title: "@kbn/elastic-assistant-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant-common'] --- import kbnElasticAssistantCommonObj from './kbn_elastic_assistant_common.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 78bc34211c6489..e2300f88a31015 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es'] --- import kbnEsObj from './kbn_es.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index da64a933321d3c..727c0410b35d15 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] --- import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json'; diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx index 1052a1a5c7e4e8..d5dcf9ba5f3087 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors'] --- import kbnEsErrorsObj from './kbn_es_errors.devdocs.json'; diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index 7a560bdee78632..83f290afe8d5dc 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index 442cd2ca9b2975..d106508e62a3f5 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] --- import kbnEsTypesObj from './kbn_es_types.devdocs.json'; diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index a6fcc77473dca8..7f3ea3894a077a 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index d25b7bef1befa6..a21c94b33bd722 100644 --- a/api_docs/kbn_event_annotation_common.mdx +++ b/api_docs/kbn_event_annotation_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-common title: "@kbn/event-annotation-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-common'] --- import kbnEventAnnotationCommonObj from './kbn_event_annotation_common.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_components.mdx b/api_docs/kbn_event_annotation_components.mdx index 7a32fcc4327fdf..4650387b4e8dec 100644 --- a/api_docs/kbn_event_annotation_components.mdx +++ b/api_docs/kbn_event_annotation_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-components title: "@kbn/event-annotation-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-components plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-components'] --- import kbnEventAnnotationComponentsObj from './kbn_event_annotation_components.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index 42a76bc1e64e73..736802ee4edf23 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/expandable-flyout'] --- import kbnExpandableFlyoutObj from './kbn_expandable_flyout.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index de2220fb4f7554..225f9154c0c877 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_field_utils.mdx b/api_docs/kbn_field_utils.mdx index 433dd6f2d93d2c..354ed95ff18342 100644 --- a/api_docs/kbn_field_utils.mdx +++ b/api_docs/kbn_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-utils title: "@kbn/field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-utils'] --- import kbnFieldUtilsObj from './kbn_field_utils.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index accdfc8e7091f4..46fd82d33a3692 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index b14b6e2ff39d24..485a82f935345f 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_ui_services.mdx b/api_docs/kbn_ftr_common_functional_ui_services.mdx index b1dda159d95555..58a04b102d2d4f 100644 --- a/api_docs/kbn_ftr_common_functional_ui_services.mdx +++ b/api_docs/kbn_ftr_common_functional_ui_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-ui-services title: "@kbn/ftr-common-functional-ui-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-ui-services plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-ui-services'] --- import kbnFtrCommonFunctionalUiServicesObj from './kbn_ftr_common_functional_ui_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index ef0c710ee84237..ced2d9b02baa12 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_generate_console_definitions.mdx b/api_docs/kbn_generate_console_definitions.mdx index b1336050fd6b54..acdd4ca7108fcd 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-console-definitions'] --- import kbnGenerateConsoleDefinitionsObj from './kbn_generate_console_definitions.devdocs.json'; diff --git a/api_docs/kbn_generate_csv.mdx b/api_docs/kbn_generate_csv.mdx index 19bc6d526e10fb..f9ab63c7b8454f 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 2730ec77cb851d..b4cb4f54e3c907 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/guided-onboarding'] --- import kbnGuidedOnboardingObj from './kbn_guided_onboarding.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index 582082df34a82c..9a30535f9846c4 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index e7d10d60558700..2348a73dada969 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_health_gateway_server.mdx b/api_docs/kbn_health_gateway_server.mdx index ef80f3ee46dc50..f1192c6392ba6a 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/health-gateway-server'] --- import kbnHealthGatewayServerObj from './kbn_health_gateway_server.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index 3c12656bb148a0..6df85d7c3fbf9b 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index c0ac5fba635db8..97f335e2b29a91 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index 658352b079658a..a7b9c0e7965e7b 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_i18n_react.mdx b/api_docs/kbn_i18n_react.mdx index 8e6eb9761b126a..b76d82f9c63a0c 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n-react'] --- import kbnI18nReactObj from './kbn_i18n_react.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index 2f50f11de3f440..063d2caa0ce095 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index 80d0a8339770b2..e16c880e29b258 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/infra-forge'] --- import kbnInfraForgeObj from './kbn_infra_forge.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index 8a2fd89d07a8ac..736f247e927c05 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index c500d50f9970ea..5ecb0dc6f48b31 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index f3ed34ef974f1e..587266e89ce0e0 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_journeys.mdx b/api_docs/kbn_journeys.mdx index 8ca3b4cc686b15..5e097f4cad1ebd 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/journeys'] --- import kbnJourneysObj from './kbn_journeys.devdocs.json'; diff --git a/api_docs/kbn_json_ast.mdx b/api_docs/kbn_json_ast.mdx index 14175629d0de0c..7a68f42df30f86 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 3de7135caca517..538469a414ea9b 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index e2934600310047..f006aeac14ef46 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_lens_embeddable_utils.mdx b/api_docs/kbn_lens_embeddable_utils.mdx index c328a9523f7fed..fa1b633c38df01 100644 --- a/api_docs/kbn_lens_embeddable_utils.mdx +++ b/api_docs/kbn_lens_embeddable_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-lens-embeddable-utils title: "@kbn/lens-embeddable-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/lens-embeddable-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/lens-embeddable-utils'] --- import kbnLensEmbeddableUtilsObj from './kbn_lens_embeddable_utils.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index d67369e99fb757..c9e80ba261d71d 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index 2deb751440b949..77180e8b6218d4 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index db808a83e1293b..a5e8bbe0c175ed 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_management_cards_navigation.mdx b/api_docs/kbn_management_cards_navigation.mdx index cf8d4712ab857c..2ade745aeb61ea 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_settings_application.mdx b/api_docs/kbn_management_settings_application.mdx index 025e2e2ac4ace6..6dff98790c046f 100644 --- a/api_docs/kbn_management_settings_application.mdx +++ b/api_docs/kbn_management_settings_application.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-application title: "@kbn/management-settings-application" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-application plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-application'] --- import kbnManagementSettingsApplicationObj from './kbn_management_settings_application.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_category.mdx b/api_docs/kbn_management_settings_components_field_category.mdx index 9d66ef487abdf8..b5f6c56a0c6a1e 100644 --- a/api_docs/kbn_management_settings_components_field_category.mdx +++ b/api_docs/kbn_management_settings_components_field_category.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-category title: "@kbn/management-settings-components-field-category" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-category plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-category'] --- import kbnManagementSettingsComponentsFieldCategoryObj from './kbn_management_settings_components_field_category.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_input.mdx b/api_docs/kbn_management_settings_components_field_input.mdx index e27fb8fde6adce..5dee0c8129f84d 100644 --- a/api_docs/kbn_management_settings_components_field_input.mdx +++ b/api_docs/kbn_management_settings_components_field_input.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-input title: "@kbn/management-settings-components-field-input" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-input plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-input'] --- import kbnManagementSettingsComponentsFieldInputObj from './kbn_management_settings_components_field_input.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_row.mdx b/api_docs/kbn_management_settings_components_field_row.mdx index 2587916d3eca32..9d0b0d59822603 100644 --- a/api_docs/kbn_management_settings_components_field_row.mdx +++ b/api_docs/kbn_management_settings_components_field_row.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-row title: "@kbn/management-settings-components-field-row" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-row plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-row'] --- import kbnManagementSettingsComponentsFieldRowObj from './kbn_management_settings_components_field_row.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_form.mdx b/api_docs/kbn_management_settings_components_form.mdx index e2e351e44a7aa2..86db4fa4d568c9 100644 --- a/api_docs/kbn_management_settings_components_form.mdx +++ b/api_docs/kbn_management_settings_components_form.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-form title: "@kbn/management-settings-components-form" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-form plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-form'] --- import kbnManagementSettingsComponentsFormObj from './kbn_management_settings_components_form.devdocs.json'; diff --git a/api_docs/kbn_management_settings_field_definition.mdx b/api_docs/kbn_management_settings_field_definition.mdx index 03888667463b6d..5728b144297fb2 100644 --- a/api_docs/kbn_management_settings_field_definition.mdx +++ b/api_docs/kbn_management_settings_field_definition.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-field-definition title: "@kbn/management-settings-field-definition" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-field-definition plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-field-definition'] --- import kbnManagementSettingsFieldDefinitionObj from './kbn_management_settings_field_definition.devdocs.json'; diff --git a/api_docs/kbn_management_settings_ids.mdx b/api_docs/kbn_management_settings_ids.mdx index 84a9ff0460b601..bf887b0f0d4951 100644 --- a/api_docs/kbn_management_settings_ids.mdx +++ b/api_docs/kbn_management_settings_ids.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-ids title: "@kbn/management-settings-ids" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-ids plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-ids'] --- import kbnManagementSettingsIdsObj from './kbn_management_settings_ids.devdocs.json'; diff --git a/api_docs/kbn_management_settings_section_registry.mdx b/api_docs/kbn_management_settings_section_registry.mdx index 7de2c8af8f74a2..8d232226abb176 100644 --- a/api_docs/kbn_management_settings_section_registry.mdx +++ b/api_docs/kbn_management_settings_section_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-section-registry title: "@kbn/management-settings-section-registry" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-section-registry plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-section-registry'] --- import kbnManagementSettingsSectionRegistryObj from './kbn_management_settings_section_registry.devdocs.json'; diff --git a/api_docs/kbn_management_settings_types.mdx b/api_docs/kbn_management_settings_types.mdx index 581101683f9d98..52f8367985b17b 100644 --- a/api_docs/kbn_management_settings_types.mdx +++ b/api_docs/kbn_management_settings_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-types title: "@kbn/management-settings-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-types plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-types'] --- import kbnManagementSettingsTypesObj from './kbn_management_settings_types.devdocs.json'; diff --git a/api_docs/kbn_management_settings_utilities.mdx b/api_docs/kbn_management_settings_utilities.mdx index 6f45cd582b1daf..b23991555ea24d 100644 --- a/api_docs/kbn_management_settings_utilities.mdx +++ b/api_docs/kbn_management_settings_utilities.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-utilities title: "@kbn/management-settings-utilities" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-utilities plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-utilities'] --- import kbnManagementSettingsUtilitiesObj from './kbn_management_settings_utilities.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index c0a82642b3e97b..40723ca74a8881 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] --- import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index b87a7f92012cb6..9527a07532e8aa 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_maps_vector_tile_utils.mdx b/api_docs/kbn_maps_vector_tile_utils.mdx index 7e6eeabac50418..d8f183ce4b63ed 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/maps-vector-tile-utils'] --- import kbnMapsVectorTileUtilsObj from './kbn_maps_vector_tile_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index eca8ce4c0ed5e0..c331dda348956d 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_anomaly_utils.mdx b/api_docs/kbn_ml_anomaly_utils.mdx index e52b8338d53550..ef511ba7c9c7a3 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_category_validator.mdx b/api_docs/kbn_ml_category_validator.mdx index 96a8c10ce1221e..1f1403134c7d08 100644 --- a/api_docs/kbn_ml_category_validator.mdx +++ b/api_docs/kbn_ml_category_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-category-validator title: "@kbn/ml-category-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-category-validator plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-category-validator'] --- import kbnMlCategoryValidatorObj from './kbn_ml_category_validator.devdocs.json'; diff --git a/api_docs/kbn_ml_chi2test.mdx b/api_docs/kbn_ml_chi2test.mdx index 4d8fe635e1206e..b4cce1b1f40561 100644 --- a/api_docs/kbn_ml_chi2test.mdx +++ b/api_docs/kbn_ml_chi2test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-chi2test title: "@kbn/ml-chi2test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-chi2test plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-chi2test'] --- import kbnMlChi2testObj from './kbn_ml_chi2test.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index 1ac479cc9ad0c6..fb9f40daf38158 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-frame-analytics-utils'] --- import kbnMlDataFrameAnalyticsUtilsObj from './kbn_ml_data_frame_analytics_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_grid.mdx b/api_docs/kbn_ml_data_grid.mdx index eb54b16550b286..663d847add458f 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-grid'] --- import kbnMlDataGridObj from './kbn_ml_data_grid.devdocs.json'; diff --git a/api_docs/kbn_ml_date_picker.mdx b/api_docs/kbn_ml_date_picker.mdx index 4b38a91390f3e7..55d74f2dc9a788 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-picker'] --- import kbnMlDatePickerObj from './kbn_ml_date_picker.devdocs.json'; diff --git a/api_docs/kbn_ml_date_utils.mdx b/api_docs/kbn_ml_date_utils.mdx index c4e3ad459a8b62..ee875c4b9b0869 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-utils'] --- import kbnMlDateUtilsObj from './kbn_ml_date_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_error_utils.mdx b/api_docs/kbn_ml_error_utils.mdx index 8c5ab1329e5c13..9625b2901c5a64 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_in_memory_table.mdx b/api_docs/kbn_ml_in_memory_table.mdx index 33548ea5b09bfb..d4b84ca095d03f 100644 --- a/api_docs/kbn_ml_in_memory_table.mdx +++ b/api_docs/kbn_ml_in_memory_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-in-memory-table title: "@kbn/ml-in-memory-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-in-memory-table plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-in-memory-table'] --- import kbnMlInMemoryTableObj from './kbn_ml_in_memory_table.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index 07e67b30d3ece7..3e8055e22bfe96 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-defined'] --- import kbnMlIsDefinedObj from './kbn_ml_is_defined.devdocs.json'; diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index 0b743eae485bdb..9b6a1a8d56e4ae 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_kibana_theme.mdx b/api_docs/kbn_ml_kibana_theme.mdx index 9939154aa79fa6..d87dcee33b8345 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-kibana-theme'] --- import kbnMlKibanaThemeObj from './kbn_ml_kibana_theme.devdocs.json'; diff --git a/api_docs/kbn_ml_local_storage.mdx b/api_docs/kbn_ml_local_storage.mdx index 87746d0d4e8002..fb528775d6d6e5 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-local-storage'] --- import kbnMlLocalStorageObj from './kbn_ml_local_storage.devdocs.json'; diff --git a/api_docs/kbn_ml_nested_property.mdx b/api_docs/kbn_ml_nested_property.mdx index 554649dde0947d..104c9bd08cbd00 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-nested-property'] --- import kbnMlNestedPropertyObj from './kbn_ml_nested_property.devdocs.json'; diff --git a/api_docs/kbn_ml_number_utils.mdx b/api_docs/kbn_ml_number_utils.mdx index da82e1a0bb3155..fa5d8a26da85c2 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-number-utils'] --- import kbnMlNumberUtilsObj from './kbn_ml_number_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index 6f150ba5c262fe..f1ec133743bf93 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-query-utils'] --- import kbnMlQueryUtilsObj from './kbn_ml_query_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_random_sampler_utils.mdx b/api_docs/kbn_ml_random_sampler_utils.mdx index cf0c6b27a830a7..d76ce7eb02acc8 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-random-sampler-utils'] --- import kbnMlRandomSamplerUtilsObj from './kbn_ml_random_sampler_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_route_utils.mdx b/api_docs/kbn_ml_route_utils.mdx index 1ef538818c1067..1c4722fb1e2734 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-route-utils'] --- import kbnMlRouteUtilsObj from './kbn_ml_route_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_runtime_field_utils.mdx b/api_docs/kbn_ml_runtime_field_utils.mdx index 37f6d28a5e5421..dfdf19203f1941 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-runtime-field-utils'] --- import kbnMlRuntimeFieldUtilsObj from './kbn_ml_runtime_field_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index ce095c3cb18be5..e4cfbe7a1c1bb3 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index 7945bcea8513a3..857f1f1f627f8c 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_ui_actions.mdx b/api_docs/kbn_ml_ui_actions.mdx index abf54b6acfab8c..161c34fe354465 100644 --- a/api_docs/kbn_ml_ui_actions.mdx +++ b/api_docs/kbn_ml_ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-ui-actions title: "@kbn/ml-ui-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-ui-actions plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-ui-actions'] --- import kbnMlUiActionsObj from './kbn_ml_ui_actions.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index d4cbe6dde603e6..8cd0569d7058b4 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index d5878e4c69cdeb..476a8ca11fe6ef 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_object_versioning.mdx b/api_docs/kbn_object_versioning.mdx index fb0d42a4954e36..e01ef66fd8acee 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index f86fdb41710a9c..d4885592b16373 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_observability_alerting_test_data.mdx b/api_docs/kbn_observability_alerting_test_data.mdx index fe5a6ce52bee5d..a933509a8fc3c5 100644 --- a/api_docs/kbn_observability_alerting_test_data.mdx +++ b/api_docs/kbn_observability_alerting_test_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alerting-test-data title: "@kbn/observability-alerting-test-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alerting-test-data plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alerting-test-data'] --- import kbnObservabilityAlertingTestDataObj from './kbn_observability_alerting_test_data.devdocs.json'; diff --git a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx index c468bf71c06a13..aee6941054ce44 100644 --- a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx +++ b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-get-padded-alert-time-range-util title: "@kbn/observability-get-padded-alert-time-range-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-get-padded-alert-time-range-util plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-get-padded-alert-time-range-util'] --- import kbnObservabilityGetPaddedAlertTimeRangeUtilObj from './kbn_observability_get_padded_alert_time_range_util.devdocs.json'; diff --git a/api_docs/kbn_openapi_bundler.mdx b/api_docs/kbn_openapi_bundler.mdx index 0b9989f5e6ee0c..9c7d00cb1c1ce5 100644 --- a/api_docs/kbn_openapi_bundler.mdx +++ b/api_docs/kbn_openapi_bundler.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-bundler title: "@kbn/openapi-bundler" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-bundler plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-bundler'] --- import kbnOpenapiBundlerObj from './kbn_openapi_bundler.devdocs.json'; diff --git a/api_docs/kbn_openapi_generator.mdx b/api_docs/kbn_openapi_generator.mdx index f4063c9da35db3..d7076d0b70c8c4 100644 --- a/api_docs/kbn_openapi_generator.mdx +++ b/api_docs/kbn_openapi_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-generator title: "@kbn/openapi-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-generator plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-generator'] --- import kbnOpenapiGeneratorObj from './kbn_openapi_generator.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index f8493369a76d7f..40ec00d6629045 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index c5200492fde1b8..1c534416c68cb2 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_osquery_io_ts_types.mdx b/api_docs/kbn_osquery_io_ts_types.mdx index fe239e48b1bb91..afb5c544aeb70e 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_panel_loader.mdx b/api_docs/kbn_panel_loader.mdx index 4f69417afdb49e..2a3e058e47b17a 100644 --- a/api_docs/kbn_panel_loader.mdx +++ b/api_docs/kbn_panel_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-panel-loader title: "@kbn/panel-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/panel-loader plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/panel-loader'] --- import kbnPanelLoaderObj from './kbn_panel_loader.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 684b35cc79146f..ca654854e531d5 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 780791e8fb99a0..cb11ae38713d90 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index a738b8145a3d10..1261d477deec46 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_profiling_utils.mdx b/api_docs/kbn_profiling_utils.mdx index cfeceaa90b0f4d..4975684673070e 100644 --- a/api_docs/kbn_profiling_utils.mdx +++ b/api_docs/kbn_profiling_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-profiling-utils title: "@kbn/profiling-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/profiling-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/profiling-utils'] --- import kbnProfilingUtilsObj from './kbn_profiling_utils.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index 1f04d432111965..bcb68a4999dfa9 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/random-sampling'] --- import kbnRandomSamplingObj from './kbn_random_sampling.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index 463cefa369ca4d..72b5d45ef3804e 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_common.mdx b/api_docs/kbn_react_kibana_context_common.mdx index 31f7c73d6d9ff2..6734b12533be6f 100644 --- a/api_docs/kbn_react_kibana_context_common.mdx +++ b/api_docs/kbn_react_kibana_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-common title: "@kbn/react-kibana-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-common'] --- import kbnReactKibanaContextCommonObj from './kbn_react_kibana_context_common.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_render.mdx b/api_docs/kbn_react_kibana_context_render.mdx index 5f62263cf9abcc..6eaef4024c13f0 100644 --- a/api_docs/kbn_react_kibana_context_render.mdx +++ b/api_docs/kbn_react_kibana_context_render.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-render title: "@kbn/react-kibana-context-render" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-render plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-render'] --- import kbnReactKibanaContextRenderObj from './kbn_react_kibana_context_render.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_root.mdx b/api_docs/kbn_react_kibana_context_root.mdx index e730837d061433..97302f7e5ddefd 100644 --- a/api_docs/kbn_react_kibana_context_root.mdx +++ b/api_docs/kbn_react_kibana_context_root.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-root title: "@kbn/react-kibana-context-root" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-root plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-root'] --- import kbnReactKibanaContextRootObj from './kbn_react_kibana_context_root.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_styled.mdx b/api_docs/kbn_react_kibana_context_styled.mdx index 94f4da60f0299d..766912c60a09c6 100644 --- a/api_docs/kbn_react_kibana_context_styled.mdx +++ b/api_docs/kbn_react_kibana_context_styled.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-styled title: "@kbn/react-kibana-context-styled" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-styled plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-styled'] --- import kbnReactKibanaContextStyledObj from './kbn_react_kibana_context_styled.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_theme.mdx b/api_docs/kbn_react_kibana_context_theme.mdx index 219366b71df2e2..1d96d5a8693f96 100644 --- a/api_docs/kbn_react_kibana_context_theme.mdx +++ b/api_docs/kbn_react_kibana_context_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-theme title: "@kbn/react-kibana-context-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-theme plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-theme'] --- import kbnReactKibanaContextThemeObj from './kbn_react_kibana_context_theme.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_mount.mdx b/api_docs/kbn_react_kibana_mount.mdx index 53845e86f97a0d..3f0fd940b4577c 100644 --- a/api_docs/kbn_react_kibana_mount.mdx +++ b/api_docs/kbn_react_kibana_mount.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-mount title: "@kbn/react-kibana-mount" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-mount plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-mount'] --- import kbnReactKibanaMountObj from './kbn_react_kibana_mount.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index c40beda979a852..2e08a38bd8f2fc 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-file-maps'] --- import kbnRepoFileMapsObj from './kbn_repo_file_maps.devdocs.json'; diff --git a/api_docs/kbn_repo_linter.mdx b/api_docs/kbn_repo_linter.mdx index 5155ff29623954..f462a62afa7693 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-linter'] --- import kbnRepoLinterObj from './kbn_repo_linter.devdocs.json'; diff --git a/api_docs/kbn_repo_path.mdx b/api_docs/kbn_repo_path.mdx index ce1dc3c6496070..9be75b489fe1eb 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-path'] --- import kbnRepoPathObj from './kbn_repo_path.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index cdd494995f0d31..ec1cad8776d5cd 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_reporting_common.mdx b/api_docs/kbn_reporting_common.mdx index 6dc4b9176db772..ae4b0db271aebe 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv.mdx b/api_docs/kbn_reporting_export_types_csv.mdx index 2afa6b59c815a0..93ff6845750a2e 100644 --- a/api_docs/kbn_reporting_export_types_csv.mdx +++ b/api_docs/kbn_reporting_export_types_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv title: "@kbn/reporting-export-types-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv'] --- import kbnReportingExportTypesCsvObj from './kbn_reporting_export_types_csv.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv_common.mdx b/api_docs/kbn_reporting_export_types_csv_common.mdx index dad19846883867..a4d9ea81b1c2c4 100644 --- a/api_docs/kbn_reporting_export_types_csv_common.mdx +++ b/api_docs/kbn_reporting_export_types_csv_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv-common title: "@kbn/reporting-export-types-csv-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv-common'] --- import kbnReportingExportTypesCsvCommonObj from './kbn_reporting_export_types_csv_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf.mdx b/api_docs/kbn_reporting_export_types_pdf.mdx index bc95c41a58d0bf..e9d60015e69f14 100644 --- a/api_docs/kbn_reporting_export_types_pdf.mdx +++ b/api_docs/kbn_reporting_export_types_pdf.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf title: "@kbn/reporting-export-types-pdf" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf'] --- import kbnReportingExportTypesPdfObj from './kbn_reporting_export_types_pdf.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf_common.mdx b/api_docs/kbn_reporting_export_types_pdf_common.mdx index 719d55649c8bf0..d71b6f36a07d24 100644 --- a/api_docs/kbn_reporting_export_types_pdf_common.mdx +++ b/api_docs/kbn_reporting_export_types_pdf_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf-common title: "@kbn/reporting-export-types-pdf-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf-common'] --- import kbnReportingExportTypesPdfCommonObj from './kbn_reporting_export_types_pdf_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png.mdx b/api_docs/kbn_reporting_export_types_png.mdx index 06b238b11b93f4..43e24ba0b2f1f8 100644 --- a/api_docs/kbn_reporting_export_types_png.mdx +++ b/api_docs/kbn_reporting_export_types_png.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png title: "@kbn/reporting-export-types-png" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png'] --- import kbnReportingExportTypesPngObj from './kbn_reporting_export_types_png.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png_common.mdx b/api_docs/kbn_reporting_export_types_png_common.mdx index 6e4772df950b08..180e38e7d74aa6 100644 --- a/api_docs/kbn_reporting_export_types_png_common.mdx +++ b/api_docs/kbn_reporting_export_types_png_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png-common title: "@kbn/reporting-export-types-png-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png-common'] --- import kbnReportingExportTypesPngCommonObj from './kbn_reporting_export_types_png_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_mocks_server.mdx b/api_docs/kbn_reporting_mocks_server.mdx index 57ed195534fede..c8c95aba2fdb6f 100644 --- a/api_docs/kbn_reporting_mocks_server.mdx +++ b/api_docs/kbn_reporting_mocks_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-mocks-server title: "@kbn/reporting-mocks-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-mocks-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-mocks-server'] --- import kbnReportingMocksServerObj from './kbn_reporting_mocks_server.devdocs.json'; diff --git a/api_docs/kbn_reporting_public.mdx b/api_docs/kbn_reporting_public.mdx index c6089a997ac4ec..fe10766f2ff6a7 100644 --- a/api_docs/kbn_reporting_public.mdx +++ b/api_docs/kbn_reporting_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-public title: "@kbn/reporting-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-public plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-public'] --- import kbnReportingPublicObj from './kbn_reporting_public.devdocs.json'; diff --git a/api_docs/kbn_reporting_server.mdx b/api_docs/kbn_reporting_server.mdx index 084a03b76449a6..a7f540efabc238 100644 --- a/api_docs/kbn_reporting_server.mdx +++ b/api_docs/kbn_reporting_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-server title: "@kbn/reporting-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-server'] --- import kbnReportingServerObj from './kbn_reporting_server.devdocs.json'; diff --git a/api_docs/kbn_resizable_layout.mdx b/api_docs/kbn_resizable_layout.mdx index ab6066ff08142b..1f20773ed98cb9 100644 --- a/api_docs/kbn_resizable_layout.mdx +++ b/api_docs/kbn_resizable_layout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-resizable-layout title: "@kbn/resizable-layout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/resizable-layout plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/resizable-layout'] --- import kbnResizableLayoutObj from './kbn_resizable_layout.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 65e8bd6973fa05..4538e15c2dd2e6 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_router_utils.mdx b/api_docs/kbn_router_utils.mdx index 2bbf09bde925fc..46792eff4da48d 100644 --- a/api_docs/kbn_router_utils.mdx +++ b/api_docs/kbn_router_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-router-utils title: "@kbn/router-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/router-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/router-utils'] --- import kbnRouterUtilsObj from './kbn_router_utils.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index 7cec1b9b998bd6..2c87eebdfbf63b 100644 --- a/api_docs/kbn_rrule.mdx +++ b/api_docs/kbn_rrule.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rrule title: "@kbn/rrule" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rrule plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rrule'] --- import kbnRruleObj from './kbn_rrule.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index 2b1e0683f309da..fb82dfcadcaf71 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_saved_objects_settings.mdx b/api_docs/kbn_saved_objects_settings.mdx index 26de1a1841cbb7..af33349d307a50 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_search_api_panels.mdx b/api_docs/kbn_search_api_panels.mdx index 732f1c5da93a09..2a641830beae68 100644 --- a/api_docs/kbn_search_api_panels.mdx +++ b/api_docs/kbn_search_api_panels.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-api-panels title: "@kbn/search-api-panels" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-api-panels plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-api-panels'] --- import kbnSearchApiPanelsObj from './kbn_search_api_panels.devdocs.json'; diff --git a/api_docs/kbn_search_connectors.mdx b/api_docs/kbn_search_connectors.mdx index b5de70f4790aeb..ac28e4ba909945 100644 --- a/api_docs/kbn_search_connectors.mdx +++ b/api_docs/kbn_search_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-connectors title: "@kbn/search-connectors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-connectors plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-connectors'] --- import kbnSearchConnectorsObj from './kbn_search_connectors.devdocs.json'; diff --git a/api_docs/kbn_search_errors.devdocs.json b/api_docs/kbn_search_errors.devdocs.json index ef729a98515f10..897b63cf2bbccc 100644 --- a/api_docs/kbn_search_errors.devdocs.json +++ b/api_docs/kbn_search_errors.devdocs.json @@ -91,6 +91,21 @@ { "parentPluginId": "@kbn/search-errors", "id": "def-common.EsError.Unnamed.$2", + "type": "string", + "tags": [], + "label": "message", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-search-errors/src/es_error.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/search-errors", + "id": "def-common.EsError.Unnamed.$3", "type": "Function", "tags": [], "label": "openInInspector", @@ -114,7 +129,7 @@ "label": "getErrorMessage", "description": [], "signature": [ - "() => JSX.Element | null" + "() => JSX.Element" ], "path": "packages/kbn-search-errors/src/es_error.tsx", "deprecated": false, @@ -130,63 +145,46 @@ "label": "getActions", "description": [], "signature": [ - "(application: ", - { - "pluginId": "@kbn/core-application-browser", - "scope": "common", - "docId": "kibKbnCoreApplicationBrowserPluginApi", - "section": "def-common.ApplicationStart", - "text": "ApplicationStart" - }, - ") => JSX.Element[]" + "() => JSX.Element[]" ], "path": "packages/kbn-search-errors/src/es_error.tsx", "deprecated": false, "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/search-errors", - "id": "def-common.EsError.getActions.$1", - "type": "Object", - "tags": [], - "label": "application", - "description": [], - "signature": [ - { - "pluginId": "@kbn/core-application-browser", - "scope": "common", - "docId": "kibKbnCoreApplicationBrowserPluginApi", - "section": "def-common.ApplicationStart", - "text": "ApplicationStart" - } - ], - "path": "packages/kbn-search-errors/src/es_error.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], + "children": [], "returnComment": [] } ], "initialIsOpen": false - }, + } + ], + "functions": [ { "parentPluginId": "@kbn/search-errors", - "id": "def-common.PainlessError", - "type": "Class", + "id": "def-common.createEsError", + "type": "Function", "tags": [], - "label": "PainlessError", + "label": "createEsError", "description": [], "signature": [ + "(err: ", { "pluginId": "@kbn/search-errors", "scope": "common", "docId": "kibKbnSearchErrorsPluginApi", - "section": "def-common.PainlessError", - "text": "PainlessError" + "section": "def-common.IEsError", + "text": "IEsError" + }, + ", openInInspector: () => void, services: ", + "Services", + ", dataView: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" }, - " extends ", + " | undefined) => ", { "pluginId": "@kbn/search-errors", "scope": "common", @@ -195,187 +193,87 @@ "text": "EsError" } ], - "path": "packages/kbn-search-errors/src/painless_error.tsx", + "path": "packages/kbn-search-errors/src/create_es_error.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "@kbn/search-errors", - "id": "def-common.PainlessError.painlessStack", - "type": "string", - "tags": [], - "label": "painlessStack", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "packages/kbn-search-errors/src/painless_error.tsx", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "@kbn/search-errors", - "id": "def-common.PainlessError.indexPattern", + "id": "def-common.createEsError.$1", "type": "Object", "tags": [], - "label": "indexPattern", + "label": "err", "description": [], "signature": [ { - "pluginId": "dataViews", + "pluginId": "@kbn/search-errors", "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataView", - "text": "DataView" - }, - " | undefined" + "docId": "kibKbnSearchErrorsPluginApi", + "section": "def-common.IEsError", + "text": "IEsError" + } ], - "path": "packages/kbn-search-errors/src/painless_error.tsx", + "path": "packages/kbn-search-errors/src/create_es_error.ts", "deprecated": false, - "trackAdoption": false + "trackAdoption": false, + "isRequired": true }, { "parentPluginId": "@kbn/search-errors", - "id": "def-common.PainlessError.Unnamed", + "id": "def-common.createEsError.$2", "type": "Function", "tags": [], - "label": "Constructor", + "label": "openInInspector", "description": [], "signature": [ - "any" + "() => void" ], - "path": "packages/kbn-search-errors/src/painless_error.tsx", + "path": "packages/kbn-search-errors/src/create_es_error.ts", "deprecated": false, "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/search-errors", - "id": "def-common.PainlessError.Unnamed.$1", - "type": "Object", - "tags": [], - "label": "err", - "description": [], - "signature": [ - { - "pluginId": "@kbn/search-errors", - "scope": "common", - "docId": "kibKbnSearchErrorsPluginApi", - "section": "def-common.IEsError", - "text": "IEsError" - } - ], - "path": "packages/kbn-search-errors/src/painless_error.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/search-errors", - "id": "def-common.PainlessError.Unnamed.$2", - "type": "Function", - "tags": [], - "label": "openInInspector", - "description": [], - "signature": [ - "() => void" - ], - "path": "packages/kbn-search-errors/src/painless_error.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/search-errors", - "id": "def-common.PainlessError.Unnamed.$3", - "type": "Object", - "tags": [], - "label": "indexPattern", - "description": [], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataView", - "text": "DataView" - }, - " | undefined" - ], - "path": "packages/kbn-search-errors/src/painless_error.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": false - } - ], - "returnComment": [] + "isRequired": true }, { "parentPluginId": "@kbn/search-errors", - "id": "def-common.PainlessError.getErrorMessage", - "type": "Function", + "id": "def-common.createEsError.$3", + "type": "Object", "tags": [], - "label": "getErrorMessage", + "label": "services", "description": [], "signature": [ - "() => JSX.Element" + "Services" ], - "path": "packages/kbn-search-errors/src/painless_error.tsx", + "path": "packages/kbn-search-errors/src/create_es_error.ts", "deprecated": false, "trackAdoption": false, - "children": [], - "returnComment": [] + "isRequired": true }, { "parentPluginId": "@kbn/search-errors", - "id": "def-common.PainlessError.getActions", - "type": "Function", + "id": "def-common.createEsError.$4", + "type": "Object", "tags": [], - "label": "getActions", + "label": "dataView", "description": [], "signature": [ - "(application: ", { - "pluginId": "@kbn/core-application-browser", + "pluginId": "dataViews", "scope": "common", - "docId": "kibKbnCoreApplicationBrowserPluginApi", - "section": "def-common.ApplicationStart", - "text": "ApplicationStart" + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" }, - ") => JSX.Element[]" + " | undefined" ], - "path": "packages/kbn-search-errors/src/painless_error.tsx", + "path": "packages/kbn-search-errors/src/create_es_error.ts", "deprecated": false, "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/search-errors", - "id": "def-common.PainlessError.getActions.$1", - "type": "Object", - "tags": [], - "label": "application", - "description": [], - "signature": [ - { - "pluginId": "@kbn/core-application-browser", - "scope": "common", - "docId": "kibKbnCoreApplicationBrowserPluginApi", - "section": "def-common.ApplicationStart", - "text": "ApplicationStart" - } - ], - "path": "packages/kbn-search-errors/src/painless_error.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] + "isRequired": false } ], + "returnComment": [], "initialIsOpen": false - } - ], - "functions": [ + }, { "parentPluginId": "@kbn/search-errors", "id": "def-common.isEsError", @@ -411,54 +309,6 @@ "returnComment": [], "initialIsOpen": false }, - { - "parentPluginId": "@kbn/search-errors", - "id": "def-common.isPainlessError", - "type": "Function", - "tags": [], - "label": "isPainlessError", - "description": [], - "signature": [ - "(err: Error | ", - { - "pluginId": "@kbn/search-errors", - "scope": "common", - "docId": "kibKbnSearchErrorsPluginApi", - "section": "def-common.IEsError", - "text": "IEsError" - }, - ") => boolean" - ], - "path": "packages/kbn-search-errors/src/painless_error.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/search-errors", - "id": "def-common.isPainlessError.$1", - "type": "CompoundType", - "tags": [], - "label": "err", - "description": [], - "signature": [ - "Error | ", - { - "pluginId": "@kbn/search-errors", - "scope": "common", - "docId": "kibKbnSearchErrorsPluginApi", - "section": "def-common.IEsError", - "text": "IEsError" - } - ], - "path": "packages/kbn-search-errors/src/painless_error.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, { "parentPluginId": "@kbn/search-errors", "id": "def-common.renderSearchError", @@ -467,15 +317,7 @@ "label": "renderSearchError", "description": [], "signature": [ - "({\n error,\n application,\n}: { error: Error; application: ", - { - "pluginId": "@kbn/core-application-browser", - "scope": "common", - "docId": "kibKbnCoreApplicationBrowserPluginApi", - "section": "def-common.ApplicationStart", - "text": "ApplicationStart" - }, - "; }) => { title: string; body: React.ReactNode; actions?: React.ReactNode[] | undefined; } | undefined" + "(error: Error) => { title: string; body: React.ReactNode; actions?: React.ReactNode[] | undefined; } | undefined" ], "path": "packages/kbn-search-errors/src/render_search_error.ts", "deprecated": false, @@ -486,47 +328,15 @@ "id": "def-common.renderSearchError.$1", "type": "Object", "tags": [], - "label": "{\n error,\n application,\n}", + "label": "error", "description": [], + "signature": [ + "Error" + ], "path": "packages/kbn-search-errors/src/render_search_error.ts", "deprecated": false, "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/search-errors", - "id": "def-common.renderSearchError.$1.error", - "type": "Object", - "tags": [], - "label": "error", - "description": [], - "signature": [ - "Error" - ], - "path": "packages/kbn-search-errors/src/render_search_error.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "@kbn/search-errors", - "id": "def-common.renderSearchError.$1.application", - "type": "Object", - "tags": [], - "label": "application", - "description": [], - "signature": [ - { - "pluginId": "@kbn/core-application-browser", - "scope": "common", - "docId": "kibKbnCoreApplicationBrowserPluginApi", - "section": "def-common.ApplicationStart", - "text": "ApplicationStart" - } - ], - "path": "packages/kbn-search-errors/src/render_search_error.ts", - "deprecated": false, - "trackAdoption": false - } - ] + "isRequired": true } ], "returnComment": [], diff --git a/api_docs/kbn_search_errors.mdx b/api_docs/kbn_search_errors.mdx index 28044c354967af..76f049106e4647 100644 --- a/api_docs/kbn_search_errors.mdx +++ b/api_docs/kbn_search_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-errors title: "@kbn/search-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-errors plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-errors'] --- import kbnSearchErrorsObj from './kbn_search_errors.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 27 | 1 | 26 | 0 | +| 18 | 1 | 17 | 1 | ## Common diff --git a/api_docs/kbn_search_index_documents.mdx b/api_docs/kbn_search_index_documents.mdx index 4e80f1e09ae492..67a450e95dc029 100644 --- a/api_docs/kbn_search_index_documents.mdx +++ b/api_docs/kbn_search_index_documents.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-index-documents title: "@kbn/search-index-documents" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-index-documents plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-index-documents'] --- import kbnSearchIndexDocumentsObj from './kbn_search_index_documents.devdocs.json'; diff --git a/api_docs/kbn_search_response_warnings.mdx b/api_docs/kbn_search_response_warnings.mdx index 872d1241f4c790..c8733af8f3b4f4 100644 --- a/api_docs/kbn_search_response_warnings.mdx +++ b/api_docs/kbn_search_response_warnings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-response-warnings title: "@kbn/search-response-warnings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-response-warnings plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-response-warnings'] --- import kbnSearchResponseWarningsObj from './kbn_search_response_warnings.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_common.mdx b/api_docs/kbn_security_plugin_types_common.mdx index 7df39a20835e17..361e44f7525b91 100644 --- a/api_docs/kbn_security_plugin_types_common.mdx +++ b/api_docs/kbn_security_plugin_types_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-common title: "@kbn/security-plugin-types-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-common plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-common'] --- import kbnSecurityPluginTypesCommonObj from './kbn_security_plugin_types_common.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_public.mdx b/api_docs/kbn_security_plugin_types_public.mdx index 0311d655af61b9..c1eddbd21e6ecd 100644 --- a/api_docs/kbn_security_plugin_types_public.mdx +++ b/api_docs/kbn_security_plugin_types_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-public title: "@kbn/security-plugin-types-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-public plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-public'] --- import kbnSecurityPluginTypesPublicObj from './kbn_security_plugin_types_public.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_server.mdx b/api_docs/kbn_security_plugin_types_server.mdx index 07bf3b3b1d0531..1ee3409edb4411 100644 --- a/api_docs/kbn_security_plugin_types_server.mdx +++ b/api_docs/kbn_security_plugin_types_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-server title: "@kbn/security-plugin-types-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-server plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-server'] --- import kbnSecurityPluginTypesServerObj from './kbn_security_plugin_types_server.devdocs.json'; diff --git a/api_docs/kbn_security_solution_features.mdx b/api_docs/kbn_security_solution_features.mdx index 2bb23757570cf4..2275e43f86531e 100644 --- a/api_docs/kbn_security_solution_features.mdx +++ b/api_docs/kbn_security_solution_features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-features title: "@kbn/security-solution-features" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-features plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-features'] --- import kbnSecuritySolutionFeaturesObj from './kbn_security_solution_features.devdocs.json'; diff --git a/api_docs/kbn_security_solution_navigation.mdx b/api_docs/kbn_security_solution_navigation.mdx index f276821476701e..e98dcbc0fb3e18 100644 --- a/api_docs/kbn_security_solution_navigation.mdx +++ b/api_docs/kbn_security_solution_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-navigation title: "@kbn/security-solution-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-navigation plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-navigation'] --- import kbnSecuritySolutionNavigationObj from './kbn_security_solution_navigation.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index f7419335104ce8..198fd8d906c6ac 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-side-nav'] --- import kbnSecuritySolutionSideNavObj from './kbn_security_solution_side_nav.devdocs.json'; diff --git a/api_docs/kbn_security_solution_storybook_config.mdx b/api_docs/kbn_security_solution_storybook_config.mdx index daae2d1b00eec3..a86bd69301014d 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-storybook-config'] --- import kbnSecuritySolutionStorybookConfigObj from './kbn_security_solution_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index e919e16c4fb9a3..d46b9573b02abb 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_data_table.mdx b/api_docs/kbn_securitysolution_data_table.mdx index c10215d400df3d..752391b00c71e6 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-data-table'] --- import kbnSecuritysolutionDataTableObj from './kbn_securitysolution_data_table.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_ecs.mdx b/api_docs/kbn_securitysolution_ecs.mdx index a1619d9228776a..1c30c2dd9ddaeb 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-ecs'] --- import kbnSecuritysolutionEcsObj from './kbn_securitysolution_ecs.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index 2e9e3fda3bd739..c69cc00e9bd5d3 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_exception_list_components.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index 2504bf49c085d7..485f91badfd291 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_grouping.mdx b/api_docs/kbn_securitysolution_grouping.mdx index c8566604b272ed..99bcebd52620c4 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-grouping'] --- import kbnSecuritysolutionGroupingObj from './kbn_securitysolution_grouping.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index d55216dc82dc69..daa59d3a14a8fe 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index aa9796b5717ac8..dad69dd4f7d3c3 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index b3ef203a1a3c01..457a7d0f43b9ac 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index 60abe223e006d1..888396c1502592 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index 9b45eb5442f017..6cd8f93dc42ce2 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index 9a894c867b6462..d6e71ec16ff109 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index 696893d05623a2..ce41a5911691f4 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index 38615542414866..f1d90b86434766 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index 67d118226936ed..a17d58fef29578 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index e2c786980f7b8d..5bc2204e82bb74 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index 731f71bba12612..7788a5d4355dd2 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index 80a6ecd781096c..609f341dc1b05b 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index f56737b1185deb..2cc9052e6efbb4 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index 92366c91ca283b..145a3a4e98f6cd 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_common_settings.mdx b/api_docs/kbn_serverless_common_settings.mdx index fba7e624924c96..4d19913b46abcf 100644 --- a/api_docs/kbn_serverless_common_settings.mdx +++ b/api_docs/kbn_serverless_common_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-common-settings title: "@kbn/serverless-common-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-common-settings plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-common-settings'] --- import kbnServerlessCommonSettingsObj from './kbn_serverless_common_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_observability_settings.mdx b/api_docs/kbn_serverless_observability_settings.mdx index bb819172290917..90e9414c322d84 100644 --- a/api_docs/kbn_serverless_observability_settings.mdx +++ b/api_docs/kbn_serverless_observability_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-observability-settings title: "@kbn/serverless-observability-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-observability-settings plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-observability-settings'] --- import kbnServerlessObservabilitySettingsObj from './kbn_serverless_observability_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index d19c30dda087f7..4dae4a8365fb99 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_search_settings.mdx b/api_docs/kbn_serverless_search_settings.mdx index d269700c68f445..1f5140ac73696e 100644 --- a/api_docs/kbn_serverless_search_settings.mdx +++ b/api_docs/kbn_serverless_search_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-search-settings title: "@kbn/serverless-search-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-search-settings plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-search-settings'] --- import kbnServerlessSearchSettingsObj from './kbn_serverless_search_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_security_settings.mdx b/api_docs/kbn_serverless_security_settings.mdx index 69fdcced5a23d1..5e1ef4e7cc4cd8 100644 --- a/api_docs/kbn_serverless_security_settings.mdx +++ b/api_docs/kbn_serverless_security_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-security-settings title: "@kbn/serverless-security-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-security-settings plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-security-settings'] --- import kbnServerlessSecuritySettingsObj from './kbn_serverless_security_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index d10b95719787b4..5e737ffe67b0c2 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-storybook-config'] --- import kbnServerlessStorybookConfigObj from './kbn_serverless_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index 0ac8433ce61cb5..34d9e1cd7c3f8f 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_solution.mdx b/api_docs/kbn_shared_ux_avatar_solution.mdx index 49f1e02ff5c1e4..0edcb0420cf0b3 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index f65e8e2cbf415a..b2a4991f0150db 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 39fc2505531366..731b7d47abda65 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index e71e76571b820e..b402fab6533ba1 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index ffaa19fe356c1d..d2d7c19d98f93b 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_chrome_navigation.mdx b/api_docs/kbn_shared_ux_chrome_navigation.mdx index 171e417021a5c8..2ee426316121dd 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_error_boundary.mdx b/api_docs/kbn_shared_ux_error_boundary.mdx index c50aae83d82f59..50108c9335524e 100644 --- a/api_docs/kbn_shared_ux_error_boundary.mdx +++ b/api_docs/kbn_shared_ux_error_boundary.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-error-boundary title: "@kbn/shared-ux-error-boundary" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-error-boundary plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-error-boundary'] --- import kbnSharedUxErrorBoundaryObj from './kbn_shared_ux_error_boundary.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index 172e010a4c1dc7..a60c0a9caec899 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-context'] --- import kbnSharedUxFileContextObj from './kbn_shared_ux_file_context.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image.mdx b/api_docs/kbn_shared_ux_file_image.mdx index 0900aa85d5405c..564d7c1f72c998 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image'] --- import kbnSharedUxFileImageObj from './kbn_shared_ux_file_image.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image_mocks.mdx b/api_docs/kbn_shared_ux_file_image_mocks.mdx index ef67141bccf4b2..db69b2c21e993f 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image-mocks'] --- import kbnSharedUxFileImageMocksObj from './kbn_shared_ux_file_image_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_mocks.mdx b/api_docs/kbn_shared_ux_file_mocks.mdx index 6b43a7bfaa4f01..ed36cadf1dd827 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-mocks'] --- import kbnSharedUxFileMocksObj from './kbn_shared_ux_file_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_picker.mdx b/api_docs/kbn_shared_ux_file_picker.mdx index b43071a29b928c..9a7b32461ba39e 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-picker'] --- import kbnSharedUxFilePickerObj from './kbn_shared_ux_file_picker.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_types.mdx b/api_docs/kbn_shared_ux_file_types.mdx index 4cd8dafad7582b..f10f62d557f53c 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-types'] --- import kbnSharedUxFileTypesObj from './kbn_shared_ux_file_types.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_upload.mdx b/api_docs/kbn_shared_ux_file_upload.mdx index 46eb79de5c2edd..cadb839de4d01e 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-upload'] --- import kbnSharedUxFileUploadObj from './kbn_shared_ux_file_upload.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_util.mdx b/api_docs/kbn_shared_ux_file_util.mdx index e4edf827ef2cdf..d1ebebbf8a1e0a 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-util'] --- import kbnSharedUxFileUtilObj from './kbn_shared_ux_file_util.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app.mdx b/api_docs/kbn_shared_ux_link_redirect_app.mdx index 983664d389a812..4e23dbadfc9bda 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app'] --- import kbnSharedUxLinkRedirectAppObj from './kbn_shared_ux_link_redirect_app.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index d62e92b1a1e043..23c1ab42492420 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown.mdx b/api_docs/kbn_shared_ux_markdown.mdx index 5ae9195fabe127..4000466839f8f7 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown'] --- import kbnSharedUxMarkdownObj from './kbn_shared_ux_markdown.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown_mocks.mdx b/api_docs/kbn_shared_ux_markdown_mocks.mdx index 48375e038a4af4..6fc345cdff8dc6 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown-mocks'] --- import kbnSharedUxMarkdownMocksObj from './kbn_shared_ux_markdown_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index 796aeae4062e18..4e0c87fcd147ca 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index 6d352e3966d99a..02dd7e6dab7587 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index beb7f0bcab7892..04b9041cfb4daf 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index a82ba439288328..8537917d2ff7a3 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx index 51be93e9e9f2ef..096853f46f3c49 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] --- import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx index c61ba39a573981..8bb57fa2a8302c 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] --- import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx index 720dba137db810..0a73e8c82489c9 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx index 537dff4ff66e15..b3a4be7b334b7c 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx index 2288c1079c75b7..038d4faba2241f 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] --- import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx index 6c0ebc1013fa6f..a8061ccfe81f24 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] --- import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index 725618eba93251..d30b04f051926c 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index d72ca3b1a54060..eb3833fa9b1e08 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index b1361b01291ee1..51da2411721391 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_not_found.mdx b/api_docs/kbn_shared_ux_prompt_not_found.mdx index 4c3e1c497c694d..2c03e16d1fc510 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-not-found'] --- import kbnSharedUxPromptNotFoundObj from './kbn_shared_ux_prompt_not_found.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router.mdx b/api_docs/kbn_shared_ux_router.mdx index e2c9d2f9413cc3..ba28fe3f7d2dc6 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router'] --- import kbnSharedUxRouterObj from './kbn_shared_ux_router.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router_mocks.mdx b/api_docs/kbn_shared_ux_router_mocks.mdx index ee8b10c4ce756d..5709c448d789f2 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router-mocks'] --- import kbnSharedUxRouterMocksObj from './kbn_shared_ux_router_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_config.mdx b/api_docs/kbn_shared_ux_storybook_config.mdx index 9db659968e67ea..9a2940efe64f9a 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-config'] --- import kbnSharedUxStorybookConfigObj from './kbn_shared_ux_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index c089cd897f9bac..fcc8046d13a633 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index 74b36dd06f4583..7c59a633a5dd47 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_slo_schema.mdx b/api_docs/kbn_slo_schema.mdx index 2230d89183b5fa..ceb9a840c2a625 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/slo-schema'] --- import kbnSloSchemaObj from './kbn_slo_schema.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index d3f8fb78d0d67e..b9411bcd7e437a 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 768a8cd40f2e97..61a90c02e971a1 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index b93e1992899585..5d042ac9453c0d 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index bec40b1c04f32b..8c83d7b479f284 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 0ac88141ae1ed7..dafa7e902090fa 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index b31ff349267def..38873e11feae91 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 06f466e44a8200..b6adb6aa52c70d 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index 1181ce81c9fe02..4634783a3495b0 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index 7f126ebb94d9dc..855e9d75cb1472 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 0965a33c7bdd07..a222ccab26b217 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_triggers_actions_ui_types.mdx b/api_docs/kbn_triggers_actions_ui_types.mdx index 09935c9dec33d8..27f68438ecc484 100644 --- a/api_docs/kbn_triggers_actions_ui_types.mdx +++ b/api_docs/kbn_triggers_actions_ui_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-triggers-actions-ui-types title: "@kbn/triggers-actions-ui-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/triggers-actions-ui-types plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/triggers-actions-ui-types'] --- import kbnTriggersActionsUiTypesObj from './kbn_triggers_actions_ui_types.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 6f51d5f3a7c4d2..e51582dcdfc2e2 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ts-projects'] --- import kbnTsProjectsObj from './kbn_ts_projects.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index df3bf00edb00f1..26bd1db7ee89c4 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_actions_browser.mdx b/api_docs/kbn_ui_actions_browser.mdx index 1311abc8cb33bf..b8cba57bb09472 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-actions-browser'] --- import kbnUiActionsBrowserObj from './kbn_ui_actions_browser.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 9623a6b3c92fba..30e320001d442f 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-shared-deps-src'] --- import kbnUiSharedDepsSrcObj from './kbn_ui_shared_deps_src.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index 4fbced2ccff16a..c749f451f72644 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_data_table.mdx b/api_docs/kbn_unified_data_table.mdx index 869008aef7bb30..4764ff63f7c4d4 100644 --- a/api_docs/kbn_unified_data_table.mdx +++ b/api_docs/kbn_unified_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-data-table title: "@kbn/unified-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-data-table plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-data-table'] --- import kbnUnifiedDataTableObj from './kbn_unified_data_table.devdocs.json'; diff --git a/api_docs/kbn_unified_doc_viewer.mdx b/api_docs/kbn_unified_doc_viewer.mdx index 02c1582cafe739..1b0ccd381712a2 100644 --- a/api_docs/kbn_unified_doc_viewer.mdx +++ b/api_docs/kbn_unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-doc-viewer title: "@kbn/unified-doc-viewer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-doc-viewer plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-doc-viewer'] --- import kbnUnifiedDocViewerObj from './kbn_unified_doc_viewer.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index f70078f4c1cb96..2700f12fc973b1 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_unsaved_changes_badge.mdx b/api_docs/kbn_unsaved_changes_badge.mdx index 49242071d22cf1..cef793436ec50b 100644 --- a/api_docs/kbn_unsaved_changes_badge.mdx +++ b/api_docs/kbn_unsaved_changes_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unsaved-changes-badge title: "@kbn/unsaved-changes-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unsaved-changes-badge plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unsaved-changes-badge'] --- import kbnUnsavedChangesBadgeObj from './kbn_unsaved_changes_badge.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index 375f32cca1a6b6..fcac56c602b0e4 100644 --- a/api_docs/kbn_url_state.mdx +++ b/api_docs/kbn_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-url-state title: "@kbn/url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/url-state plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/url-state'] --- import kbnUrlStateObj from './kbn_url_state.devdocs.json'; diff --git a/api_docs/kbn_use_tracked_promise.mdx b/api_docs/kbn_use_tracked_promise.mdx index 0e3f645e97affe..70ee024c368f18 100644 --- a/api_docs/kbn_use_tracked_promise.mdx +++ b/api_docs/kbn_use_tracked_promise.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-use-tracked-promise title: "@kbn/use-tracked-promise" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/use-tracked-promise plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/use-tracked-promise'] --- import kbnUseTrackedPromiseObj from './kbn_use_tracked_promise.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index eb981a467633f3..900a4d6c7bce8a 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index 70a7d2a2a36fbf..98862238bb9097 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index e865b4aa1aca30..819717c4d1ff90 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index 6cb0c354c7e42f..65c46038f6aeb0 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_visualization_ui_components.mdx b/api_docs/kbn_visualization_ui_components.mdx index d5892e8d250072..ed530e49d0d3c2 100644 --- a/api_docs/kbn_visualization_ui_components.mdx +++ b/api_docs/kbn_visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-ui-components title: "@kbn/visualization-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-ui-components plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-ui-components'] --- import kbnVisualizationUiComponentsObj from './kbn_visualization_ui_components.devdocs.json'; diff --git a/api_docs/kbn_visualization_utils.mdx b/api_docs/kbn_visualization_utils.mdx index db9bce5caa52ff..3050f707cb63b4 100644 --- a/api_docs/kbn_visualization_utils.mdx +++ b/api_docs/kbn_visualization_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-utils title: "@kbn/visualization-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-utils'] --- import kbnVisualizationUtilsObj from './kbn_visualization_utils.devdocs.json'; diff --git a/api_docs/kbn_xstate_utils.mdx b/api_docs/kbn_xstate_utils.mdx index 0322596c1aa40a..39f0156a7f3931 100644 --- a/api_docs/kbn_xstate_utils.mdx +++ b/api_docs/kbn_xstate_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-xstate-utils title: "@kbn/xstate-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/xstate-utils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/xstate-utils'] --- import kbnXstateUtilsObj from './kbn_xstate_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index c937220df66e18..4f4441e0d5bcd6 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kbn_zod_helpers.mdx b/api_docs/kbn_zod_helpers.mdx index bf8661b5e7b4d0..e31e880f0303cc 100644 --- a/api_docs/kbn_zod_helpers.mdx +++ b/api_docs/kbn_zod_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-zod-helpers title: "@kbn/zod-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/zod-helpers plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/zod-helpers'] --- import kbnZodHelpersObj from './kbn_zod_helpers.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 515a302398cec4..06bea3a9af2170 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.devdocs.json b/api_docs/kibana_react.devdocs.json index 8d7cb865d9f39b..193309dd1a10c8 100644 --- a/api_docs/kibana_react.devdocs.json +++ b/api_docs/kibana_react.devdocs.json @@ -1535,18 +1535,6 @@ "plugin": "crossClusterReplication", "path": "x-pack/plugins/cross_cluster_replication/public/app/index.tsx" }, - { - "plugin": "globalSearchBar", - "path": "x-pack/plugins/global_search_bar/public/plugin.tsx" - }, - { - "plugin": "globalSearchBar", - "path": "x-pack/plugins/global_search_bar/public/plugin.tsx" - }, - { - "plugin": "globalSearchBar", - "path": "x-pack/plugins/global_search_bar/public/plugin.tsx" - }, { "plugin": "graph", "path": "x-pack/plugins/graph/public/application.tsx" @@ -2758,11 +2746,11 @@ }, { "plugin": "lens", - "path": "x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.ts" + "path": "x-pack/plugins/lens/public/trigger_actions/open_lens_config/edit_action_helpers.ts" }, { "plugin": "lens", - "path": "x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.ts" + "path": "x-pack/plugins/lens/public/trigger_actions/open_lens_config/edit_action_helpers.ts" }, { "plugin": "security", diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index 0b959dc7f193c0..3a736d65bad579 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index c5f2f8fc2ee451..4fecd5e7d96e48 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index 3288494857432f..bcad5afe8964b7 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.devdocs.json b/api_docs/lens.devdocs.json index 48dc406105739b..77331951572fc1 100644 --- a/api_docs/lens.devdocs.json +++ b/api_docs/lens.devdocs.json @@ -502,7 +502,7 @@ "signature": [ "(startDependencies: ", "LensPluginStartDependencies", - ") => Promise" + ", isNewPanel?: boolean | undefined, deletePanel?: (() => void) | undefined) => Promise" ], "path": "x-pack/plugins/lens/public/embeddable/embeddable.tsx", "deprecated": false, @@ -522,6 +522,36 @@ "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "lens", + "id": "def-public.Embeddable.openConfingPanel.$2", + "type": "CompoundType", + "tags": [], + "label": "isNewPanel", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/lens/public/embeddable/embeddable.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + }, + { + "parentPluginId": "lens", + "id": "def-public.Embeddable.openConfingPanel.$3", + "type": "Function", + "tags": [], + "label": "deletePanel", + "description": [], + "signature": [ + "(() => void) | undefined" + ], + "path": "x-pack/plugins/lens/public/embeddable/embeddable.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": false } ], "returnComment": [] diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index dee02d6eee0138..43a45ad70fb15e 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 642 | 0 | 543 | 60 | +| 644 | 0 | 545 | 60 | ## Client diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 65406175b3779c..6a4c82b8a8794e 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index 028dc38a5a860e..c545d98dace7ca 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index c63f1231b414d4..5cdcdabe6ece99 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/links.mdx b/api_docs/links.mdx index 5a61455b54f899..96287b83998f40 100644 --- a/api_docs/links.mdx +++ b/api_docs/links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/links title: "links" image: https://source.unsplash.com/400x175/?github description: API docs for the links plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'links'] --- import linksObj from './links.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 9d0c651ee081d2..c9858c1b336684 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/log_explorer.mdx b/api_docs/log_explorer.mdx index 5ec0351c769a4e..f7d80ed35744e9 100644 --- a/api_docs/log_explorer.mdx +++ b/api_docs/log_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logExplorer title: "logExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the logExplorer plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logExplorer'] --- import logExplorerObj from './log_explorer.devdocs.json'; diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index abc6f480bf76bd..34f168ca6d1cdf 100644 --- a/api_docs/logs_shared.mdx +++ b/api_docs/logs_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsShared title: "logsShared" image: https://source.unsplash.com/400x175/?github description: API docs for the logsShared plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsShared'] --- import logsSharedObj from './logs_shared.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index ce0aac83f4b297..fb75971d421803 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index c90b38e41ad5b1..922773a9fa48e3 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index 3be1cb138f6948..9759248cfe03ec 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/metrics_data_access.mdx b/api_docs/metrics_data_access.mdx index b447b5fee0d23f..9d4a25d840dfe1 100644 --- a/api_docs/metrics_data_access.mdx +++ b/api_docs/metrics_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/metricsDataAccess title: "metricsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the metricsDataAccess plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'metricsDataAccess'] --- import metricsDataAccessObj from './metrics_data_access.devdocs.json'; diff --git a/api_docs/ml.devdocs.json b/api_docs/ml.devdocs.json index 46c0e7d8ec2193..7006f03c266491 100644 --- a/api_docs/ml.devdocs.json +++ b/api_docs/ml.devdocs.json @@ -1942,6 +1942,8 @@ "section": "def-common.ModelDefinitionResponse", "text": "ModelDefinitionResponse" }, + ">; installElasticModel(modelId: string): Promise<", + "MlTrainedModelConfig", ">; }" ], "path": "x-pack/plugins/ml/server/shared.ts", diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 62bd3e5f384eb8..39c8b7f0936bc0 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/mock_idp_plugin.mdx b/api_docs/mock_idp_plugin.mdx index e1fe1f71f6d7f9..d50d6bd0f569e2 100644 --- a/api_docs/mock_idp_plugin.mdx +++ b/api_docs/mock_idp_plugin.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mockIdpPlugin title: "mockIdpPlugin" image: https://source.unsplash.com/400x175/?github description: API docs for the mockIdpPlugin plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mockIdpPlugin'] --- import mockIdpPluginObj from './mock_idp_plugin.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index f3f50e0bce9dfa..e1e604ffd2fa3e 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index b6f63e843feb04..49f02cdd7ef855 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index 3dd539ffa14baf..2606500208d222 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 80236314935b73..1a1a394eb8a864 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/no_data_page.mdx b/api_docs/no_data_page.mdx index eb47ec2711c685..1a945f3286452e 100644 --- a/api_docs/no_data_page.mdx +++ b/api_docs/no_data_page.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/noDataPage title: "noDataPage" image: https://source.unsplash.com/400x175/?github description: API docs for the noDataPage plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'noDataPage'] --- import noDataPageObj from './no_data_page.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index adcdf65421338e..511c367dfd527a 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index f27da99a8627f4..6d84e75abce28e 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_a_i_assistant.mdx b/api_docs/observability_a_i_assistant.mdx index c32c8a3b28b8da..b877662dc6996e 100644 --- a/api_docs/observability_a_i_assistant.mdx +++ b/api_docs/observability_a_i_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAIAssistant title: "observabilityAIAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAIAssistant plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistant'] --- import observabilityAIAssistantObj from './observability_a_i_assistant.devdocs.json'; diff --git a/api_docs/observability_log_explorer.mdx b/api_docs/observability_log_explorer.mdx index 9f33390c3e3fd2..aba2a4083a869d 100644 --- a/api_docs/observability_log_explorer.mdx +++ b/api_docs/observability_log_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityLogExplorer title: "observabilityLogExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityLogExplorer plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityLogExplorer'] --- import observabilityLogExplorerObj from './observability_log_explorer.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index aba1582e714bb8..337c6c985de7c2 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityOnboarding'] --- import observabilityOnboardingObj from './observability_onboarding.devdocs.json'; diff --git a/api_docs/observability_shared.mdx b/api_docs/observability_shared.mdx index 1cb30444ed9157..9961c7ee45b199 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityShared'] --- import observabilitySharedObj from './observability_shared.devdocs.json'; diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index 7c844e7c20890f..5901b5a78fe7ba 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/painless_lab.mdx b/api_docs/painless_lab.mdx index f402851a03758f..76013e66cdf0e7 100644 --- a/api_docs/painless_lab.mdx +++ b/api_docs/painless_lab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/painlessLab title: "painlessLab" image: https://source.unsplash.com/400x175/?github description: API docs for the painlessLab plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'painlessLab'] --- import painlessLabObj from './painless_lab.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 17f08e2dbc8893..4747b5e1d153cf 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,18 +21,18 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 77948 | 234 | 66667 | 1632 | +| 77945 | 234 | 66664 | 1633 | ## Plugin Directory | Plugin name           | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports | |--------------|----------------|-----------|--------------|----------|---------------|--------| -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 269 | 0 | 263 | 31 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 271 | 0 | 265 | 31 | | | [@elastic/appex-sharedux @elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/appex-sharedux ) | - | 17 | 1 | 15 | 2 | | | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 2 | 0 | 2 | 0 | | | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 2 | 0 | 2 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 70 | 1 | 4 | 1 | -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 823 | 1 | 792 | 51 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 825 | 1 | 794 | 51 | | | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | The user interface for Elastic APM | 29 | 0 | 29 | 125 | | | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 9 | 0 | 9 | 0 | | | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | Asset manager plugin for entity assets (inventory, topology, etc) | 9 | 0 | 9 | 2 | @@ -120,7 +120,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | kibanaUsageCollection | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 611 | 3 | 418 | 9 | | | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | - | 5 | 0 | 5 | 1 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 642 | 0 | 543 | 60 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 644 | 0 | 545 | 60 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 8 | 0 | 8 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 4 | 0 | 4 | 1 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 10 | @@ -577,7 +577,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 0 | | | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 75 | 0 | 75 | 0 | | | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 2649 | 0 | 2649 | 0 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 27 | 1 | 26 | 0 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 18 | 1 | 17 | 1 | | | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 25 | 0 | 25 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 20 | 0 | 18 | 1 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 82 | 0 | 35 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 82c72d0602be1a..c5fcf6bfdcb845 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index d86926dbc61249..316aac69a7a248 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/profiling_data_access.mdx b/api_docs/profiling_data_access.mdx index a4dfcf9221f7a1..db31aaa30770b5 100644 --- a/api_docs/profiling_data_access.mdx +++ b/api_docs/profiling_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profilingDataAccess title: "profilingDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the profilingDataAccess plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profilingDataAccess'] --- import profilingDataAccessObj from './profiling_data_access.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index 0e3fc6069c67ef..0c3a29e2f02922 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index f777f625117c2f..0e0f3fa5e0d8bf 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 02240413d6193b..6cd47a02f92ab7 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index 20f9ca21e639c4..d7de2b78ab759f 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index 79e5feb5fdcfe3..4e93860f6f085c 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index 23c28ea734930f..aadb38dd6a1124 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index a0b3d295f0609d..e00b28a628f23f 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index ac7ac641a56a84..93157b055943f1 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 10b8f4ef1b30c7..28287a1053a899 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index 2d2c31c35d6d42..7ddd453c5b9696 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index 080da486d6653e..4d2e24cbe2e679 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index 78133a696a9996..19dd5b85890a5f 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index dc5de4e95bdc1c..3e00d449b78b61 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index d89c9efeeed036..0ede3f065f01e6 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.devdocs.json b/api_docs/security_solution.devdocs.json index a709f1d217625e..90e9ace7ef4dd4 100644 --- a/api_docs/security_solution.devdocs.json +++ b/api_docs/security_solution.devdocs.json @@ -473,7 +473,7 @@ "label": "data", "description": [], "signature": [ - "({ type: \"eql\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; query: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; from: string; to: string; language: \"eql\"; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; index?: string[] | undefined; data_view_id?: string | undefined; filters?: unknown[] | undefined; event_category_override?: string | undefined; tiebreaker_field?: string | undefined; timestamp_field?: string | undefined; } | { type: \"query\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; query: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; from: string; to: string; language: \"kuery\" | \"lucene\"; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; index?: string[] | undefined; filters?: unknown[] | undefined; data_view_id?: string | undefined; saved_id?: string | undefined; response_actions?: ({ params: { query?: string | undefined; ecs_mapping?: Zod.objectOutputType<{}, Zod.ZodObject<{ field: Zod.ZodOptional; value: Zod.ZodOptional]>>; }, \"strip\", Zod.ZodTypeAny, { field?: string | undefined; value?: string | string[] | undefined; }, { field?: string | undefined; value?: string | string[] | undefined; }>, \"strip\"> | undefined; queries?: { id: string; query: string; ecs_mapping?: Zod.objectOutputType<{}, Zod.ZodObject<{ field: Zod.ZodOptional; value: Zod.ZodOptional]>>; }, \"strip\", Zod.ZodTypeAny, { field?: string | undefined; value?: string | string[] | undefined; }, { field?: string | undefined; value?: string | string[] | undefined; }>, \"strip\"> | undefined; version?: string | undefined; platform?: string | undefined; removed?: boolean | undefined; snapshot?: boolean | undefined; }[] | undefined; pack_id?: string | undefined; saved_query_id?: string | undefined; }; action_type_id: \".osquery\"; } | { params: { command: \"isolate\"; comment?: string | undefined; }; action_type_id: \".endpoint\"; })[] | undefined; alert_suppression?: { group_by: string[]; duration?: { value: number; unit: \"m\" | \"h\" | \"s\"; } | undefined; missing_fields_strategy?: \"doNotSuppress\" | \"suppress\" | undefined; } | undefined; } | { type: \"saved_query\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; from: string; to: string; language: \"kuery\" | \"lucene\"; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; saved_id: string; license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; index?: string[] | undefined; query?: string | undefined; filters?: unknown[] | undefined; data_view_id?: string | undefined; response_actions?: ({ params: { query?: string | undefined; ecs_mapping?: Zod.objectOutputType<{}, Zod.ZodObject<{ field: Zod.ZodOptional; value: Zod.ZodOptional]>>; }, \"strip\", Zod.ZodTypeAny, { field?: string | undefined; value?: string | string[] | undefined; }, { field?: string | undefined; value?: string | string[] | undefined; }>, \"strip\"> | undefined; queries?: { id: string; query: string; ecs_mapping?: Zod.objectOutputType<{}, Zod.ZodObject<{ field: Zod.ZodOptional; value: Zod.ZodOptional]>>; }, \"strip\", Zod.ZodTypeAny, { field?: string | undefined; value?: string | string[] | undefined; }, { field?: string | undefined; value?: string | string[] | undefined; }>, \"strip\"> | undefined; version?: string | undefined; platform?: string | undefined; removed?: boolean | undefined; snapshot?: boolean | undefined; }[] | undefined; pack_id?: string | undefined; saved_query_id?: string | undefined; }; action_type_id: \".osquery\"; } | { params: { command: \"isolate\"; comment?: string | undefined; }; action_type_id: \".endpoint\"; })[] | undefined; alert_suppression?: { group_by: string[]; duration?: { value: number; unit: \"m\" | \"h\" | \"s\"; } | undefined; missing_fields_strategy?: \"doNotSuppress\" | \"suppress\" | undefined; } | undefined; } | { type: \"threshold\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; query: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; threshold: { value: number; field: (string | string[]) & (string | string[] | undefined); cardinality?: { value: number; field: string; }[] | undefined; }; from: string; to: string; language: \"kuery\" | \"lucene\"; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; index?: string[] | undefined; filters?: unknown[] | undefined; data_view_id?: string | undefined; saved_id?: string | undefined; alert_suppression?: { duration: { value: number; unit: \"m\" | \"h\" | \"s\"; }; } | undefined; } | { type: \"threat_match\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; query: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; from: string; to: string; language: \"kuery\" | \"lucene\"; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; threat_query: string; threat_mapping: { entries: { type: \"mapping\"; value: string; field: string; }[]; }[]; threat_index: string[]; license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; index?: string[] | undefined; filters?: unknown[] | undefined; data_view_id?: string | undefined; saved_id?: string | undefined; threat_filters?: unknown[] | undefined; threat_indicator_path?: string | undefined; threat_language?: \"lucene\" | \"kuery\" | undefined; concurrent_searches?: number | undefined; items_per_search?: number | undefined; } | { type: \"machine_learning\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; from: string; to: string; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; anomaly_threshold: number; machine_learning_job_id: (string | string[]) & (string | string[] | undefined); license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; } | { type: \"new_terms\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; query: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; from: string; to: string; language: \"kuery\" | \"lucene\"; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; new_terms_fields: string[]; history_window_start: string; license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; index?: string[] | undefined; filters?: unknown[] | undefined; data_view_id?: string | undefined; } | { type: \"esql\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; query: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; from: string; to: string; language: \"esql\"; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; })[]" + "({ type: \"eql\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; query: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; from: string; to: string; language: \"eql\"; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; index?: string[] | undefined; data_view_id?: string | undefined; filters?: unknown[] | undefined; event_category_override?: string | undefined; tiebreaker_field?: string | undefined; timestamp_field?: string | undefined; } | { type: \"query\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; query: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; from: string; to: string; language: \"kuery\" | \"lucene\"; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; index?: string[] | undefined; filters?: unknown[] | undefined; data_view_id?: string | undefined; saved_id?: string | undefined; response_actions?: ({ params: { query?: string | undefined; ecs_mapping?: Zod.objectOutputType<{}, Zod.ZodObject<{ field: Zod.ZodOptional; value: Zod.ZodOptional]>>; }, \"strip\", Zod.ZodTypeAny, { field?: string | undefined; value?: string | string[] | undefined; }, { field?: string | undefined; value?: string | string[] | undefined; }>, \"strip\"> | undefined; queries?: { id: string; query: string; ecs_mapping?: Zod.objectOutputType<{}, Zod.ZodObject<{ field: Zod.ZodOptional; value: Zod.ZodOptional]>>; }, \"strip\", Zod.ZodTypeAny, { field?: string | undefined; value?: string | string[] | undefined; }, { field?: string | undefined; value?: string | string[] | undefined; }>, \"strip\"> | undefined; version?: string | undefined; platform?: string | undefined; removed?: boolean | undefined; snapshot?: boolean | undefined; }[] | undefined; pack_id?: string | undefined; saved_query_id?: string | undefined; timeout?: number | undefined; }; action_type_id: \".osquery\"; } | { params: { command: \"isolate\"; comment?: string | undefined; }; action_type_id: \".endpoint\"; })[] | undefined; alert_suppression?: { group_by: string[]; duration?: { value: number; unit: \"m\" | \"h\" | \"s\"; } | undefined; missing_fields_strategy?: \"doNotSuppress\" | \"suppress\" | undefined; } | undefined; } | { type: \"saved_query\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; from: string; to: string; language: \"kuery\" | \"lucene\"; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; saved_id: string; license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; index?: string[] | undefined; query?: string | undefined; filters?: unknown[] | undefined; data_view_id?: string | undefined; response_actions?: ({ params: { query?: string | undefined; ecs_mapping?: Zod.objectOutputType<{}, Zod.ZodObject<{ field: Zod.ZodOptional; value: Zod.ZodOptional]>>; }, \"strip\", Zod.ZodTypeAny, { field?: string | undefined; value?: string | string[] | undefined; }, { field?: string | undefined; value?: string | string[] | undefined; }>, \"strip\"> | undefined; queries?: { id: string; query: string; ecs_mapping?: Zod.objectOutputType<{}, Zod.ZodObject<{ field: Zod.ZodOptional; value: Zod.ZodOptional]>>; }, \"strip\", Zod.ZodTypeAny, { field?: string | undefined; value?: string | string[] | undefined; }, { field?: string | undefined; value?: string | string[] | undefined; }>, \"strip\"> | undefined; version?: string | undefined; platform?: string | undefined; removed?: boolean | undefined; snapshot?: boolean | undefined; }[] | undefined; pack_id?: string | undefined; saved_query_id?: string | undefined; timeout?: number | undefined; }; action_type_id: \".osquery\"; } | { params: { command: \"isolate\"; comment?: string | undefined; }; action_type_id: \".endpoint\"; })[] | undefined; alert_suppression?: { group_by: string[]; duration?: { value: number; unit: \"m\" | \"h\" | \"s\"; } | undefined; missing_fields_strategy?: \"doNotSuppress\" | \"suppress\" | undefined; } | undefined; } | { type: \"threshold\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; query: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; threshold: { value: number; field: (string | string[]) & (string | string[] | undefined); cardinality?: { value: number; field: string; }[] | undefined; }; from: string; to: string; language: \"kuery\" | \"lucene\"; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; index?: string[] | undefined; filters?: unknown[] | undefined; data_view_id?: string | undefined; saved_id?: string | undefined; alert_suppression?: { duration: { value: number; unit: \"m\" | \"h\" | \"s\"; }; } | undefined; } | { type: \"threat_match\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; query: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; from: string; to: string; language: \"kuery\" | \"lucene\"; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; threat_query: string; threat_mapping: { entries: { type: \"mapping\"; value: string; field: string; }[]; }[]; threat_index: string[]; license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; index?: string[] | undefined; filters?: unknown[] | undefined; data_view_id?: string | undefined; saved_id?: string | undefined; threat_filters?: unknown[] | undefined; threat_indicator_path?: string | undefined; threat_language?: \"lucene\" | \"kuery\" | undefined; concurrent_searches?: number | undefined; items_per_search?: number | undefined; } | { type: \"machine_learning\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; from: string; to: string; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; anomaly_threshold: number; machine_learning_job_id: (string | string[]) & (string | string[] | undefined); license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; } | { type: \"new_terms\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; query: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; from: string; to: string; language: \"kuery\" | \"lucene\"; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; new_terms_fields: string[]; history_window_start: string; license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; index?: string[] | undefined; filters?: unknown[] | undefined; data_view_id?: string | undefined; } | { type: \"esql\"; id: string; name: string; actions: { id: string; params: {} & { [k: string]: unknown; }; group: string; action_type_id: string; uuid?: string | undefined; alerts_filter?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; frequency?: { throttle: string | null; notifyWhen: \"onActionGroupChange\" | \"onActiveAlert\" | \"onThrottleInterval\"; summary: boolean; } | undefined; }[]; tags: string[]; setup: string; description: string; enabled: boolean; revision: number; version: number; references: string[]; interval: string; query: string; risk_score: number; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; from: string; to: string; language: \"esql\"; created_at: string; created_by: string; updated_at: string; updated_by: string; author: string[]; immutable: boolean; rule_id: string; threat: { framework: string; tactic: { id: string; name: string; reference: string; }; technique?: { id: string; name: string; reference: string; subtechnique?: { id: string; name: string; reference: string; }[] | undefined; }[] | undefined; }[]; risk_score_mapping: { value: string; field: string; operator: \"equals\"; risk_score?: number | undefined; }[]; severity_mapping: { value: string; field: string; severity: \"medium\" | \"high\" | \"low\" | \"critical\"; operator: \"equals\"; }[]; exceptions_list: { type: \"endpoint\" | \"detection\" | \"rule_default\" | \"endpoint_trusted_apps\" | \"endpoint_events\" | \"endpoint_host_isolation_exceptions\" | \"endpoint_blocklists\"; id: string; list_id: string; namespace_type: \"single\" | \"agnostic\"; }[]; false_positives: string[]; max_signals: number; related_integrations: { version: string; package: string; integration?: string | undefined; }[]; required_fields: { type: string; name: string; ecs: boolean; }[]; license?: string | undefined; throttle?: string | undefined; outcome?: \"exactMatch\" | \"aliasMatch\" | \"conflict\" | undefined; alias_target_id?: string | undefined; alias_purpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; meta?: Zod.objectOutputType<{}, Zod.ZodUnknown, \"strip\"> | undefined; namespace?: string | undefined; note?: string | undefined; rule_name_override?: string | undefined; timestamp_override?: string | undefined; timestamp_override_fallback_disabled?: boolean | undefined; timeline_id?: string | undefined; timeline_title?: string | undefined; building_block_type?: string | undefined; output_index?: string | undefined; investigation_fields?: { field_names: string[]; } | undefined; execution_summary?: { last_execution: { message: string; date: string; status: \"running\" | \"succeeded\" | \"failed\" | \"going to run\" | \"partial failure\"; metrics: { total_search_duration_ms?: number | undefined; total_indexing_duration_ms?: number | undefined; total_enrichment_duration_ms?: number | undefined; execution_gap_duration_s?: number | undefined; }; status_order: number; }; } | undefined; })[]" ], "path": "x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/types.ts", "deprecated": false, diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 06711003763721..c35d33c5a18303 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/security_solution_ess.mdx b/api_docs/security_solution_ess.mdx index dc8561d3b52e3f..0c8033309906aa 100644 --- a/api_docs/security_solution_ess.mdx +++ b/api_docs/security_solution_ess.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionEss title: "securitySolutionEss" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionEss plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionEss'] --- import securitySolutionEssObj from './security_solution_ess.devdocs.json'; diff --git a/api_docs/security_solution_serverless.mdx b/api_docs/security_solution_serverless.mdx index 5a65ce9ac7880f..52d425948f887e 100644 --- a/api_docs/security_solution_serverless.mdx +++ b/api_docs/security_solution_serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionServerless title: "securitySolutionServerless" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionServerless plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionServerless'] --- import securitySolutionServerlessObj from './security_solution_serverless.devdocs.json'; diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index 79c8072a32a1c5..5a8d4beb657894 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverless'] --- import serverlessObj from './serverless.devdocs.json'; diff --git a/api_docs/serverless_observability.mdx b/api_docs/serverless_observability.mdx index 7968fb6705e856..503bfed68c52f6 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessObservability'] --- import serverlessObservabilityObj from './serverless_observability.devdocs.json'; diff --git a/api_docs/serverless_search.mdx b/api_docs/serverless_search.mdx index 000e66ee1ef3b2..1b254a56e0845f 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 7c69e1e1525817..7df80b70f7d48b 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index 42447b167842d6..7df436cbd7e9f1 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 95286a9e821905..65d446a3668992 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index 01cd1d29fd4e64..3b217b70a5f84e 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index c1c347c643dfc5..41fb5eba150b7e 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/stack_connectors.mdx b/api_docs/stack_connectors.mdx index ebbce17be89c19..db49c370487ca5 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.devdocs.json b/api_docs/task_manager.devdocs.json index 2bc531bde52953..23398830c4a278 100644 --- a/api_docs/task_manager.devdocs.json +++ b/api_docs/task_manager.devdocs.json @@ -387,9 +387,9 @@ "(error: Error, errorSource: ", { "pluginId": "taskManager", - "scope": "server", + "scope": "common", "docId": "kibTaskManagerPluginApi", - "section": "def-server.TaskErrorSource", + "section": "def-common.TaskErrorSource", "text": "TaskErrorSource" }, ") => ", @@ -430,9 +430,9 @@ "signature": [ { "pluginId": "taskManager", - "scope": "server", + "scope": "common", "docId": "kibTaskManagerPluginApi", - "section": "def-server.TaskErrorSource", + "section": "def-common.TaskErrorSource", "text": "TaskErrorSource" } ], @@ -633,15 +633,7 @@ "label": "throwUnrecoverableError", "description": [], "signature": [ - "(error: Error, errorSource: ", - { - "pluginId": "taskManager", - "scope": "server", - "docId": "kibTaskManagerPluginApi", - "section": "def-server.TaskErrorSource", - "text": "TaskErrorSource" - }, - ") => void" + "(error: Error) => void" ], "path": "x-pack/plugins/task_manager/server/task_running/errors.ts", "deprecated": false, @@ -661,27 +653,6 @@ "deprecated": false, "trackAdoption": false, "isRequired": true - }, - { - "parentPluginId": "taskManager", - "id": "def-server.throwUnrecoverableError.$2", - "type": "Enum", - "tags": [], - "label": "errorSource", - "description": [], - "signature": [ - { - "pluginId": "taskManager", - "scope": "server", - "docId": "kibTaskManagerPluginApi", - "section": "def-server.TaskErrorSource", - "text": "TaskErrorSource" - } - ], - "path": "x-pack/plugins/task_manager/server/task_running/errors.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true } ], "returnComment": [], @@ -1021,9 +992,9 @@ "signature": [ { "pluginId": "taskManager", - "scope": "server", + "scope": "common", "docId": "kibTaskManagerPluginApi", - "section": "def-server.TaskErrorSource", + "section": "def-common.TaskErrorSource", "text": "TaskErrorSource" }, " | undefined" @@ -1637,7 +1608,7 @@ "tags": [], "label": "TaskErrorSource", "description": [], - "path": "x-pack/plugins/task_manager/server/task_running/errors.ts", + "path": "x-pack/plugins/task_manager/common/constants.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false @@ -2001,7 +1972,20 @@ "classes": [], "functions": [], "interfaces": [], - "enums": [], + "enums": [ + { + "parentPluginId": "taskManager", + "id": "def-common.TaskErrorSource", + "type": "Enum", + "tags": [], + "label": "TaskErrorSource", + "description": [], + "path": "x-pack/plugins/task_manager/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], "misc": [], "objects": [] } diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index f5720acb909f0f..ae1bc369776341 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; @@ -49,3 +49,8 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o ### Consts, variables and types +## Common + +### Enums + + diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index 2c7e34966b6780..bec624ee7bc0a1 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index b3ece3658ff6c3..022872c85c626d 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index a249b1bc0d5777..e89823beb2c2a8 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 93af855b77f7f5..60093707708af5 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/text_based_languages.mdx b/api_docs/text_based_languages.mdx index 1b843089f13610..856b1a94c8e2a5 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'textBasedLanguages'] --- import textBasedLanguagesObj from './text_based_languages.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 63e264031d3617..5517b603b50168 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 8bda84c44e806e..66a6f9bbf7318d 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index 964343655f031b..aa7207521614e2 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.devdocs.json b/api_docs/triggers_actions_ui.devdocs.json index e33cbc84596e93..fc734b95daecbc 100644 --- a/api_docs/triggers_actions_ui.devdocs.json +++ b/api_docs/triggers_actions_ui.devdocs.json @@ -1026,7 +1026,7 @@ "label": "JsonEditorWithMessageVariables", "description": [], "signature": [ - "({ buttonTitle, messageVariables, paramsProperty, inputTargetValue, label, errors, areaLabel, onDocumentsChange, helpText, onBlur, showButtonTitle, euiCodeEditorProps, }: React.PropsWithChildren) => JSX.Element" + "({ buttonTitle, messageVariables, paramsProperty, inputTargetValue, label, errors, ariaLabel, onDocumentsChange, helpText, onBlur, showButtonTitle, dataTestSubj, euiCodeEditorProps, }: React.PropsWithChildren) => JSX.Element" ], "path": "x-pack/plugins/triggers_actions_ui/public/application/components/json_editor_with_message_variables.tsx", "deprecated": false, @@ -1037,7 +1037,7 @@ "id": "def-public.JsonEditorWithMessageVariables.$1", "type": "CompoundType", "tags": [], - "label": "{\n buttonTitle,\n messageVariables,\n paramsProperty,\n inputTargetValue,\n label,\n errors,\n areaLabel,\n onDocumentsChange,\n helpText,\n onBlur,\n showButtonTitle,\n euiCodeEditorProps = {},\n}", + "label": "{\n buttonTitle,\n messageVariables,\n paramsProperty,\n inputTargetValue,\n label,\n errors,\n ariaLabel,\n onDocumentsChange,\n helpText,\n onBlur,\n showButtonTitle,\n dataTestSubj,\n euiCodeEditorProps = {},\n}", "description": [], "signature": [ "React.PropsWithChildren" diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index 0050e9ce95a4ea..382c520ca566a8 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 6214a4ddeaefa5..1cecdd6add6b23 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index 45c4c1d21ffeda..f91f347581c573 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_doc_viewer.mdx b/api_docs/unified_doc_viewer.mdx index 2e786d70f2f717..a8145a03cb2165 100644 --- a/api_docs/unified_doc_viewer.mdx +++ b/api_docs/unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedDocViewer title: "unifiedDocViewer" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedDocViewer plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedDocViewer'] --- import unifiedDocViewerObj from './unified_doc_viewer.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index b7dfd2a6c836bc..0355b61632ed9d 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index 39c37940556043..ca4811c5b7480f 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 19d4782ec7d6bc..7700de2fe347a1 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/uptime.mdx b/api_docs/uptime.mdx index 4c3129b133478e..d217285af03b66 100644 --- a/api_docs/uptime.mdx +++ b/api_docs/uptime.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uptime title: "uptime" image: https://source.unsplash.com/400x175/?github description: API docs for the uptime plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uptime'] --- import uptimeObj from './uptime.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 5fcc62642813ae..0795f1f3e7f2fa 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index f71b562a622185..e354828fa73608 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index 8a6ba03021b09b..54bbba1608ee52 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index f24bee0440e988..99f394604f8443 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index 4c67dd85451ac6..f1397d08f3774e 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index 74cfe13aba5874..c27b5a2dbab324 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index 750aaaf624e5bb..82cc2e49381ae4 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index 93db8c2d945cba..a21e7b3b2317f6 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index 56292f6063c338..90492ffa341061 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index 7902ca81031435..d9168065f45fd5 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index 5b0bd3b1753aff..96ee0e109ece5b 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 333d3ec33541bc..71faad7c2dad5f 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index 12a82eb484d4c3..6f6eb2244bdce9 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index e10f3831933777..71206e094e36fe 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2023-12-20 +date: 2023-12-21 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From 1f3d3eaaa703ddc470ebe3e2e6140cd068434f14 Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Thu, 21 Dec 2023 09:06:02 +0100 Subject: [PATCH 058/116] [Fleet] adding upgrade details UPG_FAILED check to stuck in updating (#173628) ## Summary Closes https://github.com/elastic/kibana/issues/171419 Added upgrade details check to restart upgrade callout when agent is stuck in updating. Changed the copy slightly when the agent has failed upgrade state. image Existing copy when there is no upgrade details (stuck in updating for more than 2 hours): image Adjusted Agent list tooltip as well if upgrade details state is failed. image ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../fleet/common/services/agent_status.ts | 15 ++++-- .../agents/components/agent_health.test.tsx | 53 +++++++++++++++++++ .../agents/components/agent_health.tsx | 36 +++++++++---- .../translations/translations/fr-FR.json | 1 - .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 6 files changed, 90 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/fleet/common/services/agent_status.ts b/x-pack/plugins/fleet/common/services/agent_status.ts index a7a5257c603b84..78726667f3b13c 100644 --- a/x-pack/plugins/fleet/common/services/agent_status.ts +++ b/x-pack/plugins/fleet/common/services/agent_status.ts @@ -61,10 +61,15 @@ export const AGENT_UPDATING_TIMEOUT_HOURS = 2; export function isStuckInUpdating(agent: Agent): boolean { return ( - agent.status === 'updating' && - !!agent.upgrade_started_at && - !agent.upgraded_at && - Date.now() - Date.parse(agent.upgrade_started_at) > - AGENT_UPDATING_TIMEOUT_HOURS * 60 * 60 * 1000 + (agent.status !== 'offline' && agent.active && isAgentInFailedUpgradeState(agent)) || + (agent.status === 'updating' && + !!agent.upgrade_started_at && + !agent.upgraded_at && + Date.now() - Date.parse(agent.upgrade_started_at) > + AGENT_UPDATING_TIMEOUT_HOURS * 60 * 60 * 1000) ); } + +export function isAgentInFailedUpgradeState(agent: Agent): boolean { + return agent.upgrade_details?.state === 'UPG_FAILED'; +} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.test.tsx index 93646a544bebb8..b55190d848f8a5 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.test.tsx @@ -40,6 +40,8 @@ describe('AgentHealth', () => { true ); + utils.getByText('Agent may be stuck updating.'); + act(() => { fireEvent.click(utils.getByTestId('restartUpgradeBtn')); }); @@ -47,6 +49,56 @@ describe('AgentHealth', () => { utils.findByText('Upgrade Modal'); }); + it('should render agent health with callout when agent has upgrade state failed', () => { + const { utils } = renderAgentHealth( + { + active: true, + status: 'online', + upgrade_started_at: '2022-11-21T12:27:24Z', + upgrade_details: { + state: 'UPG_FAILED', + }, + } as any, + true + ); + + utils.getByText('Agent upgrade is stuck in failed state.'); + + utils.getByTestId('restartUpgradeBtn'); + }); + + it('should not render agent health with callout when agent has upgrade state failed but offline', () => { + const { utils } = renderAgentHealth( + { + active: true, + status: 'offline', + upgrade_started_at: '2022-11-21T12:27:24Z', + upgrade_details: { + state: 'UPG_FAILED', + }, + } as any, + true + ); + + expect(utils.queryByTestId('restartUpgradeBtn')).not.toBeInTheDocument(); + }); + + it('should not render agent health with callout when agent has upgrade state failed but inactive', () => { + const { utils } = renderAgentHealth( + { + active: false, + status: 'unenrolled', + upgrade_started_at: '2022-11-21T12:27:24Z', + upgrade_details: { + state: 'UPG_FAILED', + }, + } as any, + true + ); + + expect(utils.queryByTestId('restartUpgradeBtn')).not.toBeInTheDocument(); + }); + it('should not render agent health with callout when agent not stuck updating', () => { const { utils } = renderAgentHealth( { @@ -58,6 +110,7 @@ describe('AgentHealth', () => { ); expect(utils.queryByTestId('restartUpgradeBtn')).not.toBeInTheDocument(); + expect(utils.queryByText('Agent may be stuck updating.')).not.toBeInTheDocument(); }); it('should not render agent health with callout when not from details', () => { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.tsx index 0cb89b06b62d22..fa8e263c161706 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_health.tsx @@ -23,6 +23,7 @@ import { euiLightVars as euiVars } from '@kbn/ui-theme'; import { getPreviousAgentStatusForOfflineAgents, + isAgentInFailedUpgradeState, isStuckInUpdating, } from '../../../../../../common/services/agent_status'; @@ -152,12 +153,19 @@ export const AgentHealth: React.FunctionComponent = ({ agent, fromDetails

{lastCheckinText}

{lastCheckInMessageText}

{isStuckInUpdating(agent) ? ( -

+ isAgentInFailedUpgradeState(agent) ? ( -

+ ) : ( +

+ +

+ ) ) : null} } @@ -183,17 +191,27 @@ export const AgentHealth: React.FunctionComponent = ({ agent, fromDetails size="m" color="warning" title={ - + isAgentInFailedUpgradeState(agent) ? ( + + ) : ( + + ) } >

diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index e2ae422fddd7b5..1f97750f40911b 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -16579,7 +16579,6 @@ "xpack.fleet.agentFlyout.standaloneRadioOption": "{standaloneMessage} – Exécutez un agent Elastic Agent de façon autonome pour le configurer et le mettre à jour manuellement sur l'hôte sur lequel il est installé.", "xpack.fleet.agentHealth.checkinMessageText": "Dernier message de vérification : {lastCheckinMessage}", "xpack.fleet.agentHealth.checkInTooltipText": "Dernier archivage le {lastCheckIn}", - "xpack.fleet.agentHealth.stuckUpdatingText": "L'agent effectue la mise à jour depuis un certain temps ; il est peut-être bloqué. Envisagez de redémarrer la mise à niveau. {learnMore}", "xpack.fleet.agentList.noFilteredAgentsPrompt": "Aucun agent trouvé. {clearFiltersLink}", "xpack.fleet.agentLogs.logDisabledCallOutDescription": "Mettez à jour la politique de l'agent {settingsLink} pour activer la collecte de logs.", "xpack.fleet.agentLogs.oldAgentWarningTitle": "La vue Logs requiert Elastic Agent 7.11 ou une version ultérieure. Pour mettre à niveau un agent, accédez au menu Actions ou {downloadLink} une version plus récente.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 5097700abe0f48..0bcc41300dc7b5 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -16592,7 +16592,6 @@ "xpack.fleet.agentFlyout.standaloneRadioOption": "{standaloneMessage} – Elasticエージェントをスタンドアロンで実行して、エージェントがインストールされているホストで、手動でエージェントを構成および更新します。", "xpack.fleet.agentHealth.checkinMessageText": "前回のチェックインメッセージ:{lastCheckinMessage}", "xpack.fleet.agentHealth.checkInTooltipText": "前回確認日時:{lastCheckIn}", - "xpack.fleet.agentHealth.stuckUpdatingText": "エージェントはしばらく更新が止まっている可能性があります。アップグレードの再開を検討してください。{learnMore}", "xpack.fleet.agentList.noFilteredAgentsPrompt": "エージェントが見つかりません。{clearFiltersLink}", "xpack.fleet.agentLogs.logDisabledCallOutDescription": "エージェントのポリシー{settingsLink}を更新して、ログ収集を有効にします。", "xpack.fleet.agentLogs.oldAgentWarningTitle": "ログの表示には、Elastic Agent 7.11以降が必要です。エージェントをアップグレードするには、[アクション]メニューに移動するか、新しいバージョンを{downloadLink}。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index bfaf27a55bd58a..9e283e2a5fe0bb 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -16592,7 +16592,6 @@ "xpack.fleet.agentFlyout.standaloneRadioOption": "{standaloneMessage} – 独立运行 Elastic 代理,以在安装代理的主机上手动配置和更新代理。", "xpack.fleet.agentHealth.checkinMessageText": "上次签入消息:{lastCheckinMessage}", "xpack.fleet.agentHealth.checkInTooltipText": "上次签入时间 {lastCheckIn}", - "xpack.fleet.agentHealth.stuckUpdatingText": "代理已更新一段时间,并可能陷入停滞。请考虑重新开始升级。{learnMore}", "xpack.fleet.agentList.noFilteredAgentsPrompt": "找不到代理。{clearFiltersLink}", "xpack.fleet.agentLogs.logDisabledCallOutDescription": "更新代理的策略 {settingsLink} 以启用日志收集。", "xpack.fleet.agentLogs.oldAgentWarningTitle": "“日志”视图需要 Elastic Agent 7.11 或更高版本。要升级代理,请前往“操作”菜单或{downloadLink}更新的版本。", From b40b566e99f1f212fa9c307cd32f29362b433260 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 21 Dec 2023 11:01:15 +0200 Subject: [PATCH 059/116] [ES|QL] Add line breaks redesign (#173596) ## Summary Part of https://github.com/elastic/kibana/issues/171831 Replaces the single boolean button with two ever-present buttons that allow the user to "Add line breaks on pipes" and "Remove line breaks on pipes" image ### Note I had to use the TooltipWrapper and realized we are using this in many places and every time we are duplicating the code. I moved it to visualization-utils and changed the occurences. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../color_ranges_extra_actions.tsx | 2 +- .../color_ranges_item_buttons.tsx | 2 +- packages/kbn-coloring/tsconfig.json | 1 + .../src/text_based_languages_editor.tsx | 130 ++++++++++-------- packages/kbn-text-based-editor/tsconfig.json | 3 +- .../components/color_picker.tsx | 2 +- .../default_bucket_container.tsx | 2 +- .../fields_bucket_container.tsx | 2 +- .../components/index.ts | 2 - .../kbn-visualization-ui-components/index.ts | 1 - .../tsconfig.json | 3 +- packages/kbn-visualization-utils/index.ts | 1 + .../src}/tooltip_wrapper.tsx | 0 .../src/ui/slider_control/index.tsx | 2 +- .../src/ui/slider_control/tooltip_wrapper.tsx | 34 ----- .../kbn-random-sampling/tsconfig.json | 1 + .../graph/public/components/search_bar.tsx | 3 +- .../public/components/tooltip_wrapper.tsx | 34 ----- x-pack/plugins/graph/tsconfig.json | 1 + .../operations/definitions/date_histogram.tsx | 2 +- .../visualizations/gauge/dimension_editor.tsx | 2 +- .../heatmap/toolbar_component.tsx | 2 +- .../appearance_options_popover.tsx | 2 +- .../xy/xy_config_panel/index.tsx | 2 +- .../shared/marker_decoration_settings.tsx | 2 +- .../visual_options_popover/index.tsx | 2 +- x-pack/plugins/lens/tsconfig.json | 3 +- 27 files changed, 95 insertions(+), 148 deletions(-) rename packages/{kbn-visualization-ui-components/components => kbn-visualization-utils/src}/tooltip_wrapper.tsx (100%) delete mode 100644 x-pack/packages/kbn-random-sampling/src/ui/slider_control/tooltip_wrapper.tsx delete mode 100644 x-pack/plugins/graph/public/components/tooltip_wrapper.tsx diff --git a/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_extra_actions.tsx b/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_extra_actions.tsx index e7cdba71008f9a..fa9d09d7a6af04 100644 --- a/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_extra_actions.tsx +++ b/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_extra_actions.tsx @@ -8,11 +8,11 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; +import { TooltipWrapper } from '@kbn/visualization-utils'; import React, { useCallback, Dispatch, useContext } from 'react'; import { EuiFlexGroup, EuiButtonEmpty, EuiFlexItem } from '@elastic/eui'; import { DistributeEquallyIcon } from '../assets/distribute_equally'; -import { TooltipWrapper } from '../tooltip_wrapper'; import type { ColorRangesActions } from './types'; import { ColorRangesContext } from './color_ranges_context'; diff --git a/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item_buttons.tsx b/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item_buttons.tsx index 5cd9bb50bafb19..658d93aebdde3e 100644 --- a/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item_buttons.tsx +++ b/packages/kbn-coloring/src/shared_components/coloring/color_ranges/color_ranges_item_buttons.tsx @@ -10,11 +10,11 @@ import React, { Dispatch, useCallback, useContext } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButtonIcon, EuiIconProps } from '@elastic/eui'; +import { TooltipWrapper } from '@kbn/visualization-utils'; import type { PaletteContinuity, CustomPaletteParams } from '../../../palettes'; import { isLastItem } from './utils'; -import { TooltipWrapper } from '../tooltip_wrapper'; import type { ColorRangesActions, ColorRange, ColorRangeAccessor } from './types'; import { ColorRangesContext } from './color_ranges_context'; diff --git a/packages/kbn-coloring/tsconfig.json b/packages/kbn-coloring/tsconfig.json index 315e59225601ca..3a97faa1b9d3af 100644 --- a/packages/kbn-coloring/tsconfig.json +++ b/packages/kbn-coloring/tsconfig.json @@ -22,6 +22,7 @@ "@kbn/test-jest-helpers", "@kbn/data-plugin", "@kbn/ui-theme", + "@kbn/visualization-utils", ], "exclude": [ "target/**/*", diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx index adcff950575e3b..04e79334cf219f 100644 --- a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx +++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx @@ -22,6 +22,7 @@ import { getAggregateQueryMode, getLanguageDisplayName } from '@kbn/es-query'; import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import type { ExpressionsStart } from '@kbn/expressions-plugin/public'; import type { IndexManagementPluginSetup } from '@kbn/index-management-plugin/public'; +import { TooltipWrapper } from '@kbn/visualization-utils'; import { type LanguageDocumentationSections, LanguageDocumentationPopover, @@ -172,7 +173,6 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ const [showLineNumbers, setShowLineNumbers] = useState(isCodeEditorExpanded); const [isCompactFocused, setIsCompactFocused] = useState(isCodeEditorExpanded); const [isCodeEditorExpandedFocused, setIsCodeEditorExpandedFocused] = useState(false); - const [isWordWrapped, setIsWordWrapped] = useState(false); const [editorMessages, setEditorMessages] = useState<{ errors: MonacoMessage[]; @@ -478,15 +478,14 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ } }, [calculateVisibleCode, code, isCompactFocused, queryString]); - useEffect(() => { - if (isCodeEditorExpanded && !isWordWrapped) { - const pipes = code?.split('|'); - const pipesWithNewLine = code?.split('\n|'); - if (pipes?.length === pipesWithNewLine?.length) { - setIsWordWrapped(true); - } - } - }, [code, isCodeEditorExpanded, isWordWrapped]); + const linesBreaksButtonsStatus = useMemo(() => { + const pipes = code?.split('|'); + const pipesWithNewLine = code?.split('\n|'); + return { + addLineBreaksDisabled: pipes?.length === pipesWithNewLine?.length, + removeLineBreaksDisabled: pipesWithNewLine?.length === 1, + }; + }, [code]); const onResize = ({ width }: { width: number }) => { setIsSpaceReduced(Boolean(editorIsInline && width < BREAKPOINT_WIDTH)); @@ -499,7 +498,6 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ const onQueryUpdate = useCallback( (value: string) => { setCode(value); - setIsWordWrapped(false); onTextLangQueryChange({ [language]: value } as AggregateQuery); }, [language, onTextLangQueryChange] @@ -561,58 +559,72 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ responsive={false} > - + + + { + const updatedCode = getWrappedInPipesCode(code, false); + if (code !== updatedCode) { + setCode(updatedCode); + onTextLangQueryChange({ [language]: updatedCode } as AggregateQuery); + } + }} + /> + + + + + - { - editor1.current?.updateOptions({ - wordWrap: isWordWrapped ? 'off' : 'on', - }); - setIsWordWrapped(!isWordWrapped); - const updatedCode = getWrappedInPipesCode(code, isWordWrapped); - if (code !== updatedCode) { - setCode(updatedCode); - onTextLangQueryChange({ [language]: updatedCode } as AggregateQuery); - } - }} - /> - + )} + isDisabled={linesBreaksButtonsStatus.removeLineBreaksDisabled} + onClick={() => { + const updatedCode = getWrappedInPipesCode(code, true); + if (code !== updatedCode) { + setCode(updatedCode); + onTextLangQueryChange({ [language]: updatedCode } as AggregateQuery); + } + }} + /> + + + diff --git a/packages/kbn-text-based-editor/tsconfig.json b/packages/kbn-text-based-editor/tsconfig.json index 63222d0d6026bb..72240c8aa060d3 100644 --- a/packages/kbn-text-based-editor/tsconfig.json +++ b/packages/kbn-text-based-editor/tsconfig.json @@ -23,7 +23,8 @@ "@kbn/data-plugin", "@kbn/expressions-plugin", "@kbn/data-views-plugin", - "@kbn/index-management-plugin" + "@kbn/index-management-plugin", + "@kbn/visualization-utils" ], "exclude": [ "target/**/*", diff --git a/packages/kbn-visualization-ui-components/components/color_picker.tsx b/packages/kbn-visualization-ui-components/components/color_picker.tsx index 26a428bb17e0b9..3a2613d16d6658 100644 --- a/packages/kbn-visualization-ui-components/components/color_picker.tsx +++ b/packages/kbn-visualization-ui-components/components/color_picker.tsx @@ -8,6 +8,7 @@ import React, { useEffect, useRef, useState } from 'react'; import { i18n } from '@kbn/i18n'; +import { TooltipWrapper } from '@kbn/visualization-utils'; import { EuiFormRow, EuiColorPicker, @@ -17,7 +18,6 @@ import { euiPaletteColorBlind, } from '@elastic/eui'; import { getColorAlpha, makeColorWithAlpha } from '@kbn/coloring'; -import { TooltipWrapper } from './tooltip_wrapper'; const tooltipContent = { auto: i18n.translate('visualizationUiComponents.colorPicker.tooltip.auto', { diff --git a/packages/kbn-visualization-ui-components/components/drag_drop_bucket/default_bucket_container.tsx b/packages/kbn-visualization-ui-components/components/drag_drop_bucket/default_bucket_container.tsx index d73c46064a3ca6..0448e6bda33db8 100644 --- a/packages/kbn-visualization-ui-components/components/drag_drop_bucket/default_bucket_container.tsx +++ b/packages/kbn-visualization-ui-components/components/drag_drop_bucket/default_bucket_container.tsx @@ -16,7 +16,7 @@ import { EuiPanel, useEuiTheme, } from '@elastic/eui'; -import { TooltipWrapper } from '../tooltip_wrapper'; +import { TooltipWrapper } from '@kbn/visualization-utils'; import type { BucketContainerProps } from './types'; export const DefaultBucketContainer = ({ diff --git a/packages/kbn-visualization-ui-components/components/drag_drop_bucket/fields_bucket_container.tsx b/packages/kbn-visualization-ui-components/components/drag_drop_bucket/fields_bucket_container.tsx index cfc5b074b6c335..89f771eef4f01d 100644 --- a/packages/kbn-visualization-ui-components/components/drag_drop_bucket/fields_bucket_container.tsx +++ b/packages/kbn-visualization-ui-components/components/drag_drop_bucket/fields_bucket_container.tsx @@ -16,7 +16,7 @@ import { EuiPanel, useEuiTheme, } from '@elastic/eui'; -import { TooltipWrapper } from '../tooltip_wrapper'; +import { TooltipWrapper } from '@kbn/visualization-utils'; import type { BucketContainerProps } from './types'; export const FieldsBucketContainer = ({ diff --git a/packages/kbn-visualization-ui-components/components/index.ts b/packages/kbn-visualization-ui-components/components/index.ts index e20879f9e99902..88fecd132a8687 100644 --- a/packages/kbn-visualization-ui-components/components/index.ts +++ b/packages/kbn-visualization-ui-components/components/index.ts @@ -14,8 +14,6 @@ export * from './debounced_input'; export * from './debounced_value'; -export * from './tooltip_wrapper'; - export * from './color_picker'; export * from './icon_select'; diff --git a/packages/kbn-visualization-ui-components/index.ts b/packages/kbn-visualization-ui-components/index.ts index 16c51f96a869b4..34c14599d6f00f 100644 --- a/packages/kbn-visualization-ui-components/index.ts +++ b/packages/kbn-visualization-ui-components/index.ts @@ -11,7 +11,6 @@ export { NameInput, DebouncedInput, useDebouncedValue, - TooltipWrapper, ColorPicker, IconSelect, IconSelectSetting, diff --git a/packages/kbn-visualization-ui-components/tsconfig.json b/packages/kbn-visualization-ui-components/tsconfig.json index a9d6627828dc7e..e5dcfa9c5c8584 100644 --- a/packages/kbn-visualization-ui-components/tsconfig.json +++ b/packages/kbn-visualization-ui-components/tsconfig.json @@ -31,6 +31,7 @@ "@kbn/coloring", "@kbn/field-formats-plugin", "@kbn/field-utils", - "@kbn/calculate-width-from-char-count" + "@kbn/calculate-width-from-char-count", + "@kbn/visualization-utils" ], } diff --git a/packages/kbn-visualization-utils/index.ts b/packages/kbn-visualization-utils/index.ts index 7aa0a2c5d770c4..1665599e93d54f 100644 --- a/packages/kbn-visualization-utils/index.ts +++ b/packages/kbn-visualization-utils/index.ts @@ -7,3 +7,4 @@ */ export { getTimeZone } from './src/get_timezone'; +export { TooltipWrapper } from './src/tooltip_wrapper'; diff --git a/packages/kbn-visualization-ui-components/components/tooltip_wrapper.tsx b/packages/kbn-visualization-utils/src/tooltip_wrapper.tsx similarity index 100% rename from packages/kbn-visualization-ui-components/components/tooltip_wrapper.tsx rename to packages/kbn-visualization-utils/src/tooltip_wrapper.tsx diff --git a/x-pack/packages/kbn-random-sampling/src/ui/slider_control/index.tsx b/x-pack/packages/kbn-random-sampling/src/ui/slider_control/index.tsx index 1f7495e4312985..40a9256f9ba079 100644 --- a/x-pack/packages/kbn-random-sampling/src/ui/slider_control/index.tsx +++ b/x-pack/packages/kbn-random-sampling/src/ui/slider_control/index.tsx @@ -8,7 +8,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiRange, EuiText, useEuiTheme } from '@elastic/eui'; import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; -import { TooltipWrapper } from './tooltip_wrapper'; +import { TooltipWrapper } from '@kbn/visualization-utils'; export interface ControlSliderProps { /** Allowed values to show on the Control Slider */ diff --git a/x-pack/packages/kbn-random-sampling/src/ui/slider_control/tooltip_wrapper.tsx b/x-pack/packages/kbn-random-sampling/src/ui/slider_control/tooltip_wrapper.tsx deleted file mode 100644 index 5ab7800e053494..00000000000000 --- a/x-pack/packages/kbn-random-sampling/src/ui/slider_control/tooltip_wrapper.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { EuiToolTip, EuiToolTipProps } from '@elastic/eui'; - -export type TooltipWrapperProps = Partial> & { - tooltipContent: string; - /** When the condition is truthy, the tooltip will be shown */ - condition: boolean; -}; - -export const TooltipWrapper: React.FunctionComponent = ({ - children, - condition, - tooltipContent, - ...tooltipProps -}) => { - return ( - <> - {condition ? ( - - <>{children} - - ) : ( - children - )} - - ); -}; diff --git a/x-pack/packages/kbn-random-sampling/tsconfig.json b/x-pack/packages/kbn-random-sampling/tsconfig.json index 5c5673e4b67870..b4b34fcb94036e 100644 --- a/x-pack/packages/kbn-random-sampling/tsconfig.json +++ b/x-pack/packages/kbn-random-sampling/tsconfig.json @@ -13,6 +13,7 @@ ], "kbn_references": [ "@kbn/i18n-react", + "@kbn/visualization-utils", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/graph/public/components/search_bar.tsx b/x-pack/plugins/graph/public/components/search_bar.tsx index 101a2b3170f0b3..ad604ddc590914 100644 --- a/x-pack/plugins/graph/public/components/search_bar.tsx +++ b/x-pack/plugins/graph/public/components/search_bar.tsx @@ -12,6 +12,7 @@ import { i18n } from '@kbn/i18n'; import { connect } from 'react-redux'; import { toElasticsearchQuery, fromKueryExpression, Query } from '@kbn/es-query'; import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { TooltipWrapper } from '@kbn/visualization-utils'; import { QueryStringInput } from '@kbn/unified-search-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; import { IUnifiedSearchPluginServices } from '@kbn/unified-search-plugin/public/types'; @@ -27,8 +28,6 @@ import { selectedFieldsSelector, } from '../state_management'; -import { TooltipWrapper } from './tooltip_wrapper'; - export interface SearchBarProps { isLoading: boolean; urlQuery: string | null; diff --git a/x-pack/plugins/graph/public/components/tooltip_wrapper.tsx b/x-pack/plugins/graph/public/components/tooltip_wrapper.tsx deleted file mode 100644 index 5ab7800e053494..00000000000000 --- a/x-pack/plugins/graph/public/components/tooltip_wrapper.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { EuiToolTip, EuiToolTipProps } from '@elastic/eui'; - -export type TooltipWrapperProps = Partial> & { - tooltipContent: string; - /** When the condition is truthy, the tooltip will be shown */ - condition: boolean; -}; - -export const TooltipWrapper: React.FunctionComponent = ({ - children, - condition, - tooltipContent, - ...tooltipProps -}) => { - return ( - <> - {condition ? ( - - <>{children} - - ) : ( - children - )} - - ); -}; diff --git a/x-pack/plugins/graph/tsconfig.json b/x-pack/plugins/graph/tsconfig.json index c1fc3807c4c182..0618744404be40 100644 --- a/x-pack/plugins/graph/tsconfig.json +++ b/x-pack/plugins/graph/tsconfig.json @@ -49,6 +49,7 @@ "@kbn/content-management-utils", "@kbn/logging", "@kbn/content-management-table-list-view-common", + "@kbn/visualization-utils", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/date_histogram.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/date_histogram.tsx index bdc88a7cef4527..0d6556344a7102 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/date_histogram.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/date_histogram.tsx @@ -29,7 +29,7 @@ import { } from '@kbn/data-plugin/public'; import { extendedBoundsToAst, intervalOptions } from '@kbn/data-plugin/common'; import { buildExpressionFunction } from '@kbn/expressions-plugin/public'; -import { TooltipWrapper } from '@kbn/visualization-ui-components'; +import { TooltipWrapper } from '@kbn/visualization-utils'; import { updateColumnParam } from '../layer_helpers'; import { OperationDefinition, ParamEditorProps } from '.'; import { FieldBasedIndexPatternColumn } from './column_types'; diff --git a/x-pack/plugins/lens/public/visualizations/gauge/dimension_editor.tsx b/x-pack/plugins/lens/public/visualizations/gauge/dimension_editor.tsx index bd10558d714046..8bd02702c841a9 100644 --- a/x-pack/plugins/lens/public/visualizations/gauge/dimension_editor.tsx +++ b/x-pack/plugins/lens/public/visualizations/gauge/dimension_editor.tsx @@ -25,7 +25,7 @@ import { } from '@kbn/coloring'; import { GaugeTicksPositions, GaugeColorModes } from '@kbn/expression-gauge-plugin/common'; import { getMaxValue, getMinValue } from '@kbn/expression-gauge-plugin/public'; -import { TooltipWrapper } from '@kbn/visualization-ui-components'; +import { TooltipWrapper } from '@kbn/visualization-utils'; import { isNumericFieldForDatatable } from '../../../common/expressions/datatable/utils'; import { applyPaletteParams, PalettePanelContainer } from '../../shared_components'; import type { VisualizationDimensionEditorProps } from '../../types'; diff --git a/x-pack/plugins/lens/public/visualizations/heatmap/toolbar_component.tsx b/x-pack/plugins/lens/public/visualizations/heatmap/toolbar_component.tsx index ebc0b1040623fc..c621a59e9ea9b5 100644 --- a/x-pack/plugins/lens/public/visualizations/heatmap/toolbar_component.tsx +++ b/x-pack/plugins/lens/public/visualizations/heatmap/toolbar_component.tsx @@ -11,7 +11,7 @@ import { Position } from '@elastic/charts'; import { i18n } from '@kbn/i18n'; import { LegendSize } from '@kbn/visualizations-plugin/public'; import { EuiIconAxisLeft, EuiIconAxisBottom } from '@kbn/chart-icons'; -import { TooltipWrapper } from '@kbn/visualization-ui-components'; +import { TooltipWrapper } from '@kbn/visualization-utils'; import type { VisualizationToolbarProps } from '../../types'; import { LegendSettingsPopover, diff --git a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/appearance_options_popover.tsx b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/appearance_options_popover.tsx index fe070e50449d63..ad3215634a2610 100644 --- a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/appearance_options_popover.tsx +++ b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_config_panel/appearance_options_popover.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { TooltipWrapper } from '@kbn/visualization-ui-components'; +import { TooltipWrapper } from '@kbn/visualization-utils'; import { ToolbarPopover } from '../../../shared_components'; import { TitlePositionOptions } from './title_position_option'; import { FramePublicAPI } from '../../../types'; diff --git a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/index.tsx b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/index.tsx index 3697ce988efb5c..a02d4c1d82772a 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/index.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/index.tsx @@ -11,7 +11,7 @@ import { Position, ScaleType } from '@elastic/charts'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { AxisExtentConfig } from '@kbn/expression-xy-plugin/common'; import { LegendSize } from '@kbn/visualizations-plugin/public'; -import { TooltipWrapper } from '@kbn/visualization-ui-components'; +import { TooltipWrapper } from '@kbn/visualization-utils'; import type { LegendSettingsPopoverProps } from '../../../shared_components/legend/legend_settings_popover'; import type { VisualizationToolbarProps, FramePublicAPI } from '../../../types'; import { State, XYState, AxesSettingsConfig } from '../types'; diff --git a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/shared/marker_decoration_settings.tsx b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/shared/marker_decoration_settings.tsx index 3f620a9379538b..e2b149dfc0eb60 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/shared/marker_decoration_settings.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/shared/marker_decoration_settings.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButtonGroup, EuiFormRow } from '@elastic/eui'; import { IconPosition } from '@kbn/expression-xy-plugin/common'; -import { TooltipWrapper } from '@kbn/visualization-ui-components'; +import { TooltipWrapper } from '@kbn/visualization-utils'; import { YAxisMode } from '../../types'; import { idPrefix } from '../dimension_editor'; diff --git a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/visual_options_popover/index.tsx b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/visual_options_popover/index.tsx index bd147779fed8d5..b8b244daf85d29 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/visual_options_popover/index.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/visual_options_popover/index.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { TooltipWrapper } from '@kbn/visualization-ui-components'; +import { TooltipWrapper } from '@kbn/visualization-utils'; import { ToolbarPopover, ValueLabelsSettings } from '../../../../shared_components'; import { MissingValuesOptions } from './missing_values_option'; import { LineCurveOption } from './line_curve_option'; diff --git a/x-pack/plugins/lens/tsconfig.json b/x-pack/plugins/lens/tsconfig.json index dd714b72c998d8..6052ae05d37cfb 100644 --- a/x-pack/plugins/lens/tsconfig.json +++ b/x-pack/plugins/lens/tsconfig.json @@ -97,7 +97,8 @@ "@kbn/shared-ux-button-toolbar", "@kbn/cell-actions", "@kbn/calculate-width-from-char-count", - "@kbn/discover-utils" + "@kbn/discover-utils", + "@kbn/visualization-utils" ], "exclude": [ "target/**/*" From 34a33817a6fe32d97b7c7999fd715d0b23e5b27a Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 21 Dec 2023 11:16:45 +0200 Subject: [PATCH 060/116] [Visualizations] Get dark mode from core theme service (#173715) ## Summary Part of https://github.com/elastic/kibana/issues/173529 Correctly get the darkmode from the core theme --- .../timeseries/public/application/lib/set_is_reversed.js | 6 ++---- src/plugins/vis_types/vega/public/plugin.ts | 5 ++--- src/plugins/vis_types/vega/public/services.ts | 6 ++++-- .../vega/public/vega_view/vega_map_view/view.test.ts | 4 ++-- .../vis_types/vega/public/vega_view/vega_map_view/view.ts | 4 ++-- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/application/lib/set_is_reversed.js b/src/plugins/vis_types/timeseries/public/application/lib/set_is_reversed.js index c2a2b4bb86af1b..e37c55ab8a246c 100644 --- a/src/plugins/vis_types/timeseries/public/application/lib/set_is_reversed.js +++ b/src/plugins/vis_types/timeseries/public/application/lib/set_is_reversed.js @@ -7,9 +7,7 @@ */ import color from 'color'; -import { getUISettings } from '../../services'; - -const isDarkTheme = () => getUISettings().get('theme:darkMode'); +import { getCoreStart } from '../../services'; /** * Returns true if the color that is passed has low luminosity @@ -23,7 +21,7 @@ const isColorDark = (c) => { * Defaults to checking `theme:darkMode`. */ export const isThemeDark = (currentTheme) => { - let themeIsDark = currentTheme || isDarkTheme(); + let themeIsDark = currentTheme || getCoreStart().theme.getTheme().darkMode; // If passing a string, check the luminosity if (typeof currentTheme === 'string') { diff --git a/src/plugins/vis_types/vega/public/plugin.ts b/src/plugins/vis_types/vega/public/plugin.ts index 54f319850d817e..96e383979b854e 100644 --- a/src/plugins/vis_types/vega/public/plugin.ts +++ b/src/plugins/vis_types/vega/public/plugin.ts @@ -20,7 +20,7 @@ import { setData, setDataViews, setInjectedVars, - setUISettings, + setThemeService, setDocLinks, setMapsEms, setUsageCollectionStart, @@ -77,8 +77,6 @@ export class VegaPlugin implements Plugin { enableExternalUrls: this.initializerContext.config.get().enableExternalUrls, }); - setUISettings(core.uiSettings); - const visualizationDependencies: Readonly = { core, plugins: { @@ -104,6 +102,7 @@ export class VegaPlugin implements Plugin { setDataViews(dataViews); setDocLinks(core.docLinks); setMapsEms(mapsEms); + setThemeService(core.theme); setUsageCollectionStart(usageCollection); } } diff --git a/src/plugins/vis_types/vega/public/services.ts b/src/plugins/vis_types/vega/public/services.ts index 4b3e0ca72cdc32..04c5c5cf1f4471 100644 --- a/src/plugins/vis_types/vega/public/services.ts +++ b/src/plugins/vis_types/vega/public/services.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { NotificationsStart, IUiSettingsClient, DocLinksStart } from '@kbn/core/public'; +import type { NotificationsStart, DocLinksStart, ThemeServiceStart } from '@kbn/core/public'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; @@ -22,7 +22,6 @@ export const [getDataViews, setDataViews] = export const [getNotifications, setNotifications] = createGetterSetter('Notifications'); -export const [getUISettings, setUISettings] = createGetterSetter('UISettings'); export const [getMapsEms, setMapsEms] = createGetterSetter('mapsEms'); export const [getInjectedVars, setInjectedVars] = createGetterSetter<{ @@ -35,3 +34,6 @@ export const [getDocLinks, setDocLinks] = createGetterSetter('doc export const [getUsageCollectionStart, setUsageCollectionStart] = createGetterSetter('UsageCollection'); + +export const [getThemeService, setThemeService] = + createGetterSetter('ThemeServiceStart'); diff --git a/src/plugins/vis_types/vega/public/vega_view/vega_map_view/view.test.ts b/src/plugins/vis_types/vega/public/vega_view/vega_map_view/view.test.ts index eafe75534154a7..a42d76681c4ffc 100644 --- a/src/plugins/vis_types/vega/public/vega_view/vega_map_view/view.test.ts +++ b/src/plugins/vis_types/vega/public/vega_view/vega_map_view/view.test.ts @@ -24,7 +24,7 @@ import { setInjectedVars, setData, setNotifications, - setUISettings, + setThemeService, setDataViews, } from '../../services'; import { initVegaLayer, initTmsRasterLayer } from './layers'; @@ -121,7 +121,7 @@ describe('vega_map_view/view', () => { setData(dataPluginStart); setDataViews(dataViewsStart); setNotifications(coreStart.notifications); - setUISettings(coreStart.uiSettings); + setThemeService(coreStart.theme); async function createVegaMapView() { await vegaParser.parseAsync(); diff --git a/src/plugins/vis_types/vega/public/vega_view/vega_map_view/view.ts b/src/plugins/vis_types/vega/public/vega_view/vega_map_view/view.ts index fe1d6a27f3605b..7e4ca5a19dd6a6 100644 --- a/src/plugins/vis_types/vega/public/vega_view/vega_map_view/view.ts +++ b/src/plugins/vis_types/vega/public/vega_view/vega_map_view/view.ts @@ -15,7 +15,7 @@ import { maplibregl } from '@kbn/mapbox-gl'; import { initTmsRasterLayer, initVegaLayer } from './layers'; import { VegaBaseView } from '../vega_base_view'; -import { getUISettings } from '../../services'; +import { getThemeService } from '../../services'; import { defaultMapConfig, defaultMabBoxStyle, vegaLayerId } from './constants'; import { validateZoomSettings, injectMapPropsIntoSpec } from './utils'; @@ -98,7 +98,7 @@ export class VegaMapView extends VegaBaseView { const { mapStyle, emsTileServiceId } = this._parser.mapConfig; // if (mapStyle) { - const isDarkMode: boolean = getUISettings().get('theme:darkMode'); + const isDarkMode: boolean = getThemeService().getTheme().darkMode; return emsTileServiceId ? emsTileServiceId : await this._serviceSettings.getDefaultTmsLayer(isDarkMode); From ae289f0a276d299dd6fabdc34e56c260e1b7d0e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20G=C3=BCrkan=20YALAMAN?= Date: Thu, 21 Dec 2023 10:58:10 +0100 Subject: [PATCH 061/116] [Enterprise Search] Fix Text Extraction toggle (#173590) ## Summary https://github.com/elastic/kibana/assets/1410658/a5980bd7-1290-442e-b2d3-c6a551325de7 Fix use text extraction toggle which removed itself before when toggled. ### Checklist Delete any items that are not applicable to this PR. - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../components/configuration/connector_configuration_form.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/kbn-search-connectors/components/configuration/connector_configuration_form.tsx b/packages/kbn-search-connectors/components/configuration/connector_configuration_form.tsx index af258a807788d0..ca1a2c4e01b93b 100644 --- a/packages/kbn-search-connectors/components/configuration/connector_configuration_form.tsx +++ b/packages/kbn-search-connectors/components/configuration/connector_configuration_form.tsx @@ -137,7 +137,9 @@ export const ConnectorConfigurationForm: React.FC = setConfigEntry={(key, value) => { setConfigView({ ...configView, - advancedConfigurations: { ...configView.advancedConfigurations, [key]: value }, + advancedConfigurations: configView.advancedConfigurations.map((config) => + config.key === key ? { ...config, value } : config + ), }); }} /> From 4f186d0cc5eec718a2570e63ea81b748667388ae Mon Sep 17 00:00:00 2001 From: Konrad Szwarc Date: Thu, 21 Dec 2023 11:43:09 +0100 Subject: [PATCH 062/116] [EDR Workflows] Unskip tests skipped due to agent errors (#173589) https://github.com/elastic/security-team/issues/8244 Needs to be followed-up by https://github.com/elastic/kibana/pull/173591 unskips manually skipped tests from https://github.com/elastic/kibana/pull/173557 unskips CI skipped tests: closes https://github.com/elastic/kibana/issues/173475 closes https://github.com/elastic/kibana/issues/173458 closes https://github.com/elastic/kibana/issues/173456 closes https://github.com/elastic/kibana/issues/173463 closes https://github.com/elastic/kibana/issues/173466 closes https://github.com/elastic/kibana/issues/173467 closes https://github.com/elastic/kibana/issues/173457 closes https://github.com/elastic/kibana/issues/173465 closes https://github.com/elastic/kibana/issues/173459 closes https://github.com/elastic/kibana/issues/173473 closes https://github.com/elastic/kibana/issues/173464 closes https://github.com/elastic/kibana/issues/173471 closes https://github.com/elastic/kibana/issues/173475 closes https://github.com/elastic/kibana/issues/171444 closes https://github.com/elastic/kibana/issues/170816 closes https://github.com/elastic/kibana/issues/170814 closes https://github.com/elastic/kibana/issues/170794 closes https://github.com/elastic/kibana/issues/170706 closes https://github.com/elastic/kibana/issues/170604 closes https://github.com/elastic/kibana/issues/170601 closes https://github.com/elastic/kibana/issues/170563 closes https://github.com/elastic/kibana/issues/170373 closes https://github.com/elastic/kibana/issues/169822 closes https://github.com/elastic/kibana/issues/169821 closes https://github.com/elastic/kibana/issues/168427 --- .../automated_response_actions.cy.ts | 4 +--- .../e2e/response_actions/alerts_response_console.cy.ts | 2 +- .../cypress/e2e/response_actions/document_signing.cy.ts | 3 +-- .../response_actions/endpoints_list_response_console.cy.ts | 4 +--- .../e2e/response_actions/response_console/execute.cy.ts | 4 +--- .../response_actions/response_console/file_operations.cy.ts | 4 +--- .../e2e/response_actions/response_console/isolate.cy.ts | 4 +--- .../response_console/process_operations.cy.ts | 4 +--- .../disabled/unenroll_agent_from_fleet.cy.ts | 4 +--- .../disabled/uninstall_agent_from_host.cy.ts | 3 +-- .../tamper_protection/enabled/unenroll_agent_from_fleet.cy.ts | 4 +--- .../tamper_protection/enabled/uninstall_agent_from_host.cy.ts | 4 +--- ..._from_fleet_changing_policy_from_disabled_to_enabled.cy.ts | 4 +--- ..._from_fleet_changing_policy_from_enabled_to_disabled.cy.ts | 2 +- ...t_from_fleet_changing_policy_from_enabled_to_enabled.cy.ts | 4 +--- ...t_from_host_changing_policy_from_disabled_to_enabled.cy.ts | 4 +--- ...t_from_host_changing_policy_from_enabled_to_disabled.cy.ts | 4 +--- ...nt_from_host_changing_policy_from_enabled_to_enabled.cy.ts | 3 +-- 18 files changed, 18 insertions(+), 47 deletions(-) diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/automated_response_actions.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/automated_response_actions.cy.ts index 305ce11d165efa..1948434b39c9f5 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/automated_response_actions.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/automated_response_actions.cy.ts @@ -20,9 +20,7 @@ import { createEndpointHost } from '../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data'; import { enableAllPolicyProtections } from '../../tasks/endpoint_policy'; -// FLAKY: https://github.com/elastic/kibana/issues/168340 -// FLAKY: https://github.com/elastic/kibana/issues/168427 -describe.skip( +describe( 'Automated Response Actions', { tags: [ diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/alerts_response_console.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/alerts_response_console.cy.ts index 91557f3958f270..e51f75d8eb7373 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/alerts_response_console.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/alerts_response_console.cy.ts @@ -26,7 +26,7 @@ import { enableAllPolicyProtections } from '../../tasks/endpoint_policy'; import { createEndpointHost } from '../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data'; -describe.skip('Response console', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { +describe('Response console', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { let indexedPolicy: IndexedFleetEndpointPolicyResponse; let policy: PolicyData; let createdHost: CreateAndEnrollEndpointHostResponse; diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/document_signing.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/document_signing.cy.ts index 4093581366321e..b8063237260185 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/document_signing.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/document_signing.cy.ts @@ -22,8 +22,7 @@ import { enableAllPolicyProtections } from '../../tasks/endpoint_policy'; import { createEndpointHost } from '../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data'; -// FLAKY: https://github.com/elastic/kibana/issues/170674 -describe.skip('Document signing:', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { +describe('Document signing:', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { let indexedPolicy: IndexedFleetEndpointPolicyResponse; let policy: PolicyData; let createdHost: CreateAndEnrollEndpointHostResponse; diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/endpoints_list_response_console.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/endpoints_list_response_console.cy.ts index e932250dada6bd..75074b0d3f94ab 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/endpoints_list_response_console.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/endpoints_list_response_console.cy.ts @@ -20,9 +20,7 @@ import { enableAllPolicyProtections } from '../../tasks/endpoint_policy'; import { createEndpointHost } from '../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data'; -// FLAKY: https://github.com/elastic/kibana/issues/169821 -// FLAKY: https://github.com/elastic/kibana/issues/169822 -describe.skip('Response console', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { +describe('Response console', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { beforeEach(() => { login(); }); diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/execute.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/execute.cy.ts index 8be29e75ddd9c1..dad573bb09c2bf 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/execute.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/execute.cy.ts @@ -26,9 +26,7 @@ describe('Response console', { tags: ['@ess', '@serverless'] }, () => { login(); }); - // FLAKY: https://github.com/elastic/kibana/issues/170373 - // FLAKY: https://github.com/elastic/kibana/issues/171444 - describe.skip('Execute operations:', () => { + describe('Execute operations:', () => { const homeFilePath = process.env.CI || true ? '/home/vagrant' : `/home/ubuntu`; let indexedPolicy: IndexedFleetEndpointPolicyResponse; diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/file_operations.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/file_operations.cy.ts index a470098b4f55f8..e76a0beb82dca0 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/file_operations.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/file_operations.cy.ts @@ -26,9 +26,7 @@ describe('Response console', { tags: ['@ess', '@serverless'] }, () => { login(); }); - // FLAKY: https://github.com/elastic/kibana/issues/170424 - // FLAKY: https://github.com/elastic/kibana/issues/173456 - describe.skip('File operations:', () => { + describe('File operations:', () => { const homeFilePath = Cypress.env('IS_CI') ? '/home/vagrant' : '/home/ubuntu'; const fileContent = 'This is a test file for the get-file command.'; diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/isolate.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/isolate.cy.ts index fb5fcd0476c14b..44fdf9d63fb68e 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/isolate.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/isolate.cy.ts @@ -26,9 +26,7 @@ import { enableAllPolicyProtections } from '../../../tasks/endpoint_policy'; import { createEndpointHost } from '../../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../../tasks/delete_all_endpoint_data'; -// FLAKY: https://github.com/elastic/kibana/issues/173464 -// FLAKY: https://github.com/elastic/kibana/issues/173465 -describe.skip('Response console', { tags: ['@ess', '@serverless'] }, () => { +describe('Response console', { tags: ['@ess', '@serverless'] }, () => { let indexedPolicy: IndexedFleetEndpointPolicyResponse; let policy: PolicyData; let createdHost: CreateAndEnrollEndpointHostResponse; diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/process_operations.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/process_operations.cy.ts index ba2ebf1c1a88a4..c7120ded692b94 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/process_operations.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/process_operations.cy.ts @@ -24,9 +24,7 @@ import { enableAllPolicyProtections } from '../../../tasks/endpoint_policy'; import { createEndpointHost } from '../../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../../tasks/delete_all_endpoint_data'; -// FLAKY: https://github.com/elastic/kibana/issues/173459 -// FLAKY: https://github.com/elastic/kibana/issues/170563 -describe.skip('Response console', { tags: ['@ess', '@serverless'] }, () => { +describe('Response console', { tags: ['@ess', '@serverless'] }, () => { beforeEach(() => { login(); }); diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/disabled/unenroll_agent_from_fleet.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/disabled/unenroll_agent_from_fleet.cy.ts index 046a185babda35..e0b26bc2f77dd7 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/disabled/unenroll_agent_from_fleet.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/disabled/unenroll_agent_from_fleet.cy.ts @@ -20,9 +20,7 @@ import { enableAllPolicyProtections } from '../../../tasks/endpoint_policy'; import { createEndpointHost } from '../../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../../tasks/delete_all_endpoint_data'; -// FLAKY: https://github.com/elastic/kibana/issues/173463 -// FLAKY: https://github.com/elastic/kibana/issues/170814 -describe.skip( +describe( 'Unenroll agent from fleet with agent tamper protection is disabled', { tags: ['@ess'] }, () => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/disabled/uninstall_agent_from_host.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/disabled/uninstall_agent_from_host.cy.ts index d5b018e9b03a4a..ed47855ac894a6 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/disabled/uninstall_agent_from_host.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/disabled/uninstall_agent_from_host.cy.ts @@ -21,8 +21,7 @@ import { enableAllPolicyProtections } from '../../../tasks/endpoint_policy'; import { createEndpointHost } from '../../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../../tasks/delete_all_endpoint_data'; -// FLAKY: https://github.com/elastic/kibana/issues/173466 -describe.skip( +describe( 'Uninstall agent from host when agent tamper protection is disabled', { tags: ['@ess'] }, () => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/enabled/unenroll_agent_from_fleet.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/enabled/unenroll_agent_from_fleet.cy.ts index cf37edfb0274b7..17cb52c2cb0424 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/enabled/unenroll_agent_from_fleet.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/enabled/unenroll_agent_from_fleet.cy.ts @@ -20,9 +20,7 @@ import { login } from '../../../tasks/login'; import { createEndpointHost } from '../../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../../tasks/delete_all_endpoint_data'; -// FLAKY: https://github.com/elastic/kibana/issues/173460 -// FLAKY: https://github.com/elastic/kibana/issues/170706 -describe.skip( +describe( 'Unenroll agent from fleet when agent tamper protection is enabled', { tags: ['@ess'] }, () => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/enabled/uninstall_agent_from_host.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/enabled/uninstall_agent_from_host.cy.ts index a7220e3bd7f1dc..527566bed608b1 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/enabled/uninstall_agent_from_host.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/enabled/uninstall_agent_from_host.cy.ts @@ -22,9 +22,7 @@ import { login } from '../../../tasks/login'; import { createEndpointHost } from '../../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../../tasks/delete_all_endpoint_data'; -// FLAKY: https://github.com/elastic/kibana/issues/173471 -// FLAKY: https://github.com/elastic/kibana/issues/170601 -describe.skip( +describe( 'Uninstall agent from host when agent tamper protection is enabled', { tags: ['@ess'] }, () => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/unenroll_agent_from_fleet_changing_policy_from_disabled_to_enabled.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/unenroll_agent_from_fleet_changing_policy_from_disabled_to_enabled.cy.ts index 0bd503db67e99b..3d92528c2eee72 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/unenroll_agent_from_fleet_changing_policy_from_disabled_to_enabled.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/unenroll_agent_from_fleet_changing_policy_from_disabled_to_enabled.cy.ts @@ -22,9 +22,7 @@ import { enableAllPolicyProtections } from '../../../tasks/endpoint_policy'; import { createEndpointHost } from '../../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../../tasks/delete_all_endpoint_data'; -// FLAKY: https://github.com/elastic/kibana/issues/173470 -// FLAKY: https://github.com/elastic/kibana/issues/170811 -describe.skip( +describe( 'Unenroll agent from fleet when agent tamper protection is disabled but then is switched to a policy with it enabled', { tags: ['@ess'] }, () => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/unenroll_agent_from_fleet_changing_policy_from_enabled_to_disabled.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/unenroll_agent_from_fleet_changing_policy_from_enabled_to_disabled.cy.ts index d744abcb5b431c..a9508a13f719b3 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/unenroll_agent_from_fleet_changing_policy_from_enabled_to_disabled.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/unenroll_agent_from_fleet_changing_policy_from_enabled_to_disabled.cy.ts @@ -22,7 +22,7 @@ import { enableAllPolicyProtections } from '../../../tasks/endpoint_policy'; import { createEndpointHost } from '../../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../../tasks/delete_all_endpoint_data'; -describe.skip( +describe( 'Unenroll agent from fleet changing when agent tamper protection is enabled but then is switched to a policy with it disabled', { tags: ['@ess'] }, () => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/unenroll_agent_from_fleet_changing_policy_from_enabled_to_enabled.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/unenroll_agent_from_fleet_changing_policy_from_enabled_to_enabled.cy.ts index 55058897c4f95a..a5654734c15e43 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/unenroll_agent_from_fleet_changing_policy_from_enabled_to_enabled.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/unenroll_agent_from_fleet_changing_policy_from_enabled_to_enabled.cy.ts @@ -21,9 +21,7 @@ import { login } from '../../../tasks/login'; import { createEndpointHost } from '../../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../../tasks/delete_all_endpoint_data'; -// FLAKY: https://github.com/elastic/kibana/issues/170816 -// FLAKY: https://github.com/elastic/kibana/issues/173458 -describe.skip( +describe( 'Unenroll agent from fleet changing agent policy when agent tamper protection is enabled but then is switched to a policy with it also enabled', { tags: ['@ess'] }, () => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/uninstall_agent_from_host_changing_policy_from_disabled_to_enabled.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/uninstall_agent_from_host_changing_policy_from_disabled_to_enabled.cy.ts index ebd08694cd9850..bbb675cf56d5ed 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/uninstall_agent_from_host_changing_policy_from_disabled_to_enabled.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/uninstall_agent_from_host_changing_policy_from_disabled_to_enabled.cy.ts @@ -24,9 +24,7 @@ import { enableAllPolicyProtections } from '../../../tasks/endpoint_policy'; import { createEndpointHost } from '../../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../../tasks/delete_all_endpoint_data'; -// FLAKY: https://github.com/elastic/kibana/issues/173475 -// FLAKY: https://github.com/elastic/kibana/issues/170794 -describe.skip( +describe( 'Uninstall agent from host changing agent policy when agent tamper protection is disabled but then is switched to a policy with it enabled', { tags: ['@ess'] }, () => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/uninstall_agent_from_host_changing_policy_from_enabled_to_disabled.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/uninstall_agent_from_host_changing_policy_from_enabled_to_disabled.cy.ts index d01b5cbfdd0867..0768c4a49ca393 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/uninstall_agent_from_host_changing_policy_from_enabled_to_disabled.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/uninstall_agent_from_host_changing_policy_from_enabled_to_disabled.cy.ts @@ -23,9 +23,7 @@ import { enableAllPolicyProtections } from '../../../tasks/endpoint_policy'; import { createEndpointHost } from '../../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../../tasks/delete_all_endpoint_data'; -// FLAKY: https://github.com/elastic/kibana/issues/173457 -// FLAKY: https://github.com/elastic/kibana/issues/170604 -describe.skip( +describe( 'Uninstall agent from host changing agent policy when agent tamper protection is enabled but then is switched to a policy with it disabled', { tags: ['@ess'] }, () => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/uninstall_agent_from_host_changing_policy_from_enabled_to_enabled.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/uninstall_agent_from_host_changing_policy_from_enabled_to_enabled.cy.ts index 379afba46b7fd6..d8630a50a83b99 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/uninstall_agent_from_host_changing_policy_from_enabled_to_enabled.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/tamper_protection/switching_policies/uninstall_agent_from_host_changing_policy_from_enabled_to_enabled.cy.ts @@ -23,8 +23,7 @@ import { login } from '../../../tasks/login'; import { createEndpointHost } from '../../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../../tasks/delete_all_endpoint_data'; -// FLAKY: https://github.com/elastic/kibana/issues/173467 -describe.skip( +describe( 'Uninstall agent from host changing agent policy when agent tamper protection is enabled but then is switched to a policy with it also enabled', { tags: ['@ess'] }, () => { From 7fe9faea3c92198646a4aaf2dfd0e5afccb730b2 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Thu, 21 Dec 2023 11:44:05 +0100 Subject: [PATCH 063/116] Unskip download csv permissions test (#173660) ## Summary close https://github.com/elastic/kibana/issues/172599 I couldn't reproduce the failure, looks like it is very rare. But when reviewing the code I noticed possible race conditions and refactored. Suggest we merge the refactor and observe. Before fix https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4647 100x passed - means flakiness hard to reproduce After fix https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4649 50x passed - still stable --- .../panel_actions/get_csv_panel_action.tsx | 39 +++++++------------ .../security_roles_privileges.ts | 3 +- 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx index 40a231a5220e97..5949131df49a51 100644 --- a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx +++ b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx @@ -44,12 +44,10 @@ export class ReportingCsvPanelAction implements ActionDefinition private isDownloading: boolean; public readonly type = ''; public readonly id = CSV_REPORTING_ACTION; - private licenseHasDownloadCsv: boolean = false; - private capabilityHasDownloadCsv: boolean = false; - private notifications: NotificationsSetup; - private apiClient: ReportingAPIClient; - private startServices$: Params['startServices$']; - private usesUiCapabilities: any; + private readonly notifications: NotificationsSetup; + private readonly apiClient: ReportingAPIClient; + private readonly startServices$: Params['startServices$']; + private readonly usesUiCapabilities: boolean; constructor({ core, apiClient, startServices$, usesUiCapabilities }: Params) { this.isDownloading = false; @@ -78,31 +76,20 @@ export class ReportingCsvPanelAction implements ActionDefinition } public isCompatible = async (context: ActionContext) => { - await new Promise((resolve) => { - this.startServices$.subscribe(([{ application }, { licensing }]) => { - licensing.license$.subscribe((license) => { - const results = license.check('reporting', 'basic'); - const { showLinks } = checkLicense(results); - this.licenseHasDownloadCsv = showLinks; - }); - - if (this.usesUiCapabilities) { - this.capabilityHasDownloadCsv = application.capabilities.dashboard?.downloadCsv === true; - } else { - this.capabilityHasDownloadCsv = true; // deprecated - } - - resolve(); - }); - }); + const { embeddable } = context; - if (!this.licenseHasDownloadCsv || !this.capabilityHasDownloadCsv) { + if (embeddable.type !== 'search') { return false; } - const { embeddable } = context; + const [{ application }, { licensing }] = await firstValueFrom(this.startServices$); + const license = await firstValueFrom(licensing.license$); + const licenseHasDownloadCsv = checkLicense(license.check('reporting', 'basic')).showLinks; + const capabilityHasDownloadCsv = this.usesUiCapabilities + ? application.capabilities.dashboard?.downloadCsv === true + : true; // deprecated - if (embeddable.type !== 'search') { + if (!licenseHasDownloadCsv || !capabilityHasDownloadCsv) { return false; } diff --git a/x-pack/test/reporting_functional/reporting_and_deprecated_security/security_roles_privileges.ts b/x-pack/test/reporting_functional/reporting_and_deprecated_security/security_roles_privileges.ts index acd8b0da9e4c56..f9b84469c1eeeb 100644 --- a/x-pack/test/reporting_functional/reporting_and_deprecated_security/security_roles_privileges.ts +++ b/x-pack/test/reporting_functional/reporting_and_deprecated_security/security_roles_privileges.ts @@ -16,8 +16,7 @@ const CANVAS_TITLE = 'The Very Cool Workpad for PDF Tests'; export default function ({ getService }: FtrProviderContext) { const reportingFunctional = getService('reportingFunctional'); - // FLAKY: https://github.com/elastic/kibana/issues/172599 - describe.skip('Security with `reporting_user` built-in role', () => { + describe('Security with `reporting_user` built-in role', () => { before(async () => { await reportingFunctional.initEcommerce(); }); From 42353e772ce3f7b6dca294d1c0c6fe757d97b24d Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 21 Dec 2023 05:44:48 -0500 Subject: [PATCH 064/116] skip failing test suite (#173804) --- .../rule_bulk_actions/perform_bulk_action_ess.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_bulk_actions/perform_bulk_action_ess.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_bulk_actions/perform_bulk_action_ess.ts index 9d145dc5a7c75b..e85103b67cd22f 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_bulk_actions/perform_bulk_action_ess.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_bulk_actions/perform_bulk_action_ess.ts @@ -62,7 +62,8 @@ export default ({ getService }: FtrProviderContext): void => { const createWebHookConnector = () => createConnector(getWebHookAction()); - describe('@ess perform_bulk_action - ESS specific logic', () => { + // Failing: See https://github.com/elastic/kibana/issues/173804 + describe.skip('@ess perform_bulk_action - ESS specific logic', () => { beforeEach(async () => { await createAlertsIndex(supertest, log); await esArchiver.load('x-pack/test/functional/es_archives/auditbeat/hosts'); From b62f3b7149d1f98367f4283d614970555227963e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Thu, 21 Dec 2023 10:58:59 +0000 Subject: [PATCH 065/116] [Profiling] Enhancing the diff topN functions (#173397) - Removes Co2/Cost settings to use Kibana calculations instead of the values from the APIs - Refactoring Frame information flyout Screenshot 2023-12-14 at 15 25 47 ## How to test it: - Open Flamegraph or Diff Flamegraph and click on `Show more information` in the Tooltip. - Open Functions or Diff Functions and click on the icon on the left side of the table. --- .../server/collectors/management/schema.ts | 4 - .../server/collectors/management/types.ts | 1 - src/plugins/telemetry/schema/oss_plugins.json | 6 - x-pack/plugins/observability/common/index.ts | 1 - .../observability/common/ui_settings_keys.ts | 1 - .../observability/server/ui_settings.ts | 9 - .../e2e/profiling_views/functions.cy.ts | 17 +- .../index.tsx | 177 ++++-- .../flamegraph/flamegraph_tooltip.tsx | 33 +- .../public/components/flamegraph/index.tsx | 30 + .../frame_information_window/empty_frame.tsx | 23 + .../get_impact_rows.tsx | 96 +-- .../frame_information_window/index.tsx | 127 ++-- .../key_value_list.tsx | 11 +- .../components/frames_summary/index.tsx | 116 ++-- .../frames_summary/summary_item.tsx | 20 +- .../topn_functions/function_row.tsx | 41 +- .../components/topn_functions/index.tsx | 553 ++++++++---------- .../components/topn_functions/utils.test.ts | 11 +- .../public/components/topn_functions/utils.ts | 20 + .../use_calculate_impact_estimates.test.ts | 24 - .../hooks/use_calculate_impact_estimates.ts | 29 - .../utils/get_flamegraph_model/index.ts | 32 +- .../differential_flamegraphs/index.tsx | 6 - .../functions/differential_topn/index.tsx | 25 +- 25 files changed, 720 insertions(+), 693 deletions(-) create mode 100644 x-pack/plugins/profiling/public/components/frame_information_window/empty_frame.tsx diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts index 1fa2407cdd2877..b2e2c5ec3f748c 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts @@ -601,10 +601,6 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, }, - 'observability:profilingUseLegacyCo2Calculation': { - type: 'boolean', - _meta: { description: 'Non-default value of setting.' }, - }, 'observability:profilingCostPervCPUPerHour': { type: 'integer', _meta: { description: 'Non-default value of setting.' }, diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index 33518b5389f574..e1de9aa7842d51 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -160,7 +160,6 @@ export interface UsageStats { 'observability:profilingPervCPUWattArm64': number; 'observability:profilingCo2PerKWH': number; 'observability:profilingDatacenterPUE': number; - 'observability:profilingUseLegacyCo2Calculation': boolean; 'observability:profilingCostPervCPUPerHour': number; 'observability:profilingAWSCostDiscountRate': number; } diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index ec17c9b9d1a3b3..e04e83dc46feba 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -10091,12 +10091,6 @@ "description": "Non-default value of setting." } }, - "observability:profilingUseLegacyCo2Calculation": { - "type": "boolean", - "_meta": { - "description": "Non-default value of setting." - } - }, "observability:profilingCostPervCPUPerHour": { "type": "integer", "_meta": { diff --git a/x-pack/plugins/observability/common/index.ts b/x-pack/plugins/observability/common/index.ts index 143bf77a1b0ccb..3bd302b262fbc8 100644 --- a/x-pack/plugins/observability/common/index.ts +++ b/x-pack/plugins/observability/common/index.ts @@ -45,7 +45,6 @@ export { profilingCo2PerKWH, profilingDatacenterPUE, profilingPervCPUWattX86, - profilingUseLegacyCo2Calculation, profilingPervCPUWattArm64, profilingAWSCostDiscountRate, profilingCostPervCPUPerHour, diff --git a/x-pack/plugins/observability/common/ui_settings_keys.ts b/x-pack/plugins/observability/common/ui_settings_keys.ts index bcc2f0451caaca..b647fc8361db85 100644 --- a/x-pack/plugins/observability/common/ui_settings_keys.ts +++ b/x-pack/plugins/observability/common/ui_settings_keys.ts @@ -33,6 +33,5 @@ export const profilingPervCPUWattX86 = 'observability:profilingPerVCPUWattX86'; export const profilingPervCPUWattArm64 = 'observability:profilingPervCPUWattArm64'; export const profilingCo2PerKWH = 'observability:profilingCo2PerKWH'; export const profilingDatacenterPUE = 'observability:profilingDatacenterPUE'; -export const profilingUseLegacyCo2Calculation = 'observability:profilingUseLegacyCo2Calculation'; export const profilingAWSCostDiscountRate = 'observability:profilingAWSCostDiscountRate'; export const profilingCostPervCPUPerHour = 'observability:profilingCostPervCPUPerHour'; diff --git a/x-pack/plugins/observability/server/ui_settings.ts b/x-pack/plugins/observability/server/ui_settings.ts index 8029b412ebb6a4..5890dd4e166111 100644 --- a/x-pack/plugins/observability/server/ui_settings.ts +++ b/x-pack/plugins/observability/server/ui_settings.ts @@ -33,7 +33,6 @@ import { profilingCo2PerKWH, profilingDatacenterPUE, profilingPervCPUWattX86, - profilingUseLegacyCo2Calculation, profilingPervCPUWattArm64, profilingAWSCostDiscountRate, profilingCostPervCPUPerHour, @@ -479,14 +478,6 @@ export const uiSettings: Record = { schema: schema.number({ min: 0 }), requiresPageReload: true, }, - [profilingUseLegacyCo2Calculation]: { - category: [observabilityFeatureId], - name: i18n.translate('xpack.observability.profilingUseLegacyCo2Calculation', { - defaultMessage: 'Use legacy CO2 and Dollar cost calculations in Universal Profiling', - }), - value: false, - schema: schema.boolean(), - }, [profilingAWSCostDiscountRate]: { category: [observabilityFeatureId], name: i18n.translate('xpack.observability.profilingAWSCostDiscountRateUiSettingName', { diff --git a/x-pack/plugins/profiling/e2e/cypress/e2e/profiling_views/functions.cy.ts b/x-pack/plugins/profiling/e2e/cypress/e2e/profiling_views/functions.cy.ts index 272b5a1743d658..b2f3f743df37ed 100644 --- a/x-pack/plugins/profiling/e2e/cypress/e2e/profiling_views/functions.cy.ts +++ b/x-pack/plugins/profiling/e2e/cypress/e2e/profiling_views/functions.cy.ts @@ -174,9 +174,8 @@ describe('Functions page', () => { cy.get(firstRowSelector).eq(2).contains('/'); }); - // skipping this for now until the values are passed to the ES plugin - describe.skip('Test changing CO2 settings', () => { - afterEach(() => { + describe('Test changing CO2 settings', () => { + after(() => { cy.updateAdvancedSettings({ [profilingCo2PerKWH]: 0.000379069, [profilingDatacenterPUE]: 1.7, @@ -190,7 +189,7 @@ describe('Functions page', () => { const firstRowSelector = '[data-grid-row-index="0"] [data-test-subj="dataGridRowCell"]'; cy.get(firstRowSelector).eq(1).contains('1'); cy.get(firstRowSelector).eq(2).contains('vmlinux'); - cy.get(firstRowSelector).eq(5).contains('1.84 lbs / 0.84 kg'); + cy.get(firstRowSelector).eq(5).contains('4.07 lbs / 1.84 kg'); cy.contains('Settings').click(); cy.contains('Advanced Settings'); cy.get(`[data-test-subj="advancedSetting-editField-${profilingCo2PerKWH}"]`) @@ -209,22 +208,22 @@ describe('Functions page', () => { }); cy.go('back'); cy.wait('@getTopNFunctions'); - cy.get(firstRowSelector).eq(5).contains('24.22k lbs / 10.99k'); + cy.get(firstRowSelector).eq(5).contains('1.87k lbs / 847.83 kg'); const firstRowSelectorActionButton = '[data-grid-row-index="0"] [data-test-subj="dataGridRowCell"] .euiButtonIcon'; cy.get(firstRowSelectorActionButton).click(); [ - { parentKey: 'impactEstimates', key: 'co2Emission', value: '0.02 lbs / 0.01 kg' }, - { parentKey: 'impactEstimates', key: 'selfCo2Emission', value: '0.02 lbs / 0.01 kg' }, + { parentKey: 'impactEstimates', key: 'co2Emission', value: '~0.00 lbs / ~0.00 kg' }, + { parentKey: 'impactEstimates', key: 'selfCo2Emission', value: '~0.00 lbs / ~0.00 kg' }, { parentKey: 'impactEstimates', key: 'annualizedCo2Emission', - value: '24.22k lbs / 10.99k kg', + value: '1.87k lbs / 847.83 kg', }, { parentKey: 'impactEstimates', key: 'annualizedSelfCo2Emission', - value: '24.22k lbs / 10.99k kg', + value: '1.87k lbs / 847.83 kg', }, ].forEach(({ parentKey, key, value }) => { cy.get(`[data-test-subj="${parentKey}_${key}"]`).contains(value); diff --git a/x-pack/plugins/profiling/public/components/differential_topn_functions_grid/index.tsx b/x-pack/plugins/profiling/public/components/differential_topn_functions_grid/index.tsx index 621a3b2ba0329c..d31090f9c8c823 100644 --- a/x-pack/plugins/profiling/public/components/differential_topn_functions_grid/index.tsx +++ b/x-pack/plugins/profiling/public/components/differential_topn_functions_grid/index.tsx @@ -6,10 +6,12 @@ */ import { + EuiButtonIcon, EuiDataGrid, EuiDataGridCellValueElementProps, EuiDataGridColumn, EuiDataGridSorting, + EuiScreenReaderOnly, useEuiTheme, } from '@elastic/eui'; import { css } from '@emotion/react'; @@ -24,8 +26,14 @@ import { import { orderBy } from 'lodash'; import React, { useEffect, useMemo, useState } from 'react'; import { useCalculateImpactEstimate } from '../../hooks/use_calculate_impact_estimates'; +import { FrameInformationTooltip } from '../frame_information_window/frame_information_tooltip'; import { FunctionRow } from '../topn_functions/function_row'; -import { getFunctionsRows, IFunctionRow } from '../topn_functions/utils'; +import { + convertRowToFrame, + getFunctionsRows, + getTotalCount, + IFunctionRow, +} from '../topn_functions/utils'; import { getColumns } from './get_columns'; import { getCompareFrameAction } from './get_compare_frame_action'; @@ -83,6 +91,7 @@ interface Props { comparisonSortDirection: 'asc' | 'desc'; comparisonSortField: TopNComparisonFunctionSortField; totalSeconds: number; + comparisonTotalSeconds: number; } export function DifferentialTopNFunctionsGrid({ @@ -90,27 +99,27 @@ export function DifferentialTopNFunctionsGrid({ baselineScaleFactor, comparison, comparisonScaleFactor, + comparisonSortDirection, + comparisonSortField, + comparisonTotalSeconds, onChangePage, onChangeSort, + onFrameClick, pageIndex, sortDirection, sortField, totalSeconds, - onFrameClick, - comparisonSortDirection, - comparisonSortField, }: Props) { + const theme = useEuiTheme(); const calculateImpactEstimates = useCalculateImpactEstimate(); const [selectedFrame, setSelectedFrame] = useState(); - const theme = useEuiTheme(); - - const totalCount = useMemo(() => { - if (!base || !base.TotalCount) { - return 0; - } + const [rowsInformation, setRowsInformation] = useState< + { baseRow: IFunctionRow; comparisonRow?: IFunctionRow } | undefined + >(); - return base.TotalCount; - }, [base]); + const { totalCount, comparisonTotalCount } = useMemo(() => { + return { totalCount: getTotalCount(base), comparisonTotalCount: getTotalCount(comparison) }; + }, [base, comparison]); function onSort(newSortingColumns: EuiDataGridSorting['columns']) { // As newSortingColumns is an array and we only sort by a single field for both base and comparison @@ -151,7 +160,7 @@ export function DifferentialTopNFunctionsGrid({ comparisonScaleFactor, comparisonTopNFunctions: base, topNFunctions: comparison, - totalSeconds, + totalSeconds: comparisonTotalSeconds, }), }; }, [ @@ -160,6 +169,7 @@ export function DifferentialTopNFunctionsGrid({ calculateImpactEstimates, comparison, comparisonScaleFactor, + comparisonTotalSeconds, totalSeconds, ]); @@ -224,42 +234,109 @@ export function DifferentialTopNFunctionsGrid({ const rowCount = Math.min(Math.max(sortedBaseRows.length, sortedComparisonRows.length), 100); return ( - {}, - onChangePage, - pageSizeOptions: [], - }} - rowHeightsOptions={{ defaultHeight: 'auto' }} - toolbarVisibility={{ - showColumnSelector: false, - showKeyboardShortcuts: false, - showDisplaySelector: false, - showSortSelector: false, - }} - /> + <> + + + {i18n.translate('xpack.profiling.topNFunctionsGrid.span.controlsLabel', { + defaultMessage: 'Controls', + })} + + + ); + }, + rowCellRender: function RowCellRender({ rowIndex }) { + function handleOnClick() { + const row = sortedBaseRows[rowIndex]; + const currentFrameId = getFrameIdentification(row.frame); + const compareRow = sortedComparisonRows.find( + (item) => getFrameIdentification(item.frame) === currentFrameId + ); + setRowsInformation({ + baseRow: row, + comparisonRow: compareRow, + }); + } + return ( + + ); + }, + }, + ]} + columnVisibility={{ visibleColumns, setVisibleColumns }} + rowCount={rowCount} + renderCellValue={CellValue} + sorting={{ + columns: [ + { id: sortField, direction: sortDirection }, + { id: comparisonSortField, direction: comparisonSortDirection }, + ], + onSort, + }} + pagination={{ + pageIndex, + pageSize: 50, + // Left it empty on purpose as it is a required property on the pagination + onChangeItemsPerPage: () => {}, + onChangePage, + pageSizeOptions: [], + }} + rowHeightsOptions={{ defaultHeight: 'auto' }} + toolbarVisibility={{ + showColumnSelector: false, + showKeyboardShortcuts: false, + showDisplaySelector: false, + showSortSelector: false, + }} + /> + {rowsInformation && ( + { + setRowsInformation(undefined); + }} + /> + )} + ); } diff --git a/x-pack/plugins/profiling/public/components/flamegraph/flamegraph_tooltip.tsx b/x-pack/plugins/profiling/public/components/flamegraph/flamegraph_tooltip.tsx index 75ba9258aeaf0f..d500f556fd5ff7 100644 --- a/x-pack/plugins/profiling/public/components/flamegraph/flamegraph_tooltip.tsx +++ b/x-pack/plugins/profiling/public/components/flamegraph/flamegraph_tooltip.tsx @@ -21,14 +21,12 @@ import { css } from '@emotion/react'; import { i18n } from '@kbn/i18n'; import { isNumber } from 'lodash'; import React from 'react'; -import { profilingUseLegacyCo2Calculation } from '@kbn/observability-plugin/common'; import { useCalculateImpactEstimate } from '../../hooks/use_calculate_impact_estimates'; import { asCost } from '../../utils/formatters/as_cost'; import { asPercentage } from '../../utils/formatters/as_percentage'; import { asWeight } from '../../utils/formatters/as_weight'; import { CPULabelWithHint } from '../cpu_label_with_hint'; import { TooltipRow } from './tooltip_row'; -import { useProfilingDependencies } from '../contexts/profiling_dependencies/use_profiling_dependencies'; interface Props { annualCO2KgsInclusive: number; @@ -73,13 +71,6 @@ export function FlameGraphTooltip({ totalSamples, totalSeconds, }: Props) { - const { - start: { core }, - } = useProfilingDependencies(); - const shouldUseLegacyCo2Calculation = core.uiSettings.get( - profilingUseLegacyCo2Calculation - ); - const theme = useEuiTheme(); const calculateImpactEstimates = useCalculateImpactEstimate(); @@ -187,16 +178,8 @@ export function FlameGraphTooltip({ label={i18n.translate('xpack.profiling.flameGraphTooltip.annualizedCo2', { defaultMessage: `Annualized CO2`, })} - value={ - shouldUseLegacyCo2Calculation - ? impactEstimates.totalCPU.annualizedCo2 - : annualCO2KgsInclusive - } - comparison={ - shouldUseLegacyCo2Calculation - ? comparisonImpactEstimates?.totalCPU.annualizedCo2 - : comparisonAnnualCO2KgsInclusive - } + value={annualCO2KgsInclusive} + comparison={comparisonAnnualCO2KgsInclusive} formatValue={(value) => asWeight(value, 'kgs')} showDifference formatDifferenceAsPercentage={false} @@ -205,16 +188,8 @@ export function FlameGraphTooltip({ label={i18n.translate('xpack.profiling.flameGraphTooltip.annualizedDollarCost', { defaultMessage: `Annualized dollar cost`, })} - value={ - shouldUseLegacyCo2Calculation - ? impactEstimates.totalCPU.annualizedDollarCost - : annualCostsUSDInclusive - } - comparison={ - shouldUseLegacyCo2Calculation - ? comparisonImpactEstimates?.totalCPU.annualizedDollarCost - : comparisonAnnualCostsUSDInclusive - } + value={annualCostsUSDInclusive} + comparison={comparisonAnnualCostsUSDInclusive} formatValue={asCost} showDifference formatDifferenceAsPercentage={false} diff --git a/x-pack/plugins/profiling/public/components/flamegraph/index.tsx b/x-pack/plugins/profiling/public/components/flamegraph/index.tsx index cbebc80606703b..38fa7273bc1af3 100644 --- a/x-pack/plugins/profiling/public/components/flamegraph/index.tsx +++ b/x-pack/plugins/profiling/public/components/flamegraph/index.tsx @@ -88,6 +88,7 @@ export function FlameGraph({ }; const totalSamples = columnarData.viewModel.value[0]; + const comparisonTotalSamples = comparisonFlamegraph?.CountInclusive[0]; const [highlightedVmIndex, setHighlightedVmIndex] = useState(undefined); @@ -109,6 +110,31 @@ export function FlameGraph({ totalAnnualCostUSD: primaryFlamegraph.TotalAnnualCostsUSDItems[highlightedVmIndex], } : undefined; + const primaryFlamegraphNodeId = + highlightedVmIndex !== undefined ? primaryFlamegraph?.ID[highlightedVmIndex] : undefined; + const comparisonFlamegraphNode = + primaryFlamegraphNodeId !== undefined + ? columnarData.comparisonNodesById[primaryFlamegraphNodeId] + : undefined; + + const comparisonSelected: Frame | undefined = + comparisonFlamegraphNode !== undefined + ? { + fileID: comparisonFlamegraphNode.FileID, + frameType: comparisonFlamegraphNode.FrameType, + exeFileName: comparisonFlamegraphNode.ExeFileName, + addressOrLine: comparisonFlamegraphNode.AddressOrLine, + functionName: comparisonFlamegraphNode.FunctionName, + sourceFileName: comparisonFlamegraphNode.SourceFileName, + sourceLine: comparisonFlamegraphNode.SourceLine, + countInclusive: comparisonFlamegraphNode.CountInclusive, + countExclusive: comparisonFlamegraphNode.CountExclusive, + selfAnnualCO2Kgs: comparisonFlamegraphNode.SelfAnnualCO2Kgs, + totalAnnualCO2Kgs: comparisonFlamegraphNode.TotalAnnualCO2Kgs, + selfAnnualCostUSD: comparisonFlamegraphNode.SelfAnnualCostUSD, + totalAnnualCostUSD: comparisonFlamegraphNode.TotalAnnualCostUSD, + } + : undefined; useEffect(() => { setHighlightedVmIndex(undefined); @@ -220,7 +246,11 @@ export function FlameGraph({ {showInformationWindow && ( + + {i18n.translate('xpack.profiling.frameInformationWindow.selectFrame', { + defaultMessage: 'Click on a frame to display more information', + })} + + + ); +} diff --git a/x-pack/plugins/profiling/public/components/frame_information_window/get_impact_rows.tsx b/x-pack/plugins/profiling/public/components/frame_information_window/get_impact_rows.tsx index 29289faca843b0..1df0d55ae22e2a 100644 --- a/x-pack/plugins/profiling/public/components/frame_information_window/get_impact_rows.tsx +++ b/x-pack/plugins/profiling/public/components/frame_information_window/get_impact_rows.tsx @@ -7,16 +7,16 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; +import { + ANNUAL_SECONDS, + CalculateImpactEstimates, +} from '../../hooks/use_calculate_impact_estimates'; import { asCost } from '../../utils/formatters/as_cost'; import { asDuration } from '../../utils/formatters/as_duration'; import { asNumber } from '../../utils/formatters/as_number'; import { asPercentage } from '../../utils/formatters/as_percentage'; import { asWeight } from '../../utils/formatters/as_weight'; import { CPULabelWithHint } from '../cpu_label_with_hint'; -import { - ANNUAL_SECONDS, - CalculateImpactEstimates, -} from '../../hooks/use_calculate_impact_estimates'; interface Params { countInclusive: number; @@ -24,11 +24,56 @@ interface Params { totalSamples: number; totalSeconds: number; calculateImpactEstimates: CalculateImpactEstimates; - shouldUseLegacyCo2Calculation: boolean; selfAnnualCO2Kgs: number; totalAnnualCO2Kgs: number; selfAnnualCostUSD: number; totalAnnualCostUSD: number; + rank?: number; +} + +export interface ImpactRow { + 'data-test-subj': string; + label: React.ReactNode; + value: string; +} + +const getComparisonValue = (value: T, comparisonValue?: T) => + comparisonValue ? `${value} vs ${comparisonValue}` : value; + +/** + * e.g.: + * label: 'foo', + * value: 'abc' vs 'xyz' + */ +export function getComparisonImpactRow({ + base, + comparison, +}: { + base: Params; + comparison?: Params; +}) { + const baseImpactRows = getImpactRows(base); + const comparisonImpactRows = comparison ? getImpactRows(comparison) : []; + return [ + ...(base.rank + ? [ + { + 'data-test-subj': 'rank', + label: i18n.translate('xpack.profiling.flameGraphInformationWindow.rank', { + defaultMessage: 'Rank', + }), + value: getComparisonValue(base.rank, comparison?.rank), + }, + ] + : []), + ...baseImpactRows.map((baseItem, index) => { + const comparisonValue = comparisonImpactRows[index]?.value; + return { + ...baseItem, + value: getComparisonValue(baseItem.value, comparisonValue), + }; + }), + ]; } export function getImpactRows({ @@ -37,12 +82,11 @@ export function getImpactRows({ totalSamples, totalSeconds, calculateImpactEstimates, - shouldUseLegacyCo2Calculation, selfAnnualCO2Kgs, totalAnnualCO2Kgs, selfAnnualCostUSD, totalAnnualCostUSD, -}: Params) { +}: Params): ImpactRow[] { const { selfCPU, totalCPU } = calculateImpactEstimates({ countInclusive, countExclusive, @@ -117,10 +161,7 @@ export function getImpactRows({ defaultMessage: 'CO2 emission', } ), - value: asWeight( - shouldUseLegacyCo2Calculation ? totalCPU.co2 : totalAnnualCO2Kgs / annualSecondsRatio, - 'kgs' - ), + value: asWeight(totalAnnualCO2Kgs / annualSecondsRatio, 'kgs'), }, { 'data-test-subj': 'selfCo2Emission', @@ -128,10 +169,7 @@ export function getImpactRows({ 'xpack.profiling.flameGraphInformationWindow.co2EmissionExclusiveLabel', { defaultMessage: 'CO2 emission (excl. children)' } ), - value: asWeight( - shouldUseLegacyCo2Calculation ? selfCPU.co2 : selfAnnualCO2Kgs / annualSecondsRatio, - 'kgs' - ), + value: asWeight(selfAnnualCO2Kgs / annualSecondsRatio, 'kgs'), }, { 'data-test-subj': 'annualizedCo2Emission', @@ -139,10 +177,7 @@ export function getImpactRows({ 'xpack.profiling.flameGraphInformationWindow.annualizedCo2InclusiveLabel', { defaultMessage: 'Annualized CO2' } ), - value: asWeight( - shouldUseLegacyCo2Calculation ? totalCPU.annualizedCo2 : totalAnnualCO2Kgs, - 'kgs' - ), + value: asWeight(totalAnnualCO2Kgs, 'kgs'), }, { 'data-test-subj': 'annualizedSelfCo2Emission', @@ -150,10 +185,7 @@ export function getImpactRows({ 'xpack.profiling.flameGraphInformationWindow.annualizedCo2ExclusiveLabel', { defaultMessage: 'Annualized CO2 (excl. children)' } ), - value: asWeight( - shouldUseLegacyCo2Calculation ? selfCPU.annualizedCo2 : selfAnnualCO2Kgs, - 'kgs' - ), + value: asWeight(selfAnnualCO2Kgs, 'kgs'), }, { 'data-test-subj': 'dollarCost', @@ -161,11 +193,7 @@ export function getImpactRows({ 'xpack.profiling.flameGraphInformationWindow.dollarCostInclusiveLabel', { defaultMessage: 'Dollar cost' } ), - value: asCost( - shouldUseLegacyCo2Calculation - ? totalCPU.dollarCost - : totalAnnualCostUSD / annualSecondsRatio - ), + value: asCost(totalAnnualCostUSD / annualSecondsRatio), }, { 'data-test-subj': 'selfDollarCost', @@ -173,9 +201,7 @@ export function getImpactRows({ 'xpack.profiling.flameGraphInformationWindow.dollarCostExclusiveLabel', { defaultMessage: 'Dollar cost (excl. children)' } ), - value: asCost( - shouldUseLegacyCo2Calculation ? selfCPU.dollarCost : selfAnnualCostUSD / annualSecondsRatio - ), + value: asCost(selfAnnualCostUSD / annualSecondsRatio), }, { 'data-test-subj': 'annualizedDollarCost', @@ -183,9 +209,7 @@ export function getImpactRows({ 'xpack.profiling.flameGraphInformationWindow.annualizedDollarCostInclusiveLabel', { defaultMessage: 'Annualized dollar cost' } ), - value: asCost( - shouldUseLegacyCo2Calculation ? totalCPU.annualizedDollarCost : totalAnnualCostUSD - ), + value: asCost(totalAnnualCostUSD), }, { 'data-test-subj': 'annualizedSelfDollarCost', @@ -193,9 +217,7 @@ export function getImpactRows({ 'xpack.profiling.flameGraphInformationWindow.annualizedDollarCostExclusiveLabel', { defaultMessage: 'Annualized dollar cost (excl. children)' } ), - value: asCost( - shouldUseLegacyCo2Calculation ? selfCPU.annualizedDollarCost : selfAnnualCostUSD - ), + value: asCost(selfAnnualCostUSD), }, ]; } diff --git a/x-pack/plugins/profiling/public/components/frame_information_window/index.tsx b/x-pack/plugins/profiling/public/components/frame_information_window/index.tsx index a81eadd2152045..a0dbc1c7737b4c 100644 --- a/x-pack/plugins/profiling/public/components/frame_information_window/index.tsx +++ b/x-pack/plugins/profiling/public/components/frame_information_window/index.tsx @@ -4,19 +4,19 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { EuiFlexGroup, EuiFlexItem, EuiText, EuiTitle } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiStat, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FrameSymbolStatus, getFrameSymbolStatus } from '@kbn/profiling-utils'; import React from 'react'; -import { profilingUseLegacyCo2Calculation } from '@kbn/observability-plugin/common'; +import { useCalculateImpactEstimate } from '../../hooks/use_calculate_impact_estimates'; +import { FramesSummary } from '../frames_summary'; +import { EmptyFrame } from './empty_frame'; import { FrameInformationAIAssistant } from './frame_information_ai_assistant'; import { FrameInformationPanel } from './frame_information_panel'; -import { getImpactRows } from './get_impact_rows'; +import { getComparisonImpactRow } from './get_impact_rows'; import { getInformationRows } from './get_information_rows'; import { KeyValueList } from './key_value_list'; import { MissingSymbolsCallout } from './missing_symbols_callout'; -import { useCalculateImpactEstimate } from '../../hooks/use_calculate_impact_estimates'; -import { useProfilingDependencies } from '../contexts/profiling_dependencies/use_profiling_dependencies'; export interface Frame { fileID: string; @@ -35,37 +35,34 @@ export interface Frame { } export interface Props { + comparisonFrame?: Frame; + comparisonTotalSeconds?: number; + comparisonTotalSamples?: number; + comparisonRank?: number; frame?: Frame; totalSamples: number; totalSeconds: number; - showAIAssistant?: boolean; + rank?: number; showSymbolsStatus?: boolean; + compressed?: boolean; } export function FrameInformationWindow({ frame, + showSymbolsStatus = true, + comparisonFrame, + comparisonRank, + comparisonTotalSamples, + comparisonTotalSeconds, totalSamples, totalSeconds, - showSymbolsStatus = true, + rank, + compressed = false, }: Props) { const calculateImpactEstimates = useCalculateImpactEstimate(); - const { - start: { core }, - } = useProfilingDependencies(); - const shouldUseLegacyCo2Calculation = core.uiSettings.get( - profilingUseLegacyCo2Calculation - ); if (!frame) { - return ( - - - {i18n.translate('xpack.profiling.frameInformationWindow.selectFrame', { - defaultMessage: 'Click on a frame to display more information', - })} - - - ); + return ; } const symbolStatus = getFrameSymbolStatus({ @@ -82,12 +79,6 @@ export function FrameInformationWindow({ functionName, sourceFileName, sourceLine, - countInclusive, - countExclusive, - selfAnnualCO2Kgs, - totalAnnualCO2Kgs, - selfAnnualCostUSD, - totalAnnualCostUSD, } = frame; const informationRows = getInformationRows({ @@ -100,24 +91,57 @@ export function FrameInformationWindow({ sourceLine, }); - const impactRows = getImpactRows({ - countInclusive, - countExclusive, - totalSamples, - totalSeconds, - calculateImpactEstimates, - shouldUseLegacyCo2Calculation, - selfAnnualCO2Kgs, - totalAnnualCO2Kgs, - selfAnnualCostUSD, - totalAnnualCostUSD, + const impactRows = getComparisonImpactRow({ + base: { + countInclusive: frame.countInclusive, + countExclusive: frame.countExclusive, + selfAnnualCO2Kgs: frame.selfAnnualCO2Kgs, + totalAnnualCO2Kgs: frame.totalAnnualCO2Kgs, + selfAnnualCostUSD: frame.selfAnnualCostUSD, + totalAnnualCostUSD: frame.totalAnnualCostUSD, + rank, + totalSamples, + totalSeconds, + calculateImpactEstimates, + }, + comparison: + comparisonFrame && + comparisonTotalSamples !== undefined && + comparisonTotalSeconds !== undefined + ? { + countInclusive: comparisonFrame.countInclusive, + countExclusive: comparisonFrame.countExclusive, + selfAnnualCO2Kgs: comparisonFrame.selfAnnualCO2Kgs, + totalAnnualCO2Kgs: comparisonFrame.totalAnnualCO2Kgs, + selfAnnualCostUSD: comparisonFrame.selfAnnualCostUSD, + totalAnnualCostUSD: comparisonFrame.totalAnnualCostUSD, + rank: comparisonRank, + totalSamples: comparisonTotalSamples, + totalSeconds: comparisonTotalSeconds, + calculateImpactEstimates, + } + : undefined, }); return ( - + + {informationRows.map((item, index) => ( + + + {item.value} + + } + description={item.label} + titleSize="xs" + /> + + ))} + @@ -127,6 +151,29 @@ export function FrameInformationWindow({ ) : null} + + + diff --git a/x-pack/plugins/profiling/public/components/frame_information_window/key_value_list.tsx b/x-pack/plugins/profiling/public/components/frame_information_window/key_value_list.tsx index 367d8e921ee6b7..a7e742bdd184b3 100644 --- a/x-pack/plugins/profiling/public/components/frame_information_window/key_value_list.tsx +++ b/x-pack/plugins/profiling/public/components/frame_information_window/key_value_list.tsx @@ -15,25 +15,22 @@ interface Props { value: React.ReactNode; 'data-test-subj'?: string; }>; - prependString?: string; } -export function KeyValueList({ rows, prependString = '', ...props }: Props) { +export function KeyValueList({ rows, ...props }: Props) { return ( {rows.map((row, index) => ( - - + + {row.label}: - {prependString} {row.value} diff --git a/x-pack/plugins/profiling/public/components/frames_summary/index.tsx b/x-pack/plugins/profiling/public/components/frames_summary/index.tsx index e55f19d135f9e1..78ac1cd4111a73 100644 --- a/x-pack/plugins/profiling/public/components/frames_summary/index.tsx +++ b/x-pack/plugins/profiling/public/components/frames_summary/index.tsx @@ -14,21 +14,16 @@ import { EuiText, EuiTextColor, } from '@elastic/eui'; -import React, { useMemo } from 'react'; import { i18n } from '@kbn/i18n'; -import { profilingUseLegacyCo2Calculation } from '@kbn/observability-plugin/common'; -import { useCalculateImpactEstimate } from '../../hooks/use_calculate_impact_estimates'; +import { isEmpty } from 'lodash'; +import React, { useMemo } from 'react'; import { asCost } from '../../utils/formatters/as_cost'; import { asWeight } from '../../utils/formatters/as_weight'; import { calculateBaseComparisonDiff } from '../topn_functions/utils'; import { SummaryItem } from './summary_item'; -import { useProfilingDependencies } from '../contexts/profiling_dependencies/use_profiling_dependencies'; interface FrameValue { - selfCPU: number; - totalCPU: number; totalCount: number; - duration: number; scaleFactor?: number; totalAnnualCO2Kgs: number; totalAnnualCostUSD: number; @@ -38,6 +33,8 @@ interface Props { baseValue?: FrameValue; comparisonValue?: FrameValue; isLoading: boolean; + hasBorder?: boolean; + compressed?: boolean; } const ESTIMATED_VALUE_LABEL = i18n.translate('xpack.profiling.diffTopNFunctions.estimatedValue', { @@ -48,15 +45,13 @@ function getScaleFactor(scaleFactor: number = 1) { return scaleFactor; } -export function FramesSummary({ baseValue, comparisonValue, isLoading }: Props) { - const { - start: { core }, - } = useProfilingDependencies(); - const shouldUseLegacyCo2Calculation = core.uiSettings.get( - profilingUseLegacyCo2Calculation - ); - const calculateImpactEstimates = useCalculateImpactEstimate(); - +export function FramesSummary({ + baseValue, + comparisonValue, + isLoading, + hasBorder = false, + compressed = false, +}: Props) { const baselineScaledTotalSamples = baseValue ? baseValue.totalCount * getScaleFactor(baseValue.scaleFactor) : 0; @@ -66,62 +61,23 @@ export function FramesSummary({ baseValue, comparisonValue, isLoading }: Props) : 0; const { co2EmissionDiff, costImpactDiff, totalSamplesDiff } = useMemo(() => { - const baseImpactEstimates = baseValue - ? // Do NOT scale values here. This is intended to show the exact values spent throughout the year - calculateImpactEstimates({ - countExclusive: baseValue.selfCPU, - countInclusive: baseValue.totalCPU, - totalSamples: baseValue.totalCount, - totalSeconds: baseValue.duration, - }) - : undefined; - - const comparisonImpactEstimates = comparisonValue - ? // Do NOT scale values here. This is intended to show the exact values spent throughout the year - calculateImpactEstimates({ - countExclusive: comparisonValue.selfCPU, - countInclusive: comparisonValue.totalCPU, - totalSamples: comparisonValue.totalCount, - totalSeconds: comparisonValue.duration, - }) - : undefined; - return { totalSamplesDiff: calculateBaseComparisonDiff({ baselineValue: baselineScaledTotalSamples || 0, comparisonValue: comparisonScaledTotalSamples || 0, }), co2EmissionDiff: calculateBaseComparisonDiff({ - baselineValue: - (shouldUseLegacyCo2Calculation - ? baseImpactEstimates?.totalSamples?.annualizedCo2 - : baseValue?.totalAnnualCO2Kgs) || 0, - comparisonValue: - (shouldUseLegacyCo2Calculation - ? comparisonImpactEstimates?.totalSamples.annualizedCo2 - : comparisonValue?.totalAnnualCO2Kgs) || 0, + baselineValue: baseValue?.totalAnnualCO2Kgs || 0, + comparisonValue: comparisonValue?.totalAnnualCO2Kgs || 0, formatValue: (value) => asWeight(value, 'kgs'), }), costImpactDiff: calculateBaseComparisonDiff({ - baselineValue: - (shouldUseLegacyCo2Calculation - ? baseImpactEstimates?.totalSamples.annualizedDollarCost - : baseValue?.totalAnnualCostUSD) || 0, - comparisonValue: - (shouldUseLegacyCo2Calculation - ? comparisonImpactEstimates?.totalSamples.annualizedDollarCost - : comparisonValue?.totalAnnualCostUSD) || 0, + baselineValue: baseValue?.totalAnnualCostUSD || 0, + comparisonValue: comparisonValue?.totalAnnualCostUSD || 0, formatValue: asCost, }), }; - }, [ - baseValue, - baselineScaledTotalSamples, - calculateImpactEstimates, - comparisonScaledTotalSamples, - comparisonValue, - shouldUseLegacyCo2Calculation, - ]); + }, [baseValue, baselineScaledTotalSamples, comparisonScaledTotalSamples, comparisonValue]); const data = [ { @@ -143,6 +99,7 @@ export function FramesSummary({ baseValue, comparisonValue, isLoading }: Props) baseIcon: totalSamplesDiff.icon, baseColor: totalSamplesDiff.color, titleHint: ESTIMATED_VALUE_LABEL, + hidden: isEmpty(comparisonValue), }, { id: 'annualizedCo2', @@ -182,7 +139,31 @@ export function FramesSummary({ baseValue, comparisonValue, isLoading }: Props) }, ]; - return ( + const Summary = ( + <> + + + {data + .filter((item) => !item.hidden) + .map((item) => { + return ( + + + + ); + })} + + + ); + + return compressed ? ( + <>{Summary} + ) : ( } > - <> - - - {data.map((item, idx) => { - return ( - - - - ); - })} - - + {Summary} ); } diff --git a/x-pack/plugins/profiling/public/components/frames_summary/summary_item.tsx b/x-pack/plugins/profiling/public/components/frames_summary/summary_item.tsx index a2f63aa55df28b..19650ca4310381 100644 --- a/x-pack/plugins/profiling/public/components/frames_summary/summary_item.tsx +++ b/x-pack/plugins/profiling/public/components/frames_summary/summary_item.tsx @@ -14,6 +14,7 @@ import { EuiStat, EuiText, EuiTextColor, + EuiTextProps, EuiToolTip, } from '@elastic/eui'; import React from 'react'; @@ -30,11 +31,13 @@ interface Props { comparisonIcon?: string; comparisonColor?: string; titleHint?: string; + hasBorder?: boolean; + compressed?: boolean; } -function Title({ title }: { title: string }) { +function Title({ title, size }: { title: string; size?: EuiTextProps['size'] }) { return ( - + {title} ); @@ -83,18 +86,21 @@ export function SummaryItem({ comparisonColor, comparisonIcon, titleHint, + hasBorder = false, + compressed = false, }: Props) { + const textSize = compressed ? 's' : 'm'; return ( - + } - titleSize="m" + titleSize={textSize} description={ <> {titleHint ? ( - + <Title title={title} size={textSize} /> </EuiFlexItem> <EuiFlexItem grow={false}> <EuiToolTip content={titleHint}> @@ -103,7 +109,7 @@ export function SummaryItem({ </EuiFlexItem> </EuiFlexGroup> ) : ( - <Title title={title} /> + <Title title={title} size={textSize} /> )} <EuiSpacer /> </> @@ -112,7 +118,7 @@ export function SummaryItem({ isLoading={isLoading} > {!isLoading && comparisonValue ? ( - <EuiText color={comparisonColor}> + <EuiText color={comparisonColor} size={textSize}> {comparisonIcon ? ( <EuiIcon data-test-subj={`${id}_comparison_${comparisonIcon}_${comparisonColor}`} diff --git a/x-pack/plugins/profiling/public/components/topn_functions/function_row.tsx b/x-pack/plugins/profiling/public/components/topn_functions/function_row.tsx index 1affab1df5f086..3d20818e7b012b 100644 --- a/x-pack/plugins/profiling/public/components/topn_functions/function_row.tsx +++ b/x-pack/plugins/profiling/public/components/topn_functions/function_row.tsx @@ -17,10 +17,8 @@ import { import { i18n } from '@kbn/i18n'; import { TopNFunctionSortField } from '@kbn/profiling-utils'; import React, { useEffect } from 'react'; -import { profilingUseLegacyCo2Calculation } from '@kbn/observability-plugin/common'; import { asCost } from '../../utils/formatters/as_cost'; import { asWeight } from '../../utils/formatters/as_weight'; -import { useProfilingDependencies } from '../contexts/profiling_dependencies/use_profiling_dependencies'; import { StackFrameSummary } from '../stack_frame_summary'; import { CPUStat } from './cpu_stat'; import { SampleStat } from './sample_stat'; @@ -41,14 +39,6 @@ export function FunctionRow({ onFrameClick, setCellProps, }: Props) { - const { - start: { core }, - } = useProfilingDependencies(); - - const shouldUseLegacyCo2Calculation = core.uiSettings.get<boolean>( - profilingUseLegacyCo2Calculation - ); - if (columnId === TopNFunctionSortField.Diff) { return <DiffColumn diff={functionRow.diff} setCellProps={setCellProps} />; } @@ -80,35 +70,12 @@ export function FunctionRow({ return <CPUStat cpu={functionRow.totalCPUPerc} diffCPU={functionRow.diff?.totalCPUPerc} />; } - if ( - columnId === TopNFunctionSortField.AnnualizedCo2 && - functionRow.impactEstimates?.totalCPU?.annualizedCo2 - ) { - return ( - <div> - {asWeight( - shouldUseLegacyCo2Calculation - ? functionRow.impactEstimates.totalCPU.annualizedCo2 - : functionRow.totalAnnualCO2kgs, - 'kgs' - )} - </div> - ); + if (columnId === TopNFunctionSortField.AnnualizedCo2) { + return <div>{asWeight(functionRow.totalAnnualCO2kgs, 'kgs')}</div>; } - if ( - columnId === TopNFunctionSortField.AnnualizedDollarCost && - functionRow.impactEstimates?.totalCPU?.annualizedDollarCost - ) { - return ( - <div> - {asCost( - shouldUseLegacyCo2Calculation - ? functionRow.impactEstimates.totalCPU.annualizedDollarCost - : functionRow.totalAnnualCostUSD - )} - </div> - ); + if (columnId === TopNFunctionSortField.AnnualizedDollarCost) { + return <div>{asCost(functionRow.totalAnnualCostUSD)}</div>; } return null; diff --git a/x-pack/plugins/profiling/public/components/topn_functions/index.tsx b/x-pack/plugins/profiling/public/components/topn_functions/index.tsx index 9d3275e319cc74..6c754d61dac644 100644 --- a/x-pack/plugins/profiling/public/components/topn_functions/index.tsx +++ b/x-pack/plugins/profiling/public/components/topn_functions/index.tsx @@ -11,7 +11,6 @@ import { EuiDataGridCellValueElementProps, EuiDataGridColumn, EuiDataGridControlColumn, - EuiDataGridRefProps, EuiDataGridSorting, EuiScreenReaderOnly, } from '@elastic/eui'; @@ -19,16 +18,14 @@ import { i18n } from '@kbn/i18n'; import { useUiTracker } from '@kbn/observability-shared-plugin/public'; import { getCalleeFunction, TopNFunctions, TopNFunctionSortField } from '@kbn/profiling-utils'; import { last, orderBy } from 'lodash'; -import React, { forwardRef, Ref, useMemo, useState } from 'react'; +import React, { useMemo, useState } from 'react'; import { GridOnScrollProps } from 'react-window'; -import { profilingUseLegacyCo2Calculation } from '@kbn/observability-plugin/common'; import { useCalculateImpactEstimate } from '../../hooks/use_calculate_impact_estimates'; -import { useProfilingDependencies } from '../contexts/profiling_dependencies/use_profiling_dependencies'; import { CPULabelWithHint } from '../cpu_label_with_hint'; import { FrameInformationTooltip } from '../frame_information_window/frame_information_tooltip'; import { LabelWithHint } from '../label_with_hint'; import { FunctionRow } from './function_row'; -import { getFunctionsRows, IFunctionRow } from './utils'; +import { convertRowToFrame, getFunctionsRows, getTotalCount, IFunctionRow } from './utils'; interface Props { topNFunctions?: TopNFunctions; @@ -49,132 +46,166 @@ interface Props { isEmbedded?: boolean; } -export const TopNFunctionsGrid = forwardRef( - ( - { - topNFunctions, - comparisonTopNFunctions, - totalSeconds, - isDifferentialView, - baselineScaleFactor, - comparisonScaleFactor, - onFrameClick, - onScroll, - showDiffColumn = false, - pageIndex, - onChangePage, - sortField, - sortDirection, - onChangeSort, - dataTestSubj = 'topNFunctionsGrid', - isEmbedded = false, - }: Props, - ref: Ref<EuiDataGridRefProps> | undefined - ) => { - const { - start: { core }, - } = useProfilingDependencies(); - const shouldUseLegacyCo2Calculation = core.uiSettings.get<boolean>( - profilingUseLegacyCo2Calculation - ); - const [selectedRow, setSelectedRow] = useState<IFunctionRow | undefined>(); - const trackProfilingEvent = useUiTracker({ app: 'profiling' }); - const calculateImpactEstimates = useCalculateImpactEstimate(); +export const TopNFunctionsGrid = ({ + topNFunctions, + comparisonTopNFunctions, + totalSeconds, + isDifferentialView, + baselineScaleFactor, + comparisonScaleFactor, + onFrameClick, + onScroll, + showDiffColumn = false, + pageIndex, + onChangePage, + sortField, + sortDirection, + onChangeSort, + dataTestSubj = 'topNFunctionsGrid', + isEmbedded = false, +}: Props) => { + const [selectedRow, setSelectedRow] = useState<IFunctionRow | undefined>(); + const trackProfilingEvent = useUiTracker({ app: 'profiling' }); + const calculateImpactEstimates = useCalculateImpactEstimate(); - function onSort(newSortingColumns: EuiDataGridSorting['columns']) { - const lastItem = last(newSortingColumns); - if (lastItem) { - onChangeSort(lastItem); - } + function onSort(newSortingColumns: EuiDataGridSorting['columns']) { + const lastItem = last(newSortingColumns); + if (lastItem) { + onChangeSort(lastItem); } + } - const totalCount = useMemo(() => { - if (!topNFunctions || !topNFunctions.TotalCount) { - return 0; - } - - return topNFunctions.TotalCount; - }, [topNFunctions]); + const totalCount = useMemo(() => getTotalCount(topNFunctions), [topNFunctions]); - const rows = useMemo(() => { - return getFunctionsRows({ - baselineScaleFactor, - comparisonScaleFactor, - comparisonTopNFunctions, - topNFunctions, - totalSeconds, - calculateImpactEstimates, - }); - }, [ + const rows = useMemo(() => { + return getFunctionsRows({ baselineScaleFactor, - calculateImpactEstimates, comparisonScaleFactor, comparisonTopNFunctions, topNFunctions, totalSeconds, - ]); + calculateImpactEstimates, + }); + }, [ + baselineScaleFactor, + calculateImpactEstimates, + comparisonScaleFactor, + comparisonTopNFunctions, + topNFunctions, + totalSeconds, + ]); - const sortedRows = useMemo(() => { - switch (sortField) { - case TopNFunctionSortField.Frame: - return orderBy(rows, (row) => getCalleeFunction(row.frame), sortDirection); - case TopNFunctionSortField.SelfCPU: - return orderBy(rows, (row) => row.selfCPUPerc, sortDirection); - case TopNFunctionSortField.TotalCPU: - return orderBy(rows, (row) => row.totalCPUPerc, sortDirection); - case TopNFunctionSortField.AnnualizedCo2: - return orderBy( - rows, - (row) => - shouldUseLegacyCo2Calculation - ? row.impactEstimates?.totalCPU.annualizedCo2 - : row.totalAnnualCO2kgs, - sortDirection - ); - case TopNFunctionSortField.AnnualizedDollarCost: - return orderBy( - rows, - (row) => - shouldUseLegacyCo2Calculation - ? row.impactEstimates?.totalCPU.annualizedDollarCost - : row.totalAnnualCostUSD, - sortDirection - ); - default: - return orderBy(rows, sortField, sortDirection); - } - }, [rows, shouldUseLegacyCo2Calculation, sortDirection, sortField]); + const sortedRows = useMemo(() => { + switch (sortField) { + case TopNFunctionSortField.Frame: + return orderBy(rows, (row) => getCalleeFunction(row.frame), sortDirection); + case TopNFunctionSortField.SelfCPU: + return orderBy(rows, (row) => row.selfCPUPerc, sortDirection); + case TopNFunctionSortField.TotalCPU: + return orderBy(rows, (row) => row.totalCPUPerc, sortDirection); + case TopNFunctionSortField.AnnualizedCo2: + return orderBy(rows, (row) => row.totalAnnualCO2kgs, sortDirection); + case TopNFunctionSortField.AnnualizedDollarCost: + return orderBy(rows, (row) => row.totalAnnualCostUSD, sortDirection); + default: + return orderBy(rows, sortField, sortDirection); + } + }, [rows, sortDirection, sortField]); - const { columns, leadingControlColumns } = useMemo(() => { - const gridColumns: EuiDataGridColumn[] = [ - { - id: TopNFunctionSortField.Rank, - schema: 'numeric', - actions: { showHide: false }, - initialWidth: isDifferentialView ? 50 : 90, - displayAsText: i18n.translate('xpack.profiling.functionsView.rankColumnLabel', { - defaultMessage: 'Rank', - }), - }, + const { columns, leadingControlColumns } = useMemo(() => { + const gridColumns: EuiDataGridColumn[] = [ + { + id: TopNFunctionSortField.Rank, + schema: 'numeric', + actions: { showHide: false }, + initialWidth: isDifferentialView ? 50 : 90, + displayAsText: i18n.translate('xpack.profiling.functionsView.rankColumnLabel', { + defaultMessage: 'Rank', + }), + }, + { + id: TopNFunctionSortField.Frame, + actions: { showHide: false }, + displayAsText: i18n.translate('xpack.profiling.functionsView.functionColumnLabel', { + defaultMessage: 'Function', + }), + }, + { + id: TopNFunctionSortField.Samples, + initialWidth: isDifferentialView ? 100 : 200, + schema: 'numeric', + actions: { showHide: false }, + display: ( + <LabelWithHint + label={i18n.translate('xpack.profiling.functionsView.samplesColumnLabel', { + defaultMessage: 'Samples', + })} + hint={i18n.translate('xpack.profiling.functionsView.samplesColumnLabel.hint', { + defaultMessage: 'Estimated values', + })} + labelSize="s" + labelStyle={{ fontWeight: 700 }} + iconSize="s" + /> + ), + }, + { + id: TopNFunctionSortField.SelfCPU, + schema: 'numeric', + actions: { showHide: false }, + initialWidth: isDifferentialView ? 100 : 200, + display: ( + <CPULabelWithHint + type="self" + labelSize="s" + labelStyle={{ fontWeight: 700 }} + iconSize="s" + /> + ), + }, + { + id: TopNFunctionSortField.TotalCPU, + schema: 'numeric', + actions: { showHide: false }, + initialWidth: isDifferentialView ? 100 : 200, + display: ( + <CPULabelWithHint + type="total" + labelSize="s" + labelStyle={{ fontWeight: 700 }} + iconSize="s" + /> + ), + }, + ]; + + const gridLeadingControlColumns: EuiDataGridControlColumn[] = []; + if (showDiffColumn) { + gridColumns.push({ + initialWidth: 60, + id: TopNFunctionSortField.Diff, + actions: { showHide: false }, + displayAsText: i18n.translate('xpack.profiling.functionsView.diffColumnLabel', { + defaultMessage: 'Diff', + }), + }); + } + + if (!isDifferentialView) { + gridColumns.push( { - id: TopNFunctionSortField.Frame, + id: TopNFunctionSortField.AnnualizedCo2, actions: { showHide: false }, - displayAsText: i18n.translate('xpack.profiling.functionsView.functionColumnLabel', { - defaultMessage: 'Function', - }), - }, - { - id: TopNFunctionSortField.Samples, initialWidth: isDifferentialView ? 100 : 200, schema: 'numeric', - actions: { showHide: false }, display: ( <LabelWithHint - label={i18n.translate('xpack.profiling.functionsView.samplesColumnLabel', { - defaultMessage: 'Samples', + label={i18n.translate('xpack.profiling.functionsView.annualizedCo2', { + defaultMessage: 'Annualized CO2', })} - hint={i18n.translate('xpack.profiling.functionsView.samplesColumnLabel.hint', { - defaultMessage: 'Estimated values', + hint={i18n.translate('xpack.profiling.functionsView.annualizedCo2.hint', { + defaultMessage: + 'Indicates the CO2 emission of the function and any functions called by it.', })} labelSize="s" labelStyle={{ fontWeight: 700 }} @@ -183,211 +214,127 @@ export const TopNFunctionsGrid = forwardRef( ), }, { - id: TopNFunctionSortField.SelfCPU, - schema: 'numeric', - actions: { showHide: false }, - initialWidth: isDifferentialView ? 100 : 200, - display: ( - <CPULabelWithHint - type="self" - labelSize="s" - labelStyle={{ fontWeight: 700 }} - iconSize="s" - /> - ), - }, - { - id: TopNFunctionSortField.TotalCPU, + id: TopNFunctionSortField.AnnualizedDollarCost, schema: 'numeric', actions: { showHide: false }, initialWidth: isDifferentialView ? 100 : 200, display: ( - <CPULabelWithHint - type="total" + <LabelWithHint + label={i18n.translate('xpack.profiling.functionsView.annualizedDollarCost', { + defaultMessage: `Annualized dollar cost`, + })} + hint={i18n.translate('xpack.profiling.functionsView.annualizedDollarCost.hint', { + defaultMessage: `Indicates the Dollar cost of the function and any functions called by it.`, + })} labelSize="s" labelStyle={{ fontWeight: 700 }} iconSize="s" /> ), - }, - ]; - - const gridLeadingControlColumns: EuiDataGridControlColumn[] = []; - if (showDiffColumn) { - gridColumns.push({ - initialWidth: 60, - id: TopNFunctionSortField.Diff, - actions: { showHide: false }, - displayAsText: i18n.translate('xpack.profiling.functionsView.diffColumnLabel', { - defaultMessage: 'Diff', - }), - }); - } + } + ); - if (!isDifferentialView) { - gridColumns.push( - { - id: TopNFunctionSortField.AnnualizedCo2, - actions: { showHide: false }, - initialWidth: isDifferentialView ? 100 : 200, - schema: 'numeric', - display: ( - <LabelWithHint - label={i18n.translate('xpack.profiling.functionsView.annualizedCo2', { - defaultMessage: 'Annualized CO2', + gridLeadingControlColumns.push({ + id: 'actions', + width: 40, + headerCellRender() { + return ( + <EuiScreenReaderOnly> + <span> + {i18n.translate('xpack.profiling.topNFunctionsGrid.span.controlsLabel', { + defaultMessage: 'Controls', })} - hint={i18n.translate('xpack.profiling.functionsView.annualizedCo2.hint', { - defaultMessage: - 'Indicates the CO2 emission of the function and any functions called by it.', - })} - labelSize="s" - labelStyle={{ fontWeight: 700 }} - iconSize="s" - /> - ), - }, - { - id: TopNFunctionSortField.AnnualizedDollarCost, - schema: 'numeric', - actions: { showHide: false }, - initialWidth: isDifferentialView ? 100 : 200, - display: ( - <LabelWithHint - label={i18n.translate('xpack.profiling.functionsView.annualizedDollarCost', { - defaultMessage: `Annualized dollar cost`, - })} - hint={i18n.translate('xpack.profiling.functionsView.annualizedDollarCost.hint', { - defaultMessage: `Indicates the Dollar cost of the function and any functions called by it.`, - })} - labelSize="s" - labelStyle={{ fontWeight: 700 }} - iconSize="s" - /> - ), + </span> + </EuiScreenReaderOnly> + ); + }, + rowCellRender: function RowCellRender({ rowIndex }) { + function handleOnClick() { + trackProfilingEvent({ metric: 'topN_function_details_click' }); + setSelectedRow(sortedRows[rowIndex]); } - ); - - gridLeadingControlColumns.push({ - id: 'actions', - width: 40, - headerCellRender() { - return ( - <EuiScreenReaderOnly> - <span> - {i18n.translate('xpack.profiling.topNFunctionsGrid.span.controlsLabel', { - defaultMessage: 'Controls', - })} - </span> - </EuiScreenReaderOnly> - ); - }, - rowCellRender: function RowCellRender({ rowIndex }) { - function handleOnClick() { - trackProfilingEvent({ metric: 'topN_function_details_click' }); - setSelectedRow(sortedRows[rowIndex]); - } - return ( - <EuiButtonIcon - data-test-subj="profilingTopNFunctionsGridButton" - aria-label={i18n.translate( - 'xpack.profiling.topNFunctionsGrid.euiButtonIcon.showActionsLabel', - { defaultMessage: 'Show actions' } - )} - iconType="expand" - color="text" - onClick={handleOnClick} - /> - ); - }, - }); - } - return { columns: gridColumns, leadingControlColumns: gridLeadingControlColumns }; - }, [isDifferentialView, sortedRows, showDiffColumn, trackProfilingEvent]); + return ( + <EuiButtonIcon + data-test-subj="profilingTopNFunctionsGridButton" + aria-label={i18n.translate( + 'xpack.profiling.topNFunctionsGrid.euiButtonIcon.showActionsLabel', + { defaultMessage: 'Show actions' } + )} + iconType="expand" + color="text" + onClick={handleOnClick} + /> + ); + }, + }); + } + return { columns: gridColumns, leadingControlColumns: gridLeadingControlColumns }; + }, [isDifferentialView, sortedRows, showDiffColumn, trackProfilingEvent]); - const [visibleColumns, setVisibleColumns] = useState(columns.map(({ id }) => id)); + const [visibleColumns, setVisibleColumns] = useState(columns.map(({ id }) => id)); - function RenderCellValue({ - rowIndex, - columnId, - setCellProps, - }: EuiDataGridCellValueElementProps) { - const data = sortedRows[rowIndex]; - if (data) { - return ( - <FunctionRow - functionRow={data} - columnId={columnId} - totalCount={totalCount} - onFrameClick={onFrameClick} - setCellProps={setCellProps} - /> - ); - } - return null; + function RenderCellValue({ rowIndex, columnId, setCellProps }: EuiDataGridCellValueElementProps) { + const data = sortedRows[rowIndex]; + if (data) { + return ( + <FunctionRow + functionRow={data} + columnId={columnId} + totalCount={totalCount} + onFrameClick={onFrameClick} + setCellProps={setCellProps} + /> + ); } + return null; + } - return ( - <> - <EuiDataGrid - data-test-subj={dataTestSubj} - ref={ref} - aria-label={i18n.translate( - 'xpack.profiling.topNFunctionsGrid.euiDataGrid.topNFunctionsLabel', - { defaultMessage: 'TopN functions' } - )} - columns={columns} - columnVisibility={{ visibleColumns, setVisibleColumns }} - rowCount={sortedRows.length > 100 ? 100 : sortedRows.length} - renderCellValue={RenderCellValue} - sorting={{ columns: [{ id: sortField, direction: sortDirection }], onSort }} - leadingControlColumns={leadingControlColumns} - pagination={{ - pageIndex, - pageSize: 50, - // Left it empty on purpose as it is a required property on the pagination - onChangeItemsPerPage: () => {}, - onChangePage, - pageSizeOptions: [], - }} - rowHeightsOptions={{ defaultHeight: 'auto' }} - toolbarVisibility={{ - showColumnSelector: false, - showKeyboardShortcuts: !isDifferentialView, - showDisplaySelector: !isDifferentialView, - showFullScreenSelector: !isDifferentialView, - showSortSelector: false, - }} - virtualizationOptions={{ - onScroll, + return ( + <> + <EuiDataGrid + data-test-subj={dataTestSubj} + aria-label={i18n.translate( + 'xpack.profiling.topNFunctionsGrid.euiDataGrid.topNFunctionsLabel', + { defaultMessage: 'TopN functions' } + )} + columns={columns} + columnVisibility={{ visibleColumns, setVisibleColumns }} + rowCount={sortedRows.length > 100 ? 100 : sortedRows.length} + renderCellValue={RenderCellValue} + sorting={{ columns: [{ id: sortField, direction: sortDirection }], onSort }} + leadingControlColumns={leadingControlColumns} + pagination={{ + pageIndex, + pageSize: 50, + // Left it empty on purpose as it is a required property on the pagination + onChangeItemsPerPage: () => {}, + onChangePage, + pageSizeOptions: [], + }} + rowHeightsOptions={{ defaultHeight: 'auto' }} + toolbarVisibility={{ + showColumnSelector: false, + showKeyboardShortcuts: !isDifferentialView, + showDisplaySelector: !isDifferentialView, + showFullScreenSelector: !isDifferentialView, + showSortSelector: false, + }} + virtualizationOptions={{ + onScroll, + }} + /> + {selectedRow && ( + <FrameInformationTooltip + compressed + onClose={() => { + setSelectedRow(undefined); }} + frame={convertRowToFrame(selectedRow)} + totalSeconds={totalSeconds} + totalSamples={totalCount} + showSymbolsStatus={!isEmbedded} /> - {selectedRow && ( - <FrameInformationTooltip - onClose={() => { - setSelectedRow(undefined); - }} - frame={{ - addressOrLine: selectedRow.frame.AddressOrLine, - countExclusive: selectedRow.selfCPU, - countInclusive: selectedRow.totalCPU, - exeFileName: selectedRow.frame.ExeFileName, - fileID: selectedRow.frame.FileID, - frameType: selectedRow.frame.FrameType, - functionName: selectedRow.frame.FunctionName, - sourceFileName: selectedRow.frame.SourceFilename, - sourceLine: selectedRow.frame.SourceLine, - selfAnnualCO2Kgs: selectedRow.selfAnnualCO2kgs, - totalAnnualCO2Kgs: selectedRow.totalAnnualCO2kgs, - selfAnnualCostUSD: selectedRow.selfAnnualCostUSD, - totalAnnualCostUSD: selectedRow.totalAnnualCostUSD, - }} - totalSeconds={totalSeconds} - totalSamples={totalCount} - showAIAssistant={!isEmbedded} - showSymbolsStatus={!isEmbedded} - /> - )} - </> - ); - } -); + )} + </> + ); +}; diff --git a/x-pack/plugins/profiling/public/components/topn_functions/utils.test.ts b/x-pack/plugins/profiling/public/components/topn_functions/utils.test.ts index f0c6ca1a25c8d1..c7598f55acb0ba 100644 --- a/x-pack/plugins/profiling/public/components/topn_functions/utils.test.ts +++ b/x-pack/plugins/profiling/public/components/topn_functions/utils.test.ts @@ -4,7 +4,8 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { getColorLabel } from './utils'; +import { TopNFunctions } from '@kbn/profiling-utils'; +import { getColorLabel, getTotalCount } from './utils'; describe('Top N functions: Utils', () => { describe('getColorLabel', () => { @@ -40,4 +41,12 @@ describe('Top N functions: Utils', () => { }); }); }); + describe('getTotalCount', () => { + it('returns default value', () => { + expect(getTotalCount()).toEqual(0); + }); + it('returns value from topNFunctions', () => { + expect(getTotalCount({ TotalCount: 10 } as TopNFunctions)).toEqual(10); + }); + }); }); diff --git a/x-pack/plugins/profiling/public/components/topn_functions/utils.ts b/x-pack/plugins/profiling/public/components/topn_functions/utils.ts index 3e8389e4e1e9b8..f57d96ed07f8db 100644 --- a/x-pack/plugins/profiling/public/components/topn_functions/utils.ts +++ b/x-pack/plugins/profiling/public/components/topn_functions/utils.ts @@ -32,6 +32,8 @@ export function scaleValue({ value, scaleFactor = 1 }: { value: number; scaleFac return value * scaleFactor; } +export const getTotalCount = (topNFunctions?: TopNFunctions) => topNFunctions?.TotalCount ?? 0; + export interface IFunctionRow { id: string; rank: number; @@ -196,3 +198,21 @@ export function calculateBaseComparisonDiff({ label, }; } + +export function convertRowToFrame(row: IFunctionRow) { + return { + addressOrLine: row.frame.AddressOrLine, + countExclusive: row.selfCPU, + countInclusive: row.totalCPU, + exeFileName: row.frame.ExeFileName, + fileID: row.frame.FileID, + frameType: row.frame.FrameType, + functionName: row.frame.FunctionName, + sourceFileName: row.frame.SourceFilename, + sourceLine: row.frame.SourceLine, + selfAnnualCO2Kgs: row.selfAnnualCO2kgs, + totalAnnualCO2Kgs: row.totalAnnualCO2kgs, + selfAnnualCostUSD: row.selfAnnualCostUSD, + totalAnnualCostUSD: row.totalAnnualCostUSD, + }; +} diff --git a/x-pack/plugins/profiling/public/hooks/use_calculate_impact_estimates.test.ts b/x-pack/plugins/profiling/public/hooks/use_calculate_impact_estimates.test.ts index f0e6d2cda5c313..1c4017a468eaee 100644 --- a/x-pack/plugins/profiling/public/hooks/use_calculate_impact_estimates.test.ts +++ b/x-pack/plugins/profiling/public/hooks/use_calculate_impact_estimates.test.ts @@ -50,30 +50,18 @@ describe('useCalculateImpactEstimate', () => { percentage: 0.1, coreSeconds: 50, annualizedCoreSeconds: 1752000, - co2: 0.00006265168194444443, - annualizedCo2: 2.1953149353333328, - dollarCost: 0.0005902777777777778, - annualizedDollarCost: 20.683333333333334, }); expect(selfCPU).toEqual({ percentage: 0.05, coreSeconds: 25, annualizedCoreSeconds: 876000, - co2: 0.000031325840972222215, - annualizedCo2: 1.0976574676666664, - dollarCost: 0.0002951388888888889, - annualizedDollarCost: 10.341666666666667, }); expect(totalSamples).toEqual({ percentage: 1, coreSeconds: 500, annualizedCoreSeconds: 17520000, - co2: 0.0006265168194444444, - annualizedCo2: 21.95314935333333, - dollarCost: 0.0059027777777777785, - annualizedDollarCost: 206.83333333333337, }); }); @@ -90,30 +78,18 @@ describe('useCalculateImpactEstimate', () => { percentage: 0.1, coreSeconds: 50, annualizedCoreSeconds: 1752000, - co2: 0.00006265168194444443, - annualizedCo2: 2.1953149353333328, - dollarCost: 0.0005902777777777778, - annualizedDollarCost: 20.683333333333334, }); expect(selfCPU).toEqual({ percentage: 0.1, coreSeconds: 50, annualizedCoreSeconds: 1752000, - co2: 0.00006265168194444443, - annualizedCo2: 2.1953149353333328, - dollarCost: 0.0005902777777777778, - annualizedDollarCost: 20.683333333333334, }); expect(totalSamples).toEqual({ percentage: 1, coreSeconds: 500, annualizedCoreSeconds: 17520000, - co2: 0.0006265168194444444, - annualizedCo2: 21.95314935333333, - dollarCost: 0.0059027777777777785, - annualizedDollarCost: 206.83333333333337, }); }); }); diff --git a/x-pack/plugins/profiling/public/hooks/use_calculate_impact_estimates.ts b/x-pack/plugins/profiling/public/hooks/use_calculate_impact_estimates.ts index 69820a5090a89c..d148e0cc262dd3 100644 --- a/x-pack/plugins/profiling/public/hooks/use_calculate_impact_estimates.ts +++ b/x-pack/plugins/profiling/public/hooks/use_calculate_impact_estimates.ts @@ -5,13 +5,6 @@ * 2.0. */ -import { - profilingCo2PerKWH, - profilingDatacenterPUE, - profilingPervCPUWattX86, -} from '@kbn/observability-plugin/common'; -import { useProfilingDependencies } from '../components/contexts/profiling_dependencies/use_profiling_dependencies'; - interface Params { countInclusive: number; countExclusive: number; @@ -24,19 +17,7 @@ export type ImpactEstimates = ReturnType<CalculateImpactEstimates>; export const ANNUAL_SECONDS = 60 * 60 * 24 * 365; -// The cost of an x86 CPU core per hour, in US$. -// (ARM is 60% less based graviton 3 data, see https://aws.amazon.com/ec2/graviton/) -const CORE_COST_PER_HOUR = 0.0425; - export function useCalculateImpactEstimate() { - const { - start: { core }, - } = useProfilingDependencies(); - - const perCoreWatts = core.uiSettings.get<number>(profilingPervCPUWattX86); - const co2PerTonKWH = core.uiSettings.get<number>(profilingCo2PerKWH); - const datacenterPUE = core.uiSettings.get<number>(profilingDatacenterPUE); - function calculateImpact({ samples, totalSamples, @@ -51,21 +32,11 @@ export function useCalculateImpactEstimate() { const percentage = samples / totalSamples; const coreSeconds = totalCoreSeconds * percentage; const annualizedCoreSeconds = coreSeconds * annualizedScaleUp; - const coreHours = coreSeconds / (60 * 60); - const co2PerKWH = co2PerTonKWH * 1000; - const co2 = ((perCoreWatts * coreHours) / 1000.0) * co2PerKWH * datacenterPUE; - const annualizedCo2 = co2 * annualizedScaleUp; - const dollarCost = coreHours * CORE_COST_PER_HOUR; - const annualizedDollarCost = dollarCost * annualizedScaleUp; return { percentage, coreSeconds, annualizedCoreSeconds, - co2, - annualizedCo2, - dollarCost, - annualizedDollarCost, }; } diff --git a/x-pack/plugins/profiling/public/utils/get_flamegraph_model/index.ts b/x-pack/plugins/profiling/public/utils/get_flamegraph_model/index.ts index 16d2b6a7a1644a..614c17810a626a 100644 --- a/x-pack/plugins/profiling/public/utils/get_flamegraph_model/index.ts +++ b/x-pack/plugins/profiling/public/utils/get_flamegraph_model/index.ts @@ -25,6 +25,22 @@ const nullColumnarViewModel = { size1: new Float32Array(), }; +interface ComparisonNode { + FileID: string; + FrameType: number; + ExeFileName: string; + AddressOrLine: number; + FunctionName: string; + SourceFileName: string; + SourceLine: number; + CountInclusive: number; + CountExclusive: number; + SelfAnnualCO2Kgs: number; + TotalAnnualCO2Kgs: number; + SelfAnnualCostUSD: number; + TotalAnnualCostUSD: number; +} + export function getFlamegraphModel({ primaryFlamegraph, comparisonFlamegraph, @@ -46,11 +62,10 @@ export function getFlamegraphModel({ }): { key: string; viewModel: ColumnarViewModel; - comparisonNodesById: Record<string, { CountInclusive: number; CountExclusive: number }>; + comparisonNodesById: Record<string, ComparisonNode>; legendItems: Array<{ label: string; color: string }>; } { - const comparisonNodesById: Record<string, { CountInclusive: number; CountExclusive: number }> = - {}; + const comparisonNodesById: Record<string, ComparisonNode> = {}; if (!primaryFlamegraph || !primaryFlamegraph.Label || primaryFlamegraph.Label.length === 0) { return { @@ -97,6 +112,17 @@ export function getFlamegraphModel({ comparisonFlamegraph.ID.forEach((nodeID, index) => { comparisonNodesById[nodeID] = { + FileID: comparisonFlamegraph.FileID[index], + FrameType: comparisonFlamegraph.FrameType[index], + ExeFileName: comparisonFlamegraph.ExeFilename[index], + AddressOrLine: comparisonFlamegraph.AddressOrLine[index], + FunctionName: comparisonFlamegraph.FunctionName[index], + SourceFileName: comparisonFlamegraph.SourceFilename[index], + SourceLine: comparisonFlamegraph.SourceLine[index], + SelfAnnualCO2Kgs: comparisonFlamegraph.SelfAnnualCO2KgsItems[index], + TotalAnnualCO2Kgs: comparisonFlamegraph.TotalAnnualCO2KgsItems[index], + SelfAnnualCostUSD: comparisonFlamegraph.SelfAnnualCostsUSDItems[index], + TotalAnnualCostUSD: comparisonFlamegraph.TotalAnnualCostsUSDItems[index], CountInclusive: comparisonFlamegraph.CountInclusive[index], CountExclusive: comparisonFlamegraph.CountExclusive[index], }; diff --git a/x-pack/plugins/profiling/public/views/flamegraphs/differential_flamegraphs/index.tsx b/x-pack/plugins/profiling/public/views/flamegraphs/differential_flamegraphs/index.tsx index 82c7c0f92c071c..a956a6d715fbbc 100644 --- a/x-pack/plugins/profiling/public/views/flamegraphs/differential_flamegraphs/index.tsx +++ b/x-pack/plugins/profiling/public/views/flamegraphs/differential_flamegraphs/index.tsx @@ -126,9 +126,6 @@ export function DifferentialFlameGraphsView() { baseValue={ state.data?.primaryFlamegraph ? { - duration: totalSeconds, - selfCPU: state.data.primaryFlamegraph.SelfCPU, - totalCPU: state.data.primaryFlamegraph.TotalCPU, totalCount: state.data.primaryFlamegraph.TotalSamples, scaleFactor: isNormalizedByTime ? baselineTime : baseline, totalAnnualCO2Kgs: state.data.primaryFlamegraph.TotalAnnualCO2KgsItems[0], @@ -139,9 +136,6 @@ export function DifferentialFlameGraphsView() { comparisonValue={ state.data?.comparisonFlamegraph ? { - duration: totalComparisonSeconds, - selfCPU: state.data.comparisonFlamegraph.SelfCPU, - totalCPU: state.data.comparisonFlamegraph.TotalCPU, totalCount: state.data.comparisonFlamegraph.TotalSamples, scaleFactor: isNormalizedByTime ? comparisonTime : comparison, totalAnnualCO2Kgs: state.data.comparisonFlamegraph.TotalAnnualCO2KgsItems[0], diff --git a/x-pack/plugins/profiling/public/views/functions/differential_topn/index.tsx b/x-pack/plugins/profiling/public/views/functions/differential_topn/index.tsx index 9551645bb7567d..007f6a3546b7bf 100644 --- a/x-pack/plugins/profiling/public/views/functions/differential_topn/index.tsx +++ b/x-pack/plugins/profiling/public/views/functions/differential_topn/index.tsx @@ -54,9 +54,7 @@ export function DifferentialTopNFunctionsView() { const totalSeconds = timeRange.inSeconds.end - timeRange.inSeconds.start; const totalComparisonSeconds = - (new Date(comparisonTimeRange.end!).getTime() - - new Date(comparisonTimeRange.start!).getTime()) / - 1000; + comparisonTimeRange.inSeconds.end! - comparisonTimeRange.inSeconds.start!; const comparisonTime = totalSeconds / totalComparisonSeconds; @@ -175,10 +173,7 @@ export function DifferentialTopNFunctionsView() { baseValue={ state.data ? { - duration: totalSeconds, - selfCPU: state.data.selfCPU, totalCount: state.data.TotalCount, - totalCPU: state.data.totalCPU, scaleFactor: isNormalizedByTime ? baselineTime : baseline, totalAnnualCO2Kgs: state.data.totalAnnualCO2Kgs, totalAnnualCostUSD: state.data.totalAnnualCostUSD, @@ -188,10 +183,7 @@ export function DifferentialTopNFunctionsView() { comparisonValue={ comparisonState.data ? { - duration: totalComparisonSeconds, - selfCPU: comparisonState.data.selfCPU, totalCount: comparisonState.data.TotalCount, - totalCPU: comparisonState.data.totalCPU, scaleFactor: isNormalizedByTime ? comparisonTime : comparison, totalAnnualCO2Kgs: comparisonState.data.totalAnnualCO2Kgs, totalAnnualCostUSD: comparisonState.data.totalAnnualCostUSD, @@ -209,18 +201,19 @@ export function DifferentialTopNFunctionsView() { > <DifferentialTopNFunctionsGrid base={state.data} - comparison={comparisonState.data} baselineScaleFactor={isNormalizedByTime ? comparisonTime : comparison} + comparison={comparisonState.data} comparisonScaleFactor={isNormalizedByTime ? baselineTime : baseline} - totalSeconds={totalSeconds} - pageIndex={pageIndex} + comparisonSortDirection={comparisonSortDirection} + comparisonSortField={comparisonSortField} + comparisonTotalSeconds={totalComparisonSeconds} onChangePage={handlePageChange} onChangeSort={handleOnSort} - sortField={sortField} - sortDirection={sortDirection} onFrameClick={handleOnFrameClick} - comparisonSortDirection={comparisonSortDirection} - comparisonSortField={comparisonSortField} + pageIndex={pageIndex} + sortDirection={sortDirection} + sortField={sortField} + totalSeconds={totalSeconds} /> </AsyncComponent> </EuiFlexItem> From 99224539f863a04d68a418294774bdd553841669 Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Thu, 21 Dec 2023 12:59:19 +0200 Subject: [PATCH 066/116] [Cases] Do not check for version conflicts when adding/updating comments to a case (#173740) ## Summary When we add or update a comment (attachment) to a case we update the `updatedAt` and `updatedBy` attributes of the case. When we update the case we pass the version of the current case to the SO client for concurrency control. If the version of the current case is different from the one we updating (someone else updated the case) the SO client will throw an error. Although we always fetch the case before adding a comment it may be possible in some weird race conditions for one Kibana node to get the case and before updating another node to update the case. This is extremely difficult to produce when users interact but it may be possible (still rare) when we introduce the case action. This PR does not do any concurrency control when updating the `updatedAt` and `updatedBy` attributes of the case when adding/updating a comment. ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../common/models/case_with_comments.test.ts | 54 ++++++++++++++++++- .../common/models/case_with_comments.ts | 13 +++-- .../tests/common/comments/patch_comment.ts | 44 +++++++++++++++ .../tests/common/comments/post_comment.ts | 30 +++++++++++ .../internal/bulk_create_attachments.ts | 30 +++++++++++ 5 files changed, 163 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/cases/server/common/models/case_with_comments.test.ts b/x-pack/plugins/cases/server/common/models/case_with_comments.test.ts index 3a194645c3fca1..f55c1c78b11080 100644 --- a/x-pack/plugins/cases/server/common/models/case_with_comments.test.ts +++ b/x-pack/plugins/cases/server/common/models/case_with_comments.test.ts @@ -6,11 +6,15 @@ */ import type { AlertAttachmentAttributes } from '../../../common/types/domain'; +import { AttachmentType } from '../../../common/types/domain'; import type { SavedObject } from '@kbn/core-saved-objects-api-server'; import { createCasesClientMockArgs } from '../../client/mocks'; import { alertComment, comment, mockCaseComments, mockCases, multipleAlert } from '../../mocks'; import { CaseCommentModel } from './case_with_comments'; -import { MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES } from '../../../common/constants'; +import { + MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES, + SECURITY_SOLUTION_OWNER, +} from '../../../common/constants'; import { commentExternalReference, commentFileExternalReference, @@ -25,6 +29,7 @@ describe('CaseCommentModel', () => { clientArgs.services.caseService.getCase.mockResolvedValue(theCase); clientArgs.services.caseService.patchCase.mockResolvedValue(theCase); clientArgs.services.attachmentService.create.mockResolvedValue(mockCaseComments[0]); + clientArgs.services.attachmentService.update.mockResolvedValue(mockCaseComments[0]); clientArgs.services.attachmentService.bulkCreate.mockResolvedValue({ saved_objects: mockCaseComments, }); @@ -274,6 +279,18 @@ describe('CaseCommentModel', () => { expect(clientArgs.services.attachmentService.create).not.toHaveBeenCalled(); }); + it('partial updates the case', async () => { + await model.createComment({ + id: 'comment-1', + commentReq: comment, + createdDate, + }); + + const args = clientArgs.services.caseService.patchCase.mock.calls[0][0]; + + expect(args.version).toBeUndefined(); + }); + describe('validation', () => { clientArgs.services.attachmentService.countPersistableStateAndExternalReferenceAttachments.mockResolvedValue( MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES @@ -579,6 +596,21 @@ describe('CaseCommentModel', () => { expect(multipleAlertsCall.attributes.index).toEqual(['test-index-3', 'test-index-5']); }); + it('partial updates the case', async () => { + await model.bulkCreate({ + attachments: [ + { + id: 'comment-1', + ...comment, + }, + ], + }); + + const args = clientArgs.services.caseService.patchCase.mock.calls[0][0]; + + expect(args.version).toBeUndefined(); + }); + describe('validation', () => { clientArgs.services.attachmentService.countPersistableStateAndExternalReferenceAttachments.mockResolvedValue( MAX_PERSISTABLE_STATE_AND_EXTERNAL_REFERENCES @@ -619,4 +651,24 @@ describe('CaseCommentModel', () => { }); }); }); + + describe('updateComment', () => { + it('partial updates the case', async () => { + await model.updateComment({ + updateRequest: { + id: 'comment-id', + version: 'comment-version', + type: AttachmentType.user, + comment: 'my updated comment', + owner: SECURITY_SOLUTION_OWNER, + }, + updatedAt: createdDate, + owner: SECURITY_SOLUTION_OWNER, + }); + + const args = clientArgs.services.caseService.patchCase.mock.calls[0][0]; + + expect(args.version).toBeUndefined(); + }); + }); }); diff --git a/x-pack/plugins/cases/server/common/models/case_with_comments.ts b/x-pack/plugins/cases/server/common/models/case_with_comments.ts index e1b89d7af791e1..a1eb5cbfdb8b51 100644 --- a/x-pack/plugins/cases/server/common/models/case_with_comments.ts +++ b/x-pack/plugins/cases/server/common/models/case_with_comments.ts @@ -129,7 +129,7 @@ export class CaseCommentModel { }, options, }), - this.updateCaseUserAndDateSkipRefresh(updatedAt), + this.partialUpdateCaseUserAndDateSkipRefresh(updatedAt), ]); await commentableCase.createUpdateCommentUserAction(comment, updateRequest, owner); @@ -144,11 +144,11 @@ export class CaseCommentModel { } } - private async updateCaseUserAndDateSkipRefresh(date: string) { - return this.updateCaseUserAndDate(date, false); + private async partialUpdateCaseUserAndDateSkipRefresh(date: string) { + return this.partialUpdateCaseUserAndDate(date, false); } - private async updateCaseUserAndDate( + private async partialUpdateCaseUserAndDate( date: string, refresh: RefreshSetting ): Promise<CaseCommentModel> { @@ -160,7 +160,6 @@ export class CaseCommentModel { updated_at: date, updated_by: { ...this.params.user }, }, - version: this.caseInfo.version, refresh, }); @@ -242,7 +241,7 @@ export class CaseCommentModel { id, refresh: false, }), - this.updateCaseUserAndDateSkipRefresh(createdDate), + this.partialUpdateCaseUserAndDateSkipRefresh(createdDate), ]); await Promise.all([ @@ -502,7 +501,7 @@ export class CaseCommentModel { }), refresh: false, }), - this.updateCaseUserAndDateSkipRefresh(new Date().toISOString()), + this.partialUpdateCaseUserAndDateSkipRefresh(new Date().toISOString()), ]); const savedObjectsWithoutErrors = newlyCreatedAttachments.saved_objects.filter( diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/patch_comment.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/patch_comment.ts index 8c2c356b6090e6..1ea5013b165060 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/patch_comment.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/patch_comment.ts @@ -12,6 +12,7 @@ import { AlertAttachmentAttributes, UserCommentAttachmentAttributes, AttachmentType, + CaseStatuses, } from '@kbn/cases-plugin/common/types/domain'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; @@ -34,6 +35,7 @@ import { updateComment, superUserSpace1Auth, removeServerGeneratedPropertiesFromSavedObject, + updateCase, } from '../../../../common/lib/api'; import { globalRead, @@ -549,6 +551,48 @@ export default ({ getService }: FtrProviderContext): void => { } }); + describe('partial updates', () => { + it('should not result to a version conflict (409) when updating a comment to an updated case', async () => { + const postedCase = await createCase(supertest, postCaseReq); + const caseWithComments = await createComment({ + supertest, + caseId: postedCase.id, + params: postCommentUserReq, + expectedHttpCode: 200, + }); + + /** + * Updating the status of the case will + * change the version of the case + */ + await updateCase({ + supertest, + params: { + cases: [ + { + id: caseWithComments.id, + version: caseWithComments.version, + status: CaseStatuses['in-progress'], + }, + ], + }, + }); + + await updateComment({ + supertest, + caseId: postedCase.id, + req: { + id: caseWithComments.comments![0].id, + version: caseWithComments.comments![0].version, + comment: 'my new comment', + type: AttachmentType.user, + owner: 'securitySolutionFixture', + }, + expectedHttpCode: 200, + }); + }); + }); + describe('rbac', () => { const supertestWithoutAuth = getService('supertestWithoutAuth'); diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/post_comment.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/post_comment.ts index 88723df678f8a4..fcb376e4df5220 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/post_comment.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/comments/post_comment.ts @@ -1123,6 +1123,36 @@ export default ({ getService }: FtrProviderContext): void => { }); }); + describe('partial updates', () => { + it('should not result to a version conflict (409) when adding a comment to an updated case', async () => { + const postedCase = await createCase(supertest, postCaseReq); + + /** + * Updating the status of the case will + * change the version of the case + */ + await updateCase({ + supertest, + params: { + cases: [ + { + id: postedCase.id, + version: postedCase.version, + status: CaseStatuses['in-progress'], + }, + ], + }, + }); + + await createComment({ + supertest, + caseId: postedCase.id, + params: postCommentUserReq, + expectedHttpCode: 200, + }); + }); + }); + describe('rbac', () => { afterEach(async () => { await deleteAllCaseItems(es); diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_create_attachments.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_create_attachments.ts index 3c3748a844ea6a..6c929f67b8c901 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_create_attachments.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_create_attachments.ts @@ -1512,6 +1512,36 @@ export default ({ getService }: FtrProviderContext): void => { }); }); + describe('partial updates', () => { + it('should not result to a version conflict (409) when adding comments to an updated case', async () => { + const postedCase = await createCase(supertest, postCaseReq); + + /** + * Updating the status of the case will + * change the version of the case + */ + await updateCase({ + supertest, + params: { + cases: [ + { + id: postedCase.id, + version: postedCase.version, + status: CaseStatuses['in-progress'], + }, + ], + }, + }); + + await bulkCreateAttachments({ + supertest, + caseId: postedCase.id, + params: [postCommentUserReq], + expectedHttpCode: 200, + }); + }); + }); + describe('rbac', () => { afterEach(async () => { await deleteAllCaseItems(es); From 85df7c994930c9dccd30e8f30b81d703f5521d34 Mon Sep 17 00:00:00 2001 From: Coen Warmer <coen.warmer@gmail.com> Date: Thu, 21 Dec 2023 12:03:02 +0100 Subject: [PATCH 067/116] Adjust wording in Set up KB message (#173814) --- .../components/chat/welcome_message_knowledge_base.tsx | 6 +++--- .../public/components/feedback_buttons.tsx | 9 +++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/welcome_message_knowledge_base.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/welcome_message_knowledge_base.tsx index 849a07b7cabfc1..afdbed9ed4c43d 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/welcome_message_knowledge_base.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/welcome_message_knowledge_base.tsx @@ -113,7 +113,7 @@ export function WelcomeMessageKnowledgeBase({ <EuiText color="subdued" size="s"> {i18n.translate( 'xpack.observabilityAiAssistant.welcomeMessageKnowledgeBase.yourKnowledgeBaseIsNotSetUpCorrectlyLabel', - { defaultMessage: 'Your Knowledge base is not set up correctly' } + { defaultMessage: `Your Knowledge base hasn't been set up.` } )} </EuiText> @@ -127,13 +127,13 @@ export function WelcomeMessageKnowledgeBase({ data-test-subj="observabilityAiAssistantWelcomeMessageSetUpKnowledgeBaseButton" fill isLoading={checkForInstallStatus} - iconType="refresh" + iconType="importAction" onClick={handleRetryInstall} > {i18n.translate( 'xpack.observabilityAiAssistant.welcomeMessage.retryButtonLabel', { - defaultMessage: 'Retry install', + defaultMessage: 'Install Knowledge base', } )} </EuiButton> diff --git a/x-pack/plugins/observability_ai_assistant/public/components/feedback_buttons.tsx b/x-pack/plugins/observability_ai_assistant/public/components/feedback_buttons.tsx index 2187817e7228e3..6315d493078c56 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/feedback_buttons.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/feedback_buttons.tsx @@ -16,6 +16,11 @@ interface FeedbackButtonsProps { onClickFeedback: (feedback: Feedback) => void; } +const THANK_YOU_MESSAGE = i18n.translate( + 'xpack.observabilityAiAssistant.feedbackButtons.em.thanksForYourFeedbackLabel', + { defaultMessage: 'Thanks for your feedback' } +); + export function FeedbackButtons({ onClickFeedback }: FeedbackButtonsProps) { const { notifications } = useKibana().services; @@ -24,13 +29,13 @@ export function FeedbackButtons({ onClickFeedback }: FeedbackButtonsProps) { const handleClickPositive = () => { onClickFeedback('positive'); setHasBeenClicked(true); - notifications.toasts.addSuccess('Thanks for your feedback!'); + notifications.toasts.addSuccess(THANK_YOU_MESSAGE); }; const handleClickNegative = () => { onClickFeedback('negative'); setHasBeenClicked(true); - notifications.toasts.addSuccess('Thanks for your feedback!'); + notifications.toasts.addSuccess(THANK_YOU_MESSAGE); }; return ( From e51a3f9efc93912d86df9248200c7c6b91918858 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet <nicolas.chaulet@elastic.co> Date: Thu, 21 Dec 2023 12:21:17 +0100 Subject: [PATCH 068/116] [Fleet] Allow to skipDatastreamRollover from preconfiguration (#173766) --- .../common/types/models/preconfiguration.ts | 1 + .../epm/packages/bulk_install_packages.ts | 17 +++- .../server/services/preconfiguration.test.ts | 88 ++++++++++++------- .../fleet/server/services/preconfiguration.ts | 6 +- .../server/types/models/preconfiguration.ts | 1 + 5 files changed, 79 insertions(+), 34 deletions(-) diff --git a/x-pack/plugins/fleet/common/types/models/preconfiguration.ts b/x-pack/plugins/fleet/common/types/models/preconfiguration.ts index ac3f8f566ec1f2..c6ad134fb31c90 100644 --- a/x-pack/plugins/fleet/common/types/models/preconfiguration.ts +++ b/x-pack/plugins/fleet/common/types/models/preconfiguration.ts @@ -35,6 +35,7 @@ export interface PreconfiguredAgentPolicy extends Omit<NewAgentPolicy, 'namespac export interface PreconfiguredPackage extends Omit<PackagePolicyPackage, 'title'> { prerelease?: boolean; + skipDataStreamRollover?: boolean; } export interface PreconfiguredOutput extends Omit<Output, 'config_yaml'> { diff --git a/x-pack/plugins/fleet/server/services/epm/packages/bulk_install_packages.ts b/x-pack/plugins/fleet/server/services/epm/packages/bulk_install_packages.ts index 70cdd766b0a66f..da5ee0bcc8e5ca 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/bulk_install_packages.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/bulk_install_packages.ts @@ -19,7 +19,10 @@ import type { BulkInstallResponse, IBulkInstallPackageError } from './install'; interface BulkInstallPackagesParams { savedObjectsClient: SavedObjectsClientContract; - packagesToInstall: Array<string | { name: string; version?: string; prerelease?: boolean }>; + packagesToInstall: Array< + | string + | { name: string; version?: string; prerelease?: boolean; skipDataStreamRollover?: boolean } + >; esClient: ElasticsearchClient; force?: boolean; spaceId: string; @@ -48,10 +51,18 @@ export async function bulkInstallPackages({ name: pkgRes.name, version: pkgRes.version, prerelease: undefined, + skipDataStreamRollover: undefined, })); } if (pkg.version !== undefined) { - return Promise.resolve(pkg as { name: string; version: string; prerelease?: boolean }); + return Promise.resolve( + pkg as { + name: string; + version: string; + prerelease?: boolean; + skipDataStreamRollover?: boolean; + } + ); } return Registry.fetchFindLatestPackageOrThrow(pkg.name, { @@ -60,6 +71,7 @@ export async function bulkInstallPackages({ name: pkgRes.name, version: pkgRes.version, prerelease: pkg.prerelease, + skipDataStreamRollover: pkg.skipDataStreamRollover, })); }) ); @@ -114,6 +126,7 @@ export async function bulkInstallPackages({ force, prerelease: prerelease || ('prerelease' in pkgKeyProps && pkgKeyProps.prerelease), authorizationHeader, + skipDataStreamRollover: pkgKeyProps.skipDataStreamRollover, }); if (installResult.error) { diff --git a/x-pack/plugins/fleet/server/services/preconfiguration.test.ts b/x-pack/plugins/fleet/server/services/preconfiguration.test.ts index 8c150aabb5b893..bf70ef7652d9ae 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration.test.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration.test.ts @@ -30,7 +30,7 @@ import { } from './preconfiguration'; import { packagePolicyService } from './package_policy'; import { getBundledPackages } from './epm/packages/bundled_packages'; -import type { InstallPackageParams } from './epm/packages/install'; +import { installPackage, type InstallPackageParams } from './epm/packages/install'; jest.mock('./agent_policy_update'); jest.mock('./output'); @@ -144,44 +144,46 @@ jest.mock('./epm/registry', () => ({ })); jest.mock('./epm/packages/install', () => ({ - async installPackage(args: InstallPackageParams): Promise<InstallResult | undefined> { - if (args.installSource === 'registry') { - const [pkgName, pkgVersion] = args.pkgkey.split('-'); - const installError = mockInstallPackageErrors.get(pkgName); - if (installError) { + installPackage: jest.fn( + async (args: InstallPackageParams): Promise<InstallResult | undefined> => { + if (args.installSource === 'registry') { + const [pkgName, pkgVersion] = args.pkgkey.split('-'); + const installError = mockInstallPackageErrors.get(pkgName); + if (installError) { + return { + error: new Error(installError), + installType: 'install', + installSource: 'registry', + }; + } + + const installedPackage = mockInstalledPackages.get(pkgName); + if (installedPackage) { + if (installedPackage.version === pkgVersion) return installedPackage; + } + + const packageInstallation = { name: pkgName, version: pkgVersion, title: pkgName }; + mockInstalledPackages.set(pkgName, packageInstallation); + return { - error: new Error(installError), + status: 'installed', installType: 'install', installSource: 'registry', }; - } - - const installedPackage = mockInstalledPackages.get(pkgName); - if (installedPackage) { - if (installedPackage.version === pkgVersion) return installedPackage; - } + } else if (args.installSource === 'upload') { + const { archiveBuffer } = args; - const packageInstallation = { name: pkgName, version: pkgVersion, title: pkgName }; - mockInstalledPackages.set(pkgName, packageInstallation); + // Treat the buffer value passed in tests as the package's name for simplicity + const pkgName = archiveBuffer.toString('utf8'); - return { - status: 'installed', - installType: 'install', - installSource: 'registry', - }; - } else if (args.installSource === 'upload') { - const { archiveBuffer } = args; - - // Treat the buffer value passed in tests as the package's name for simplicity - const pkgName = archiveBuffer.toString('utf8'); - - // Just install every bundled package at version '1.0.0' - const packageInstallation = { name: pkgName, version: '1.0.0', title: pkgName }; - mockInstalledPackages.set(pkgName, packageInstallation); + // Just install every bundled package at version '1.0.0' + const packageInstallation = { name: pkgName, version: '1.0.0', title: pkgName }; + mockInstalledPackages.set(pkgName, packageInstallation); - return { status: 'installed', installType: 'install', installSource: 'upload' }; + return { status: 'installed', installType: 'install', installSource: 'upload' }; + } } - }, + ), ensurePackagesCompletedInstall() { return []; }, @@ -395,6 +397,30 @@ describe('policy preconfiguration', () => { expect(nonFatalErrors.length).toBe(0); }); + it('should pass skipDatastreamRollover flag if configured', async () => { + const soClient = getPutPreconfiguredPackagesMock(); + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + + const { policies, packages, nonFatalErrors } = await ensurePreconfiguredPackagesAndPolicies( + soClient, + esClient, + [] as PreconfiguredAgentPolicy[], + [{ name: 'test_package', version: 'latest', skipDataStreamRollover: true }], + mockDefaultOutput, + mockDefaultDownloadService, + DEFAULT_SPACE_ID + ); + + expect(policies.length).toEqual(0); + expect(packages).toEqual(expect.arrayContaining(['test_package-1.0.0'])); + expect(nonFatalErrors.length).toBe(0); + expect(jest.mocked(installPackage)).toBeCalledWith( + expect.objectContaining({ + skipDataStreamRollover: true, + }) + ); + }); + it('should not add new package policy to existing non managed policies', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; diff --git a/x-pack/plugins/fleet/server/services/preconfiguration.ts b/x-pack/plugins/fleet/server/services/preconfiguration.ts index ad1e1c0ddb8b59..8a4944ddb99ad4 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration.ts @@ -81,7 +81,11 @@ export async function ensurePreconfiguredPackagesAndPolicies( const packagesToInstall = packages.map((pkg) => pkg.version === PRECONFIGURATION_LATEST_KEYWORD - ? { name: pkg.name, prerelease: pkg.prerelease } + ? { + name: pkg.name, + prerelease: pkg.prerelease, + skipDataStreamRollover: pkg.skipDataStreamRollover, + } : pkg ); diff --git a/x-pack/plugins/fleet/server/types/models/preconfiguration.ts b/x-pack/plugins/fleet/server/types/models/preconfiguration.ts index 821debf37bca0a..2928db35587d18 100644 --- a/x-pack/plugins/fleet/server/types/models/preconfiguration.ts +++ b/x-pack/plugins/fleet/server/types/models/preconfiguration.ts @@ -45,6 +45,7 @@ export const PreconfiguredPackagesSchema = schema.arrayOf( }, }), prerelease: schema.maybe(schema.boolean()), + skipDataStreamRollover: schema.maybe(schema.boolean()), }), { defaultValue: [], From d7b99a587799e34c9534e4ba793aad65b4f78d55 Mon Sep 17 00:00:00 2001 From: Nikita Indik <nikita.indik@elastic.co> Date: Thu, 21 Dec 2023 12:39:16 +0100 Subject: [PATCH 069/116] [Security Solution] Enable the feature flag for JSON diffing in prebuilt rules (#173368) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Ticket:** https://github.com/elastic/kibana/issues/169160 ## Summary Sets the `jsonPrebuiltRulesDiffingEnabled` to `true` to enable the new "Updates" tab in prebuilt rules flyout. ### IMPORTANT: Merge only once acceptance and exploratory testing are passed! <img width="1178" alt="Scherm­afbeelding 2023-12-13 om 17 37 07" src="https://github.com/elastic/kibana/assets/15949146/9e07e069-595f-49a6-98c2-d2ed4aa3f977"> Co-authored-by: Georgii Gorbachev <georgii.gorbachev@elastic.co> --- .../plugins/security_solution/common/experimental_features.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index a9f3affba56d76..8c16307ab5b8c5 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -162,7 +162,7 @@ export const allowedExperimentalValues = Object.freeze({ * This tab shows the JSON diff between the installed prebuilt rule * version and the latest available version. */ - jsonPrebuiltRulesDiffingEnabled: false, + jsonPrebuiltRulesDiffingEnabled: true, }); type ExperimentalConfigKeys = Array<keyof ExperimentalFeatures>; From 87d5d6be262068d52d7125a6d75670d4c2c09ea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Kopyci=C5=84ski?= <contact@patrykkopycinski.com> Date: Thu, 21 Dec 2023 12:51:58 +0100 Subject: [PATCH 070/116] Replace deprecated node-sass with sass (#161813) ## Summary https://sass-lang.com/blog/libsass-is-deprecated/ Most of the changes related to https://sass-lang.com/documentation/breaking-changes/slash-div/ --------- Co-authored-by: Tiago Costa <tiago.costa@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- WORKSPACE.bazel | 1 - kbn_pm/src/lib/bazel.mjs | 2 - package.json | 4 +- .../kbn-dom-drag-drop/src/sass/drag_drop.scss | 2 +- .../src/worker/webpack.config.ts | 8 +- packages/kbn-storybook/src/webpack.config.ts | 3 +- .../field_list_sidebar.scss | 2 +- renovate.json | 4 +- .../build/tasks/install_dependencies_task.ts | 2 - src/dev/license_checker/config.ts | 1 + src/plugins/console/public/styles/_app.scss | 2 +- .../options_list/components/options_list.scss | 4 +- .../components/doc_table/_doc_table.scss | 2 +- .../public/markdown/_markdown.scss | 2 +- .../filter_bar/filter_item/filter_item.scss | 8 +- .../saved_query_management_list.scss | 4 +- .../public/_agg_params.scss | 2 +- .../components/_vis_with_splits.scss | 2 +- .../visualizations/views/_metric.scss | 2 +- .../public/vislib/lib/layout/_layout.scss | 2 +- .../shareable_runtime/webpack.config.js | 4 +- .../canvas/storybook/canvas_webpack.ts | 2 +- .../field_data_row/column_chart.scss | 2 +- .../guidance_panel/_guidance_panel.scss | 2 +- .../editor_frame/suggestion_panel.scss | 4 +- .../layer_toc/toc_entry/_toc_entry.scss | 2 +- .../influencers_list/_influencers_list.scss | 4 +- .../components/rule_editor/_rule_editor.scss | 2 +- .../explorer_charts/_explorer_chart.scss | 2 +- .../_timeseriesexplorer_annotations.scss | 8 +- .../shard_allocation/shard_allocation.scss | 2 +- .../components/status_icon/_status_icon.scss | 2 +- .../components/policy_form/_policy_form.scss | 4 +- .../_restore_snapshot_form.scss | 4 +- .../_deprecation_logging_toggle.scss | 2 +- yarn.lock | 452 +++++------------- 36 files changed, 166 insertions(+), 391 deletions(-) diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index e614bdff172f99..49623728f1afe9 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel @@ -60,7 +60,6 @@ yarn_install( "GECKODRIVER_CDNURL": "https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache", "CHROMEDRIVER_CDNURL": "https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache", "CHROMEDRIVER_CDNBINARIESURL": "https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache", - "SASS_BINARY_SITE": "https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-sass", "RE2_DOWNLOAD_MIRROR": "https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2", "CYPRESS_DOWNLOAD_MIRROR": "https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/cypress", } diff --git a/kbn_pm/src/lib/bazel.mjs b/kbn_pm/src/lib/bazel.mjs index 2ec27b359f1533..022447ded129c1 100644 --- a/kbn_pm/src/lib/bazel.mjs +++ b/kbn_pm/src/lib/bazel.mjs @@ -150,8 +150,6 @@ export async function installYarnDeps(log, opts = undefined) { offline: opts?.offline, quiet: opts?.quiet, env: { - SASS_BINARY_SITE: - 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-sass', RE2_DOWNLOAD_MIRROR: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2', }, diff --git a/package.json b/package.json index 2553521b662be4..972f7df2bc0f7c 100644 --- a/package.json +++ b/package.json @@ -1597,7 +1597,6 @@ "mutation-observer": "^1.0.3", "native-hdr-histogram": "^1.0.0", "nock": "12.0.3", - "node-sass": "^8.0.0", "null-loader": "^3.0.0", "nyc": "^15.1.0", "oboe": "^2.1.4", @@ -1625,7 +1624,8 @@ "regenerate": "^1.4.0", "resolve": "^1.22.0", "rxjs-marbles": "^7.0.1", - "sass-loader": "^10.4.1", + "sass-embedded": "^1.69.5", + "sass-loader": "^10.5.0", "selenium-webdriver": "^4.16.0", "simple-git": "^3.16.0", "sinon": "^7.4.2", diff --git a/packages/kbn-dom-drag-drop/src/sass/drag_drop.scss b/packages/kbn-dom-drag-drop/src/sass/drag_drop.scss index c26bb6c49b6cff..c68ae0c0d6f1e0 100644 --- a/packages/kbn-dom-drag-drop/src/sass/drag_drop.scss +++ b/packages/kbn-dom-drag-drop/src/sass/drag_drop.scss @@ -99,7 +99,7 @@ $reorderItemMargin: $euiSizeS; position: absolute; width: 100%; top: 0; - height: calc(100% + #{$reorderItemMargin / 2}); + height: calc(100% + #{calc($reorderItemMargin / 2)}); } .domDragDrop-translatableDrop { diff --git a/packages/kbn-optimizer/src/worker/webpack.config.ts b/packages/kbn-optimizer/src/worker/webpack.config.ts index 189ca29072afe6..7b4a5b27b78c7a 100644 --- a/packages/kbn-optimizer/src/worker/webpack.config.ts +++ b/packages/kbn-optimizer/src/worker/webpack.config.ts @@ -185,12 +185,12 @@ export function getWebpackConfig( ) )};\n${content}`; }, - webpackImporter: false, - implementation: require('node-sass'), + implementation: require('sass-embedded'), sassOptions: { - outputStyle: worker.dist ? 'compressed' : 'nested', + outputStyle: worker.dist ? 'compressed' : 'expanded', includePaths: [Path.resolve(worker.repoRoot, 'node_modules')], - sourceMapRoot: `/${bundle.type}:${bundle.id}`, + sourceMap: true, + quietDeps: true, }, }, }, diff --git a/packages/kbn-storybook/src/webpack.config.ts b/packages/kbn-storybook/src/webpack.config.ts index 35bda9718d7cb6..282a41dcbd4532 100644 --- a/packages/kbn-storybook/src/webpack.config.ts +++ b/packages/kbn-storybook/src/webpack.config.ts @@ -115,9 +115,10 @@ export default ({ config: storybookConfig }: { config: Configuration }) => { resolve(REPO_ROOT, 'src/core/public/styles/core_app/_globals_v8light.scss') )};\n${content}`; }, - implementation: require('node-sass'), + implementation: require('sass-embedded'), sassOptions: { includePaths: [resolve(REPO_ROOT, 'node_modules')], + quietDeps: true, }, }, }, diff --git a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.scss b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.scss index 48fb44f1663e37..08402941bf74b5 100644 --- a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.scss +++ b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.scss @@ -53,7 +53,7 @@ .unifiedFieldListSidebar .unifiedFieldListItemButton { &.kbnFieldButton { - margin-bottom: $euiSizeXS / 2; + margin-bottom: calc($euiSizeXS / 2); } &.domDragDrop-isDraggable { diff --git a/renovate.json b/renovate.json index 4a725ce80a5f5d..7fb5b9020388c4 100644 --- a/renovate.json +++ b/renovate.json @@ -362,7 +362,7 @@ { "groupName": "scss", "packageNames": [ - "node-sass" + "sass-embedded" ], "reviewers": [ "team:kibana-operations" @@ -673,4 +673,4 @@ "enabled": true } ] -} \ No newline at end of file +} diff --git a/src/dev/build/tasks/install_dependencies_task.ts b/src/dev/build/tasks/install_dependencies_task.ts index 59c9e389112435..0eebadec5ca791 100644 --- a/src/dev/build/tasks/install_dependencies_task.ts +++ b/src/dev/build/tasks/install_dependencies_task.ts @@ -32,8 +32,6 @@ export const InstallDependencies: Task = { { cwd: build.resolvePath(), env: { - SASS_BINARY_SITE: - 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-sass', RE2_DOWNLOAD_MIRROR: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2', }, diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index b0919d0ab61415..6ba5deb6408acc 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -88,4 +88,5 @@ export const LICENSE_OVERRIDES = { '@elastic/eui@91.0.0-backport.0': ['SSPL-1.0 OR Elastic License 2.0'], 'language-subtag-registry@0.3.21': ['CC-BY-4.0'], // retired ODC‑By license https://github.com/mattcg/language-subtag-registry 'buffers@0.1.1': ['MIT'], // license in importing module https://www.npmjs.com/package/binary + '@bufbuild/protobuf@1.2.1': ['Apache-2.0'], // license (Apache-2.0 AND BSD-3-Clause) }; diff --git a/src/plugins/console/public/styles/_app.scss b/src/plugins/console/public/styles/_app.scss index 9cbe6437220477..2f4340f1de0ab1 100644 --- a/src/plugins/console/public/styles/_app.scss +++ b/src/plugins/console/public/styles/_app.scss @@ -42,7 +42,7 @@ padding: 0 $euiSizeS; display: inline-block; text-decoration: none; - border-radius: $euiBorderRadius / 2; + border-radius: calc($euiBorderRadius / 2); white-space: nowrap; vertical-align: middle; cursor: default; diff --git a/src/plugins/controls/public/options_list/components/options_list.scss b/src/plugins/controls/public/options_list/components/options_list.scss index ff4014d0cc41d5..e0c749441ff6af 100644 --- a/src/plugins/controls/public/options_list/components/options_list.scss +++ b/src/plugins/controls/public/options_list/components/options_list.scss @@ -65,7 +65,7 @@ } .optionsList__actionsRow { - margin: ($euiSizeS / 2) 0 !important; + margin: calc($euiSizeS / 2) 0 !important; .optionsList__actionBarDivider { height: $euiSize; @@ -97,4 +97,4 @@ color: $euiTextSubduedColor; padding: $euiSizeM; } -} \ No newline at end of file +} diff --git a/src/plugins/discover/public/components/doc_table/_doc_table.scss b/src/plugins/discover/public/components/doc_table/_doc_table.scss index 8a9b629a9694bc..67de9cfae42e1f 100644 --- a/src/plugins/discover/public/components/doc_table/_doc_table.scss +++ b/src/plugins/discover/public/components/doc_table/_doc_table.scss @@ -69,7 +69,7 @@ dt { background-color: transparentize(shade($euiColorPrimary, 20%), .9); color: $euiTextColor; - padding: ($euiSizeXS / 2) $euiSizeXS; + padding: calc($euiSizeXS / 2) $euiSizeXS; margin-right: $euiSizeXS; word-break: normal; border-radius: $euiBorderRadius; diff --git a/src/plugins/kibana_react/public/markdown/_markdown.scss b/src/plugins/kibana_react/public/markdown/_markdown.scss index c11aefe1f4d97c..a3bba38509bcdb 100644 --- a/src/plugins/kibana_react/public/markdown/_markdown.scss +++ b/src/plugins/kibana_react/public/markdown/_markdown.scss @@ -14,7 +14,7 @@ $kbnDefaultFontSize: 14px; @function canvasToEm($size) { - @return #{$size / $kbnDefaultFontSize}em; + @return #{calc($size / $kbnDefaultFontSize)}em; } .kbnMarkdown__body { diff --git a/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.scss b/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.scss index 1c16adbfc8c133..362aec7264983e 100644 --- a/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.scss +++ b/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.scss @@ -8,8 +8,8 @@ line-height: $euiSize; border: none; color: $euiTextColor; - padding-top: $euiSizeM / 2 + 1px; - padding-bottom: $euiSizeM / 2 + 1px; + padding-top: calc($euiSizeM / 2) + 1px; + padding-bottom: calc($euiSizeM / 2) + 1px; white-space: normal; /* 1 */ &:not(.globalFilterItem-isDisabled) { @@ -54,8 +54,8 @@ left: 0; width: $euiSizeXS; background-color: $kbnGlobalFilterItemBorderColor; - border-top-left-radius: $euiBorderRadius / 2; - border-bottom-left-radius: $euiBorderRadius / 2; + border-top-left-radius: calc($euiBorderRadius / 2); + border-bottom-left-radius: calc($euiBorderRadius / 2); } } diff --git a/src/plugins/unified_search/public/saved_query_management/saved_query_management_list.scss b/src/plugins/unified_search/public/saved_query_management/saved_query_management_list.scss index 7ce304310ae56a..2e6f639ea792d7 100644 --- a/src/plugins/unified_search/public/saved_query_management/saved_query_management_list.scss +++ b/src/plugins/unified_search/public/saved_query_management/saved_query_management_list.scss @@ -5,7 +5,7 @@ } .kbnSavedQueryManagement__text { - padding: $euiSizeM $euiSizeM ($euiSizeM / 2) $euiSizeM; + padding: $euiSizeM $euiSizeM calc($euiSizeM / 2) $euiSizeM; } .kbnSavedQueryManagement__list { @@ -13,5 +13,5 @@ max-height: inherit; // Fixes overflow for applied max-height // Left/Right padding is calculated to match the left alignment of the // popover text and buttons - padding: ($euiSizeM / 2) $euiSizeXS !important; // Override flush + padding: calc($euiSizeM / 2) $euiSizeXS !important; // Override flush } diff --git a/src/plugins/vis_default_editor/public/_agg_params.scss b/src/plugins/vis_default_editor/public/_agg_params.scss index 81faa06681c0d9..c56ef94c3a4baf 100644 --- a/src/plugins/vis_default_editor/public/_agg_params.scss +++ b/src/plugins/vis_default_editor/public/_agg_params.scss @@ -1,7 +1,7 @@ .visEditorAggParam--half { margin: $euiSize 0; display: inline-block; - width: calc(50% - #{$euiSizeS / 2}); + width: calc(50% - #{calc($euiSizeS / 2)}); } .visEditorAggParam--half-size { diff --git a/src/plugins/vis_types/timeseries/public/application/components/_vis_with_splits.scss b/src/plugins/vis_types/timeseries/public/application/components/_vis_with_splits.scss index 9e09a6c3477f3c..036cf3f6a8fbdc 100644 --- a/src/plugins/vis_types/timeseries/public/application/components/_vis_with_splits.scss +++ b/src/plugins/vis_types/timeseries/public/application/components/_vis_with_splits.scss @@ -20,7 +20,7 @@ > .tvbVis { // Apply the minimum height on the vis itself so it doesn't interfere with flex calculations // Gauges are not completely square, so the height is just slightly less than the width - min-height: $euiSize * 12 / 1.25; + min-height: calc($euiSize * 12 / 1.25); } } diff --git a/src/plugins/vis_types/timeseries/public/application/visualizations/views/_metric.scss b/src/plugins/vis_types/timeseries/public/application/visualizations/views/_metric.scss index bc2ce4f1a9e441..d5eb056dd172e4 100644 --- a/src/plugins/vis_types/timeseries/public/application/visualizations/views/_metric.scss +++ b/src/plugins/vis_types/timeseries/public/application/visualizations/views/_metric.scss @@ -101,7 +101,7 @@ .tvbVisMetric__label--additional { @include euiTextTruncate; font-size: .25em; /* 1 */ - padding: ($euiSizeXS / 2) 0 0; + padding: calc($euiSizeXS / 2) 0 0; text-align: center; color: $tvbValueColor; line-height: 1.2; // Ensure the descenders don't get cut off diff --git a/src/plugins/vis_types/vislib/public/vislib/lib/layout/_layout.scss b/src/plugins/vis_types/vislib/public/vislib/lib/layout/_layout.scss index 4612602d93f1cc..8b92af5a4fdcf9 100644 --- a/src/plugins/vis_types/vislib/public/vislib/lib/layout/_layout.scss +++ b/src/plugins/vis_types/vislib/public/vislib/lib/layout/_layout.scss @@ -203,7 +203,7 @@ } .slice { - stroke-width: $euiSizeXS / 2; + stroke-width: calc($euiSizeXS / 2); stroke: $euiColorEmptyShade; &:hover { diff --git a/x-pack/plugins/canvas/shareable_runtime/webpack.config.js b/x-pack/plugins/canvas/shareable_runtime/webpack.config.js index c60230c6bd6848..ccc04a846236eb 100644 --- a/x-pack/plugins/canvas/shareable_runtime/webpack.config.js +++ b/x-pack/plugins/canvas/shareable_runtime/webpack.config.js @@ -110,7 +110,7 @@ module.exports = { { loader: 'sass-loader', options: { - implementation: require('node-sass'), + implementation: require('sass-embedded'), sourceMap: !isProd, }, }, @@ -147,7 +147,7 @@ module.exports = { path.resolve(KIBANA_ROOT, 'src/core/public/styles/core_app/_globals_v8light.scss') )};\n${content}`; }, - implementation: require('node-sass'), + implementation: require('sass-embedded'), webpackImporter: false, sassOptions: { outputStyle: 'nested', diff --git a/x-pack/plugins/canvas/storybook/canvas_webpack.ts b/x-pack/plugins/canvas/storybook/canvas_webpack.ts index 946b6c5b78ceca..c6ae4a9dbaa950 100644 --- a/x-pack/plugins/canvas/storybook/canvas_webpack.ts +++ b/x-pack/plugins/canvas/storybook/canvas_webpack.ts @@ -38,7 +38,7 @@ export const canvasWebpack = { { loader: 'sass-loader', options: { - implementation: require('node-sass'), + implementation: require('sass-embedded'), }, }, ], diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_row/column_chart.scss b/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_row/column_chart.scss index 8a0b9cc992c3ec..a98eb200f022e7 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_row/column_chart.scss +++ b/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_row/column_chart.scss @@ -16,7 +16,7 @@ font-weight: normal; text-align: left; line-height: 1.1; - font-size: #{$euiFontSizeL / 2}; // 10px + font-size: #{calc($euiFontSizeL / 2)}; // 10px } .dataGridChart__legend--numeric { diff --git a/x-pack/plugins/graph/public/components/guidance_panel/_guidance_panel.scss b/x-pack/plugins/graph/public/components/guidance_panel/_guidance_panel.scss index add1d0bdf8aa33..28e05afe0c7816 100644 --- a/x-pack/plugins/graph/public/components/guidance_panel/_guidance_panel.scss +++ b/x-pack/plugins/graph/public/components/guidance_panel/_guidance_panel.scss @@ -28,7 +28,7 @@ .gphGuidancePanel__itemIcon { position: absolute; left: 0; - top: -($euiSizeXS / 2); + top: -(calc($euiSizeXS / 2)); width: $euiSizeL; height: $euiSizeL; padding: $euiSizeXS; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.scss index cd2ee706c1e18e..35606c67382d58 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.scss +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.scss @@ -25,8 +25,8 @@ flex: 0 0 auto; height: $lnsSuggestionHeight; margin-right: $euiSizeS; - margin-left: $euiSizeXS / 2; - margin-bottom: $euiSizeXS / 2; + margin-left: calc($euiSizeXS / 2); + margin-bottom: calc($euiSizeXS / 2); padding: 0 $euiSizeS; box-shadow: none !important; // sass-lint:disable-line no-important diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss index c88f343f7dbfa1..7f1c61801a4f3c 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss @@ -128,7 +128,7 @@ background-color: $euiColorEmptyShade; border: $euiBorderThin; color: $euiTextColor; - border-radius: $euiBorderRadius / 2; + border-radius: calc($euiBorderRadius / 2); height: $euiSize; width: $euiSizeXL; line-height: $euiSize; diff --git a/x-pack/plugins/ml/public/application/components/influencers_list/_influencers_list.scss b/x-pack/plugins/ml/public/application/components/influencers_list/_influencers_list.scss index e33811aa9a8ccc..1b091e4046c502 100644 --- a/x-pack/plugins/ml/public/application/components/influencers_list/_influencers_list.scss +++ b/x-pack/plugins/ml/public/application/components/influencers_list/_influencers_list.scss @@ -28,7 +28,7 @@ } .progress-bar { - height: $euiSizeXS / 2; + height: calc($euiSizeXS / 2); margin-top: $euiSizeM; text-align: right; line-height: 18px; // SASSTODO: Calc proper value @@ -96,7 +96,7 @@ font-size: 11px; line-height: 14px; border-radius: $euiBorderRadius; - padding: $euiSizeXS / 2; + padding: calc($euiSizeXS / 2); margin-top: $euiSizeXS; display: inline-block; border: $euiBorderThin; diff --git a/x-pack/plugins/ml/public/application/components/rule_editor/_rule_editor.scss b/x-pack/plugins/ml/public/application/components/rule_editor/_rule_editor.scss index 03eca2842c3002..09605c4016565d 100644 --- a/x-pack/plugins/ml/public/application/components/rule_editor/_rule_editor.scss +++ b/x-pack/plugins/ml/public/application/components/rule_editor/_rule_editor.scss @@ -41,7 +41,7 @@ // SASSTODO: Dangerous EUI overwrite .scope-field-checkbox { - margin-right: $euiSizeXS / 2; + margin-right: calc($euiSizeXS / 2); .euiCheckbox { margin-top: $euiSizeXS; diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/_explorer_chart.scss b/x-pack/plugins/ml/public/application/explorer/explorer_charts/_explorer_chart.scss index 55ebfe8ab3edb9..29967e8db9b3f0 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/_explorer_chart.scss +++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/_explorer_chart.scss @@ -15,7 +15,7 @@ rect.selected-interval { fill: rgba(200, 200, 200, .1); stroke: $euiColorDarkShade; - stroke-width: $euiSizeXS / 2; + stroke-width: calc($euiSizeXS / 2); stroke-opacity: .8; } diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/_timeseriesexplorer_annotations.scss b/x-pack/plugins/ml/public/application/timeseriesexplorer/_timeseriesexplorer_annotations.scss index a7186597b41356..656f38590d3a5e 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/_timeseriesexplorer_annotations.scss +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/_timeseriesexplorer_annotations.scss @@ -40,10 +40,10 @@ $mlAnnotationRectDefaultFillOpacity: .05; } .mlAnnotationRect-isBlur { - stroke-opacity: $mlAnnotationRectDefaultStrokeOpacity / 2; + stroke-opacity: calc($mlAnnotationRectDefaultStrokeOpacity / 2); transition: stroke-opacity $euiAnimSpeedFast; - fill-opacity: $mlAnnotationRectDefaultFillOpacity / 2; + fill-opacity: calc($mlAnnotationRectDefaultFillOpacity / 2); transition: fill-opacity $euiAnimSpeedFast; } @@ -95,9 +95,9 @@ $mlAnnotationRectDefaultFillOpacity: .05; } .mlContextAnnotationRect-isBlur { - stroke-opacity: $mlAnnotationRectDefaultStrokeOpacity / 2; + stroke-opacity: calc($mlAnnotationRectDefaultStrokeOpacity / 2); transition: stroke-opacity $euiAnimSpeedFast; - fill-opacity: $mlAnnotationRectDefaultFillOpacity / 2; + fill-opacity: calc($mlAnnotationRectDefaultFillOpacity / 2); transition: fill-opacity $euiAnimSpeedFast; } diff --git a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/shard_allocation.scss b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/shard_allocation.scss index c46d7a048b93ba..961e0350ccc85f 100644 --- a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/shard_allocation.scss +++ b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/shard_allocation.scss @@ -22,7 +22,7 @@ margin: $euiSizeS; border: 1px solid $euiColorMediumShade; border-radius: $euiSizeXS; - padding: $euiSizeXS / 2 0; + padding: calc($euiSizeXS / 2) 0; &.monChild--index { border-left: $euiSizeXS solid $euiColorSuccess; diff --git a/x-pack/plugins/monitoring/public/components/status_icon/_status_icon.scss b/x-pack/plugins/monitoring/public/components/status_icon/_status_icon.scss index 2d36e7fc90f225..50c705f80650ef 100644 --- a/x-pack/plugins/monitoring/public/components/status_icon/_status_icon.scss +++ b/x-pack/plugins/monitoring/public/components/status_icon/_status_icon.scss @@ -1,7 +1,7 @@ .monStatusIcon { display: inline-block; margin-left: $euiSizeXS; - padding: ($euiSizeXS / 2) $euiSizeS; + padding: calc($euiSizeXS / 2) $euiSizeS; border-radius: $euiBorderRadius; color: $euiColorGhost; min-width: 1.9em; diff --git a/x-pack/plugins/snapshot_restore/public/application/components/policy_form/_policy_form.scss b/x-pack/plugins/snapshot_restore/public/application/components/policy_form/_policy_form.scss index 0a5187908f8542..389e925f392c27 100644 --- a/x-pack/plugins/snapshot_restore/public/application/components/policy_form/_policy_form.scss +++ b/x-pack/plugins/snapshot_restore/public/application/components/policy_form/_policy_form.scss @@ -4,7 +4,7 @@ .snapshotRestore__policyForm__stepSettings { .euiFormRow--hasEmptyLabelSpace { min-height: auto; - margin-top: $euiFontSizeXS + $euiSizeS + ($euiSizeXXL / 4); + margin-top: $euiFontSizeXS + $euiSizeS + calc($euiSizeXXL / 4); } } @@ -13,4 +13,4 @@ */ .snapshotRestore__policyForm__stepSettings__indicesFieldWrapper .euiFormLabel { width: 100%; -} \ No newline at end of file +} diff --git a/x-pack/plugins/snapshot_restore/public/application/components/restore_snapshot_form/_restore_snapshot_form.scss b/x-pack/plugins/snapshot_restore/public/application/components/restore_snapshot_form/_restore_snapshot_form.scss index 6a8f0b951c99fe..ec680472edf465 100644 --- a/x-pack/plugins/snapshot_restore/public/application/components/restore_snapshot_form/_restore_snapshot_form.scss +++ b/x-pack/plugins/snapshot_restore/public/application/components/restore_snapshot_form/_restore_snapshot_form.scss @@ -5,7 +5,7 @@ .snapshotRestore__restoreForm__stepSettings { .euiFormRow--hasEmptyLabelSpace { min-height: auto; - margin-top: $euiFontSizeXS + $euiSizeS + ($euiSizeXXL / 4); + margin-top: $euiFontSizeXS + $euiSizeS + calc($euiSizeXXL / 4); } } @@ -14,4 +14,4 @@ */ .snapshotRestore__restoreForm__stepLogistics__indicesFieldWrapper .euiFormLabel { width: 100%; -} \ No newline at end of file +} diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecation_logs/fix_deprecation_logs/deprecation_logging_toggle/_deprecation_logging_toggle.scss b/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecation_logs/fix_deprecation_logs/deprecation_logging_toggle/_deprecation_logging_toggle.scss index e8b6ec06ed7c99..abcc87b75cd081 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecation_logs/fix_deprecation_logs/deprecation_logging_toggle/_deprecation_logging_toggle.scss +++ b/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecation_logs/fix_deprecation_logs/deprecation_logging_toggle/_deprecation_logging_toggle.scss @@ -3,5 +3,5 @@ // them. With this selector we offset the difference so that the content // of the page doesnt jump when toggling between states. .upgToggleLoading > .upgLoadingItem { - margin: $euiSizeM / 2; + margin: calc($euiSizeM / 2); } diff --git a/yarn.lock b/yarn.lock index 7b2754c8719c8f..e7bf86c9eb972c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1321,6 +1321,11 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@bufbuild/protobuf@^1.0.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@bufbuild/protobuf/-/protobuf-1.2.1.tgz#f8b1fbbe79726a4eafa9772ddde147b57f85d177" + integrity sha512-cwwGvLGqvoaOZmoP5+i4v/rbW+rHkguvTehuZyM2p/xpmaNSdT2h3B7kHw33aiffv35t1XrYHIkdJSEkSEMJuA== + "@cbor-extract/cbor-extract-darwin-arm64@2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.0.0.tgz#cf0667e4c22111c9d45e16c29964892b12460a76" @@ -2243,7 +2248,7 @@ pngjs "7.0.0" sharp "0.32.1" -"@gar/promisify@^1.0.1", "@gar/promisify@^1.1.3": +"@gar/promisify@^1.0.1": version "1.1.3" resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== @@ -6786,14 +6791,6 @@ "@gar/promisify" "^1.0.1" semver "^7.3.5" -"@npmcli/fs@^2.1.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-2.1.2.tgz#a9e2541a4a2fec2e69c29b35e6060973da79b865" - integrity sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ== - dependencies: - "@gar/promisify" "^1.1.3" - semver "^7.3.5" - "@npmcli/fs@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e" @@ -6808,14 +6805,6 @@ dependencies: mkdirp "^1.0.4" -"@npmcli/move-file@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-2.0.1.tgz#26f6bdc379d87f75e55739bab89db525b06100e4" - integrity sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ== - dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" - "@octokit/auth-token@^2.4.0": version "2.4.4" resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.4.4.tgz#ee31c69b01d0378c12fd3ffe406030f3d94d3b56" @@ -8553,11 +8542,6 @@ dependencies: "@babel/runtime" "^7.12.5" -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" @@ -10889,7 +10873,7 @@ after-all-results@^2.0.0: resolved "https://registry.yarnpkg.com/after-all-results/-/after-all-results-2.0.0.tgz#6ac2fc202b500f88da8f4f5530cfa100f4c6a2d0" integrity sha1-asL8ICtQD4jaj09VMM+hAPTGotA= -agent-base@6, agent-base@^6.0.2: +agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== @@ -11250,14 +11234,6 @@ are-we-there-yet@^2.0.0: delegates "^1.0.0" readable-stream "^3.6.0" -are-we-there-yet@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz#ba20bd6b553e31d62fc8c31bd23d22b95734390d" - integrity sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - arg@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" @@ -11559,11 +11535,6 @@ async-cache@^1.1.0: dependencies: lru-cache "^4.0.0" -async-foreach@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" - integrity sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI= - async-value-promise@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/async-value-promise/-/async-value-promise-1.1.1.tgz#68957819e3eace804f3b4b69477e2bd276c15378" @@ -12403,6 +12374,11 @@ btoa-lite@^1.0.0: resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" integrity sha1-M3dm2hWAEhD92VbCLpxokaudAzc= +buffer-builder@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/buffer-builder/-/buffer-builder-0.2.0.tgz#3322cd307d8296dab1f604618593b261a3fade8f" + integrity sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg== + buffer-crc32@^0.2.1, buffer-crc32@^0.2.13, buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" @@ -12529,7 +12505,7 @@ cacache@^12.0.2: unique-filename "^1.1.1" y18n "^4.0.0" -cacache@^15.0.4, cacache@^15.0.5, cacache@^15.2.0: +cacache@^15.0.4, cacache@^15.0.5: version "15.3.0" resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== @@ -12553,30 +12529,6 @@ cacache@^15.0.4, cacache@^15.0.5, cacache@^15.2.0: tar "^6.0.2" unique-filename "^1.1.1" -cacache@^16.1.0: - version "16.1.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.3.tgz#a02b9f34ecfaf9a78c9f4bc16fceb94d5d67a38e" - integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ== - dependencies: - "@npmcli/fs" "^2.1.0" - "@npmcli/move-file" "^2.0.0" - chownr "^2.0.0" - fs-minipass "^2.1.0" - glob "^8.0.1" - infer-owner "^1.0.4" - lru-cache "^7.7.1" - minipass "^3.1.6" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - mkdirp "^1.0.4" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^9.0.0" - tar "^6.1.11" - unique-filename "^2.0.0" - cacache@^18.0.0: version "18.0.0" resolved "https://registry.yarnpkg.com/cacache/-/cacache-18.0.0.tgz#17a9ecd6e1be2564ebe6cdca5f7cfed2bfeb6ddc" @@ -12996,9 +12948,9 @@ ci-info@^2.0.0: integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== ci-info@^3.2.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.1.tgz#58331f6f472a25fe3a50a351ae3052936c2c7f32" - integrity sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg== + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" @@ -14509,7 +14461,7 @@ debug@3.X, debug@^3.0.0, debug@^3.1.0, debug@^3.2.7: dependencies: ms "^2.1.1" -debug@4, debug@4.3.4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: +debug@4, debug@4.3.4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -15533,7 +15485,7 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.12, encoding@^0.1.13: +encoding@^0.1.13: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== @@ -17311,7 +17263,7 @@ fs-extra@^9.0.0, fs-extra@^9.0.1, fs-extra@^9.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-minipass@^2.0.0, fs-minipass@^2.1.0: +fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== @@ -17413,28 +17365,6 @@ gauge@^3.0.0: strip-ansi "^6.0.1" wide-align "^1.1.2" -gauge@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.2.tgz#c3777652f542b6ef62797246e8c7caddecb32cc7" - integrity sha512-aSPRm2CvA9R8QyU5eXMFPd+cYkyxLsXHd2l5/FOH2V/eml//M04G6KZOmTap07O1PvEwNcl2NndyLfK8g3QrKA== - dependencies: - ansi-regex "^5.0.1" - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.3" - console-control-strings "^1.1.0" - has-unicode "^2.0.1" - signal-exit "^3.0.7" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.5" - -gaze@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" - integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== - dependencies: - globule "^1.0.0" - geckodriver@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/geckodriver/-/geckodriver-4.3.0.tgz#8586e80ddd23e5d5cd47382d9f6897051ca12ea3" @@ -17688,7 +17618,7 @@ glob@7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@8.1.0, glob@^8.0.1, glob@^8.0.3: +glob@8.1.0, glob@^8.0.3: version "8.1.0" resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== @@ -17722,18 +17652,6 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, gl once "^1.3.0" path-is-absolute "^1.0.0" -glob@~7.1.1: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - global-dirs@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" @@ -17866,15 +17784,6 @@ globjoin@^0.1.4: resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43" integrity sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM= -globule@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d" - integrity sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ== - dependencies: - glob "~7.1.1" - lodash "~4.17.10" - minimatch "~3.0.2" - gonzales-pe@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.3.0.tgz#fe9dec5f3c557eead09ff868c65826be54d067b3" @@ -18532,7 +18441,7 @@ htmlparser2@^8.0.1: domutils "^3.0.1" entities "^4.4.0" -http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0, http-cache-semantics@^4.1.1: +http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== @@ -18580,15 +18489,6 @@ http-parser-js@>=0.5.1: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg== -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -18648,7 +18548,7 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1: +https-proxy-agent@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== @@ -18759,6 +18659,11 @@ immer@^9.0.15, immer@^9.0.7: resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.15.tgz#0b9169e5b1d22137aba7d43f8a81a495dd1b62dc" integrity sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ== +immutable@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.1.0.tgz#f795787f0db780183307b9eb2091fcac1f6fafef" + integrity sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ== + import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -20414,11 +20319,6 @@ jquery@^3.5.0: resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw== -js-base64@^2.4.9: - version "2.5.2" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.2.tgz#313b6274dda718f714d00b3330bbae6e38e90209" - integrity sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ== - js-beautify@1.10.3: version "1.10.3" resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.10.3.tgz#c73fa10cf69d3dfa52d8ed624f23c64c0a6a94c1" @@ -21353,7 +21253,7 @@ lodash.uniq@4.5.0, lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@>4.17.4, lodash@^4.0.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@~4.17.10: +lodash@>4.17.4, lodash@^4.0.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -21522,7 +21422,7 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^7.14.1, lru-cache@^7.7.1: +lru-cache@^7.14.1: version "7.18.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== @@ -21581,28 +21481,6 @@ make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -make-fetch-happen@^10.0.4: - version "10.2.1" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" - integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== - dependencies: - agentkeepalive "^4.2.1" - cacache "^16.1.0" - http-cache-semantics "^4.1.0" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^7.7.1" - minipass "^3.1.6" - minipass-collect "^1.0.2" - minipass-fetch "^2.0.3" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.3" - promise-retry "^2.0.1" - socks-proxy-agent "^7.0.0" - ssri "^9.0.0" - make-fetch-happen@^13.0.0: version "13.0.0" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-13.0.0.tgz#705d6f6cbd7faecb8eac2432f551e49475bfedf0" @@ -21620,28 +21498,6 @@ make-fetch-happen@^13.0.0: promise-retry "^2.0.1" ssri "^10.0.0" -make-fetch-happen@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" - integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== - dependencies: - agentkeepalive "^4.1.3" - cacache "^15.2.0" - http-cache-semantics "^4.1.0" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^6.0.0" - minipass "^3.1.3" - minipass-collect "^1.0.2" - minipass-fetch "^1.3.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.2" - promise-retry "^2.0.1" - socks-proxy-agent "^6.0.0" - ssri "^8.0.0" - makeerror@1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" @@ -22248,7 +22104,7 @@ minimatch@5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2, minimatch@~3.0.2: +minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -22290,28 +22146,6 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" -minipass-fetch@^1.3.2: - version "1.3.4" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.3.4.tgz#63f5af868a38746ca7b33b03393ddf8c291244fe" - integrity sha512-TielGogIzbUEtd1LsjZFs47RWuHHfhl6TiCx1InVxApBAmQ8bL0dL5ilkLGcRvuyW/A9nE+Lvn855Ewz8S0PnQ== - dependencies: - minipass "^3.1.0" - minipass-sized "^1.0.3" - minizlib "^2.0.0" - optionalDependencies: - encoding "^0.1.12" - -minipass-fetch@^2.0.3: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.2.tgz#95560b50c472d81a3bc76f20ede80eaed76d8add" - integrity sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA== - dependencies: - minipass "^3.1.6" - minipass-sized "^1.0.3" - minizlib "^2.1.2" - optionalDependencies: - encoding "^0.1.13" - minipass-fetch@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.3.tgz#d9df70085609864331b533c960fd4ffaa78d15ce" @@ -22344,7 +22178,7 @@ minipass-sized@^1.0.3: dependencies: minipass "^3.0.0" -minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3, minipass@^3.1.6: +minipass@^3.0.0, minipass@^3.1.1: version "3.3.6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== @@ -22368,7 +22202,7 @@ minipass@^5.0.0: resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== -minizlib@^2.0.0, minizlib@^2.1.1, minizlib@^2.1.2: +minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== @@ -22743,7 +22577,7 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nan@^2.17.0, nan@^2.18.0: +nan@^2.18.0: version "2.18.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.18.0.tgz#26a6faae7ffbeb293a39660e88a76b82e30b7554" integrity sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w== @@ -22824,7 +22658,7 @@ nearley@^2.7.10: randexp "0.4.6" semver "^5.4.1" -negotiator@0.6.3, negotiator@^0.6.2, negotiator@^0.6.3: +negotiator@0.6.3, negotiator@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== @@ -22991,22 +22825,6 @@ node-gyp@^10.0.1: tar "^6.1.2" which "^4.0.0" -node-gyp@^8.4.1: - version "8.4.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" - integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.6" - make-fetch-happen "^9.1.0" - nopt "^5.0.0" - npmlog "^6.0.0" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.2" - which "^2.0.2" - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -23068,26 +22886,6 @@ node-releases@^2.0.6: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== -node-sass@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-8.0.0.tgz#c80d52148db0ce88610bcf1e1d112027393c13e1" - integrity sha512-jPzqCF2/e6JXw6r3VxfIqYc8tKQdkj5Z/BDATYyG6FL6b/LuYBNFGFVhus0mthcWifHm/JzBpKAd+3eXsWeK/A== - dependencies: - async-foreach "^0.1.3" - chalk "^4.1.2" - cross-spawn "^7.0.3" - gaze "^1.0.0" - get-stdin "^4.0.1" - glob "^7.0.3" - lodash "^4.17.15" - make-fetch-happen "^10.0.4" - meow "^9.0.0" - nan "^2.17.0" - node-gyp "^8.4.1" - sass-graph "^4.0.1" - stdout-stream "^1.4.0" - "true-case-path" "^2.2.1" - node-source-walk@^6.0.0, node-source-walk@^6.0.1, node-source-walk@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/node-source-walk/-/node-source-walk-6.0.2.tgz#ba81bc4bc0f6f05559b084bea10be84c3f87f211" @@ -23108,13 +22906,6 @@ nopt@^4.0.1, nopt@~4.0.1: abbrev "1" osenv "^0.1.4" -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - nopt@^7.0.0: version "7.2.0" resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.0.tgz#067378c68116f602f552876194fd11f1292503d7" @@ -23205,16 +22996,6 @@ npmlog@^5.0.1: gauge "^3.0.0" set-blocking "^2.0.0" -npmlog@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.1.tgz#06f1344a174c06e8de9c6c70834cfba2964bba17" - integrity sha512-BTHDvY6nrRHuRfyjt1MAufLxYdVXZfd099H4+i1f0lPywNQyI4foeNXJRObB/uy+TYqUW0vAD9gbdSOXPst7Eg== - dependencies: - are-we-there-yet "^3.0.0" - console-control-strings "^1.1.0" - gauge "^4.0.0" - set-blocking "^2.0.0" - nth-check@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" @@ -23494,9 +23275,9 @@ onetime@^5.1.0, onetime@^5.1.2: mimic-fn "^2.1.0" open@^7.0.3: - version "7.1.0" - resolved "https://registry.yarnpkg.com/open/-/open-7.1.0.tgz#68865f7d3cb238520fa1225a63cf28bcf8368a1c" - integrity sha512-lLPI5KgOwEYCDKXf4np7y1PBEkj7HYIyP2DY8mVDRnx0VIIu6bNrRB0R66TuO7Mack6EnTNLm4uvcl1UoklTpA== + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== dependencies: is-docker "^2.0.0" is-wsl "^2.1.1" @@ -26899,10 +26680,10 @@ rxjs@^6.3.3, rxjs@^6.4.0, rxjs@^6.5.1, rxjs@^6.6.0, rxjs@^6.6.7: dependencies: tslib "^1.9.0" -rxjs@^7.0.0, rxjs@^7.5.5: - version "7.5.5" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.5.tgz#2ebad89af0f560f460ad5cc4213219e1f7dd4e9f" - integrity sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw== +rxjs@^7.0.0, rxjs@^7.4.0, rxjs@^7.5.5: + version "7.8.0" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" + integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== dependencies: tslib "^2.1.0" @@ -26984,20 +26765,71 @@ sane@^4.0.3: minimist "^1.1.1" walker "~1.0.5" -sass-graph@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-4.0.1.tgz#2ff8ca477224d694055bf4093f414cf6cfad1d2e" - integrity sha512-5YCfmGBmxoIRYHnKK2AKzrAkCoQ8ozO+iumT8K4tXJXRVCPf+7s1/9KxTSW3Rbvf+7Y7b4FR3mWyLnQr3PHocA== - dependencies: - glob "^7.0.0" - lodash "^4.17.11" - scss-tokenizer "^0.4.3" - yargs "^17.2.1" - -sass-loader@^10.4.1: - version "10.4.1" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.4.1.tgz#bea4e173ddf512c9d7f53e9ec686186146807cbf" - integrity sha512-aX/iJZTTpNUNx/OSYzo2KsjIUQHqvWsAhhUijFjAPdZTEhstjZI9zTNvkTTwsx+uNUJqUwOw5gacxQMx4hJxGQ== +sass-embedded-darwin-arm64@1.69.5: + version "1.69.5" + resolved "https://registry.yarnpkg.com/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.69.5.tgz#69e246d4a6875184a593906dfd7b84a21eb6eeb2" + integrity sha512-zVuXJzgT54t24E4QPP/iteHsw/cawZE8gAXGEm20cP2DKsIQBF7bvSTk0zzY0bS01YFtJviYM13HcGUe4q7/7w== + +sass-embedded-darwin-x64@1.69.5: + version "1.69.5" + resolved "https://registry.yarnpkg.com/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.69.5.tgz#82c2a659dafa93b54d2690f08f7aac9b2447c43f" + integrity sha512-HcA9YER3Ax7lMnHouxnIY462gnst5lNL56QXkZaTQmg9nH7oqR2bMfWbckEQL+mHIXGSM/QfX0aD59VOm5iKZw== + +sass-embedded-linux-arm64@1.69.5: + version "1.69.5" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.69.5.tgz#8585bbcc6996ba04d8aa4216a2bf65de2e6592ea" + integrity sha512-HWCjdFSLGh0dMUNLNh+slc2j9koSZnfTEO9qQR6WEIuC+We6vYKJugGPo1V9pFbBeoW6VAJGYdlqsRPquteCZw== + +sass-embedded-linux-arm@1.69.5: + version "1.69.5" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.69.5.tgz#ded653fe37d6b07d778c5f414cba5f28107dc438" + integrity sha512-m0NxVkrfcS3UsF33q0FgItMWIz/F1FZdfVZpjp+dP6qd0KLeTuoPUCh2GSize0DAU5T0Zj24b2mXeowDKv463g== + +sass-embedded-linux-ia32@1.69.5: + version "1.69.5" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-ia32/-/sass-embedded-linux-ia32-1.69.5.tgz#61ad8b3b43be563f6fcd6ff04d0e121b195ecc2a" + integrity sha512-0taR6AJDb+eLOBTEMc1nfX2fI1hgRF9M+Hmv+wwGrxfBu/MkASk6fmR9B8MDw9hPHIqGVUkTVizjOh50O7nIKg== + +sass-embedded-linux-x64@1.69.5: + version "1.69.5" + resolved "https://registry.yarnpkg.com/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.69.5.tgz#3d490f520200d596b2b6072d6d3f4460b7114241" + integrity sha512-gN9yLTbKC0hUHukx4mdRs4V39WD719PM2GhWQBUA+3Z8qr9ywywi7LiU2atWrKESRF34V+eqF9lYiYVQxtTHZw== + +sass-embedded-win32-ia32@1.69.5: + version "1.69.5" + resolved "https://registry.yarnpkg.com/sass-embedded-win32-ia32/-/sass-embedded-win32-ia32-1.69.5.tgz#e84a053d25aec1176fac485bee65a384f39dfa9e" + integrity sha512-9OgSaufHP53b33gaH1Y5NZ/Im3druCHIQvLUEqJBCFuOzly47g/hZGrO+dBDiWgYGYKbSYI7Z4/PBtQoK5Vkxg== + +sass-embedded-win32-x64@1.69.5: + version "1.69.5" + resolved "https://registry.yarnpkg.com/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.69.5.tgz#8d803e99cccc0e8105dde50e49a2fd7839e360ec" + integrity sha512-p1PsOJnpwXdPfiRbX6QdRa4PnL2QXPpIRy8fkeAZpQFYZ278ZIlwemC2MukKMVLcE3iQ5lBulbC8IYm91rod6Q== + +sass-embedded@^1.69.5: + version "1.69.5" + resolved "https://registry.yarnpkg.com/sass-embedded/-/sass-embedded-1.69.5.tgz#ae217d4b17b0fb07e5ed146917c9c9de0c4383c6" + integrity sha512-0YNcRcbSpgGd4AnE+mm3a3g4S97puFLIZ0cYJgbwdD4iGz/hiOzE+yh72XS+u1LMhE+pQfNeC9MNnRsc8n1yRg== + dependencies: + "@bufbuild/protobuf" "^1.0.0" + buffer-builder "^0.2.0" + immutable "^4.0.0" + rxjs "^7.4.0" + supports-color "^8.1.1" + varint "^6.0.0" + optionalDependencies: + sass-embedded-darwin-arm64 "1.69.5" + sass-embedded-darwin-x64 "1.69.5" + sass-embedded-linux-arm "1.69.5" + sass-embedded-linux-arm64 "1.69.5" + sass-embedded-linux-ia32 "1.69.5" + sass-embedded-linux-x64 "1.69.5" + sass-embedded-win32-ia32 "1.69.5" + sass-embedded-win32-x64 "1.69.5" + +sass-loader@^10.5.0: + version "10.5.0" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.5.0.tgz#011c92ea529029e296aea37508e034b94f7dd2dc" + integrity sha512-VsU71W7VR6SChMJZUqtrfLeMSA8ns7QTHbnA7cfevtjb3c392mX93lr0Dmr4uU1ch5uIbEmfmHjdrDYcXXkQ7w== dependencies: klona "^2.0.4" loader-utils "^2.0.0" @@ -27095,14 +26927,6 @@ screenfull@^5.0.0: resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.0.0.tgz#5c2010c0e84fd4157bf852877698f90b8cbe96f6" integrity sha512-yShzhaIoE9OtOhWVyBBffA6V98CDCoyHTsp8228blmqYy1Z5bddzE/4FPiJKlr8DVR4VBiiUyfPzIQPIYDkeMA== -scss-tokenizer@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.4.3.tgz#1058400ee7d814d71049c29923d2b25e61dc026c" - integrity sha512-raKLgf1LI5QMQnG+RxHz6oK0sL3x3I4FN2UDLqgLOGO8hodECNnNh5BXn7fAyBxrA8zVzdQizQ6XjNJQ+uBwMw== - dependencies: - js-base64 "^2.4.9" - source-map "^0.7.3" - secure-json-parse@^2.4.0: version "2.6.0" resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.6.0.tgz#95d89f84adf32d76ff7800e68a673b129fe918b0" @@ -27603,24 +27427,6 @@ sockjs@^0.3.24: uuid "^8.3.2" websocket-driver "^0.7.4" -socks-proxy-agent@^6.0.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz#e664e8f1aaf4e1fb3df945f09e3d94f911137f87" - integrity sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew== - dependencies: - agent-base "^6.0.2" - debug "^4.3.1" - socks "^2.6.1" - -socks-proxy-agent@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" - integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== - dependencies: - agent-base "^6.0.2" - debug "^4.3.3" - socks "^2.6.2" - socks-proxy-agent@^8.0.1, socks-proxy-agent@^8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz#5acbd7be7baf18c46a3f293a840109a430a640ad" @@ -27630,7 +27436,7 @@ socks-proxy-agent@^8.0.1, socks-proxy-agent@^8.0.2: debug "^4.3.4" socks "^2.7.1" -socks@^2.6.1, socks@^2.6.2, socks@^2.7.1: +socks@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== @@ -27964,20 +27770,13 @@ ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" -ssri@^8.0.0, ssri@^8.0.1: +ssri@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== dependencies: minipass "^3.1.1" -ssri@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" - integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== - dependencies: - minipass "^3.1.1" - stable@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" @@ -28086,13 +27885,6 @@ stats-lite@^2.2.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -stdout-stream@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.0.tgz#a2c7c8587e54d9427ea9edb3ac3f2cd522df378b" - integrity sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s= - dependencies: - readable-stream "^2.0.1" - store2@^2.12.0: version "2.12.0" resolved "https://registry.yarnpkg.com/store2/-/store2-2.12.0.tgz#e1f1b7e1a59b6083b2596a8d067f6ee88fd4d3cf" @@ -29222,11 +29014,6 @@ trough@^1.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.1.tgz#a9fd8b0394b0ae8fff82e0633a0a36ccad5b5f86" integrity sha1-qf2LA5Swro//guBjOgo2zK1bX4Y= -"true-case-path@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-2.2.1.tgz#c5bf04a5bbec3fd118be4084461b3a27c4d796bf" - integrity sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q== - ts-algebra@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/ts-algebra/-/ts-algebra-1.2.0.tgz#f91c481207a770f0d14d055c376cbee040afdfc9" @@ -29671,13 +29458,6 @@ unique-filename@^1.1.1: dependencies: unique-slug "^2.0.0" -unique-filename@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" - integrity sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A== - dependencies: - unique-slug "^3.0.0" - unique-filename@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" @@ -29692,13 +29472,6 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" -unique-slug@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-3.0.0.tgz#6d347cf57c8a7a7a6044aabd0e2d74e4d76dc7c9" - integrity sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w== - dependencies: - imurmurhash "^0.1.4" - unique-slug@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" @@ -30139,6 +29912,11 @@ variable-diff@1.1.0: chalk "^1.1.1" object-assign "^4.0.1" +varint@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0" + integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg== + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -31047,7 +30825,7 @@ which@^1.2.9, which@^1.3.1: dependencies: isexe "^2.0.0" -which@^2.0.1, which@^2.0.2: +which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== @@ -31061,7 +30839,7 @@ which@^4.0.0: dependencies: isexe "^3.1.1" -wide-align@^1.1.2, wide-align@^1.1.5: +wide-align@^1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== From 306debfb43907e0228ab69bc758f1705cfc6d813 Mon Sep 17 00:00:00 2001 From: Pablo Machado <pablo.nevesmachado@elastic.co> Date: Thu, 21 Dec 2023 14:48:54 +0100 Subject: [PATCH 071/116] [Security Solution] Co-locate Frontend Entity Analytics Code (#173499) ## Summary Move all files owned by the Entity Analytics team to `x-pack/plugins/security_solution/public/entity_analytics` Initially, files inside `public/entity_analytics/components` look disorganised because many of them have similar names and do not follow the same conventions. I minimized the PR scope to avoid putting too much of a burden on reviewers. ### Changes * Moves files to the `entity_analytics` folder * Updates imports * Moves the content of some files to a new file inside the `entity_analytics` folder * Inlines copies that were previously inside `translation.ts`. * No changes to the user experience are expected. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .github/CODEOWNERS | 5 --- .../cti_details/threat_summary_view.tsx | 4 +- .../event_details/cti_details/translations.ts | 4 +- .../event_details/event_details.tsx | 2 +- .../ml/anomaly/use_anomalies_search.ts | 2 +- .../visualization_embeddable.test.tsx | 5 +-- .../public/entity_analytics/api/api.ts | 24 +++++++++++ .../api/hooks/use_risk_score.test.tsx} | 22 +++++----- .../api/hooks/use_risk_score.tsx} | 37 ++++++++-------- .../api/hooks}/use_risk_score_data.test.ts | 6 +-- .../api/hooks}/use_risk_score_data.ts | 4 +- .../use_risk_score_feature_status.test.ts} | 18 ++++---- .../hooks/use_risk_score_feature_status.ts} | 11 ++--- .../api/hooks/use_risk_score_kpi.tsx} | 30 +++++++------ .../public/entity_analytics/api/types.ts | 20 +++++++++ .../public/entity_analytics/common/utils.ts | 12 ++++++ .../components}/enable_risk_score/index.tsx | 8 ++-- .../enable_risk_score/translations.ts | 4 +- .../anomalies_count_link.test.tsx | 10 ++--- .../anomalies_count_link.tsx | 16 +++---- .../columns.test.tsx | 4 +- .../entity_analytics_anomalies}/columns.tsx | 6 +-- .../components/anomalies_tab_link.tsx | 14 +++---- .../components/enable_job.test.tsx | 6 +-- .../components/enable_job.tsx | 6 +-- .../components/total_anomalies.test.tsx | 6 +-- .../components/total_anomalies.tsx | 6 +-- .../index.test.tsx | 18 ++++---- .../entity_analytics_anomalies}/index.tsx | 28 ++++++------- .../query/index.ts | 0 .../translations.ts | 0 .../entity_analytics_header}/index.test.tsx | 19 +++++---- .../entity_analytics_header}/index.tsx | 40 +++++++++--------- .../entity_analytics_header}/translations.ts | 0 .../__mocks__/index.ts | 2 +- .../chart_content.test.tsx | 18 ++++---- .../chart_content.tsx | 27 +++++++----- .../entity_analytics_risk_score}/columns.tsx | 22 +++++----- .../header_content.test.tsx | 10 ++--- .../header_content.tsx | 14 +++---- .../index.test.tsx | 26 ++++++------ .../entity_analytics_risk_score}/index.tsx | 42 +++++++++---------- .../translations.ts | 6 +-- .../use_entity.test.ts | 2 +- .../use_entity.ts | 16 +++---- .../components/action_column.test.tsx | 2 +- .../components/action_column.tsx | 0 .../components/utility_bar.test.tsx | 0 .../components/utility_bar.tsx | 0 .../hooks/use_risk_input_actions.ts | 0 .../use_risk_input_actions_panels.test.tsx | 0 .../hooks/use_risk_input_actions_panels.tsx | 0 .../entity_details_flyout/index.tsx | 26 ++++++++++++ .../entity_details_flyout}/mocks/index.ts | 0 .../tabs/risk_inputs.test.tsx | 2 +- .../tabs/risk_inputs.tsx | 0 .../host_risk_score_table/columns.test.tsx | 2 +- .../host_risk_score_table/columns.tsx | 20 ++++----- .../host_risk_score_table/index.tsx | 26 ++++++------ .../host_risk_score_table/translations.ts | 0 .../risk_details_tab_body/index.test.tsx | 19 ++++----- .../risk_details_tab_body/index.tsx | 35 +++++++--------- .../risk_details_tab_body/translations.ts | 4 +- .../risk_information/index.test.tsx | 4 +- .../components}/risk_information/index.tsx | 4 +- .../risk_information/translations.ts | 4 +- .../components/risk_score/constants.ts | 0 .../components/risk_score/translations.ts | 0 .../risk_score_donut_chart/index.test.tsx} | 8 ++-- .../risk_score_donut_chart/index.tsx} | 23 +++++----- .../use_risk_donut_chart_data.test.ts | 4 +- .../use_risk_donut_chart_data.ts | 10 ++--- .../components/risk_score_enable_section.tsx | 2 +- .../risk_score_doc_link.tsx | 6 +-- .../risk_score_enable_button.test.tsx | 4 +- .../risk_score_enable_button.tsx | 16 +++---- .../risk_score_header_title.tsx | 17 ++++++-- .../risk_score_no_data_detected.tsx | 8 ++-- .../risk_score_restart_button.test.tsx | 4 +- .../risk_score_restart_button.tsx | 10 ++--- .../risk_score_onboarding/translations.ts | 4 +- .../use_risk_score_toast_content.tsx | 2 +- .../risk_score_onboarding/utils.test.ts | 10 ++--- .../risk_score_onboarding/utils.ts | 10 ++--- .../risk_score_over_time/index.test.tsx | 12 +++--- .../risk_score_over_time/index.tsx | 24 +++++------ .../risk_score_over_time/translations.ts | 0 .../components/risk_score_preview_table.tsx | 2 +- .../components}/risk_summary.test.tsx | 8 ++-- .../components}/risk_summary.tsx | 21 ++++++---- .../risk_summary.stories.tsx | 4 +- .../risk_summary.test.tsx | 6 +-- .../risk_summary_flyout}/risk_summary.tsx | 18 ++++---- .../severity/common/index.test.tsx | 6 +-- .../components}/severity/common/index.tsx | 6 +-- .../components}/severity/severity_badges.tsx | 4 +- .../components}/severity/severity_bar.tsx | 4 +- .../severity/severity_filter_group.test.tsx | 8 ++-- .../severity/severity_filter_group.tsx | 8 ++-- .../components}/severity/types.ts | 2 +- .../components}/styled_basic_table.tsx | 0 .../index.test.tsx | 7 ++-- .../top_risk_score_contributors/index.tsx | 8 ++-- .../translations.ts | 0 .../index.tsx | 26 ++++++------ .../translations.ts | 0 .../user_risk_score_tab_body.test.tsx | 16 +++---- .../components}/user_risk_score_tab_body.tsx | 33 +++++++-------- .../user_risk_score_table/columns.test.tsx | 4 +- .../user_risk_score_table/columns.tsx | 22 +++++----- .../user_risk_score_table/index.test.tsx | 8 ++-- .../user_risk_score_table/index.tsx | 28 ++++++------- .../user_risk_score_table/translations.ts | 0 .../deprecated_risk_engine}/api/index.ts | 0 .../api/ingest_pipelines.test.ts | 0 .../api/ingest_pipelines.ts | 0 .../deprecated_risk_engine}/api/onboarding.ts | 4 +- .../api/saved_objects.ts | 6 +-- .../api/stored_scripts.test.ts | 0 .../api/stored_scripts.ts | 2 +- .../api/transforms.test.ts | 0 .../deprecated_risk_engine}/api/transforms.ts | 0 .../api/translations.ts | 0 .../deprecated_risk_engine}/api/types.ts | 0 .../risk_score_donut.test.ts.snap | 0 .../risk_score_over_time_area.test.ts.snap | 0 .../risk_score_summary.test.ts.snap | 0 .../lens_attributes}/risk_score_donut.test.ts | 9 ++-- .../lens_attributes}/risk_score_donut.ts | 2 +- .../risk_score_over_time_area.test.ts | 9 ++-- .../risk_score_over_time_area.ts | 2 +- .../risk_score_summary.test.ts | 10 ++--- .../lens_attributes}/risk_score_summary.ts | 12 ++---- .../pages/entity_analytics_dashboard.tsx} | 11 +++-- .../components/paginated_table/index.tsx | 2 +- .../containers/risk_score/all/translations.ts | 22 ---------- .../risk_score/feature_status/api.ts | 33 --------------- .../explore/containers/risk_score/index.ts | 38 ----------------- .../containers/risk_score/kpi/translations.ts | 15 ------- .../hosts/components/hosts_table/columns.tsx | 6 +-- .../hosts/pages/details/details_tabs.tsx | 2 +- .../host_risk_score_tab_body.test.tsx | 6 ++- .../navigation/host_risk_score_tab_body.tsx | 14 +++---- .../users/components/all_users/index.tsx | 4 +- .../users/pages/details/details_tabs.tsx | 2 +- .../public/explore/users/pages/users_tabs.tsx | 2 +- .../left/components/entities_details.test.tsx | 4 +- .../left/components/host_details.test.tsx | 4 +- .../left/components/host_details.tsx | 4 +- .../left/components/user_details.test.tsx | 4 +- .../left/components/user_details.tsx | 4 +- .../components/entities_overview.test.tsx | 4 +- .../components/host_entity_overview.test.tsx | 4 +- .../right/components/host_entity_overview.tsx | 4 +- .../components/insights_section.test.tsx | 4 +- .../components/user_entity_overview.test.tsx | 4 +- .../right/components/user_entity_overview.tsx | 5 ++- .../content.tsx | 0 .../header.tsx | 0 .../index.tsx | 0 .../tabs.tsx | 16 +------ .../tabs/asset_document.test.tsx | 0 .../tabs/asset_document.tsx | 0 .../tabs/test_ids.ts | 0 .../test_ids.ts | 1 - .../entity_details/user_right/content.tsx | 6 +-- .../entity_details/user_right/index.test.tsx | 2 +- .../entity_details/user_right/index.tsx | 6 +-- .../entity_details/user_right/mocks/index.ts | 2 +- .../security_solution/public/flyout/index.tsx | 4 +- .../public/overview/components/common.tsx | 2 +- .../entity_analytics/common/translations.ts | 26 ------------ .../components/host_overview/index.test.tsx | 4 +- .../components/host_overview/index.tsx | 6 +-- .../components/user_overview/index.test.tsx | 4 +- .../components/user_overview/index.tsx | 6 +-- .../public/overview/pages/overview.test.tsx | 4 +- .../public/overview/routes.tsx | 2 +- .../side_panel/event_details/index.test.tsx | 2 +- .../new_user_detail/managed_user.tsx | 2 +- .../managed_user_accordion.tsx | 2 +- .../new_user_detail/risk_score_field.tsx | 4 +- .../plugins/security_solution/tsconfig.json | 3 +- .../translations/translations/fr-FR.json | 2 - .../translations/translations/ja-JP.json | 2 - .../translations/translations/zh-CN.json | 2 - 186 files changed, 731 insertions(+), 790 deletions(-) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/all/index.test.tsx => entity_analytics/api/hooks/use_risk_score.test.tsx} (88%) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/all/index.tsx => entity_analytics/api/hooks/use_risk_score.tsx} (81%) rename x-pack/plugins/security_solution/public/{common/components/event_details => entity_analytics/api/hooks}/use_risk_score_data.test.ts (94%) rename x-pack/plugins/security_solution/public/{common/components/event_details => entity_analytics/api/hooks}/use_risk_score_data.ts (93%) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/feature_status/index.test.ts => entity_analytics/api/hooks/use_risk_score_feature_status.test.ts} (85%) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/feature_status/index.ts => entity_analytics/api/hooks/use_risk_score_feature_status.ts} (83%) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/kpi/index.tsx => entity_analytics/api/hooks/use_risk_score_kpi.tsx} (78%) create mode 100644 x-pack/plugins/security_solution/public/entity_analytics/api/types.ts rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/enable_risk_score/index.tsx (86%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/enable_risk_score/translations.ts (92%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/anomalies => entity_analytics/components/entity_analytics_anomalies}/anomalies_count_link.test.tsx (73%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/anomalies => entity_analytics/components/entity_analytics_anomalies}/anomalies_count_link.tsx (75%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/anomalies => entity_analytics/components/entity_analytics_anomalies}/columns.test.tsx (90%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/anomalies => entity_analytics/components/entity_analytics_anomalies}/columns.tsx (90%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/anomalies => entity_analytics/components/entity_analytics_anomalies}/components/anomalies_tab_link.tsx (75%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/anomalies => entity_analytics/components/entity_analytics_anomalies}/components/enable_job.test.tsx (88%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/anomalies => entity_analytics/components/entity_analytics_anomalies}/components/enable_job.tsx (80%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/anomalies => entity_analytics/components/entity_analytics_anomalies}/components/total_anomalies.test.tsx (81%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/anomalies => entity_analytics/components/entity_analytics_anomalies}/components/total_anomalies.tsx (85%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/anomalies => entity_analytics/components/entity_analytics_anomalies}/index.test.tsx (92%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/anomalies => entity_analytics/components/entity_analytics_anomalies}/index.tsx (85%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/anomalies => entity_analytics/components/entity_analytics_anomalies}/query/index.ts (100%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/anomalies => entity_analytics/components/entity_analytics_anomalies}/translations.ts (100%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/header => entity_analytics/components/entity_analytics_header}/index.test.tsx (84%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/header => entity_analytics/components/entity_analytics_header}/index.tsx (82%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/header => entity_analytics/components/entity_analytics_header}/translations.ts (100%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/risk_score => entity_analytics/components/entity_analytics_risk_score}/__mocks__/index.ts (82%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/risk_score => entity_analytics/components/entity_analytics_risk_score}/chart_content.test.tsx (79%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/risk_score => entity_analytics/components/entity_analytics_risk_score}/chart_content.tsx (66%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/risk_score => entity_analytics/components/entity_analytics_risk_score}/columns.tsx (85%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/risk_score => entity_analytics/components/entity_analytics_risk_score}/header_content.test.tsx (86%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/risk_score => entity_analytics/components/entity_analytics_risk_score}/header_content.tsx (80%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/risk_score => entity_analytics/components/entity_analytics_risk_score}/index.test.tsx (87%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/risk_score => entity_analytics/components/entity_analytics_risk_score}/index.tsx (77%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/risk_score => entity_analytics/components/entity_analytics_risk_score}/translations.ts (82%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/risk_score => entity_analytics/components/entity_analytics_risk_score}/use_entity.test.ts (93%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/risk_score => entity_analytics/components/entity_analytics_risk_score}/use_entity.ts (71%) rename x-pack/plugins/security_solution/public/{flyout/entity_details/user_detais_left => entity_analytics/components/entity_details_flyout}/components/action_column.test.tsx (100%) rename x-pack/plugins/security_solution/public/{flyout/entity_details/user_detais_left => entity_analytics/components/entity_details_flyout}/components/action_column.tsx (100%) rename x-pack/plugins/security_solution/public/{flyout/entity_details/user_detais_left => entity_analytics/components/entity_details_flyout}/components/utility_bar.test.tsx (100%) rename x-pack/plugins/security_solution/public/{flyout/entity_details/user_detais_left => entity_analytics/components/entity_details_flyout}/components/utility_bar.tsx (100%) rename x-pack/plugins/security_solution/public/{flyout/entity_details/user_detais_left => entity_analytics/components/entity_details_flyout}/hooks/use_risk_input_actions.ts (100%) rename x-pack/plugins/security_solution/public/{flyout/entity_details/user_detais_left => entity_analytics/components/entity_details_flyout}/hooks/use_risk_input_actions_panels.test.tsx (100%) rename x-pack/plugins/security_solution/public/{flyout/entity_details/user_detais_left => entity_analytics/components/entity_details_flyout}/hooks/use_risk_input_actions_panels.tsx (100%) create mode 100644 x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/index.tsx rename x-pack/plugins/security_solution/public/{flyout/entity_details/user_detais_left => entity_analytics/components/entity_details_flyout}/mocks/index.ts (100%) rename x-pack/plugins/security_solution/public/{flyout/entity_details/user_detais_left => entity_analytics/components/entity_details_flyout}/tabs/risk_inputs.test.tsx (100%) rename x-pack/plugins/security_solution/public/{flyout/entity_details/user_detais_left => entity_analytics/components/entity_details_flyout}/tabs/risk_inputs.tsx (100%) rename x-pack/plugins/security_solution/public/{explore/hosts => entity_analytics}/components/host_risk_score_table/columns.test.tsx (94%) rename x-pack/plugins/security_solution/public/{explore/hosts => entity_analytics}/components/host_risk_score_table/columns.tsx (78%) rename x-pack/plugins/security_solution/public/{explore/hosts => entity_analytics}/components/host_risk_score_table/index.tsx (85%) rename x-pack/plugins/security_solution/public/{explore/hosts => entity_analytics}/components/host_risk_score_table/translations.ts (100%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_details_tab_body/index.test.tsx (84%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_details_tab_body/index.tsx (85%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_details_tab_body/translations.ts (83%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_information/index.test.tsx (92%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_information/index.tsx (98%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_information/translations.ts (91%) rename x-pack/plugins/security_solution/public/{explore => entity_analytics}/components/risk_score/constants.ts (100%) rename x-pack/plugins/security_solution/public/{explore => entity_analytics}/components/risk_score/translations.ts (100%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/common/risk_score_donut_chart.test.tsx => entity_analytics/components/risk_score_donut_chart/index.test.tsx} (78%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/common/risk_score_donut_chart.tsx => entity_analytics/components/risk_score_donut_chart/index.tsx} (67%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/common => entity_analytics/components/risk_score_donut_chart}/use_risk_donut_chart_data.test.ts (88%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/common => entity_analytics/components/risk_score_donut_chart}/use_risk_donut_chart_data.ts (70%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_score_onboarding/risk_score_doc_link.tsx (85%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_score_onboarding/risk_score_enable_button.test.tsx (89%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_score_onboarding/risk_score_enable_button.tsx (81%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_score_onboarding/risk_score_header_title.tsx (53%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_score_onboarding/risk_score_no_data_detected.tsx (84%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_score_onboarding/risk_score_restart_button.test.tsx (94%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_score_onboarding/risk_score_restart_button.tsx (83%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_score_onboarding/translations.ts (93%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_score_onboarding/use_risk_score_toast_content.tsx (94%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_score_onboarding/utils.test.ts (94%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_score_onboarding/utils.ts (96%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_score_over_time/index.test.tsx (85%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_score_over_time/index.tsx (87%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/risk_score_over_time/translations.ts (100%) rename x-pack/plugins/security_solution/public/{common/components/event_details/cti_details => entity_analytics/components}/risk_summary.test.tsx (89%) rename x-pack/plugins/security_solution/public/{common/components/event_details/cti_details => entity_analytics/components}/risk_summary.tsx (80%) rename x-pack/plugins/security_solution/public/{flyout/entity_details/shared/components => entity_analytics/components/risk_summary_flyout}/risk_summary.stories.tsx (86%) rename x-pack/plugins/security_solution/public/{flyout/entity_details/shared/components => entity_analytics/components/risk_summary_flyout}/risk_summary.test.tsx (90%) rename x-pack/plugins/security_solution/public/{flyout/entity_details/shared/components => entity_analytics/components/risk_summary_flyout}/risk_summary.tsx (90%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/severity/common/index.test.tsx (93%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/severity/common/index.tsx (87%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/severity/severity_badges.tsx (91%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/severity/severity_bar.tsx (90%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/severity/severity_filter_group.test.tsx (91%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/severity/severity_filter_group.tsx (94%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/severity/types.ts (80%) rename x-pack/plugins/security_solution/public/{overview/components/entity_analytics/common => entity_analytics/components}/styled_basic_table.tsx (100%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/top_risk_score_contributors/index.test.tsx (91%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/top_risk_score_contributors/index.tsx (91%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/top_risk_score_contributors/translations.ts (100%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/top_risk_score_contributors_alerts/index.tsx (78%) rename x-pack/plugins/security_solution/public/{explore/components/risk_score => entity_analytics/components}/top_risk_score_contributors_alerts/translations.ts (100%) rename x-pack/plugins/security_solution/public/{explore/users/pages/navigation => entity_analytics/components}/user_risk_score_tab_body.test.tsx (81%) rename x-pack/plugins/security_solution/public/{explore/users/pages/navigation => entity_analytics/components}/user_risk_score_tab_body.tsx (76%) rename x-pack/plugins/security_solution/public/{explore/users => entity_analytics}/components/user_risk_score_table/columns.test.tsx (93%) rename x-pack/plugins/security_solution/public/{explore/users => entity_analytics}/components/user_risk_score_table/columns.tsx (77%) rename x-pack/plugins/security_solution/public/{explore/users => entity_analytics}/components/user_risk_score_table/index.test.tsx (83%) rename x-pack/plugins/security_solution/public/{explore/users => entity_analytics}/components/user_risk_score_table/index.tsx (83%) rename x-pack/plugins/security_solution/public/{explore/users => entity_analytics}/components/user_risk_score_table/translations.ts (100%) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/onboarding => entity_analytics/deprecated_risk_engine}/api/index.ts (100%) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/onboarding => entity_analytics/deprecated_risk_engine}/api/ingest_pipelines.test.ts (100%) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/onboarding => entity_analytics/deprecated_risk_engine}/api/ingest_pipelines.ts (100%) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/onboarding => entity_analytics/deprecated_risk_engine}/api/onboarding.ts (94%) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/onboarding => entity_analytics/deprecated_risk_engine}/api/saved_objects.ts (96%) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/onboarding => entity_analytics/deprecated_risk_engine}/api/stored_scripts.test.ts (100%) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/onboarding => entity_analytics/deprecated_risk_engine}/api/stored_scripts.ts (97%) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/onboarding => entity_analytics/deprecated_risk_engine}/api/transforms.test.ts (100%) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/onboarding => entity_analytics/deprecated_risk_engine}/api/transforms.ts (100%) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/onboarding => entity_analytics/deprecated_risk_engine}/api/translations.ts (100%) rename x-pack/plugins/security_solution/public/{explore/containers/risk_score/onboarding => entity_analytics/deprecated_risk_engine}/api/types.ts (100%) rename x-pack/plugins/security_solution/public/{common/components/visualization_actions/lens_attributes/common/risk_scores => entity_analytics/lens_attributes}/__snapshots__/risk_score_donut.test.ts.snap (100%) rename x-pack/plugins/security_solution/public/{common/components/visualization_actions/lens_attributes/common/risk_scores => entity_analytics/lens_attributes}/__snapshots__/risk_score_over_time_area.test.ts.snap (100%) rename x-pack/plugins/security_solution/public/{common/components/visualization_actions/lens_attributes/common/risk_scores => entity_analytics/lens_attributes}/__snapshots__/risk_score_summary.test.ts.snap (100%) rename x-pack/plugins/security_solution/public/{common/components/visualization_actions/lens_attributes/common/risk_scores => entity_analytics/lens_attributes}/risk_score_donut.test.ts (82%) rename x-pack/plugins/security_solution/public/{common/components/visualization_actions/lens_attributes/common/risk_scores => entity_analytics/lens_attributes}/risk_score_donut.ts (98%) rename x-pack/plugins/security_solution/public/{common/components/visualization_actions/lens_attributes/common/risk_scores => entity_analytics/lens_attributes}/risk_score_over_time_area.test.ts (89%) rename x-pack/plugins/security_solution/public/{common/components/visualization_actions/lens_attributes/common/risk_scores => entity_analytics/lens_attributes}/risk_score_over_time_area.ts (98%) rename x-pack/plugins/security_solution/public/{common/components/visualization_actions/lens_attributes/common/risk_scores => entity_analytics/lens_attributes}/risk_score_summary.test.ts (85%) rename x-pack/plugins/security_solution/public/{common/components/visualization_actions/lens_attributes/common/risk_scores => entity_analytics/lens_attributes}/risk_score_summary.ts (93%) rename x-pack/plugins/security_solution/public/{overview/pages/entity_analytics.tsx => entity_analytics/pages/entity_analytics_dashboard.tsx} (92%) delete mode 100644 x-pack/plugins/security_solution/public/explore/containers/risk_score/all/translations.ts delete mode 100644 x-pack/plugins/security_solution/public/explore/containers/risk_score/feature_status/api.ts delete mode 100644 x-pack/plugins/security_solution/public/explore/containers/risk_score/index.ts delete mode 100644 x-pack/plugins/security_solution/public/explore/containers/risk_score/kpi/translations.ts rename x-pack/plugins/security_solution/public/flyout/entity_details/{user_detais_left => user_details_left}/content.tsx (100%) rename x-pack/plugins/security_solution/public/flyout/entity_details/{user_detais_left => user_details_left}/header.tsx (100%) rename x-pack/plugins/security_solution/public/flyout/entity_details/{user_detais_left => user_details_left}/index.tsx (100%) rename x-pack/plugins/security_solution/public/flyout/entity_details/{user_detais_left => user_details_left}/tabs.tsx (84%) rename x-pack/plugins/security_solution/public/flyout/entity_details/{user_detais_left => user_details_left}/tabs/asset_document.test.tsx (100%) rename x-pack/plugins/security_solution/public/flyout/entity_details/{user_detais_left => user_details_left}/tabs/asset_document.tsx (100%) rename x-pack/plugins/security_solution/public/flyout/entity_details/{user_detais_left => user_details_left}/tabs/test_ids.ts (100%) rename x-pack/plugins/security_solution/public/flyout/entity_details/{user_detais_left => user_details_left}/test_ids.ts (85%) delete mode 100644 x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/translations.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9ec0cc7fab0a4c..7d95257248bfc8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1497,17 +1497,12 @@ x-pack/test/threat_intelligence_cypress @elastic/protections-experience x-pack/plugins/security_solution/common/entity_analytics @elastic/security-entity-analytics x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score @elastic/security-entity-analytics x-pack/plugins/security_solution/public/entity_analytics @elastic/security-entity-analytics -x-pack/plugins/security_solution/public/explore/components/risk_score @elastic/security-entity-analytics -x-pack/plugins/security_solution/public/overview/pages/entity_analytics.tsx @elastic/security-entity-analytics -x-pack/plugins/security_solution/public/overview/components/entity_analytics x-pack/plugins/security_solution/server/lib/entity_analytics @elastic/security-entity-analytics x-pack/plugins/security_solution/server/lib/risk_score @elastic/security-entity-analytics x-pack/test/security_solution_api_integration/test_suites/entity_analytics @elastic/security-entity-analytics x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics @elastic/security-entity-analytics x-pack/plugins/security_solution/public/flyout/entity_details @elastic/security-entity-analytics x-pack/plugins/security_solution/common/api/entity_analytics @elastic/security-entity-analytics -/x-pack/plugins/security_solution/public/entity_analytics @elastic/security-entity-analytics -/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics @elastic/security-entity-analytics # Security Defend Workflows - OSQuery Ownership /x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions @elastic/security-defend-workflows diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.tsx index 4f5e1f847ad83d..ce22e6e09b4336 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/threat_summary_view.tsx @@ -8,6 +8,7 @@ import styled from 'styled-components'; import React from 'react'; import { EuiTitle, EuiHorizontalRule, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; +import type { HostRisk, UserRisk } from '../../../../entity_analytics/api/types'; import * as i18n from './translations'; import type { CtiEnrichment } from '../../../../../common/search_strategy/security_solution/cti'; @@ -16,9 +17,8 @@ import type { TimelineEventsDetailsItem, RiskSeverity, } from '../../../../../common/search_strategy'; -import { RiskSummary } from './risk_summary'; +import { RiskSummary } from '../../../../entity_analytics/components/risk_summary'; import { EnrichmentSummary } from './enrichment_summary'; -import type { HostRisk, UserRisk } from '../../../../explore/containers/risk_score'; import { RiskScoreEntity } from '../../../../../common/search_strategy'; import { useHasSecurityCapability } from '../../../../helper_hooks'; import { RiskScoreInfoTooltip } from '../../../../overview/components/common'; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/translations.ts b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/translations.ts index 0ba5a464dc9d5a..973b438c866c34 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/translations.ts +++ b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/translations.ts @@ -6,9 +6,9 @@ */ import { i18n } from '@kbn/i18n'; -import { getRiskEntityTranslation } from '../../../../explore/components/risk_score/translations'; +import { getRiskEntityTranslation } from '../../../../entity_analytics/components/risk_score/translations'; import type { RiskScoreEntity } from '../../../../../common/search_strategy'; -export * from '../../../../explore/components/risk_score/translations'; +export * from '../../../../entity_analytics/components/risk_score/translations'; export const FEED_NAME_PREPOSITION = i18n.translate( 'xpack.securitySolution.eventDetails.ctiSummary.feedNamePreposition', diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx index 2273389e537331..6c1dd9bce910a0 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx @@ -55,7 +55,7 @@ import { EnrichmentRangePicker } from './cti_details/enrichment_range_picker'; import { InvestigationGuideView } from './investigation_guide_view'; import { Overview } from './overview'; import { Insights } from './insights/insights'; -import { useRiskScoreData } from './use_risk_score_data'; +import { useRiskScoreData } from '../../../entity_analytics/api/hooks/use_risk_score_data'; import { getRowRenderer } from '../../../timelines/components/timeline/body/renderers/get_row_renderer'; import { DETAILS_CLASS_NAME } from '../../../timelines/components/timeline/body/renderers/helpers'; import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers'; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_search.ts b/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_search.ts index d21e7a8087cbc2..88b03516e5aa82 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_search.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_search.ts @@ -8,12 +8,12 @@ import { useState, useEffect, useMemo } from 'react'; import { has, sortBy } from 'lodash/fp'; +import { getAggregatedAnomaliesQuery } from '../../../../entity_analytics/components/entity_analytics_anomalies/query'; import { DEFAULT_ANOMALY_SCORE } from '../../../../../common/constants'; import * as i18n from './translations'; import { useUiSetting$ } from '../../../lib/kibana'; import { useAppToasts } from '../../../hooks/use_app_toasts'; import { anomaliesSearch } from '../api/anomalies_search'; -import { getAggregatedAnomaliesQuery } from '../../../../overview/components/entity_analytics/anomalies/query'; import type { inputsModel } from '../../../store'; import { useSecurityJobs } from '../../ml_popover/hooks/use_security_jobs'; import type { SecurityJob } from '../../ml_popover/types'; diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/visualization_embeddable.test.tsx b/x-pack/plugins/security_solution/public/common/components/visualization_actions/visualization_embeddable.test.tsx index ee77776e60a91b..8d5ef1a3b6e84c 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/visualization_embeddable.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/visualization_embeddable.test.tsx @@ -22,8 +22,7 @@ import { import { createStore } from '../../store'; import type { State } from '../../store'; import { useRefetchByRestartingSession } from '../page/use_refetch_by_session'; -import { getRiskScoreDonutAttributes } from './lens_attributes/common/risk_scores/risk_score_donut'; -import { TOTAL_LABEL } from '../../../overview/components/entity_analytics/common/translations'; +import { getRiskScoreDonutAttributes } from '../../../entity_analytics/lens_attributes/risk_score_donut'; jest.mock('./lens_embeddable'); jest.mock('../page/use_refetch_by_session', () => ({ @@ -183,7 +182,7 @@ describe('VisualizationEmbeddable', () => { getLensAttributes={getRiskScoreDonutAttributes} id="testId" isDonut={true} - label={TOTAL_LABEL} + label={'Total'} timerange={{ from: '2022-10-27T23:00:00.000Z', to: '2022-11-04T10:46:16.204Z' }} /> </TestProviders> diff --git a/x-pack/plugins/security_solution/public/entity_analytics/api/api.ts b/x-pack/plugins/security_solution/public/entity_analytics/api/api.ts index 73cb1cbd57ff09..9f2b7bb319f7d4 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/api/api.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/api.ts @@ -5,6 +5,7 @@ * 2.0. */ +import type { RiskScoreEntity } from '../../../common/search_strategy'; import { RISK_ENGINE_STATUS_URL, RISK_SCORE_PREVIEW_URL, @@ -13,6 +14,7 @@ import { RISK_ENGINE_INIT_URL, RISK_ENGINE_PRIVILEGES_URL, ASSET_CRITICALITY_PRIVILEGES_URL, + RISK_SCORE_INDEX_STATUS_API_URL, } from '../../../common/constants'; import type { @@ -101,6 +103,27 @@ export const useEntityAnalyticsRoutes = () => { method: 'GET', }); + const getRiskScoreIndexStatus = ({ + query, + signal, + }: { + query: { + indexName: string; + entity: RiskScoreEntity; + }; + signal?: AbortSignal; + }): Promise<{ + isDeprecated: boolean; + isEnabled: boolean; + }> => + http.fetch<{ isDeprecated: boolean; isEnabled: boolean }>(RISK_SCORE_INDEX_STATUS_API_URL, { + version: '1', + method: 'GET', + query, + asSystemRequest: true, + signal, + }); + return { fetchRiskScorePreview, fetchRiskEngineStatus, @@ -109,5 +132,6 @@ export const useEntityAnalyticsRoutes = () => { disableRiskEngine, fetchRiskEnginePrivileges, fetchAssetCriticalityPrivileges, + getRiskScoreIndexStatus, }; }; diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/all/index.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.test.tsx similarity index 88% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/all/index.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.test.tsx index dfbba68e25c97b..8f61796f0861b7 100644 --- a/x-pack/plugins/security_solution/public/explore/containers/risk_score/all/index.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.test.tsx @@ -5,25 +5,25 @@ * 2.0. */ import { renderHook } from '@testing-library/react-hooks'; -import { useRiskScore } from '.'; -import { TestProviders } from '../../../../common/mock'; +import { useRiskScore } from './use_risk_score'; +import { TestProviders } from '../../../common/mock'; -import { useSearchStrategy } from '../../../../common/containers/use_search_strategy'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { useAppToastsMock } from '../../../../common/hooks/use_app_toasts.mock'; -import { useRiskScoreFeatureStatus } from '../feature_status'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; +import { useSearchStrategy } from '../../../common/containers/use_search_strategy'; +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import { useAppToastsMock } from '../../../common/hooks/use_app_toasts.mock'; +import { useRiskScoreFeatureStatus } from './use_risk_score_feature_status'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; -jest.mock('../../../../common/containers/use_search_strategy', () => ({ +jest.mock('../../../common/containers/use_search_strategy', () => ({ useSearchStrategy: jest.fn(), })); -jest.mock('../../../../common/hooks/use_space_id', () => ({ +jest.mock('../../../common/hooks/use_space_id', () => ({ useSpaceId: jest.fn().mockReturnValue('default'), })); -jest.mock('../../../../common/hooks/use_app_toasts'); -jest.mock('../feature_status'); +jest.mock('../../../common/hooks/use_app_toasts'); +jest.mock('./use_risk_score_feature_status'); const mockUseRiskScoreFeatureStatus = useRiskScoreFeatureStatus as jest.Mock; const mockUseSearchStrategy = useSearchStrategy as jest.Mock; diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/all/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.tsx similarity index 81% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/all/index.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.tsx index b2be80f74ab713..3038e33d4bfab3 100644 --- a/x-pack/plugins/security_solution/public/explore/containers/risk_score/all/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.tsx @@ -7,28 +7,25 @@ import { useCallback, useEffect, useMemo } from 'react'; -import { useRiskScoreFeatureStatus } from '../feature_status'; -import { createFilter } from '../../../../common/containers/helpers'; -import type { - RiskScoreSortField, - StrategyResponseType, -} from '../../../../../common/search_strategy'; +import { i18n } from '@kbn/i18n'; +import { useRiskScoreFeatureStatus } from './use_risk_score_feature_status'; +import { createFilter } from '../../../common/containers/helpers'; +import type { RiskScoreSortField, StrategyResponseType } from '../../../../common/search_strategy'; import { RiskQueries, getUserRiskIndex, RiskScoreEntity, getHostRiskIndex, -} from '../../../../../common/search_strategy'; -import type { ESQuery } from '../../../../../common/typed_json'; - -import * as i18n from './translations'; -import type { InspectResponse } from '../../../../types'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { isIndexNotFoundError } from '../../../../common/utils/exceptions'; -import type { inputsModel } from '../../../../common/store'; -import { useSpaceId } from '../../../../common/hooks/use_space_id'; -import { useSearchStrategy } from '../../../../common/containers/use_search_strategy'; -import { useIsNewRiskScoreModuleInstalled } from '../../../../entity_analytics/api/hooks/use_risk_engine_status'; +} from '../../../../common/search_strategy'; +import type { ESQuery } from '../../../../common/typed_json'; + +import type { InspectResponse } from '../../../types'; +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import { isIndexNotFoundError } from '../../../common/utils/exceptions'; +import type { inputsModel } from '../../../common/store'; +import { useSpaceId } from '../../../common/hooks/use_space_id'; +import { useSearchStrategy } from '../../../common/containers/use_search_strategy'; +import { useIsNewRiskScoreModuleInstalled } from './use_risk_engine_status'; export interface RiskScoreState<T extends RiskScoreEntity.host | RiskScoreEntity.user> { data: @@ -181,7 +178,11 @@ export const useRiskScore = <T extends RiskScoreEntity.host | RiskScoreEntity.us useEffect(() => { if (error) { if (!isIndexNotFoundError(error)) { - addError(error, { title: i18n.FAIL_RISK_SCORE }); + addError(error, { + title: i18n.translate('xpack.securitySolution.riskScore.failSearchDescription', { + defaultMessage: `Failed to run search on risk score`, + }), + }); } } }, [addError, error]); diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/use_risk_score_data.test.ts b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_data.test.ts similarity index 94% rename from x-pack/plugins/security_solution/public/common/components/event_details/use_risk_score_data.test.ts rename to x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_data.test.ts index 656c13b22d8560..123d4662768c19 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/use_risk_score_data.test.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_data.test.ts @@ -6,13 +6,13 @@ */ import { renderHook } from '@testing-library/react-hooks'; -import { TestProviders } from '../../mock'; +import { TestProviders } from '../../../common/mock'; import { ONLY_FIRST_ITEM_PAGINATION, useRiskScoreData } from './use_risk_score_data'; -import { useRiskScore } from '../../../explore/containers/risk_score'; import { useBasicDataFromDetailsData } from '../../../timelines/components/side_panel/event_details/helpers'; import { RiskScoreEntity } from '../../../../common/search_strategy'; +import { useRiskScore } from './use_risk_score'; -jest.mock('../../../explore/containers/risk_score'); +jest.mock('./use_risk_score'); jest.mock('../../../timelines/components/side_panel/event_details/helpers'); const mockUseRiskScore = useRiskScore as jest.Mock; const mockUseBasicDataFromDetailsData = useBasicDataFromDetailsData as jest.Mock; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/use_risk_score_data.ts b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_data.ts similarity index 93% rename from x-pack/plugins/security_solution/public/common/components/event_details/use_risk_score_data.ts rename to x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_data.ts index 8ac02b1ce47e43..545d12d0851f7d 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/use_risk_score_data.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_data.ts @@ -12,8 +12,8 @@ import { buildUserNamesFilter, RiskScoreEntity, } from '../../../../common/search_strategy'; -import type { HostRisk, UserRisk } from '../../../explore/containers/risk_score'; -import { useRiskScore } from '../../../explore/containers/risk_score'; +import { useRiskScore } from './use_risk_score'; +import type { HostRisk, UserRisk } from '../types'; export const ONLY_FIRST_ITEM_PAGINATION = { cursorStart: 0, diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/feature_status/index.test.ts b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_feature_status.test.ts similarity index 85% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/feature_status/index.test.ts rename to x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_feature_status.test.ts index 9464ecb9d8380b..30719d1559f54d 100644 --- a/x-pack/plugins/security_solution/public/explore/containers/risk_score/feature_status/index.test.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_feature_status.test.ts @@ -5,17 +5,17 @@ * 2.0. */ import { act, renderHook } from '@testing-library/react-hooks'; -import { TestProviders } from '../../../../common/mock'; +import { TestProviders } from '../../../common/mock'; -import { useRiskScoreFeatureStatus } from '.'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { useFetch } from '../../../../common/hooks/use_fetch'; -import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; -import { useHasSecurityCapability } from '../../../../helper_hooks'; +import { useRiskScoreFeatureStatus } from './use_risk_score_feature_status'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; +import { useFetch } from '../../../common/hooks/use_fetch'; +import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities'; +import { useHasSecurityCapability } from '../../../helper_hooks'; -jest.mock('../../../../common/hooks/use_fetch'); -jest.mock('../../../../common/components/ml/hooks/use_ml_capabilities'); -jest.mock('../../../../helper_hooks'); +jest.mock('../../../common/hooks/use_fetch'); +jest.mock('../../../common/components/ml/hooks/use_ml_capabilities'); +jest.mock('../../../helper_hooks'); const mockFetch = jest.fn(); const mockUseMlCapabilities = useMlCapabilities as jest.Mock; diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/feature_status/index.ts b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_feature_status.ts similarity index 83% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/feature_status/index.ts rename to x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_feature_status.ts index 97994f58295c16..03fb48f56559a8 100644 --- a/x-pack/plugins/security_solution/public/explore/containers/risk_score/feature_status/index.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_feature_status.ts @@ -6,11 +6,11 @@ */ import { useCallback, useEffect, useMemo } from 'react'; -import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; -import { REQUEST_NAMES, useFetch } from '../../../../common/hooks/use_fetch'; -import type { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { getRiskScoreIndexStatus } from './api'; -import { useHasSecurityCapability } from '../../../../helper_hooks'; +import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities'; +import { REQUEST_NAMES, useFetch } from '../../../common/hooks/use_fetch'; +import type { RiskScoreEntity } from '../../../../common/search_strategy'; +import { useHasSecurityCapability } from '../../../helper_hooks'; +import { useEntityAnalyticsRoutes } from '../api'; interface RiskScoresFeatureStatus { error: unknown; @@ -31,6 +31,7 @@ export const useRiskScoreFeatureStatus = ( const { isPlatinumOrTrialLicense, capabilitiesFetched } = useMlCapabilities(); const hasEntityAnalyticsCapability = useHasSecurityCapability('entity-analytics'); const isAuthorized = isPlatinumOrTrialLicense && hasEntityAnalyticsCapability; + const { getRiskScoreIndexStatus } = useEntityAnalyticsRoutes(); const { fetch, data, isLoading, error } = useFetch( REQUEST_NAMES.GET_RISK_SCORE_DEPRECATED, diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/kpi/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_kpi.tsx similarity index 78% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/kpi/index.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_kpi.tsx index 2197d5553c4319..4105dfc28d83d6 100644 --- a/x-pack/plugins/security_solution/public/explore/containers/risk_score/kpi/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_kpi.tsx @@ -7,6 +7,7 @@ import { useCallback, useEffect, useMemo } from 'react'; +import { i18n } from '@kbn/i18n'; import { getHostRiskIndex, getUserRiskIndex, @@ -14,18 +15,17 @@ import { RiskSeverity, RiskScoreEntity, EMPTY_SEVERITY_COUNT, -} from '../../../../../common/search_strategy'; -import * as i18n from './translations'; -import { isIndexNotFoundError } from '../../../../common/utils/exceptions'; -import type { ESQuery } from '../../../../../common/typed_json'; -import type { SeverityCount } from '../../../components/risk_score/severity/types'; -import { useSpaceId } from '../../../../common/hooks/use_space_id'; -import { useSearchStrategy } from '../../../../common/containers/use_search_strategy'; -import type { InspectResponse } from '../../../../types'; -import type { inputsModel } from '../../../../common/store'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { useIsNewRiskScoreModuleInstalled } from '../../../../entity_analytics/api/hooks/use_risk_engine_status'; -import { useRiskScoreFeatureStatus } from '../feature_status'; +} from '../../../../common/search_strategy'; +import { isIndexNotFoundError } from '../../../common/utils/exceptions'; +import type { ESQuery } from '../../../../common/typed_json'; +import type { SeverityCount } from '../../components/severity/types'; +import { useSpaceId } from '../../../common/hooks/use_space_id'; +import { useSearchStrategy } from '../../../common/containers/use_search_strategy'; +import type { InspectResponse } from '../../../types'; +import type { inputsModel } from '../../../common/store'; +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import { useIsNewRiskScoreModuleInstalled } from './use_risk_engine_status'; +import { useRiskScoreFeatureStatus } from './use_risk_score_feature_status'; interface RiskScoreKpi { error: unknown; @@ -123,7 +123,11 @@ export const useRiskScoreKpi = ({ useEffect(() => { if (error) { if (!isIndexNotFoundError(error)) { - addError(error, { title: i18n.FAIL_RISK_SCORE }); + addError(error, { + title: i18n.translate('xpack.securitySolution.riskScore.kpi.failSearchDescription', { + defaultMessage: `Failed to run search on risk score`, + }), + }); } } }, [addError, error]); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/api/types.ts b/x-pack/plugins/security_solution/public/entity_analytics/api/types.ts new file mode 100644 index 00000000000000..419ebc60c4923d --- /dev/null +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/types.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { HostRiskScore, UserRiskScore } from '../../../common/search_strategy'; + +export interface HostRisk { + loading: boolean; + isModuleEnabled: boolean; + result?: HostRiskScore[]; +} + +export interface UserRisk { + loading: boolean; + isModuleEnabled: boolean; + result?: UserRiskScore[]; +} diff --git a/x-pack/plugins/security_solution/public/entity_analytics/common/utils.ts b/x-pack/plugins/security_solution/public/entity_analytics/common/utils.ts index 361d6d133a93d5..ee343526ea2b09 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/common/utils.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/common/utils.ts @@ -32,3 +32,15 @@ export const RISK_SCORE_RANGES = { [RiskSeverity.high]: { start: 70, stop: 90 }, [RiskSeverity.critical]: { start: 90, stop: 100 }, }; + +export enum UserRiskScoreQueryId { + USERS_BY_RISK = 'UsersByRisk', + USER_DETAILS_RISK_SCORE = 'UserDetailsRiskScore', +} + +export enum HostRiskScoreQueryId { + DEFAULT = 'HostRiskScore', + HOST_DETAILS_RISK_SCORE = 'HostDetailsRiskScore', + OVERVIEW_RISKY_HOSTS = 'OverviewRiskyHosts', + HOSTS_BY_RISK = 'HostsByRisk', +} diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/enable_risk_score/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/index.tsx similarity index 86% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/enable_risk_score/index.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/index.tsx index ac064feb35f047..994158104df5b0 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/enable_risk_score/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/index.tsx @@ -6,11 +6,11 @@ */ import { EuiEmptyPrompt, EuiPanel, EuiToolTip } from '@elastic/eui'; import React from 'react'; -import type { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { useCheckSignalIndex } from '../../../../detections/containers/detection_engine/alerts/use_check_signal_index'; -import type { inputsModel } from '../../../../common/store'; +import type { RiskScoreEntity } from '../../../../common/search_strategy'; +import { useCheckSignalIndex } from '../../../detections/containers/detection_engine/alerts/use_check_signal_index'; +import type { inputsModel } from '../../../common/store'; import { RiskScoreHeaderTitle } from '../risk_score_onboarding/risk_score_header_title'; -import { HeaderSection } from '../../../../common/components/header_section'; +import { HeaderSection } from '../../../common/components/header_section'; import { RiskScoreDocLink } from '../risk_score_onboarding/risk_score_doc_link'; import { RiskScoreEnableButton } from '../risk_score_onboarding/risk_score_enable_button'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/enable_risk_score/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/translations.ts similarity index 92% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/enable_risk_score/translations.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/translations.ts index 4c4d7073ed1dbd..c109c403a091ee 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/enable_risk_score/translations.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/translations.ts @@ -5,8 +5,8 @@ * 2.0. */ import { i18n } from '@kbn/i18n'; -import type { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { getRiskEntityTranslation } from '../translations'; +import type { RiskScoreEntity } from '../../../../common/search_strategy'; +import { getRiskEntityTranslation } from '../risk_score/translations'; export const ENABLE_RISK_SCORE_POPOVER = i18n.translate( 'xpack.securitySolution.enableRiskScore.enableRiskScorePopoverTitle', diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/anomalies_count_link.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/anomalies_count_link.test.tsx similarity index 73% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/anomalies_count_link.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/anomalies_count_link.test.tsx index 4ce4b6810ec981..8400578b85c4f8 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/anomalies_count_link.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/anomalies_count_link.test.tsx @@ -6,14 +6,14 @@ */ import { fireEvent, render } from '@testing-library/react'; import React from 'react'; -import { AnomalyEntity } from '../../../../common/components/ml/anomaly/use_anomalies_search'; -import { createTelemetryServiceMock } from '../../../../common/lib/telemetry/telemetry_service.mock'; -import { TestProviders } from '../../../../common/mock'; +import { AnomalyEntity } from '../../../common/components/ml/anomaly/use_anomalies_search'; +import { createTelemetryServiceMock } from '../../../common/lib/telemetry/telemetry_service.mock'; +import { TestProviders } from '../../../common/mock'; import { AnomaliesCountLink } from './anomalies_count_link'; const mockedTelemetry = createTelemetryServiceMock(); -jest.mock('../../../../common/lib/kibana', () => { - const original = jest.requireActual('../../../../common/lib/kibana'); +jest.mock('../../../common/lib/kibana', () => { + const original = jest.requireActual('../../../common/lib/kibana'); return { ...original, diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/anomalies_count_link.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/anomalies_count_link.tsx similarity index 75% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/anomalies_count_link.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/anomalies_count_link.tsx index 529f197c62e440..bb32564acb1b94 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/anomalies_count_link.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/anomalies_count_link.tsx @@ -6,15 +6,15 @@ */ import { useDispatch } from 'react-redux'; import React, { useCallback } from 'react'; -import { AnomalyEntity } from '../../../../common/components/ml/anomaly/use_anomalies_search'; -import { SecuritySolutionLinkAnchor } from '../../../../common/components/links'; -import { SecurityPageName } from '../../../../app/types'; -import { usersActions } from '../../../../explore/users/store'; -import { hostsActions } from '../../../../explore/hosts/store'; -import { HostsType } from '../../../../explore/hosts/store/model'; -import { UsersType } from '../../../../explore/users/store/model'; +import { AnomalyEntity } from '../../../common/components/ml/anomaly/use_anomalies_search'; +import { SecuritySolutionLinkAnchor } from '../../../common/components/links'; +import { SecurityPageName } from '../../../app/types'; +import { usersActions } from '../../../explore/users/store'; +import { hostsActions } from '../../../explore/hosts/store'; +import { HostsType } from '../../../explore/hosts/store/model'; +import { UsersType } from '../../../explore/users/store/model'; -import { useKibana } from '../../../../common/lib/kibana'; +import { useKibana } from '../../../common/lib/kibana'; export const AnomaliesCountLink = ({ count, diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/columns.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/columns.test.tsx similarity index 90% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/columns.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/columns.test.tsx index f4349df20dc51a..6083c18dfb38d7 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/columns.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/columns.test.tsx @@ -6,8 +6,8 @@ */ import { renderHook } from '@testing-library/react-hooks'; -import { AnomalyEntity } from '../../../../common/components/ml/anomaly/use_anomalies_search'; -import type { SecurityJob } from '../../../../common/components/ml_popover/types'; +import { AnomalyEntity } from '../../../common/components/ml/anomaly/use_anomalies_search'; +import type { SecurityJob } from '../../../common/components/ml_popover/types'; import { useAnomaliesColumns } from './columns'; describe('useAnomaliesColumns', () => { diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/columns.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/columns.tsx similarity index 90% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/columns.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/columns.tsx index 9faabf8d43f1c8..6574f6a566b155 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/columns.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/columns.tsx @@ -8,11 +8,11 @@ import React, { useMemo } from 'react'; import styled from 'styled-components'; import type { EuiTableFieldDataColumnType } from '@elastic/eui'; import * as i18n from './translations'; -import type { SecurityJob } from '../../../../common/components/ml_popover/types'; -import { isJobStarted } from '../../../../../common/machine_learning/helpers'; +import type { SecurityJob } from '../../../common/components/ml_popover/types'; +import { isJobStarted } from '../../../../common/machine_learning/helpers'; import { TotalAnomalies } from './components/total_anomalies'; -import type { AnomaliesCount } from '../../../../common/components/ml/anomaly/use_anomalies_search'; +import type { AnomaliesCount } from '../../../common/components/ml/anomaly/use_anomalies_search'; type AnomaliesColumns = Array<EuiTableFieldDataColumnType<AnomaliesCount>>; diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/components/anomalies_tab_link.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/components/anomalies_tab_link.tsx similarity index 75% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/components/anomalies_tab_link.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/components/anomalies_tab_link.tsx index 80f78ee50331ef..9f515d8439a668 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/components/anomalies_tab_link.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/components/anomalies_tab_link.tsx @@ -7,13 +7,13 @@ import React, { useCallback } from 'react'; import { useDispatch } from 'react-redux'; -import { SecuritySolutionLinkAnchor } from '../../../../../common/components/links'; -import { SecurityPageName } from '../../../../../app/types'; -import { usersActions } from '../../../../../explore/users/store'; -import { hostsActions } from '../../../../../explore/hosts/store'; -import { HostsType } from '../../../../../explore/hosts/store/model'; -import { UsersType } from '../../../../../explore/users/store/model'; -import { AnomalyEntity } from '../../../../../common/components/ml/anomaly/use_anomalies_search'; +import { SecuritySolutionLinkAnchor } from '../../../../common/components/links'; +import { SecurityPageName } from '../../../../app/types'; +import { usersActions } from '../../../../explore/users/store'; +import { hostsActions } from '../../../../explore/hosts/store'; +import { HostsType } from '../../../../explore/hosts/store/model'; +import { UsersType } from '../../../../explore/users/store/model'; +import { AnomalyEntity } from '../../../../common/components/ml/anomaly/use_anomalies_search'; export const AnomaliesTabLink = ({ count, diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/components/enable_job.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/components/enable_job.test.tsx similarity index 88% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/components/enable_job.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/components/enable_job.test.tsx index c5c199b79df095..1fe70e558cbdcd 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/components/enable_job.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/components/enable_job.test.tsx @@ -7,11 +7,11 @@ import React from 'react'; import { render, fireEvent, waitFor } from '@testing-library/react'; -import { useEnableDataFeed } from '../../../../../common/components/ml_popover/hooks/use_enable_data_feed'; -import type { SecurityJob } from '../../../../../common/components/ml_popover/types'; +import { useEnableDataFeed } from '../../../../common/components/ml_popover/hooks/use_enable_data_feed'; +import type { SecurityJob } from '../../../../common/components/ml_popover/types'; import { EnableJob } from './enable_job'; -jest.mock('../../../../../common/components/ml_popover/hooks/use_enable_data_feed', () => ({ +jest.mock('../../../../common/components/ml_popover/hooks/use_enable_data_feed', () => ({ useEnableDataFeed: jest.fn(() => ({ enableDatafeed: jest.fn(), isLoading: false })), })); diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/components/enable_job.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/components/enable_job.tsx similarity index 80% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/components/enable_job.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/components/enable_job.tsx index 533a0eddcbc1a8..b98933a34e09cc 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/components/enable_job.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/components/enable_job.tsx @@ -7,10 +7,10 @@ import React, { useCallback } from 'react'; import { EuiLoadingSpinner } from '@elastic/eui'; -import type { SecurityJob } from '../../../../../common/components/ml_popover/types'; -import { LinkAnchor } from '../../../../../common/components/links'; +import type { SecurityJob } from '../../../../common/components/ml_popover/types'; +import { LinkAnchor } from '../../../../common/components/links'; import * as i18n from '../translations'; -import { useEnableDataFeed } from '../../../../../common/components/ml_popover/hooks/use_enable_data_feed'; +import { useEnableDataFeed } from '../../../../common/components/ml_popover/hooks/use_enable_data_feed'; export const EnableJob = ({ job, diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/components/total_anomalies.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/components/total_anomalies.test.tsx similarity index 81% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/components/total_anomalies.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/components/total_anomalies.test.tsx index 3cd8e25869763c..4d064682f5c8d9 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/components/total_anomalies.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/components/total_anomalies.test.tsx @@ -6,11 +6,11 @@ */ import React from 'react'; -import { AnomalyEntity } from '../../../../../common/components/ml/anomaly/use_anomalies_search'; -import type { SecurityJob } from '../../../../../common/components/ml_popover/types'; +import { AnomalyEntity } from '../../../../common/components/ml/anomaly/use_anomalies_search'; +import type { SecurityJob } from '../../../../common/components/ml_popover/types'; import { render } from '@testing-library/react'; import { TotalAnomalies } from './total_anomalies'; -import { TestProviders } from '../../../../../common/mock'; +import { TestProviders } from '../../../../common/mock'; const defaultProps = { count: 0, diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/components/total_anomalies.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/components/total_anomalies.tsx similarity index 85% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/components/total_anomalies.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/components/total_anomalies.tsx index 8311b28177a08a..b72f1ef8879bb5 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/components/total_anomalies.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/components/total_anomalies.tsx @@ -11,9 +11,9 @@ import { isJobFailed, isJobLoading, isJobStarted, -} from '../../../../../../common/machine_learning/helpers'; -import type { AnomalyEntity } from '../../../../../common/components/ml/anomaly/use_anomalies_search'; -import type { SecurityJob } from '../../../../../common/components/ml_popover/types'; +} from '../../../../../common/machine_learning/helpers'; +import type { AnomalyEntity } from '../../../../common/components/ml/anomaly/use_anomalies_search'; +import type { SecurityJob } from '../../../../common/components/ml_popover/types'; import * as i18n from '../translations'; import { AnomaliesTabLink } from './anomalies_tab_link'; import { EnableJob } from './enable_job'; diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/index.test.tsx similarity index 92% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/index.test.tsx index 3e6b85d7beca9f..ee3c4cfd022d89 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/index.test.tsx @@ -8,13 +8,13 @@ import { act, fireEvent, render, waitFor } from '@testing-library/react'; import React from 'react'; import { EntityAnalyticsAnomalies } from '.'; -import type { AnomaliesCount } from '../../../../common/components/ml/anomaly/use_anomalies_search'; -import { AnomalyEntity } from '../../../../common/components/ml/anomaly/use_anomalies_search'; +import type { AnomaliesCount } from '../../../common/components/ml/anomaly/use_anomalies_search'; +import { AnomalyEntity } from '../../../common/components/ml/anomaly/use_anomalies_search'; -import { TestProviders } from '../../../../common/mock'; -import type { SecurityJob } from '../../../../common/components/ml_popover/types'; +import { TestProviders } from '../../../common/mock'; +import type { SecurityJob } from '../../../common/components/ml_popover/types'; -jest.mock('../../../../common/components/ml_popover/hooks/use_enable_data_feed', () => ({ +jest.mock('../../../common/components/ml_popover/hooks/use_enable_data_feed', () => ({ useEnableDataFeed: () => ({ loading: false, enableDatafeed: jest.fn().mockResolvedValue({ enabled: true }), @@ -22,7 +22,7 @@ jest.mock('../../../../common/components/ml_popover/hooks/use_enable_data_feed', })); // Query toggle only works if pageName.lenght > 0 -jest.mock('../../../../common/utils/route/use_route_spy', () => ({ +jest.mock('../../../common/utils/route/use_route_spy', () => ({ useRouteSpy: jest.fn().mockReturnValue([ { pageName: 'not_empty', @@ -45,10 +45,8 @@ jest.mock( } ); -jest.mock('../../../../common/components/ml/anomaly/use_anomalies_search', () => { - const original = jest.requireActual( - '../../../../common/components/ml/anomaly/use_anomalies_search' - ); +jest.mock('../../../common/components/ml/anomaly/use_anomalies_search', () => { + const original = jest.requireActual('../../../common/components/ml/anomaly/use_anomalies_search'); return { ...original, useAggregatedAnomaliesByJob: () => mockUseAggregatedAnomaliesByJob(), diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/index.tsx similarity index 85% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/index.tsx index 3e6f2e570cc22c..d841e59aeb67a8 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/index.tsx @@ -16,26 +16,26 @@ import { import { MLJobsAwaitingNodeWarning, ML_PAGES, useMlHref } from '@kbn/ml-plugin/public'; import { FormattedMessage } from '@kbn/i18n-react'; -import { HeaderSection } from '../../../../common/components/header_section'; -import { useQueryToggle } from '../../../../common/containers/query_toggle'; -import { LastUpdatedAt } from '../../../../common/components/last_updated_at'; +import { HeaderSection } from '../../../common/components/header_section'; +import { useQueryToggle } from '../../../common/containers/query_toggle'; +import { LastUpdatedAt } from '../../../common/components/last_updated_at'; import * as i18n from './translations'; -import { useAggregatedAnomaliesByJob } from '../../../../common/components/ml/anomaly/use_anomalies_search'; +import { useAggregatedAnomaliesByJob } from '../../../common/components/ml/anomaly/use_anomalies_search'; import { useAnomaliesColumns } from './columns'; -import { useQueryInspector } from '../../../../common/components/page/manage_query'; -import { useGlobalTime } from '../../../../common/containers/use_global_time'; +import { useQueryInspector } from '../../../common/components/page/manage_query'; +import { useGlobalTime } from '../../../common/containers/use_global_time'; import { LinkAnchor, LinkButton, useGetSecuritySolutionLinkProps, -} from '../../../../common/components/links'; -import { HostsTableType } from '../../../../explore/hosts/store/model'; -import { getTabsOnHostsUrl } from '../../../../common/components/link_to/redirect_to_hosts'; -import { SecurityPageName } from '../../../../app/types'; -import { getTabsOnUsersUrl } from '../../../../common/components/link_to/redirect_to_users'; -import { UsersTableType } from '../../../../explore/users/store/model'; -import { useKibana } from '../../../../common/lib/kibana'; -import type { SecurityJob } from '../../../../common/components/ml_popover/types'; +} from '../../../common/components/links'; +import { HostsTableType } from '../../../explore/hosts/store/model'; +import { getTabsOnHostsUrl } from '../../../common/components/link_to/redirect_to_hosts'; +import { SecurityPageName } from '../../../app/types'; +import { getTabsOnUsersUrl } from '../../../common/components/link_to/redirect_to_users'; +import { UsersTableType } from '../../../explore/users/store/model'; +import { useKibana } from '../../../common/lib/kibana'; +import type { SecurityJob } from '../../../common/components/ml_popover/types'; const TABLE_QUERY_ID = 'entityAnalyticsDashboardAnomaliesTable'; diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/query/index.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/query/index.ts similarity index 100% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/query/index.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/query/index.ts diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/translations.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_anomalies/translations.ts diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/index.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_header/index.test.tsx similarity index 84% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/index.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_header/index.test.tsx index 62820ee2c0de96..392656402c63eb 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/index.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_header/index.test.tsx @@ -8,13 +8,14 @@ import { act, fireEvent, render, waitFor } from '@testing-library/react'; import React from 'react'; import { EntityAnalyticsHeader } from '.'; -import { Direction, RiskScoreFields, RiskSeverity } from '../../../../../common/search_strategy'; -import type { SeverityCount } from '../../../../explore/components/risk_score/severity/types'; -import { TestProviders } from '../../../../common/mock'; -import { hostsActions } from '../../../../explore/hosts/store'; -import { HostsType } from '../../../../explore/hosts/store/model'; -import { usersActions } from '../../../../explore/users/store'; -import { UsersTableType } from '../../../../explore/users/store/model'; +import { Direction, RiskScoreFields, RiskSeverity } from '../../../../common/search_strategy'; +import { TestProviders } from '../../../common/mock'; +import { hostsActions } from '../../../explore/hosts/store'; +import { HostsType } from '../../../explore/hosts/store/model'; +import { usersActions } from '../../../explore/users/store'; +import { UsersTableType } from '../../../explore/users/store/model'; + +import type { SeverityCount } from '../severity/types'; const mockSeverityCount: SeverityCount = { [RiskSeverity.low]: 1, @@ -24,11 +25,11 @@ const mockSeverityCount: SeverityCount = { [RiskSeverity.critical]: 99, }; -jest.mock('../../../../common/components/ml/hooks/use_ml_capabilities', () => ({ +jest.mock('../../../common/components/ml/hooks/use_ml_capabilities', () => ({ useMlCapabilities: () => ({ isPlatinumOrTrialLicense: true, capabilities: {} }), })); -jest.mock('../../../../explore/containers/risk_score', () => { +jest.mock('../../api/hooks/use_risk_score_kpi', () => { return { useRiskScoreKpi: () => ({ severityCount: mockSeverityCount }), }; diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_header/index.tsx similarity index 82% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/index.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_header/index.tsx index 3be1dd65f48eb4..8a814a1ee5a2e7 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_header/index.tsx @@ -9,34 +9,34 @@ import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle, EuiLink } from '@elastic import styled from 'styled-components'; import { useDispatch } from 'react-redux'; import { sumBy } from 'lodash/fp'; -import { useRiskScoreKpi } from '../../../../explore/containers/risk_score'; -import { LinkAnchor, useGetSecuritySolutionLinkProps } from '../../../../common/components/links'; +import { SEVERITY_COLOR } from '../../../overview/components/detection_response/utils'; +import { LinkAnchor, useGetSecuritySolutionLinkProps } from '../../../common/components/links'; import { Direction, RiskScoreEntity, RiskScoreFields, RiskSeverity, -} from '../../../../../common/search_strategy'; +} from '../../../../common/search_strategy'; import * as i18n from './translations'; -import { getTabsOnHostsUrl } from '../../../../common/components/link_to/redirect_to_hosts'; -import { SecurityPageName } from '../../../../app/types'; -import { HostsTableType, HostsType } from '../../../../explore/hosts/store/model'; -import { hostsActions } from '../../../../explore/hosts/store'; -import { usersActions } from '../../../../explore/users/store'; -import { getTabsOnUsersUrl } from '../../../../common/components/link_to/redirect_to_users'; -import { UsersTableType } from '../../../../explore/users/store/model'; -import { useAggregatedAnomaliesByJob } from '../../../../common/components/ml/anomaly/use_anomalies_search'; -import { useGlobalTime } from '../../../../common/containers/use_global_time'; -import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; -import { useQueryInspector } from '../../../../common/components/page/manage_query'; -import { ENTITY_ANALYTICS_ANOMALIES_PANEL } from '../anomalies'; -import { isJobStarted } from '../../../../../common/machine_learning/helpers'; -import { FormattedCount } from '../../../../common/components/formatted_number'; -import { SEVERITY_COLOR } from '../../detection_response/utils'; -import { useGlobalFilterQuery } from '../../../../common/hooks/use_global_filter_query'; +import { getTabsOnHostsUrl } from '../../../common/components/link_to/redirect_to_hosts'; +import { SecurityPageName } from '../../../app/types'; +import { HostsTableType, HostsType } from '../../../explore/hosts/store/model'; +import { hostsActions } from '../../../explore/hosts/store'; +import { usersActions } from '../../../explore/users/store'; +import { getTabsOnUsersUrl } from '../../../common/components/link_to/redirect_to_users'; +import { UsersTableType } from '../../../explore/users/store/model'; +import { useAggregatedAnomaliesByJob } from '../../../common/components/ml/anomaly/use_anomalies_search'; +import { useGlobalTime } from '../../../common/containers/use_global_time'; +import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities'; +import { useQueryInspector } from '../../../common/components/page/manage_query'; +import { ENTITY_ANALYTICS_ANOMALIES_PANEL } from '../entity_analytics_anomalies'; +import { isJobStarted } from '../../../../common/machine_learning/helpers'; +import { FormattedCount } from '../../../common/components/formatted_number'; +import { useGlobalFilterQuery } from '../../../common/hooks/use_global_filter_query'; +import { useRiskScoreKpi } from '../../api/hooks/use_risk_score_kpi'; const StyledEuiTitle = styled(EuiTitle)` - color: ${({ theme: { eui } }) => SEVERITY_COLOR.critical}; + color: ${SEVERITY_COLOR.critical}; `; const HOST_RISK_QUERY_ID = 'hostRiskScoreKpiQuery'; diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_header/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/translations.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_header/translations.ts diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/__mocks__/index.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/__mocks__/index.ts similarity index 82% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/__mocks__/index.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/__mocks__/index.ts index bf863d0011ad38..19f3a03e41c037 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/__mocks__/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { RiskSeverity } from '../../../../../../common/search_strategy/security_solution'; +import { RiskSeverity } from '../../../../../common/search_strategy/security_solution'; export const mockSeverityCount = { [RiskSeverity.unknown]: 1, diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/chart_content.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/chart_content.test.tsx similarity index 79% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/chart_content.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/chart_content.test.tsx index 69816567f90cab..e346e999f8bd18 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/chart_content.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/chart_content.test.tsx @@ -7,20 +7,20 @@ import { render } from '@testing-library/react'; import React from 'react'; -import { RiskScoreEntity, RiskSeverity } from '../../../../../common/search_strategy'; -import { VisualizationEmbeddable } from '../../../../common/components/visualization_actions/visualization_embeddable'; -import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; -import { useSpaceId } from '../../../../common/hooks/use_space_id'; -import { TestProviders } from '../../../../common/mock'; -import { generateSeverityFilter } from '../../../../explore/hosts/store/helpers'; +import { RiskScoreEntity, RiskSeverity } from '../../../../common/search_strategy'; +import { VisualizationEmbeddable } from '../../../common/components/visualization_actions/visualization_embeddable'; +import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; +import { useSpaceId } from '../../../common/hooks/use_space_id'; +import { TestProviders } from '../../../common/mock'; +import { generateSeverityFilter } from '../../../explore/hosts/store/helpers'; import { ChartContent } from './chart_content'; import { mockSeverityCount } from './__mocks__'; -jest.mock('../../../../common/components/visualization_actions/visualization_embeddable'); -jest.mock('../../../../common/hooks/use_experimental_features', () => ({ +jest.mock('../../../common/components/visualization_actions/visualization_embeddable'); +jest.mock('../../../common/hooks/use_experimental_features', () => ({ useIsExperimentalFeatureEnabled: jest.fn(), })); -jest.mock('../../../../common/hooks/use_space_id', () => ({ +jest.mock('../../../common/hooks/use_space_id', () => ({ useSpaceId: jest.fn(), })); describe('ChartContent', () => { diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/chart_content.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/chart_content.tsx similarity index 66% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/chart_content.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/chart_content.tsx index 8f03cb08594aad..78828b1c769724 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/chart_content.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/chart_content.tsx @@ -6,16 +6,16 @@ */ import React, { useMemo } from 'react'; -import type { RiskScoreEntity, RiskSeverity } from '../../../../../common/search_strategy'; -import { EMPTY_SEVERITY_COUNT } from '../../../../../common/search_strategy'; -import { getRiskScoreDonutAttributes } from '../../../../common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_donut'; -import { VisualizationEmbeddable } from '../../../../common/components/visualization_actions/visualization_embeddable'; -import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; -import { useSpaceId } from '../../../../common/hooks/use_space_id'; -import type { SeverityCount } from '../../../../explore/components/risk_score/severity/types'; -import { generateSeverityFilter } from '../../../../explore/hosts/store/helpers'; -import { RiskScoreDonutChart } from '../common/risk_score_donut_chart'; -import { TOTAL_LABEL } from '../common/translations'; +import { i18n } from '@kbn/i18n'; +import type { RiskScoreEntity, RiskSeverity } from '../../../../common/search_strategy'; +import { EMPTY_SEVERITY_COUNT } from '../../../../common/search_strategy'; +import { VisualizationEmbeddable } from '../../../common/components/visualization_actions/visualization_embeddable'; +import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; +import { useSpaceId } from '../../../common/hooks/use_space_id'; +import type { SeverityCount } from '../severity/types'; +import { generateSeverityFilter } from '../../../explore/hosts/store/helpers'; +import { RiskScoreDonutChart } from '../risk_score_donut_chart'; +import { getRiskScoreDonutAttributes } from '../../lens_attributes/risk_score_donut'; const CHART_HEIGHT = 180; const ChartContentComponent = ({ @@ -56,7 +56,12 @@ const ChartContentComponent = ({ height={CHART_HEIGHT} id={`${kpiQueryId}-donut`} isDonut={true} - label={TOTAL_LABEL} + label={i18n.translate( + 'xpack.securitySolution.entityAnalytics.riskScore.chart.totalLabel', + { + defaultMessage: 'Total', + } + )} stackByField={riskEntity} timerange={timerange} width="270px" diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/columns.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/columns.tsx similarity index 85% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/columns.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/columns.tsx index 120a4cf3d4c7f5..e5926c2df7b4f3 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/columns.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/columns.tsx @@ -9,28 +9,28 @@ import React from 'react'; import type { EuiBasicTableColumn } from '@elastic/eui'; import { EuiLink } from '@elastic/eui'; import styled from 'styled-components'; -import { UsersTableType } from '../../../../explore/users/store/model'; -import { getEmptyTagValue } from '../../../../common/components/empty_value'; -import { HostDetailsLink, UserDetailsLink } from '../../../../common/components/links'; -import { HostsTableType } from '../../../../explore/hosts/store/model'; -import { RiskScoreLevel } from '../../../../explore/components/risk_score/severity/common'; -import { CELL_ACTIONS_TELEMETRY } from '../../../../explore/components/risk_score/constants'; +import { UsersTableType } from '../../../explore/users/store/model'; +import { getEmptyTagValue } from '../../../common/components/empty_value'; +import { HostDetailsLink, UserDetailsLink } from '../../../common/components/links'; +import { HostsTableType } from '../../../explore/hosts/store/model'; +import { RiskScoreLevel } from '../severity/common'; +import { CELL_ACTIONS_TELEMETRY } from '../risk_score/constants'; import type { HostRiskScore, Maybe, RiskSeverity, UserRiskScore, -} from '../../../../../common/search_strategy'; -import { RiskScoreEntity, RiskScoreFields } from '../../../../../common/search_strategy'; +} from '../../../../common/search_strategy'; +import { RiskScoreEntity, RiskScoreFields } from '../../../../common/search_strategy'; import * as i18n from './translations'; -import { FormattedCount } from '../../../../common/components/formatted_number'; +import { FormattedCount } from '../../../common/components/formatted_number'; import { SecurityCellActions, CellActionsMode, SecurityCellActionsTrigger, SecurityCellActionType, -} from '../../../../common/components/cell_actions'; -import { FormattedRelativePreferenceDate } from '../../../../common/components/formatted_date'; +} from '../../../common/components/cell_actions'; +import { FormattedRelativePreferenceDate } from '../../../common/components/formatted_date'; type HostRiskScoreColumns = Array<EuiBasicTableColumn<HostRiskScore & UserRiskScore>>; diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/header_content.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/header_content.test.tsx similarity index 86% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/header_content.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/header_content.test.tsx index d6e7c39b4fada4..b4f24e0d27d6f9 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/header_content.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/header_content.test.tsx @@ -7,14 +7,14 @@ import type { RenderResult } from '@testing-library/react'; import { render } from '@testing-library/react'; import React from 'react'; -import { SecurityPageName } from '../../../../../common/constants'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { useGetSecuritySolutionLinkProps } from '../../../../common/components/links'; +import { SecurityPageName } from '../../../../common/constants'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; +import { useGetSecuritySolutionLinkProps } from '../../../common/components/links'; import { RiskScoreHeaderContent } from './header_content'; import { mockSeverityCount } from './__mocks__'; -jest.mock('../../../../common/components/links', () => { - const actual = jest.requireActual('../../../../common/components/links'); +jest.mock('../../../common/components/links', () => { + const actual = jest.requireActual('../../../common/components/links'); return { ...actual, useGetSecuritySolutionLinkProps: jest.fn(), diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/header_content.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/header_content.tsx similarity index 80% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/header_content.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/header_content.tsx index e9b1f56c6e0ec0..10b94b95a886ff 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/header_content.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/header_content.tsx @@ -6,14 +6,14 @@ */ import React, { useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import type { RiskSeverity, RiskScoreEntity } from '../../../../../common/search_strategy'; -import { SeverityFilterGroup } from '../../../../explore/components/risk_score/severity/severity_filter_group'; -import type { SeverityCount } from '../../../../explore/components/risk_score/severity/types'; -import { EMPTY_SEVERITY_COUNT } from '../../../../../common/search_strategy'; -import { LinkButton, useGetSecuritySolutionLinkProps } from '../../../../common/components/links'; -import type { SecurityPageName } from '../../../../../common/constants'; +import type { RiskSeverity, RiskScoreEntity } from '../../../../common/search_strategy'; +import { SeverityFilterGroup } from '../severity/severity_filter_group'; +import type { SeverityCount } from '../severity/types'; +import { EMPTY_SEVERITY_COUNT } from '../../../../common/search_strategy'; +import { LinkButton, useGetSecuritySolutionLinkProps } from '../../../common/components/links'; +import type { SecurityPageName } from '../../../../common/constants'; import * as i18n from './translations'; -import { RiskInformationButtonEmpty } from '../../../../explore/components/risk_score/risk_information'; +import { RiskInformationButtonEmpty } from '../risk_information'; const RiskScoreHeaderContentComponent = ({ entityLinkProps, diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.test.tsx similarity index 87% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.test.tsx index 8af9349d9bceac..d9a265e662a7ee 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.test.tsx @@ -7,18 +7,19 @@ import { render, fireEvent, waitFor } from '@testing-library/react'; import React from 'react'; -import { TestProviders } from '../../../../common/mock'; +import { TestProviders } from '../../../common/mock'; import { EntityAnalyticsRiskScores } from '.'; -import { RiskScoreEntity, RiskSeverity } from '../../../../../common/search_strategy'; -import type { SeverityCount } from '../../../../explore/components/risk_score/severity/types'; -import { useRiskScore, useRiskScoreKpi } from '../../../../explore/containers/risk_score'; -import { useKibana as mockUseKibana } from '../../../../common/lib/kibana/__mocks__'; -import { createTelemetryServiceMock } from '../../../../common/lib/telemetry/telemetry_service.mock'; +import { RiskScoreEntity, RiskSeverity } from '../../../../common/search_strategy'; +import type { SeverityCount } from '../severity/types'; +import { useKibana as mockUseKibana } from '../../../common/lib/kibana/__mocks__'; +import { createTelemetryServiceMock } from '../../../common/lib/telemetry/telemetry_service.mock'; +import { useRiskScore } from '../../api/hooks/use_risk_score'; +import { useRiskScoreKpi } from '../../api/hooks/use_risk_score_kpi'; const mockedTelemetry = createTelemetryServiceMock(); const mockedUseKibana = mockUseKibana(); -jest.mock('../../../../common/lib/kibana', () => { - const original = jest.requireActual('../../../../common/lib/kibana'); +jest.mock('../../../common/lib/kibana', () => { + const original = jest.requireActual('../../../common/lib/kibana'); return { ...original, @@ -43,7 +44,7 @@ const mockSeverityCount: SeverityCount = { const mockUseQueryToggle = jest .fn() .mockReturnValue({ toggleStatus: false, setToggleStatus: jest.fn() }); -jest.mock('../../../../common/containers/query_toggle', () => { +jest.mock('../../../common/containers/query_toggle', () => { return { useQueryToggle: () => mockUseQueryToggle(), }; @@ -58,16 +59,17 @@ const defaultProps = { }; const mockUseRiskScore = useRiskScore as jest.Mock; const mockUseRiskScoreKpi = useRiskScoreKpi as jest.Mock; -jest.mock('../../../../explore/containers/risk_score'); +jest.mock('../../api/hooks/use_risk_score'); +jest.mock('../../api/hooks/use_risk_score_kpi'); const mockOpenAlertsPageWithFilters = jest.fn(); -jest.mock('../../../../common/hooks/use_navigate_to_alerts_page_with_filters', () => { +jest.mock('../../../common/hooks/use_navigate_to_alerts_page_with_filters', () => { return { useNavigateToAlertsPageWithFilters: () => mockOpenAlertsPageWithFilters, }; }); -jest.mock('../../../../common/components/hover_actions', () => ({ HoverActions: () => null })); +jest.mock('../../../common/components/hover_actions', () => ({ HoverActions: () => null })); describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( 'EntityAnalyticsRiskScores entityType: %s', diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.tsx similarity index 77% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.tsx index 97cf4363f690da..ce695e75f58f16 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.tsx @@ -7,32 +7,32 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { EnableRiskScore } from '../../../../explore/components/risk_score/enable_risk_score'; +import { EnableRiskScore } from '../enable_risk_score'; import { getRiskScoreColumns } from './columns'; -import { LastUpdatedAt } from '../../../../common/components/last_updated_at'; -import { HeaderSection } from '../../../../common/components/header_section'; -import { useRiskScore, useRiskScoreKpi } from '../../../../explore/containers/risk_score'; - -import type { RiskSeverity } from '../../../../../common/search_strategy'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { generateSeverityFilter } from '../../../../explore/hosts/store/helpers'; -import { useQueryInspector } from '../../../../common/components/page/manage_query'; -import { useGlobalTime } from '../../../../common/containers/use_global_time'; -import { InspectButtonContainer } from '../../../../common/components/inspect'; -import { useQueryToggle } from '../../../../common/containers/query_toggle'; -import { StyledBasicTable } from '../common/styled_basic_table'; -import { RiskScoreHeaderTitle } from '../../../../explore/components/risk_score/risk_score_onboarding/risk_score_header_title'; -import { RiskScoresNoDataDetected } from '../../../../explore/components/risk_score/risk_score_onboarding/risk_score_no_data_detected'; -import { useRefetchQueries } from '../../../../common/hooks/use_refetch_queries'; -import { Loader } from '../../../../common/components/loader'; -import { Panel } from '../../../../common/components/panel'; +import { LastUpdatedAt } from '../../../common/components/last_updated_at'; +import { HeaderSection } from '../../../common/components/header_section'; +import type { RiskSeverity } from '../../../../common/search_strategy'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; +import { generateSeverityFilter } from '../../../explore/hosts/store/helpers'; +import { useQueryInspector } from '../../../common/components/page/manage_query'; +import { useGlobalTime } from '../../../common/containers/use_global_time'; +import { InspectButtonContainer } from '../../../common/components/inspect'; +import { useQueryToggle } from '../../../common/containers/query_toggle'; +import { StyledBasicTable } from '../styled_basic_table'; +import { RiskScoreHeaderTitle } from '../risk_score_onboarding/risk_score_header_title'; +import { RiskScoresNoDataDetected } from '../risk_score_onboarding/risk_score_no_data_detected'; +import { useRefetchQueries } from '../../../common/hooks/use_refetch_queries'; +import { Loader } from '../../../common/components/loader'; +import { Panel } from '../../../common/components/panel'; import { useEntityInfo } from './use_entity'; import { RiskScoreHeaderContent } from './header_content'; import { ChartContent } from './chart_content'; -import { useNavigateToAlertsPageWithFilters } from '../../../../common/hooks/use_navigate_to_alerts_page_with_filters'; +import { useNavigateToAlertsPageWithFilters } from '../../../common/hooks/use_navigate_to_alerts_page_with_filters'; import { getRiskEntityTranslation } from './translations'; -import { useKibana } from '../../../../common/lib/kibana'; -import { useGlobalFilterQuery } from '../../../../common/hooks/use_global_filter_query'; +import { useKibana } from '../../../common/lib/kibana'; +import { useGlobalFilterQuery } from '../../../common/hooks/use_global_filter_query'; +import { useRiskScoreKpi } from '../../api/hooks/use_risk_score_kpi'; +import { useRiskScore } from '../../api/hooks/use_risk_score'; const EntityAnalyticsRiskScoresComponent = ({ riskEntity }: { riskEntity: RiskScoreEntity }) => { const { deleteQuery, setQuery, from, to } = useGlobalTime(); diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/translations.ts similarity index 82% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/translations.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/translations.ts index 22fe8a3d528236..5816accea220aa 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/translations.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/translations.ts @@ -6,9 +6,9 @@ */ import { i18n } from '@kbn/i18n'; -import { getRiskEntityTranslation } from '../../../../explore/components/risk_score/translations'; -import type { RiskScoreEntity } from '../../../../../common/search_strategy'; -export * from '../../../../explore/components/risk_score/translations'; +import { getRiskEntityTranslation } from '../risk_score/translations'; +import type { RiskScoreEntity } from '../../../../common/search_strategy'; +export * from '../risk_score/translations'; export const ENTITY_NAME = (riskEntity: RiskScoreEntity) => i18n.translate('xpack.securitySolution.entityAnalytics.riskDashboard.nameTitle', { diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/use_entity.test.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/use_entity.test.ts similarity index 93% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/use_entity.test.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/use_entity.test.ts index 3e0f475d47fa98..25d772c26762ce 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/use_entity.test.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/use_entity.test.ts @@ -6,7 +6,7 @@ */ import { renderHook } from '@testing-library/react-hooks'; -import { RiskScoreEntity } from '../../../../../common/search_strategy/security_solution/risk_score'; +import { RiskScoreEntity } from '../../../../common/search_strategy/security_solution/risk_score'; import { useEntityInfo } from './use_entity'; jest.mock('react-redux', () => { diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/use_entity.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/use_entity.ts similarity index 71% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/use_entity.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/use_entity.ts index dc5d947ad44954..3b3640a7cecae6 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/use_entity.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/use_entity.ts @@ -5,16 +5,16 @@ * 2.0. */ import { useDispatch } from 'react-redux'; -import { getTabsOnUsersUrl } from '../../../../common/components/link_to/redirect_to_users'; -import { UsersTableType } from '../../../../explore/users/store/model'; +import { getTabsOnUsersUrl } from '../../../common/components/link_to/redirect_to_users'; +import { UsersTableType } from '../../../explore/users/store/model'; -import { getTabsOnHostsUrl } from '../../../../common/components/link_to/redirect_to_hosts'; -import { HostsTableType, HostsType } from '../../../../explore/hosts/store/model'; +import { getTabsOnHostsUrl } from '../../../common/components/link_to/redirect_to_hosts'; +import { HostsTableType, HostsType } from '../../../explore/hosts/store/model'; -import { RiskScoreEntity } from '../../../../../common/search_strategy/security_solution/risk_score'; -import { usersActions } from '../../../../explore/users/store'; -import { hostsActions } from '../../../../explore/hosts/store'; -import { SecurityPageName } from '../../../../app/types'; +import { RiskScoreEntity } from '../../../../common/search_strategy/security_solution/risk_score'; +import { usersActions } from '../../../explore/users/store'; +import { hostsActions } from '../../../explore/hosts/store'; +import { SecurityPageName } from '../../../app/types'; const HOST_RISK_TABLE_QUERY_ID = 'hostRiskDashboardTable'; const HOST_RISK_KPI_QUERY_ID = 'headerHostRiskScoreKpiQuery'; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/action_column.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/components/action_column.test.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/action_column.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/components/action_column.test.tsx index 9df74c2d608460..d5ff5425ccaa6b 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/action_column.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/components/action_column.test.tsx @@ -8,8 +8,8 @@ import { fireEvent, render } from '@testing-library/react'; import React from 'react'; import { TestProviders } from '../../../../common/mock'; -import { ActionColumn } from './action_column'; import { alertDataMock } from '../mocks'; +import { ActionColumn } from './action_column'; describe('ActionColumn', () => { it('renders', () => { diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/action_column.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/components/action_column.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/action_column.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/components/action_column.tsx diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/utility_bar.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/components/utility_bar.test.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/utility_bar.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/components/utility_bar.test.tsx diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/utility_bar.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/components/utility_bar.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/components/utility_bar.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/components/utility_bar.tsx diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/hooks/use_risk_input_actions.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/hooks/use_risk_input_actions.ts similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/hooks/use_risk_input_actions.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/hooks/use_risk_input_actions.ts diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/hooks/use_risk_input_actions_panels.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/hooks/use_risk_input_actions_panels.test.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/hooks/use_risk_input_actions_panels.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/hooks/use_risk_input_actions_panels.test.tsx diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/hooks/use_risk_input_actions_panels.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/hooks/use_risk_input_actions_panels.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/hooks/use_risk_input_actions_panels.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/hooks/use_risk_input_actions_panels.tsx diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/index.tsx new file mode 100644 index 00000000000000..428f98530d55f8 --- /dev/null +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/index.tsx @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { PREFIX } from '../../../flyout/shared/test_ids'; +import { UserDetailsLeftPanelTab } from '../../../flyout/entity_details/user_details_left/tabs'; +import { RiskInputsTab } from './tabs/risk_inputs'; + +export const RISK_INPUTS_TAB_TEST_ID = `${PREFIX}RiskInputsTab` as const; + +export const getRiskInputTab = (alertIds: string[]) => ({ + id: UserDetailsLeftPanelTab.RISK_INPUTS, + 'data-test-subj': RISK_INPUTS_TAB_TEST_ID, + name: ( + <FormattedMessage + id="xpack.securitySolution.flyout.entityDetails.userDetails.riskInputs.tabLabel" + defaultMessage="Risk Inputs" + /> + ), + content: <RiskInputsTab alertIds={alertIds} />, +}); diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/mocks/index.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/mocks/index.ts similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/mocks/index.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/mocks/index.ts diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/risk_inputs.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/tabs/risk_inputs.test.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/risk_inputs.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/tabs/risk_inputs.test.tsx index efd47e50009c97..038d6f7d622d41 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/risk_inputs.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/tabs/risk_inputs.test.tsx @@ -9,8 +9,8 @@ import { fireEvent, render } from '@testing-library/react'; import React from 'react'; import { TestProviders } from '../../../../common/mock'; import { times } from 'lodash/fp'; -import { alertDataMock } from '../mocks'; import { RiskInputsTab } from './risk_inputs'; +import { alertDataMock } from '../mocks'; const mockUseAlertsByIds = jest.fn().mockReturnValue({ loading: false, data: [] }); diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/risk_inputs.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/tabs/risk_inputs.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/risk_inputs.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_details_flyout/tabs/risk_inputs.tsx diff --git a/x-pack/plugins/security_solution/public/explore/hosts/components/host_risk_score_table/columns.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/host_risk_score_table/columns.test.tsx similarity index 94% rename from x-pack/plugins/security_solution/public/explore/hosts/components/host_risk_score_table/columns.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/host_risk_score_table/columns.test.tsx index 98cfa4895fbd40..d439c627365a09 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/components/host_risk_score_table/columns.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/host_risk_score_table/columns.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { getHostRiskScoreColumns } from './columns'; -import { TestProviders } from '../../../../common/mock'; +import { TestProviders } from '../../../common/mock'; import type { HostRiskScoreColumns } from '.'; describe('getHostRiskScoreColumns', () => { diff --git a/x-pack/plugins/security_solution/public/explore/hosts/components/host_risk_score_table/columns.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/host_risk_score_table/columns.tsx similarity index 78% rename from x-pack/plugins/security_solution/public/explore/hosts/components/host_risk_score_table/columns.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/host_risk_score_table/columns.tsx index af6c0d502351e4..e1509a03a9a905 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/components/host_risk_score_table/columns.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/host_risk_score_table/columns.tsx @@ -11,18 +11,18 @@ import { SecurityCellActions, CellActionsMode, SecurityCellActionsTrigger, -} from '../../../../common/components/cell_actions'; -import { getEmptyTagValue } from '../../../../common/components/empty_value'; -import { HostDetailsLink } from '../../../../common/components/links'; +} from '../../../common/components/cell_actions'; +import { getEmptyTagValue } from '../../../common/components/empty_value'; +import { HostDetailsLink } from '../../../common/components/links'; import type { HostRiskScoreColumns } from '.'; import * as i18n from './translations'; -import { HostsTableType } from '../../store/model'; -import type { Maybe, RiskSeverity } from '../../../../../common/search_strategy'; -import { RiskScoreFields, RiskScoreEntity } from '../../../../../common/search_strategy'; -import { RiskScoreLevel } from '../../../components/risk_score/severity/common'; -import { ENTITY_RISK_LEVEL } from '../../../components/risk_score/translations'; -import { CELL_ACTIONS_TELEMETRY } from '../../../components/risk_score/constants'; -import { FormattedRelativePreferenceDate } from '../../../../common/components/formatted_date'; +import { HostsTableType } from '../../../explore/hosts/store/model'; +import type { Maybe, RiskSeverity } from '../../../../common/search_strategy'; +import { RiskScoreFields, RiskScoreEntity } from '../../../../common/search_strategy'; +import { RiskScoreLevel } from '../severity/common'; +import { ENTITY_RISK_LEVEL } from '../risk_score/translations'; +import { CELL_ACTIONS_TELEMETRY } from '../risk_score/constants'; +import { FormattedRelativePreferenceDate } from '../../../common/components/formatted_date'; export const getHostRiskScoreColumns = ({ dispatchSeverityUpdate, diff --git a/x-pack/plugins/security_solution/public/explore/hosts/components/host_risk_score_table/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/host_risk_score_table/index.tsx similarity index 85% rename from x-pack/plugins/security_solution/public/explore/hosts/components/host_risk_score_table/index.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/host_risk_score_table/index.tsx index 9c486c96fdece8..5dca054f013cd9 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/components/host_risk_score_table/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/host_risk_score_table/index.tsx @@ -9,10 +9,10 @@ import React, { useMemo, useCallback } from 'react'; import { useDispatch } from 'react-redux'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import type { Columns, Criteria, ItemsPerRow } from '../../../components/paginated_table'; -import { PaginatedTable } from '../../../components/paginated_table'; -import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; -import { hostsActions, hostsModel, hostsSelectors } from '../../store'; +import type { Columns, Criteria, ItemsPerRow } from '../../../explore/components/paginated_table'; +import { PaginatedTable } from '../../../explore/components/paginated_table'; +import { useDeepEqualSelector } from '../../../common/hooks/use_selector'; +import { hostsActions, hostsModel, hostsSelectors } from '../../../explore/hosts/store'; import { getHostRiskScoreColumns } from './columns'; import type { HostRiskScore, @@ -20,18 +20,18 @@ import type { RiskScoreSortField, RiskSeverity, RiskScoreFields, -} from '../../../../../common/search_strategy'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import type { State } from '../../../../common/store'; -import * as i18n from '../hosts_table/translations'; +} from '../../../../common/search_strategy'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; +import type { State } from '../../../common/store'; +import * as i18n from '../../../explore/hosts/components/hosts_table/translations'; import * as i18nHosts from './translations'; -import { SeverityBadges } from '../../../components/risk_score/severity/severity_badges'; -import { SeverityBar } from '../../../components/risk_score/severity/severity_bar'; -import { SeverityFilterGroup } from '../../../components/risk_score/severity/severity_filter_group'; +import { SeverityBadges } from '../severity/severity_badges'; +import { SeverityBar } from '../severity/severity_bar'; +import { SeverityFilterGroup } from '../severity/severity_filter_group'; -import type { SeverityCount } from '../../../components/risk_score/severity/types'; -import { RiskInformationButtonEmpty } from '../../../components/risk_score/risk_information'; +import type { SeverityCount } from '../severity/types'; +import { RiskInformationButtonEmpty } from '../risk_information'; export const rowItems: ItemsPerRow[] = [ { diff --git a/x-pack/plugins/security_solution/public/explore/hosts/components/host_risk_score_table/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/host_risk_score_table/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/explore/hosts/components/host_risk_score_table/translations.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/host_risk_score_table/translations.ts diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_details_tab_body/index.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.test.tsx similarity index 84% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_details_tab_body/index.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.test.tsx index d446645a739daa..c521542f1f7b1a 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_details_tab_body/index.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.test.tsx @@ -7,18 +7,17 @@ import React from 'react'; import { render } from '@testing-library/react'; -import { TestProviders } from '../../../../common/mock'; -import { useQueryToggle } from '../../../../common/containers/query_toggle'; - -import { useRiskScore } from '../../../containers/risk_score'; +import { TestProviders } from '../../../common/mock'; +import { useQueryToggle } from '../../../common/containers/query_toggle'; import { RiskDetailsTabBody } from '.'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { HostsType } from '../../../hosts/store/model'; -import { UsersType } from '../../../users/store/model'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; +import { HostsType } from '../../../explore/hosts/store/model'; +import { UsersType } from '../../../explore/users/store/model'; +import { useRiskScore } from '../../api/hooks/use_risk_score'; -jest.mock('../../../containers/risk_score'); -jest.mock('../../../../common/containers/query_toggle'); -jest.mock('../../../../common/lib/kibana'); +jest.mock('../../api/hooks/use_risk_score'); +jest.mock('../../../common/containers/query_toggle'); +jest.mock('../../../common/lib/kibana'); describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( 'Risk Tab Body entityType: %s', diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_details_tab_body/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.tsx similarity index 85% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_details_tab_body/index.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.tsx index 37b61a86fbea3c..ed132ade204dd5 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_details_tab_body/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.tsx @@ -9,33 +9,30 @@ import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; -import { RISKY_HOSTS_DASHBOARD_TITLE, RISKY_USERS_DASHBOARD_TITLE } from '../constants'; +import { RISKY_HOSTS_DASHBOARD_TITLE, RISKY_USERS_DASHBOARD_TITLE } from '../risk_score/constants'; import { EnableRiskScore } from '../enable_risk_score'; -import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; -import type { State } from '../../../../common/store'; -import { hostsModel, hostsSelectors } from '../../../hosts/store'; -import { usersSelectors } from '../../../users/store'; +import { useDeepEqualSelector } from '../../../common/hooks/use_selector'; +import type { State } from '../../../common/store'; +import { hostsModel, hostsSelectors } from '../../../explore/hosts/store'; +import { usersSelectors } from '../../../explore/users/store'; import { RiskInformationButtonEmpty } from '../risk_information'; import * as i18n from './translations'; -import { useQueryInspector } from '../../../../common/components/page/manage_query'; +import { useQueryInspector } from '../../../common/components/page/manage_query'; import { RiskScoreOverTime } from '../risk_score_over_time'; import { TopRiskScoreContributors } from '../top_risk_score_contributors'; import { TopRiskScoreContributorsAlerts } from '../top_risk_score_contributors_alerts'; -import { useQueryToggle } from '../../../../common/containers/query_toggle'; -import { - HostRiskScoreQueryId, - UserRiskScoreQueryId, - useRiskScore, -} from '../../../containers/risk_score'; -import type { HostRiskScore, UserRiskScore } from '../../../../../common/search_strategy'; -import { buildEntityNameFilter, RiskScoreEntity } from '../../../../../common/search_strategy'; -import type { UsersComponentsQueryProps } from '../../../users/pages/navigation/types'; -import type { HostsComponentsQueryProps } from '../../../hosts/pages/navigation/types'; -import { useDashboardHref } from '../../../../common/hooks/use_dashboard_href'; +import { useQueryToggle } from '../../../common/containers/query_toggle'; +import type { HostRiskScore, UserRiskScore } from '../../../../common/search_strategy'; +import { buildEntityNameFilter, RiskScoreEntity } from '../../../../common/search_strategy'; +import type { UsersComponentsQueryProps } from '../../../explore/users/pages/navigation/types'; +import type { HostsComponentsQueryProps } from '../../../explore/hosts/pages/navigation/types'; +import { useDashboardHref } from '../../../common/hooks/use_dashboard_href'; import { RiskScoresNoDataDetected } from '../risk_score_onboarding/risk_score_no_data_detected'; -import { useRiskEngineStatus } from '../../../../entity_analytics/api/hooks/use_risk_engine_status'; -import { RiskScoreUpdatePanel } from '../../../../entity_analytics/components/risk_score_update_panel'; +import { useRiskEngineStatus } from '../../api/hooks/use_risk_engine_status'; +import { RiskScoreUpdatePanel } from '../risk_score_update_panel'; +import { HostRiskScoreQueryId, UserRiskScoreQueryId } from '../../common/utils'; +import { useRiskScore } from '../../api/hooks/use_risk_score'; const StyledEuiFlexGroup = styled(EuiFlexGroup)` margin-top: ${({ theme }) => theme.eui.euiSizeL}; diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_details_tab_body/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/translations.ts similarity index 83% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_details_tab_body/translations.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/translations.ts index 4a98a8fc749d4e..f24f0716e4eb82 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_details_tab_body/translations.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/translations.ts @@ -6,8 +6,8 @@ */ import { i18n } from '@kbn/i18n'; -import type { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { getRiskEntityTranslation } from '../translations'; +import type { RiskScoreEntity } from '../../../../common/search_strategy'; +import { getRiskEntityTranslation } from '../risk_score/translations'; export const RISK_SCORE_OVER_TIME = (riskEntity: RiskScoreEntity) => i18n.translate('xpack.securitySolution.riskTabBody.scoreOverTimeTitle', { diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/index.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_information/index.test.tsx similarity index 92% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/index.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_information/index.test.tsx index 19e21a57e5559e..44aee022f2f537 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/index.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_information/index.test.tsx @@ -8,8 +8,8 @@ import { render, fireEvent } from '@testing-library/react'; import React from 'react'; import { RiskInformationButtonEmpty, RiskInformationButtonIcon } from '.'; -import { TestProviders } from '../../../../common/mock'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; +import { TestProviders } from '../../../common/mock'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( 'Risk Information entityType: %s', diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_information/index.tsx similarity index 98% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/index.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_information/index.tsx index bd099341419f0b..888854cebeb51b 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_information/index.tsx @@ -30,9 +30,9 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { css } from '@emotion/react'; import * as i18n from './translations'; -import { useOnOpenCloseHandler } from '../../../../helper_hooks'; +import { useOnOpenCloseHandler } from '../../../helper_hooks'; import { RiskScoreLevel } from '../severity/common'; -import { RiskScoreEntity, RiskSeverity } from '../../../../../common/search_strategy'; +import { RiskScoreEntity, RiskSeverity } from '../../../../common/search_strategy'; import { RiskScoreDocLink } from '../risk_score_onboarding/risk_score_doc_link'; import { BETA } from '../risk_score_onboarding/translations'; diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_information/translations.ts similarity index 91% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/translations.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_information/translations.ts index 20fa22bbc26f51..114da512b99744 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/translations.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_information/translations.ts @@ -6,8 +6,8 @@ */ import { i18n } from '@kbn/i18n'; -import type { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { getRiskEntityTranslation } from '../translations'; +import type { RiskScoreEntity } from '../../../../common/search_strategy'; +import { getRiskEntityTranslation } from '../risk_score/translations'; export const INFORMATION_LEVEL_HEADER = i18n.translate( 'xpack.securitySolution.riskInformation.levelHeader', diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/constants.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score/constants.ts similarity index 100% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/constants.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score/constants.ts diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/translations.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score/translations.ts diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/risk_score_donut_chart.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_donut_chart/index.test.tsx similarity index 78% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/risk_score_donut_chart.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_donut_chart/index.test.tsx index 1b93d6545d8383..30a05bcfef1264 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/risk_score_donut_chart.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_donut_chart/index.test.tsx @@ -5,12 +5,12 @@ * 2.0. */ -import { RiskSeverity } from '../../../../../common/search_strategy'; -import type { SeverityCount } from '../../../../explore/components/risk_score/severity/types'; +import { RiskSeverity } from '../../../../common/search_strategy'; +import type { SeverityCount } from '../severity/types'; import { render } from '@testing-library/react'; import React from 'react'; -import { RiskScoreDonutChart } from './risk_score_donut_chart'; -import { TestProviders } from '../../../../common/mock'; +import { RiskScoreDonutChart } from '.'; +import { TestProviders } from '../../../common/mock'; const severityCount: SeverityCount = { [RiskSeverity.low]: 1, diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/risk_score_donut_chart.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_donut_chart/index.tsx similarity index 67% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/risk_score_donut_chart.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_donut_chart/index.tsx index 2bb850e0c312c7..92ae592368ba58 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/risk_score_donut_chart.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_donut_chart/index.tsx @@ -8,16 +8,16 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React from 'react'; import styled from 'styled-components'; -import { RISK_SEVERITY_COLOUR } from '../../../../entity_analytics/common/utils'; -import type { SeverityCount } from '../../../../explore/components/risk_score/severity/types'; +import { i18n } from '@kbn/i18n'; +import { ChartLabel } from '../../../overview/components/detection_response/alerts_by_status/chart_label'; +import { RISK_SEVERITY_COLOUR } from '../../common/utils'; +import type { SeverityCount } from '../severity/types'; import { useRiskDonutChartData } from './use_risk_donut_chart_data'; -import type { FillColor } from '../../../../common/components/charts/donutchart'; -import { emptyDonutColor } from '../../../../common/components/charts/donutchart_empty'; -import { DonutChart } from '../../../../common/components/charts/donutchart'; -import { Legend } from '../../../../common/components/charts/legend'; -import { ChartLabel } from '../../detection_response/alerts_by_status/chart_label'; -import * as i18n from './translations'; -import type { RiskSeverity } from '../../../../../common/search_strategy'; +import type { FillColor } from '../../../common/components/charts/donutchart'; +import { emptyDonutColor } from '../../../common/components/charts/donutchart_empty'; +import { DonutChart } from '../../../common/components/charts/donutchart'; +import { Legend } from '../../../common/components/charts/legend'; +import type { RiskSeverity } from '../../../../common/search_strategy'; const DONUT_HEIGHT = 120; @@ -53,7 +53,10 @@ export const RiskScoreDonutChart = ({ severityCount }: RiskScoreDonutChartProps) data={donutChartData ?? null} fillColor={fillColor} height={DONUT_HEIGHT} - label={i18n.TOTAL_LABEL} + label={i18n.translate( + 'xpack.securitySolution.entityAnalytics.riskScore.donut_chart.totalLabel', + { defaultMessage: 'Total' } + )} title={<ChartLabel count={total} />} totalCount={total} /> diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/use_risk_donut_chart_data.test.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_donut_chart/use_risk_donut_chart_data.test.ts similarity index 88% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/use_risk_donut_chart_data.test.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_donut_chart/use_risk_donut_chart_data.test.ts index 2a7af3c2a28aae..933a9f98b5bea5 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/use_risk_donut_chart_data.test.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_donut_chart/use_risk_donut_chart_data.test.ts @@ -6,9 +6,9 @@ */ import { renderHook } from '@testing-library/react-hooks'; -import { RiskSeverity } from '../../../../../common/search_strategy'; +import { RiskSeverity } from '../../../../common/search_strategy'; import { useRiskDonutChartData } from './use_risk_donut_chart_data'; -import type { SeverityCount } from '../../../../explore/components/risk_score/severity/types'; +import type { SeverityCount } from '../severity/types'; describe('useRiskDonutChartData', () => { it('returns the total', () => { diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/use_risk_donut_chart_data.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_donut_chart/use_risk_donut_chart_data.ts similarity index 70% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/use_risk_donut_chart_data.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_donut_chart/use_risk_donut_chart_data.ts index 4b31142aef3c92..8505f229d893f7 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/use_risk_donut_chart_data.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_donut_chart/use_risk_donut_chart_data.ts @@ -6,11 +6,11 @@ */ import { sum } from 'lodash/fp'; import { useMemo } from 'react'; -import { RISK_SEVERITY_COLOUR } from '../../../../entity_analytics/common/utils'; -import type { LegendItem } from '../../../../common/components/charts/legend_item'; -import type { SeverityCount } from '../../../../explore/components/risk_score/severity/types'; -import type { DonutChartProps } from '../../../../common/components/charts/donutchart'; -import type { RiskSeverity } from '../../../../../common/search_strategy'; +import { RISK_SEVERITY_COLOUR } from '../../common/utils'; +import type { LegendItem } from '../../../common/components/charts/legend_item'; +import type { SeverityCount } from '../severity/types'; +import type { DonutChartProps } from '../../../common/components/charts/donutchart'; +import type { RiskSeverity } from '../../../../common/search_strategy'; const legendField = 'kibana.alert.severity'; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx index fa61a6c15b9e83..8e49e90c4cadd6 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx @@ -37,7 +37,7 @@ import { useEnableRiskEngineMutation } from '../api/hooks/use_enable_risk_engine import { useDisableRiskEngineMutation } from '../api/hooks/use_disable_risk_engine_mutation'; import { RiskEngineStatus, MAX_SPACES_COUNT } from '../../../common/entity_analytics/risk_engine'; -import { RiskInformationFlyout } from '../../explore/components/risk_score/risk_information'; +import { RiskInformationFlyout } from './risk_information'; import { useOnOpenCloseHandler } from '../../helper_hooks'; import type { RiskEngineMissingPrivilegesResponse } from '../hooks/use_missing_risk_engine_privileges'; diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_doc_link.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_doc_link.tsx similarity index 85% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_doc_link.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_doc_link.tsx index a54bb9e6276265..ca7b67134b29dc 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_doc_link.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_doc_link.tsx @@ -7,9 +7,9 @@ import { EuiLink } from '@elastic/eui'; import React, { useMemo } from 'react'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { LEARN_MORE } from '../../../../overview/components/entity_analytics/risk_score/translations'; -import { useKibana } from '../../../../common/lib/kibana'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; +import { useKibana } from '../../../common/lib/kibana'; +import { LEARN_MORE } from '../entity_analytics_risk_score/translations'; const useLearnMoreLinkForEntity = (riskScoreEntity?: RiskScoreEntity) => { const { docLinks } = useKibana().services; diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_enable_button.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_enable_button.test.tsx similarity index 89% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_enable_button.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_enable_button.test.tsx index a92496316c3ce3..92e022b55aeeb2 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_enable_button.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_enable_button.test.tsx @@ -6,8 +6,8 @@ */ import { render, screen } from '@testing-library/react'; import React from 'react'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { TestProviders } from '../../../../common/mock'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; +import { TestProviders } from '../../../common/mock'; import { RiskScoreEnableButton } from './risk_score_enable_button'; diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_enable_button.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_enable_button.tsx similarity index 81% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_enable_button.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_enable_button.tsx index 6e84308911eddb..e6242e75677c13 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_enable_button.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_enable_button.tsx @@ -9,16 +9,16 @@ import { EuiButton } from '@elastic/eui'; import React, { useCallback } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; -import type { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { useSpaceId } from '../../../../common/hooks/use_space_id'; -import { useKibana } from '../../../../common/lib/kibana'; -import type { inputsModel } from '../../../../common/store'; -import { REQUEST_NAMES, useFetch } from '../../../../common/hooks/use_fetch'; +import type { RiskScoreEntity } from '../../../../common/search_strategy'; +import { useSpaceId } from '../../../common/hooks/use_space_id'; +import { useKibana } from '../../../common/lib/kibana'; +import type { inputsModel } from '../../../common/store'; +import { REQUEST_NAMES, useFetch } from '../../../common/hooks/use_fetch'; import { useRiskScoreToastContent } from './use_risk_score_toast_content'; import { installRiskScoreModule } from './utils'; -import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; -import { SecuritySolutionLinkButton } from '../../../../common/components/links'; -import { SecurityPageName } from '../../../../../common/constants'; +import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; +import { SecuritySolutionLinkButton } from '../../../common/components/links'; +import { SecurityPageName } from '../../../../common/constants'; const RiskScoreEnableButtonComponent = ({ refetch, diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_header_title.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_header_title.tsx similarity index 53% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_header_title.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_header_title.tsx index 741469833f92d0..1ec4edd65fe3b4 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_header_title.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_header_title.tsx @@ -4,10 +4,11 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import React from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import * as i18n from '../../../../overview/components/entity_analytics/common/translations'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; const RiskScoreHeaderTitleComponent = ({ riskScoreEntity, @@ -18,7 +19,17 @@ const RiskScoreHeaderTitleComponent = ({ }) => ( <> {title ?? - (riskScoreEntity === RiskScoreEntity.user ? i18n.USER_RISK_TITLE : i18n.HOST_RISK_TITLE)} + (riskScoreEntity === RiskScoreEntity.user ? ( + <FormattedMessage + id="xpack.securitySolution.entityAnalytics.usersRiskDashboard.title" + defaultMessage="User Risk Scores" + /> + ) : ( + <FormattedMessage + id="xpack.securitySolution.entityAnalytics.hostsRiskDashboard.title" + defaultMessage="Host Risk Scores" + /> + ))} </> ); diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_no_data_detected.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_no_data_detected.tsx similarity index 84% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_no_data_detected.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_no_data_detected.tsx index 533a7d00729cd3..c7bd233c7030a3 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_no_data_detected.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_no_data_detected.tsx @@ -7,14 +7,14 @@ import { EuiEmptyPrompt, EuiPanel, EuiToolTip } from '@elastic/eui'; import React, { useMemo } from 'react'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; -import { HeaderSection } from '../../../../common/components/header_section'; +import { HeaderSection } from '../../../common/components/header_section'; import * as i18n from './translations'; import { RiskScoreHeaderTitle } from './risk_score_header_title'; import { RiskScoreRestartButton } from './risk_score_restart_button'; -import type { inputsModel } from '../../../../common/store'; -import { useIsNewRiskScoreModuleInstalled } from '../../../../entity_analytics/api/hooks/use_risk_engine_status'; +import type { inputsModel } from '../../../common/store'; +import { useIsNewRiskScoreModuleInstalled } from '../../api/hooks/use_risk_engine_status'; const RiskScoresNoDataDetectedComponent = ({ entityType, diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_restart_button.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_restart_button.test.tsx similarity index 94% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_restart_button.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_restart_button.test.tsx index d6785847cd833c..dbccdd9a0c0852 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_restart_button.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_restart_button.test.tsx @@ -7,8 +7,8 @@ import { act, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { TestProviders } from '../../../../common/mock'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; +import { TestProviders } from '../../../common/mock'; import { RiskScoreRestartButton } from './risk_score_restart_button'; import { restartRiskScoreTransforms } from './utils'; diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_restart_button.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_restart_button.tsx similarity index 83% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_restart_button.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_restart_button.tsx index be1f5b5d16621d..7f4316b77ee973 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_restart_button.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_restart_button.tsx @@ -9,11 +9,11 @@ import { EuiButton } from '@elastic/eui'; import React, { useCallback } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; -import type { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { useSpaceId } from '../../../../common/hooks/use_space_id'; -import { useKibana } from '../../../../common/lib/kibana'; -import type { inputsModel } from '../../../../common/store'; -import { REQUEST_NAMES, useFetch } from '../../../../common/hooks/use_fetch'; +import type { RiskScoreEntity } from '../../../../common/search_strategy'; +import { useSpaceId } from '../../../common/hooks/use_space_id'; +import { useKibana } from '../../../common/lib/kibana'; +import type { inputsModel } from '../../../common/store'; +import { REQUEST_NAMES, useFetch } from '../../../common/hooks/use_fetch'; import { useRiskScoreToastContent } from './use_risk_score_toast_content'; import { restartRiskScoreTransforms } from './utils'; diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/translations.ts similarity index 93% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/translations.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/translations.ts index 105036bd1be338..f8bcbf29725f9b 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/translations.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/translations.ts @@ -5,8 +5,8 @@ * 2.0. */ import { i18n } from '@kbn/i18n'; -import type { RiskScoreEntity } from '../../../../../common/entity_analytics/risk_engine'; -import { getRiskEntityTranslation } from '../translations'; +import type { RiskScoreEntity } from '../../../../common/entity_analytics/risk_engine'; +import { getRiskEntityTranslation } from '../risk_score/translations'; export const BETA = i18n.translate('xpack.securitySolution.riskScore.technicalPreviewLabel', { defaultMessage: 'Beta', diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/use_risk_score_toast_content.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/use_risk_score_toast_content.tsx similarity index 94% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/use_risk_score_toast_content.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/use_risk_score_toast_content.tsx index 60c00ab9d8cb63..7df01d9f8bd86e 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/use_risk_score_toast_content.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/use_risk_score_toast_content.tsx @@ -10,7 +10,7 @@ import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; import { FormattedMessage } from '@kbn/i18n-react'; -import type { RiskScoreEntity } from '../../../../../common/search_strategy'; +import type { RiskScoreEntity } from '../../../../common/search_strategy'; import { RiskScoreDocLink } from './risk_score_doc_link'; const StyledButton = styled(EuiButton)` diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/utils.test.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/utils.test.ts similarity index 94% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/utils.test.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/utils.test.ts index 770c5b8caf72d2..816ba871249d2c 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/utils.test.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/utils.test.ts @@ -5,26 +5,26 @@ * 2.0. */ import type { HttpSetup } from '@kbn/core/public'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; import { getIngestPipelineName, getLegacyIngestPipelineName, getRiskScoreLatestTransformId, getRiskScorePivotTransformId, -} from '../../../../../common/utils/risk_score_modules'; +} from '../../../../common/utils/risk_score_modules'; import { bulkDeletePrebuiltSavedObjects, bulkCreatePrebuiltSavedObjects, -} from '../../../containers/risk_score/onboarding/api'; +} from '../../deprecated_risk_engine/api'; -import * as api from '../../../containers/risk_score/onboarding/api'; +import * as api from '../../deprecated_risk_engine/api'; import { installRiskScoreModule, restartRiskScoreTransforms, uninstallRiskScoreModule, } from './utils'; -jest.mock('../../../containers/risk_score/onboarding/api'); +jest.mock('../../deprecated_risk_engine/api'); const mockHttp = { post: jest.fn(), diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/utils.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/utils.ts similarity index 96% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/utils.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/utils.ts index 65677900f979e2..f1e582e1ed847c 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/utils.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/utils.ts @@ -6,9 +6,9 @@ */ import type { HttpSetup, NotificationsStart, ThemeServiceStart } from '@kbn/core/public'; import type { DashboardStart } from '@kbn/dashboard-plugin/public'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import * as utils from '../../../../../common/utils/risk_score_modules'; -import type { inputsModel } from '../../../../common/store'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; +import * as utils from '../../../../common/utils/risk_score_modules'; +import type { inputsModel } from '../../../common/store'; import { deleteStoredScripts, @@ -19,12 +19,12 @@ import { bulkCreatePrebuiltSavedObjects, stopTransforms, startTransforms, -} from '../../../containers/risk_score/onboarding/api'; +} from '../../deprecated_risk_engine/api'; import { INGEST_PIPELINE_DELETION_ERROR_MESSAGE, TRANSFORM_DELETION_ERROR_MESSAGE, UNINSTALLATION_ERROR, -} from '../../../containers/risk_score/onboarding/api/translations'; +} from '../../deprecated_risk_engine/api/translations'; interface InstallRiskScoreModule { dashboard?: DashboardStart; diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_over_time/index.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_over_time/index.test.tsx similarity index 85% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_over_time/index.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_over_time/index.test.tsx index 109a51c1a829c1..22458a6d00fd11 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_over_time/index.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_over_time/index.test.tsx @@ -8,10 +8,10 @@ import { render } from '@testing-library/react'; import React from 'react'; import { RiskScoreOverTime, scoreFormatter } from '.'; -import { TestProviders } from '../../../../common/mock'; +import { TestProviders } from '../../../common/mock'; import { LineSeries } from '@elastic/charts'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; +import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; const mockLineSeries = LineSeries as jest.Mock; const mockUseIsExperimentalFeatureEnabled = useIsExperimentalFeatureEnabled as jest.Mock; @@ -23,11 +23,11 @@ jest.mock('@elastic/charts', () => { }; }); -jest.mock('../../../../common/hooks/use_experimental_features', () => ({ +jest.mock('../../../common/hooks/use_experimental_features', () => ({ useIsExperimentalFeatureEnabled: jest.fn(), })); -jest.mock('../../../../common/components/visualization_actions/visualization_embeddable'); -jest.mock('../../../../common/hooks/use_space_id', () => ({ +jest.mock('../../../common/components/visualization_actions/visualization_embeddable'); +jest.mock('../../../common/hooks/use_space_id', () => ({ useSpaceId: jest.fn().mockReturnValue('default'), })); diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_over_time/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_over_time/index.tsx similarity index 87% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_over_time/index.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_over_time/index.tsx index 96381b3681c8b6..210f578b36ad72 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_over_time/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_over_time/index.tsx @@ -22,23 +22,23 @@ import { EuiFlexGroup, EuiFlexItem, EuiLoadingChart, EuiText, EuiPanel } from '@ import styled from 'styled-components'; import { euiThemeVars } from '@kbn/ui-theme'; import { i18n } from '@kbn/i18n'; -import { chartDefaultSettings, useThemes } from '../../../../common/components/charts/common'; -import { useTimeZone } from '../../../../common/lib/kibana'; -import { histogramDateTimeFormatter } from '../../../../common/components/utils'; -import { HeaderSection } from '../../../../common/components/header_section'; -import { InspectButton, InspectButtonContainer } from '../../../../common/components/inspect'; +import { chartDefaultSettings, useThemes } from '../../../common/components/charts/common'; +import { useTimeZone } from '../../../common/lib/kibana'; +import { histogramDateTimeFormatter } from '../../../common/components/utils'; +import { HeaderSection } from '../../../common/components/header_section'; +import { InspectButton, InspectButtonContainer } from '../../../common/components/inspect'; import * as translations from './translations'; -import { PreferenceFormattedDate } from '../../../../common/components/formatted_date'; +import { PreferenceFormattedDate } from '../../../common/components/formatted_date'; import type { HostRiskScore, RiskScoreEntity, UserRiskScore, -} from '../../../../../common/search_strategy'; -import { isUserRiskScore } from '../../../../../common/search_strategy'; -import { useSpaceId } from '../../../../common/hooks/use_space_id'; -import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; -import { VisualizationEmbeddable } from '../../../../common/components/visualization_actions/visualization_embeddable'; -import { getRiskScoreOverTimeAreaAttributes } from '../../../../common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_over_time_area'; +} from '../../../../common/search_strategy'; +import { isUserRiskScore } from '../../../../common/search_strategy'; +import { useSpaceId } from '../../../common/hooks/use_space_id'; +import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; +import { VisualizationEmbeddable } from '../../../common/components/visualization_actions/visualization_embeddable'; +import { getRiskScoreOverTimeAreaAttributes } from '../../lens_attributes/risk_score_over_time_area'; export interface RiskScoreOverTimeProps { from: string; diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_over_time/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_over_time/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_over_time/translations.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_over_time/translations.ts diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_preview_table.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_preview_table.tsx index 05fa3c18809a6f..9b3a362e634953 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_preview_table.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_preview_table.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { EuiInMemoryTable } from '@elastic/eui'; import type { EuiBasicTableColumn } from '@elastic/eui'; import type { RiskSeverity } from '../../../common/search_strategy'; -import { RiskScoreLevel } from '../../explore/components/risk_score/severity/common'; +import { RiskScoreLevel } from './severity/common'; import { HostDetailsLink, UserDetailsLink } from '../../common/components/links'; import { diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/risk_summary.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary.test.tsx similarity index 89% rename from x-pack/plugins/security_solution/public/common/components/event_details/cti_details/risk_summary.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary.test.tsx index a02c7729f4e0ae..9bb495118385f0 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/risk_summary.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary.test.tsx @@ -8,12 +8,12 @@ import React from 'react'; import { render } from '@testing-library/react'; -import { TestProviders } from '../../../mock'; +import { TestProviders } from '../../common/mock'; import type { RiskEntity } from './risk_summary'; -import * as i18n from './translations'; +import * as i18n from '../../common/components/event_details/cti_details/translations'; import { RiskSummary } from './risk_summary'; -import { RiskScoreEntity, RiskSeverity } from '../../../../../common/search_strategy'; -import { getEmptyValue } from '../../empty_value'; +import { RiskScoreEntity, RiskSeverity } from '../../../common/search_strategy'; +import { getEmptyValue } from '../../common/components/empty_value'; describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( 'RiskSummary entityType: %s', diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/risk_summary.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary.tsx similarity index 80% rename from x-pack/plugins/security_solution/public/common/components/event_details/cti_details/risk_summary.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary.tsx index e0bc4637ea54b8..df3933ae50e5b7 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/risk_summary.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary.tsx @@ -8,15 +8,18 @@ import React from 'react'; import { EuiLoadingSpinner, EuiPanel } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import * as i18n from './translations'; -import { EnrichedDataRow, ThreatSummaryPanelHeader } from './threat_summary_view'; -import { RiskScoreLevel } from '../../../../explore/components/risk_score/severity/common'; -import type { RiskSeverity } from '../../../../../common/search_strategy'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import type { HostRisk, UserRisk } from '../../../../explore/containers/risk_score'; -import { getEmptyValue } from '../../empty_value'; -import { RiskScoreDocLink } from '../../../../explore/components/risk_score/risk_score_onboarding/risk_score_doc_link'; -import { RiskScoreHeaderTitle } from '../../../../explore/components/risk_score/risk_score_onboarding/risk_score_header_title'; +import * as i18n from '../../common/components/event_details/cti_details/translations'; +import { + EnrichedDataRow, + ThreatSummaryPanelHeader, +} from '../../common/components/event_details/cti_details/threat_summary_view'; +import { RiskScoreLevel } from './severity/common'; +import type { RiskSeverity } from '../../../common/search_strategy'; +import { RiskScoreEntity } from '../../../common/search_strategy'; +import { getEmptyValue } from '../../common/components/empty_value'; +import { RiskScoreDocLink } from './risk_score_onboarding/risk_score_doc_link'; +import { RiskScoreHeaderTitle } from './risk_score_onboarding/risk_score_header_title'; +import type { HostRisk, UserRisk } from '../api/types'; interface HostRiskEntity { originalRisk?: RiskSeverity | undefined; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.stories.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary_flyout/risk_summary.stories.tsx similarity index 86% rename from x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.stories.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary_flyout/risk_summary.stories.tsx index 06828be073f32f..0f00959845ff3e 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.stories.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary_flyout/risk_summary.stories.tsx @@ -9,8 +9,8 @@ import React from 'react'; import type { Story } from '@storybook/react'; import type { ExpandableFlyoutContextValue } from '@kbn/expandable-flyout/src/context'; import { ExpandableFlyoutContext } from '@kbn/expandable-flyout/src/context'; -import { StorybookProviders } from '../../../../common/mock/storybook_providers'; -import { mockRiskScoreState } from '../../../../timelines/components/side_panel/new_user_detail/__mocks__'; +import { StorybookProviders } from '../../../common/mock/storybook_providers'; +import { mockRiskScoreState } from '../../../timelines/components/side_panel/new_user_detail/__mocks__'; import { RiskSummary } from './risk_summary'; export default { diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary_flyout/risk_summary.test.tsx similarity index 90% rename from x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary_flyout/risk_summary.test.tsx index fb89ef61ad79f6..5862ac7cd94640 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary_flyout/risk_summary.test.tsx @@ -7,11 +7,11 @@ import { render } from '@testing-library/react'; import React from 'react'; -import { TestProviders } from '../../../../common/mock'; -import { mockRiskScoreState } from '../../user_right/mocks'; +import { TestProviders } from '../../../common/mock'; +import { mockRiskScoreState } from '../../../flyout/entity_details/user_right/mocks'; import { RiskSummary } from './risk_summary'; -jest.mock('../../../../common/components/visualization_actions/visualization_embeddable'); +jest.mock('../../../common/components/visualization_actions/visualization_embeddable'); describe('RiskSummary', () => { it('renders risk summary table', () => { diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary_flyout/risk_summary.tsx similarity index 90% rename from x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary_flyout/risk_summary.tsx index 09c57cc61e02b5..50259cd6ca1340 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/risk_summary.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_summary_flyout/risk_summary.tsx @@ -21,15 +21,15 @@ import { css } from '@emotion/react'; import { FormattedMessage } from '@kbn/i18n-react'; import { euiThemeVars } from '@kbn/ui-theme'; import { i18n } from '@kbn/i18n'; -import { InspectButton, InspectButtonContainer } from '../../../../common/components/inspect'; -import { ONE_WEEK_IN_HOURS } from '../../../../timelines/components/side_panel/new_user_detail/constants'; -import { FormattedRelativePreferenceDate } from '../../../../common/components/formatted_date'; -import { RiskScoreEntity } from '../../../../../common/entity_analytics/risk_engine'; -import type { RiskScoreState } from '../../../../explore/containers/risk_score'; -import { VisualizationEmbeddable } from '../../../../common/components/visualization_actions/visualization_embeddable'; -import { getRiskScoreSummaryAttributes } from '../../../../common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_summary'; -import { ExpandablePanel } from '../../../shared/components/expandable_panel'; -import { UserDetailsLeftPanelTab } from '../../user_detais_left/tabs'; +import { UserDetailsLeftPanelTab } from '../../../flyout/entity_details/user_details_left/tabs'; +import { InspectButton, InspectButtonContainer } from '../../../common/components/inspect'; +import { ONE_WEEK_IN_HOURS } from '../../../timelines/components/side_panel/new_user_detail/constants'; +import { FormattedRelativePreferenceDate } from '../../../common/components/formatted_date'; +import { RiskScoreEntity } from '../../../../common/entity_analytics/risk_engine'; +import { VisualizationEmbeddable } from '../../../common/components/visualization_actions/visualization_embeddable'; +import { ExpandablePanel } from '../../../flyout/shared/components/expandable_panel'; +import type { RiskScoreState } from '../../api/hooks/use_risk_score'; +import { getRiskScoreSummaryAttributes } from '../../lens_attributes/risk_score_summary'; export interface RiskSummaryProps { riskScoreData: RiskScoreState<RiskScoreEntity.user>; diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/severity/common/index.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/common/index.test.tsx similarity index 93% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/severity/common/index.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/severity/common/index.test.tsx index 9068c01a760ca3..c9b75129bb0a27 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/severity/common/index.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/common/index.test.tsx @@ -8,15 +8,15 @@ import { render } from '@testing-library/react'; import React from 'react'; -import { TestProviders } from '../../../../../common/mock'; +import { TestProviders } from '../../../../common/mock'; import type { EuiHealthProps } from '@elastic/eui'; import { EuiHealth } from '@elastic/eui'; import { euiThemeVars } from '@kbn/ui-theme'; -import { RiskSeverity } from '../../../../../../common/search_strategy'; +import { RiskSeverity } from '../../../../../common/search_strategy'; import { RiskScoreLevel } from '.'; -import { SEVERITY_COLOR } from '../../../../../overview/components/detection_response/utils'; +import { SEVERITY_COLOR } from '../../../../overview/components/detection_response/utils'; jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/severity/common/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/common/index.tsx similarity index 87% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/severity/common/index.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/severity/common/index.tsx index 9430690394b49d..0706eb117c5d74 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/severity/common/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/common/index.tsx @@ -12,9 +12,9 @@ import { EuiHealth, transparentize } from '@elastic/eui'; import styled, { css } from 'styled-components'; import { euiLightVars } from '@kbn/ui-theme'; -import { RISK_SEVERITY_COLOUR } from '../../../../../entity_analytics/common/utils'; -import { WithHoverActions } from '../../../../../common/components/with_hover_actions'; -import type { RiskSeverity } from '../../../../../../common/search_strategy'; +import { RISK_SEVERITY_COLOUR } from '../../../common/utils'; +import { WithHoverActions } from '../../../../common/components/with_hover_actions'; +import type { RiskSeverity } from '../../../../../common/search_strategy'; const RiskBadge = styled.div<{ $severity: RiskSeverity; $hideBackgroundColor: boolean }>` ${({ theme, $severity, $hideBackgroundColor }) => css` diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/severity/severity_badges.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_badges.tsx similarity index 91% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/severity/severity_badges.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_badges.tsx index 53c7e270f2e314..373a8dd5a56932 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/severity/severity_badges.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_badges.tsx @@ -7,8 +7,8 @@ import { EuiFlexGroup, EuiNotificationBadge, EuiFlexItem } from '@elastic/eui'; import React from 'react'; -import { RISK_SEVERITY_COLOUR } from '../../../../entity_analytics/common/utils'; -import type { RiskSeverity } from '../../../../../common/search_strategy'; +import { RISK_SEVERITY_COLOUR } from '../../common/utils'; +import type { RiskSeverity } from '../../../../common/search_strategy'; import { RiskScoreLevel } from './common'; import type { SeverityCount } from './types'; diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/severity/severity_bar.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_bar.tsx similarity index 90% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/severity/severity_bar.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_bar.tsx index 847488869bcd3b..149d8f2cf74b94 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/severity/severity_bar.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_bar.tsx @@ -9,8 +9,8 @@ import styled from 'styled-components'; import { EuiColorPaletteDisplay } from '@elastic/eui'; import React, { useMemo } from 'react'; -import { RISK_SEVERITY_COLOUR } from '../../../../entity_analytics/common/utils'; -import type { RiskSeverity } from '../../../../../common/search_strategy'; +import { RISK_SEVERITY_COLOUR } from '../../common/utils'; +import type { RiskSeverity } from '../../../../common/search_strategy'; import type { SeverityCount } from './types'; const StyledEuiColorPaletteDisplay = styled(EuiColorPaletteDisplay)` diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/severity/severity_filter_group.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_filter_group.test.tsx similarity index 91% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/severity/severity_filter_group.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_filter_group.test.tsx index 07297f9af4042e..ef978fdf80546b 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/severity/severity_filter_group.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_filter_group.test.tsx @@ -7,12 +7,12 @@ import React from 'react'; import { render, fireEvent } from '@testing-library/react'; import { SeverityFilterGroup } from './severity_filter_group'; -import { RiskScoreEntity, RiskSeverity } from '../../../../../common/search_strategy'; -import { TestProviders } from '../../../../common/mock'; -import { createTelemetryServiceMock } from '../../../../common/lib/telemetry/telemetry_service.mock'; +import { RiskScoreEntity, RiskSeverity } from '../../../../common/search_strategy'; +import { TestProviders } from '../../../common/mock'; +import { createTelemetryServiceMock } from '../../../common/lib/telemetry/telemetry_service.mock'; const mockedTelemetry = createTelemetryServiceMock(); -jest.mock('../../../../common/lib/kibana', () => { +jest.mock('../../../common/lib/kibana', () => { return { useKibana: () => ({ services: { diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/severity/severity_filter_group.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_filter_group.tsx similarity index 94% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/severity/severity_filter_group.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_filter_group.tsx index 1ca7020bc818df..c5373199192a4d 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/severity/severity_filter_group.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/severity_filter_group.tsx @@ -16,12 +16,12 @@ import { useEuiTheme, } from '@elastic/eui'; -import { SEVERITY_UI_SORT_ORDER } from '../../../../entity_analytics/common/utils'; -import type { RiskScoreEntity, RiskSeverity } from '../../../../../common/search_strategy'; +import { SEVERITY_UI_SORT_ORDER } from '../../common/utils'; +import type { RiskScoreEntity, RiskSeverity } from '../../../../common/search_strategy'; import type { SeverityCount } from './types'; import { RiskScoreLevel } from './common'; -import { ENTITY_RISK_LEVEL } from '../translations'; -import { useKibana } from '../../../../common/lib/kibana'; +import { ENTITY_RISK_LEVEL } from '../risk_score/translations'; +import { useKibana } from '../../../common/lib/kibana'; interface SeverityItems { risk: RiskSeverity; diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/severity/types.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/types.ts similarity index 80% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/severity/types.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/severity/types.ts index c4760b55b6a838..0c161ddd814702 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/severity/types.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/severity/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { RiskSeverity } from '../../../../../common/search_strategy'; +import type { RiskSeverity } from '../../../../common/search_strategy'; export type SeverityCount = { [k in RiskSeverity]: number; diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/styled_basic_table.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/styled_basic_table.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/styled_basic_table.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/styled_basic_table.tsx diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/top_risk_score_contributors/index.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/index.test.tsx similarity index 91% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/top_risk_score_contributors/index.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/index.test.tsx index 8b1f3e7cfffff7..710b5427a7479d 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/top_risk_score_contributors/index.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/index.test.tsx @@ -8,11 +8,10 @@ import { render } from '@testing-library/react'; import React from 'react'; import { TopRiskScoreContributors } from '.'; -import { TestProviders } from '../../../../common/mock'; -import type { RuleRisk } from '../../../../../common/search_strategy'; +import { TestProviders } from '../../../common/mock'; +import type { RuleRisk } from '../../../../common/search_strategy'; -jest.mock('../../../../common/containers/query_toggle'); -jest.mock('../../../containers/risk_score'); +jest.mock('../../../common/containers/query_toggle'); const testProps = { riskScore: [], setQuery: jest.fn(), diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/top_risk_score_contributors/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/index.tsx similarity index 91% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/top_risk_score_contributors/index.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/index.tsx index 9f33fc9b7bc278..587f3a60824691 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/top_risk_score_contributors/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/index.tsx @@ -10,13 +10,13 @@ import React, { useMemo } from 'react'; import type { EuiTableFieldDataColumnType } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiInMemoryTable } from '@elastic/eui'; -import { HeaderSection } from '../../../../common/components/header_section'; -import { InspectButton, InspectButtonContainer } from '../../../../common/components/inspect'; +import { HeaderSection } from '../../../common/components/header_section'; +import { InspectButton, InspectButtonContainer } from '../../../common/components/inspect'; import * as i18n from './translations'; -import type { RuleRisk } from '../../../../../common/search_strategy'; +import type { RuleRisk } from '../../../../common/search_strategy'; -import { RuleLink } from '../../../../detection_engine/rule_management_ui/components/rules_table/use_columns'; +import { RuleLink } from '../../../detection_engine/rule_management_ui/components/rules_table/use_columns'; export interface TopRiskScoreContributorsProps { loading: boolean; diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/top_risk_score_contributors/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/top_risk_score_contributors/translations.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/translations.ts diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/top_risk_score_contributors_alerts/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors_alerts/index.tsx similarity index 78% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/top_risk_score_contributors_alerts/index.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors_alerts/index.tsx index 4223acb1f44d4a..eac4de0fecf1c2 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/top_risk_score_contributors_alerts/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors_alerts/index.tsx @@ -10,21 +10,21 @@ import { TableId } from '@kbn/securitysolution-data-table'; import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; import type { Filter } from '@kbn/es-query'; -import { HeaderSection } from '../../../../common/components/header_section'; +import { HeaderSection } from '../../../common/components/header_section'; import * as i18n from './translations'; -import type { RiskInputs } from '../../../../../common/entity_analytics/risk_engine'; -import { RiskScoreEntity } from '../../../../../common/entity_analytics/risk_engine'; -import type { HostRiskScore, UserRiskScore } from '../../../../../common/search_strategy'; -import { ALERTS_TABLE_REGISTRY_CONFIG_IDS } from '../../../../../common/constants'; -import { AlertsTableComponent } from '../../../../detections/components/alerts_table'; -import { GroupedAlertsTable } from '../../../../detections/components/alerts_table/alerts_grouping'; -import { useGlobalTime } from '../../../../common/containers/use_global_time'; -import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; -import { inputsSelectors } from '../../../../common/store/inputs'; -import { useUserData } from '../../../../detections/components/user_info'; -import { useSourcererDataView } from '../../../../common/containers/sourcerer'; -import { SourcererScopeName } from '../../../../common/store/sourcerer/model'; +import type { RiskInputs } from '../../../../common/entity_analytics/risk_engine'; +import { RiskScoreEntity } from '../../../../common/entity_analytics/risk_engine'; +import type { HostRiskScore, UserRiskScore } from '../../../../common/search_strategy'; +import { ALERTS_TABLE_REGISTRY_CONFIG_IDS } from '../../../../common/constants'; +import { AlertsTableComponent } from '../../../detections/components/alerts_table'; +import { GroupedAlertsTable } from '../../../detections/components/alerts_table/alerts_grouping'; +import { useGlobalTime } from '../../../common/containers/use_global_time'; +import { useDeepEqualSelector } from '../../../common/hooks/use_selector'; +import { inputsSelectors } from '../../../common/store/inputs'; +import { useUserData } from '../../../detections/components/user_info'; +import { useSourcererDataView } from '../../../common/containers/sourcerer'; +import { SourcererScopeName } from '../../../common/store/sourcerer/model'; import { RiskInformationButtonEmpty } from '../risk_information'; export interface TopRiskScoreContributorsAlertsProps { diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/top_risk_score_contributors_alerts/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors_alerts/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/explore/components/risk_score/top_risk_score_contributors_alerts/translations.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors_alerts/translations.ts diff --git a/x-pack/plugins/security_solution/public/explore/users/pages/navigation/user_risk_score_tab_body.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.test.tsx similarity index 81% rename from x-pack/plugins/security_solution/public/explore/users/pages/navigation/user_risk_score_tab_body.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.test.tsx index 78406353fb477a..3103a8437f384c 100644 --- a/x-pack/plugins/security_solution/public/explore/users/pages/navigation/user_risk_score_tab_body.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.test.tsx @@ -7,15 +7,17 @@ import React from 'react'; import { render } from '@testing-library/react'; -import { TestProviders } from '../../../../common/mock'; -import { useRiskScore, useRiskScoreKpi } from '../../../containers/risk_score'; -import { useQueryToggle } from '../../../../common/containers/query_toggle'; +import { TestProviders } from '../../common/mock'; +import { useQueryToggle } from '../../common/containers/query_toggle'; import { UserRiskScoreQueryTabBody } from './user_risk_score_tab_body'; -import { UsersType } from '../../store/model'; +import { UsersType } from '../../explore/users/store/model'; +import { useRiskScore } from '../api/hooks/use_risk_score'; +import { useRiskScoreKpi } from '../api/hooks/use_risk_score_kpi'; -jest.mock('../../../containers/risk_score'); -jest.mock('../../../../common/containers/query_toggle'); -jest.mock('../../../../common/lib/kibana'); +jest.mock('../api/hooks/use_risk_score_kpi'); +jest.mock('../api/hooks/use_risk_score'); +jest.mock('../../common/containers/query_toggle'); +jest.mock('../../common/lib/kibana'); describe('All users query tab body', () => { const mockUseRiskScore = useRiskScore as jest.Mock; diff --git a/x-pack/plugins/security_solution/public/explore/users/pages/navigation/user_risk_score_tab_body.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx similarity index 76% rename from x-pack/plugins/security_solution/public/explore/users/pages/navigation/user_risk_score_tab_body.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx index 4097d673f39828..c216d3786434e1 100644 --- a/x-pack/plugins/security_solution/public/explore/users/pages/navigation/user_risk_score_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx @@ -8,24 +8,21 @@ import React, { useEffect, useMemo, useState } from 'react'; import { noop } from 'lodash/fp'; -import { EnableRiskScore } from '../../../components/risk_score/enable_risk_score'; -import type { UsersComponentsQueryProps } from './types'; -import { manageQuery } from '../../../../common/components/page/manage_query'; -import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; -import type { State } from '../../../../common/store'; - -import { UserRiskScoreTable } from '../../components/user_risk_score_table'; -import { usersSelectors } from '../../store'; -import { - UserRiskScoreQueryId, - useRiskScore, - useRiskScoreKpi, -} from '../../../containers/risk_score'; -import { useQueryToggle } from '../../../../common/containers/query_toggle'; -import { EMPTY_SEVERITY_COUNT, RiskScoreEntity } from '../../../../../common/search_strategy'; -import { RiskScoresNoDataDetected } from '../../../components/risk_score/risk_score_onboarding/risk_score_no_data_detected'; -import { useRiskEngineStatus } from '../../../../entity_analytics/api/hooks/use_risk_engine_status'; -import { RiskScoreUpdatePanel } from '../../../../entity_analytics/components/risk_score_update_panel'; +import { useRiskScoreKpi } from '../api/hooks/use_risk_score_kpi'; +import { useRiskScore } from '../api/hooks/use_risk_score'; +import { UserRiskScoreQueryId } from '../common/utils'; +import { EnableRiskScore } from './enable_risk_score'; +import type { UsersComponentsQueryProps } from '../../explore/users/pages/navigation/types'; +import { manageQuery } from '../../common/components/page/manage_query'; +import { useDeepEqualSelector } from '../../common/hooks/use_selector'; +import type { State } from '../../common/store'; +import { UserRiskScoreTable } from './user_risk_score_table'; +import { usersSelectors } from '../../explore/users/store'; +import { useQueryToggle } from '../../common/containers/query_toggle'; +import { EMPTY_SEVERITY_COUNT, RiskScoreEntity } from '../../../common/search_strategy'; +import { RiskScoresNoDataDetected } from './risk_score_onboarding/risk_score_no_data_detected'; +import { useRiskEngineStatus } from '../api/hooks/use_risk_engine_status'; +import { RiskScoreUpdatePanel } from './risk_score_update_panel'; const UserRiskScoreTableManage = manageQuery(UserRiskScoreTable); diff --git a/x-pack/plugins/security_solution/public/explore/users/components/user_risk_score_table/columns.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/columns.test.tsx similarity index 93% rename from x-pack/plugins/security_solution/public/explore/users/components/user_risk_score_table/columns.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/columns.test.tsx index 3f9fe129815098..5fbbcf30d13bfb 100644 --- a/x-pack/plugins/security_solution/public/explore/users/components/user_risk_score_table/columns.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/columns.test.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { render } from '@testing-library/react'; import type { UserRiskScoreColumns } from '.'; import { getUserRiskScoreColumns } from './columns'; -import { TestProviders } from '../../../../common/mock'; -import { RiskScoreFields } from '../../../../../common/search_strategy'; +import { TestProviders } from '../../../common/mock'; +import { RiskScoreFields } from '../../../../common/search_strategy'; describe('getUserRiskScoreColumns', () => { const defaultProps = { diff --git a/x-pack/plugins/security_solution/public/explore/users/components/user_risk_score_table/columns.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/columns.tsx similarity index 77% rename from x-pack/plugins/security_solution/public/explore/users/components/user_risk_score_table/columns.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/columns.tsx index a23d62d0e83d5a..49eaf7b3cc26ba 100644 --- a/x-pack/plugins/security_solution/public/explore/users/components/user_risk_score_table/columns.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/columns.tsx @@ -11,19 +11,19 @@ import { SecurityCellActions, SecurityCellActionsTrigger, CellActionsMode, -} from '../../../../common/components/cell_actions'; -import { escapeDataProviderId } from '../../../../common/components/drag_and_drop/helpers'; -import { getEmptyTagValue } from '../../../../common/components/empty_value'; +} from '../../../common/components/cell_actions'; +import { escapeDataProviderId } from '../../../common/components/drag_and_drop/helpers'; +import { getEmptyTagValue } from '../../../common/components/empty_value'; import type { UserRiskScoreColumns } from '.'; import * as i18n from './translations'; -import { RiskScoreLevel } from '../../../components/risk_score/severity/common'; -import type { Maybe, RiskSeverity } from '../../../../../common/search_strategy'; -import { RiskScoreEntity, RiskScoreFields } from '../../../../../common/search_strategy'; -import { UserDetailsLink } from '../../../../common/components/links'; -import { UsersTableType } from '../../store/model'; -import { ENTITY_RISK_LEVEL } from '../../../components/risk_score/translations'; -import { CELL_ACTIONS_TELEMETRY } from '../../../components/risk_score/constants'; -import { FormattedRelativePreferenceDate } from '../../../../common/components/formatted_date'; +import { RiskScoreLevel } from '../severity/common'; +import type { Maybe, RiskSeverity } from '../../../../common/search_strategy'; +import { RiskScoreEntity, RiskScoreFields } from '../../../../common/search_strategy'; +import { UserDetailsLink } from '../../../common/components/links'; +import { UsersTableType } from '../../../explore/users/store/model'; +import { ENTITY_RISK_LEVEL } from '../risk_score/translations'; +import { CELL_ACTIONS_TELEMETRY } from '../risk_score/constants'; +import { FormattedRelativePreferenceDate } from '../../../common/components/formatted_date'; export const getUserRiskScoreColumns = ({ dispatchSeverityUpdate, diff --git a/x-pack/plugins/security_solution/public/explore/users/components/user_risk_score_table/index.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/index.test.tsx similarity index 83% rename from x-pack/plugins/security_solution/public/explore/users/components/user_risk_score_table/index.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/index.test.tsx index 2d3cedad6bea11..87905b248a7d97 100644 --- a/x-pack/plugins/security_solution/public/explore/users/components/user_risk_score_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/index.test.tsx @@ -9,10 +9,10 @@ import { render } from '@testing-library/react'; import { noop } from 'lodash'; import React from 'react'; import { UserRiskScoreTable } from '.'; -import type { UserRiskScore } from '../../../../../common/search_strategy'; -import { RiskSeverity } from '../../../../../common/search_strategy'; -import { TestProviders } from '../../../../common/mock'; -import { UsersType } from '../../store/model'; +import type { UserRiskScore } from '../../../../common/search_strategy'; +import { RiskSeverity } from '../../../../common/search_strategy'; +import { TestProviders } from '../../../common/mock'; +import { UsersType } from '../../../explore/users/store/model'; describe('UserRiskScoreTable', () => { const username = 'test_user_name'; diff --git a/x-pack/plugins/security_solution/public/explore/users/components/user_risk_score_table/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/index.tsx similarity index 83% rename from x-pack/plugins/security_solution/public/explore/users/components/user_risk_score_table/index.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/index.tsx index 01a2df82b40c94..6a99e64d04b279 100644 --- a/x-pack/plugins/security_solution/public/explore/users/components/user_risk_score_table/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/index.tsx @@ -9,29 +9,29 @@ import React, { useMemo, useCallback } from 'react'; import { useDispatch } from 'react-redux'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import type { Columns, Criteria, ItemsPerRow } from '../../../components/paginated_table'; -import { PaginatedTable } from '../../../components/paginated_table'; +import type { Columns, Criteria, ItemsPerRow } from '../../../explore/components/paginated_table'; +import { PaginatedTable } from '../../../explore/components/paginated_table'; import { getUserRiskScoreColumns } from './columns'; -import * as i18nUsers from '../../pages/translations'; +import * as i18nUsers from '../../../explore/users/pages/translations'; import * as i18n from './translations'; -import { usersModel, usersSelectors, usersActions } from '../../store'; -import type { UserRiskScoreItem } from '../../../../../common/search_strategy/security_solution/users/common'; -import type { SeverityCount } from '../../../components/risk_score/severity/types'; -import { SeverityBadges } from '../../../components/risk_score/severity/severity_badges'; -import { SeverityBar } from '../../../components/risk_score/severity/severity_bar'; -import { SeverityFilterGroup } from '../../../components/risk_score/severity/severity_filter_group'; -import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; -import type { State } from '../../../../common/store'; +import { usersModel, usersSelectors, usersActions } from '../../../explore/users/store'; +import type { UserRiskScoreItem } from '../../../../common/search_strategy/security_solution/users/common'; +import type { SeverityCount } from '../severity/types'; +import { SeverityBadges } from '../severity/severity_badges'; +import { SeverityBar } from '../severity/severity_bar'; +import { SeverityFilterGroup } from '../severity/severity_filter_group'; +import { useDeepEqualSelector } from '../../../common/hooks/use_selector'; +import type { State } from '../../../common/store'; import type { RiskScoreFields, RiskScoreSortField, RiskSeverity, UserRiskScore, -} from '../../../../../common/search_strategy'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { RiskInformationButtonEmpty } from '../../../components/risk_score/risk_information'; +} from '../../../../common/search_strategy'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; +import { RiskInformationButtonEmpty } from '../risk_information'; export const rowItems: ItemsPerRow[] = [ { diff --git a/x-pack/plugins/security_solution/public/explore/users/components/user_risk_score_table/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/explore/users/components/user_risk_score_table/translations.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_table/translations.ts diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/index.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/index.ts similarity index 100% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/index.ts rename to x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/index.ts diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/ingest_pipelines.test.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/ingest_pipelines.test.ts similarity index 100% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/ingest_pipelines.test.ts rename to x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/ingest_pipelines.test.ts diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/ingest_pipelines.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/ingest_pipelines.ts similarity index 100% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/ingest_pipelines.ts rename to x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/ingest_pipelines.ts diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/onboarding.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/onboarding.ts similarity index 94% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/onboarding.ts rename to x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/onboarding.ts index a8578d4d53f7e4..ff6344679455f2 100644 --- a/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/onboarding.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/onboarding.ts @@ -7,9 +7,9 @@ import type { HttpSetup, NotificationsStart } from '@kbn/core/public'; -import { INTERNAL_RISK_SCORE_URL } from '../../../../../../common/constants'; +import { INTERNAL_RISK_SCORE_URL } from '../../../../common/constants'; -import { RiskScoreEntity } from '../../../../../../common/search_strategy'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; import { HOST_RISK_SCORES_ENABLED_TITLE, INSTALLATION_ERROR, diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/saved_objects.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/saved_objects.ts similarity index 96% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/saved_objects.ts rename to x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/saved_objects.ts index 6e5369f2337f90..4c3f863ddbeae7 100644 --- a/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/saved_objects.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/saved_objects.ts @@ -11,13 +11,13 @@ import type { DashboardStart } from '@kbn/dashboard-plugin/public'; import { RISKY_HOSTS_DASHBOARD_TITLE, RISKY_USERS_DASHBOARD_TITLE, -} from '../../../../components/risk_score/constants'; +} from '../../components/risk_score/constants'; import { prebuiltSavedObjectsBulkCreateUrl, prebuiltSavedObjectsBulkDeleteUrl, -} from '../../../../../../common/constants'; +} from '../../../../common/constants'; -import { RiskScoreEntity } from '../../../../../../common/search_strategy'; +import { RiskScoreEntity } from '../../../../common/search_strategy'; import { DELETE_SAVED_OBJECTS_FAILURE, diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/stored_scripts.test.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.test.ts similarity index 100% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/stored_scripts.test.ts rename to x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.test.ts diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/stored_scripts.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.ts similarity index 97% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/stored_scripts.ts rename to x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.ts index 6a7fa486bc729e..243106325982a4 100644 --- a/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/stored_scripts.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.ts @@ -9,7 +9,7 @@ import { toMountPoint } from '@kbn/kibana-react-plugin/public'; import { RISK_SCORE_CREATE_STORED_SCRIPT, RISK_SCORE_DELETE_STORED_SCRIPT, -} from '../../../../../../common/constants'; +} from '../../../../common/constants'; import { STORED_SCRIPT_CREATION_ERROR_MESSAGE, STORED_SCRIPT_DELETION_ERROR_MESSAGE, diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/transforms.test.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/transforms.test.ts similarity index 100% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/transforms.test.ts rename to x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/transforms.test.ts diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/transforms.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/transforms.ts similarity index 100% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/transforms.ts rename to x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/transforms.ts diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/translations.ts rename to x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/translations.ts diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/types.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/types.ts similarity index 100% rename from x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/types.ts rename to x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/types.ts diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/__snapshots__/risk_score_donut.test.ts.snap b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/__snapshots__/risk_score_donut.test.ts.snap similarity index 100% rename from x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/__snapshots__/risk_score_donut.test.ts.snap rename to x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/__snapshots__/risk_score_donut.test.ts.snap diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/__snapshots__/risk_score_over_time_area.test.ts.snap b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/__snapshots__/risk_score_over_time_area.test.ts.snap similarity index 100% rename from x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/__snapshots__/risk_score_over_time_area.test.ts.snap rename to x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/__snapshots__/risk_score_over_time_area.test.ts.snap diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/__snapshots__/risk_score_summary.test.ts.snap b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/__snapshots__/risk_score_summary.test.ts.snap similarity index 100% rename from x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/__snapshots__/risk_score_summary.test.ts.snap rename to x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/__snapshots__/risk_score_summary.test.ts.snap diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_donut.test.ts b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_donut.test.ts similarity index 82% rename from x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_donut.test.ts rename to x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_donut.test.ts index df536a7e33d179..00b91ceb44e2b9 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_donut.test.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_donut.test.ts @@ -6,13 +6,12 @@ */ import { renderHook } from '@testing-library/react-hooks'; -import { wrapper } from '../../../mocks'; - -import { useLensAttributes } from '../../../use_lens_attributes'; +import { wrapper } from '../../common/components/visualization_actions/mocks'; +import { useLensAttributes } from '../../common/components/visualization_actions/use_lens_attributes'; import { getRiskScoreDonutAttributes } from './risk_score_donut'; -jest.mock('../../../../../containers/sourcerer', () => ({ +jest.mock('../../common/containers/sourcerer', () => ({ useSourcererDataView: jest.fn().mockReturnValue({ selectedPatterns: ['auditbeat-mytest-*'], dataViewId: 'security-solution-my-test', @@ -20,7 +19,7 @@ jest.mock('../../../../../containers/sourcerer', () => ({ }), })); -jest.mock('../../../../../utils/route/use_route_spy', () => ({ +jest.mock('../../common/utils/route/use_route_spy', () => ({ useRouteSpy: jest.fn().mockReturnValue([ { detailName: 'undefined', diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_donut.ts b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_donut.ts similarity index 98% rename from x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_donut.ts rename to x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_donut.ts index 5260a98c5b8740..dccdab8984607a 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_donut.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_donut.ts @@ -6,7 +6,7 @@ */ import { v4 as uuidv4 } from 'uuid'; -import type { GetLensAttributes } from '../../../types'; +import type { GetLensAttributes } from '../../common/components/visualization_actions/types'; const internalReferenceIdMapping: Record<string, string> = { host: uuidv4(), user: uuidv4() }; diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_over_time_area.test.ts b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_over_time_area.test.ts similarity index 89% rename from x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_over_time_area.test.ts rename to x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_over_time_area.test.ts index 97dbe4ea17e48b..5a642e804befd2 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_over_time_area.test.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_over_time_area.test.ts @@ -7,13 +7,12 @@ import { renderHook } from '@testing-library/react-hooks'; import type { XYState } from '@kbn/lens-plugin/public'; -import { wrapper } from '../../../mocks'; - -import { useLensAttributes } from '../../../use_lens_attributes'; import { getRiskScoreOverTimeAreaAttributes } from './risk_score_over_time_area'; +import { useLensAttributes } from '../../common/components/visualization_actions/use_lens_attributes'; +import { wrapper } from '../../common/components/visualization_actions/mocks'; -jest.mock('../../../../../containers/sourcerer', () => ({ +jest.mock('../../common/containers/sourcerer', () => ({ useSourcererDataView: jest.fn().mockReturnValue({ selectedPatterns: ['auditbeat-mytest-*'], dataViewId: 'security-solution-my-test', @@ -21,7 +20,7 @@ jest.mock('../../../../../containers/sourcerer', () => ({ }), })); -jest.mock('../../../../../utils/route/use_route_spy', () => ({ +jest.mock('../../common/utils/route/use_route_spy', () => ({ useRouteSpy: jest.fn().mockReturnValue([ { detailName: 'mockHost', diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_over_time_area.ts b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_over_time_area.ts similarity index 98% rename from x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_over_time_area.ts rename to x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_over_time_area.ts index b100e5042a33a5..af76c9282873df 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_over_time_area.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_over_time_area.ts @@ -6,7 +6,7 @@ */ import { v4 as uuidv4 } from 'uuid'; -import type { GetLensAttributes } from '../../../types'; +import type { GetLensAttributes } from '../../common/components/visualization_actions/types'; const internalReferenceIdMapping: Record<string, string> = { host: uuidv4(), user: uuidv4() }; diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_summary.test.ts b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_summary.test.ts similarity index 85% rename from x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_summary.test.ts rename to x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_summary.test.ts index e8af897c51cea1..6ef0abbf77693d 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_summary.test.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_summary.test.ts @@ -5,15 +5,15 @@ * 2.0. */ -import { RiskScoreEntity } from '../../../../../../../common/entity_analytics/risk_engine'; +import { RiskScoreEntity } from '../../../common/entity_analytics/risk_engine'; import { renderHook } from '@testing-library/react-hooks'; -import { wrapper } from '../../../mocks'; -import { useLensAttributes } from '../../../use_lens_attributes'; import { getRiskScoreSummaryAttributes } from './risk_score_summary'; -import { RiskSeverity } from '../../../../../../../common/search_strategy'; +import { RiskSeverity } from '../../../common/search_strategy'; import type { MetricVisualizationState } from '@kbn/lens-plugin/public'; +import { wrapper } from '../../common/components/visualization_actions/mocks'; +import { useLensAttributes } from '../../common/components/visualization_actions/use_lens_attributes'; -jest.mock('../../../../../containers/sourcerer', () => ({ +jest.mock('../../common/containers/sourcerer', () => ({ useSourcererDataView: jest.fn().mockReturnValue({ selectedPatterns: ['auditbeat-mytest-*'], dataViewId: 'security-solution-my-test', diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_summary.ts b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_summary.ts similarity index 93% rename from x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_summary.ts rename to x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_summary.ts index 728c6e17713734..544badd18b5e98 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/risk_scores/risk_score_summary.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_summary.ts @@ -6,14 +6,10 @@ */ import { v4 as uuidv4 } from 'uuid'; -import { - SEVERITY_UI_SORT_ORDER, - RISK_SEVERITY_COLOUR, - RISK_SCORE_RANGES, -} from '../../../../../../entity_analytics/common/utils'; -import type { RiskSeverity } from '../../../../../../../common/search_strategy'; -import { RiskScoreEntity, RiskScoreFields } from '../../../../../../../common/search_strategy'; -import type { LensAttributes } from '../../../types'; +import type { LensAttributes } from '@kbn/lens-embeddable-utils'; +import { SEVERITY_UI_SORT_ORDER, RISK_SEVERITY_COLOUR, RISK_SCORE_RANGES } from '../common/utils'; +import type { RiskSeverity } from '../../../common/search_strategy'; +import { RiskScoreEntity, RiskScoreFields } from '../../../common/search_strategy'; interface GetRiskScoreSummaryAttributesProps { query?: string; diff --git a/x-pack/plugins/security_solution/public/overview/pages/entity_analytics.tsx b/x-pack/plugins/security_solution/public/entity_analytics/pages/entity_analytics_dashboard.tsx similarity index 92% rename from x-pack/plugins/security_solution/public/overview/pages/entity_analytics.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/pages/entity_analytics_dashboard.tsx index 96476c90aa1806..76efd79b4d63d2 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/entity_analytics.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/pages/entity_analytics_dashboard.tsx @@ -7,7 +7,6 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui'; -import { EntityAnalyticsRiskScores } from '../components/entity_analytics/risk_score'; import { RiskScoreEntity } from '../../../common/search_strategy'; import { ENTITY_ANALYTICS } from '../../app/translations'; import { SpyRoute } from '../../common/utils/route/spy_routes'; @@ -16,15 +15,15 @@ import { useSourcererDataView } from '../../common/containers/sourcerer'; import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper'; import { HeaderPage } from '../../common/components/header_page'; import { LandingPageComponent } from '../../common/components/landing_page'; - -import { EntityAnalyticsHeader } from '../components/entity_analytics/header'; -import { EntityAnalyticsAnomalies } from '../components/entity_analytics/anomalies'; import { SiemSearchBar } from '../../common/components/search_bar'; import { InputsModelId } from '../../common/store/inputs/constants'; import { FiltersGlobal } from '../../common/components/filters_global'; -import { useRiskEngineStatus } from '../../entity_analytics/api/hooks/use_risk_engine_status'; -import { RiskScoreUpdatePanel } from '../../entity_analytics/components/risk_score_update_panel'; +import { useRiskEngineStatus } from '../api/hooks/use_risk_engine_status'; +import { RiskScoreUpdatePanel } from '../components/risk_score_update_panel'; import { useHasSecurityCapability } from '../../helper_hooks'; +import { EntityAnalyticsHeader } from '../components/entity_analytics_header'; +import { EntityAnalyticsAnomalies } from '../components/entity_analytics_anomalies'; +import { EntityAnalyticsRiskScores } from '../components/entity_analytics_risk_score'; const EntityAnalyticsComponent = () => { const { data: riskScoreEngineStatus } = useRiskEngineStatus(); diff --git a/x-pack/plugins/security_solution/public/explore/components/paginated_table/index.tsx b/x-pack/plugins/security_solution/public/explore/components/paginated_table/index.tsx index 6c870c313a4128..cbee7c586bbf5d 100644 --- a/x-pack/plugins/security_solution/public/explore/components/paginated_table/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/components/paginated_table/index.tsx @@ -41,7 +41,7 @@ import type { } from '../../network/components/network_top_countries_table/columns'; import type { TlsColumns } from '../../network/components/tls_table/columns'; import type { UncommonProcessTableColumns } from '../../hosts/components/uncommon_process_table'; -import type { HostRiskScoreColumns } from '../../hosts/components/host_risk_score_table'; +import type { HostRiskScoreColumns } from '../../../entity_analytics/components/host_risk_score_table'; import type { UsersColumns } from '../../network/components/users_table/columns'; import { HeaderSection } from '../../../common/components/header_section'; diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/all/translations.ts b/x-pack/plugins/security_solution/public/explore/containers/risk_score/all/translations.ts deleted file mode 100644 index 8cc275674d4e9f..00000000000000 --- a/x-pack/plugins/security_solution/public/explore/containers/risk_score/all/translations.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const ERROR_RISK_SCORE = i18n.translate( - 'xpack.securitySolution.riskScore.errorSearchDescription', - { - defaultMessage: `An error has occurred on risk score search`, - } -); - -export const FAIL_RISK_SCORE = i18n.translate( - 'xpack.securitySolution.riskScore.failSearchDescription', - { - defaultMessage: `Failed to run search on risk score`, - } -); diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/feature_status/api.ts b/x-pack/plugins/security_solution/public/explore/containers/risk_score/feature_status/api.ts deleted file mode 100644 index 2cfaa2265f527c..00000000000000 --- a/x-pack/plugins/security_solution/public/explore/containers/risk_score/feature_status/api.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { KibanaServices } from '../../../../common/lib/kibana'; -import { RISK_SCORE_INDEX_STATUS_API_URL } from '../../../../../common/constants'; -import type { RiskScoreEntity } from '../../../../../common/search_strategy'; - -export const getRiskScoreIndexStatus = async (params: { - query: { - indexName: string; - entity: RiskScoreEntity; - }; - signal?: AbortSignal; -}): Promise<{ - isDeprecated: boolean; - isEnabled: boolean; -}> => { - const { indexName, entity } = params.query; - return KibanaServices.get().http.fetch<{ isDeprecated: boolean; isEnabled: boolean }>( - RISK_SCORE_INDEX_STATUS_API_URL, - { - method: 'GET', - version: '1', - query: { indexName, entity }, - asSystemRequest: true, - signal: params.signal, - } - ); -}; diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/index.ts b/x-pack/plugins/security_solution/public/explore/containers/risk_score/index.ts deleted file mode 100644 index 892bcd24dee747..00000000000000 --- a/x-pack/plugins/security_solution/public/explore/containers/risk_score/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { - HostRiskScore, - UserRiskScore, -} from '../../../../common/search_strategy/security_solution/risk_score'; - -export * from './all'; -export * from './kpi'; - -export enum UserRiskScoreQueryId { - USERS_BY_RISK = 'UsersByRisk', - USER_DETAILS_RISK_SCORE = 'UserDetailsRiskScore', -} - -export enum HostRiskScoreQueryId { - DEFAULT = 'HostRiskScore', - HOST_DETAILS_RISK_SCORE = 'HostDetailsRiskScore', - OVERVIEW_RISKY_HOSTS = 'OverviewRiskyHosts', - HOSTS_BY_RISK = 'HostsByRisk', -} - -export interface HostRisk { - loading: boolean; - isModuleEnabled: boolean; - result?: HostRiskScore[]; -} - -export interface UserRisk { - loading: boolean; - isModuleEnabled: boolean; - result?: UserRiskScore[]; -} diff --git a/x-pack/plugins/security_solution/public/explore/containers/risk_score/kpi/translations.ts b/x-pack/plugins/security_solution/public/explore/containers/risk_score/kpi/translations.ts deleted file mode 100644 index 83b402220f3d45..00000000000000 --- a/x-pack/plugins/security_solution/public/explore/containers/risk_score/kpi/translations.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const FAIL_RISK_SCORE = i18n.translate( - 'xpack.securitySolution.riskScore.kpi.failSearchDescription', - { - defaultMessage: `Failed to run search on risk score`, - } -); diff --git a/x-pack/plugins/security_solution/public/explore/hosts/components/hosts_table/columns.tsx b/x-pack/plugins/security_solution/public/explore/hosts/components/hosts_table/columns.tsx index 292e106fa5d4d0..270a10b52155a7 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/components/hosts_table/columns.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/components/hosts_table/columns.tsx @@ -19,9 +19,9 @@ import type { HostsTableColumns } from '.'; import * as i18n from './translations'; import type { Maybe, RiskSeverity } from '../../../../../common/search_strategy'; import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { VIEW_HOSTS_BY_SEVERITY } from '../host_risk_score_table/translations'; -import { RiskScoreLevel } from '../../../components/risk_score/severity/common'; -import { ENTITY_RISK_LEVEL } from '../../../components/risk_score/translations'; +import { VIEW_HOSTS_BY_SEVERITY } from '../../../../entity_analytics/components/host_risk_score_table/translations'; +import { RiskScoreLevel } from '../../../../entity_analytics/components/severity/common'; +import { ENTITY_RISK_LEVEL } from '../../../../entity_analytics/components/risk_score/translations'; export const getHostsColumns = ( showRiskColumn: boolean, diff --git a/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.tsx b/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.tsx index cc21c96ac9405d..4a758dadc5cbd2 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/pages/details/details_tabs.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { Routes, Route } from '@kbn/shared-ux-router'; import { TableId } from '@kbn/securitysolution-data-table'; import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { RiskDetailsTabBody } from '../../../components/risk_score/risk_details_tab_body'; +import { RiskDetailsTabBody } from '../../../../entity_analytics/components/risk_details_tab_body'; import { HostsType, HostsTableType } from '../../store/model'; import { AnomaliesQueryTabBody } from '../../../../common/containers/anomalies/anomalies_query_tab_body'; import { useGlobalTime } from '../../../../common/containers/use_global_time'; diff --git a/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.test.tsx b/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.test.tsx index 0ea63088628bfd..30083b2452d94c 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.test.tsx @@ -8,12 +8,14 @@ import React from 'react'; import { render } from '@testing-library/react'; import { TestProviders } from '../../../../common/mock'; -import { useRiskScore, useRiskScoreKpi } from '../../../containers/risk_score'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; import { HostRiskScoreQueryTabBody } from './host_risk_score_tab_body'; import { HostsType } from '../../store/model'; +import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score'; +import { useRiskScoreKpi } from '../../../../entity_analytics/api/hooks/use_risk_score_kpi'; -jest.mock('../../../containers/risk_score'); +jest.mock('../../../../entity_analytics/api/hooks/use_risk_score_kpi'); +jest.mock('../../../../entity_analytics/api/hooks/use_risk_score'); jest.mock('../../../../common/containers/query_toggle'); jest.mock('../../../../common/lib/kibana'); diff --git a/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx b/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx index 7139102bd35a55..c9ab211c8dc079 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx @@ -8,21 +8,19 @@ import React, { useEffect, useMemo, useState } from 'react'; import { EuiPanel } from '@elastic/eui'; import { noop } from 'lodash/fp'; -import { EnableRiskScore } from '../../../components/risk_score/enable_risk_score'; +import { HostRiskScoreQueryId } from '../../../../entity_analytics/common/utils'; +import { useRiskScoreKpi } from '../../../../entity_analytics/api/hooks/use_risk_score_kpi'; +import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score'; +import { EnableRiskScore } from '../../../../entity_analytics/components/enable_risk_score'; import type { HostsComponentsQueryProps } from './types'; import { manageQuery } from '../../../../common/components/page/manage_query'; -import { HostRiskScoreTable } from '../../components/host_risk_score_table'; +import { HostRiskScoreTable } from '../../../../entity_analytics/components/host_risk_score_table'; import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; import { hostsModel, hostsSelectors } from '../../store'; import type { State } from '../../../../common/store'; -import { - HostRiskScoreQueryId, - useRiskScore, - useRiskScoreKpi, -} from '../../../containers/risk_score'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; import { EMPTY_SEVERITY_COUNT, RiskScoreEntity } from '../../../../../common/search_strategy'; -import { RiskScoresNoDataDetected } from '../../../components/risk_score/risk_score_onboarding/risk_score_no_data_detected'; +import { RiskScoresNoDataDetected } from '../../../../entity_analytics/components/risk_score_onboarding/risk_score_no_data_detected'; import { useRiskEngineStatus } from '../../../../entity_analytics/api/hooks/use_risk_engine_status'; import { RiskScoreUpdatePanel } from '../../../../entity_analytics/components/risk_score_update_panel'; diff --git a/x-pack/plugins/security_solution/public/explore/users/components/all_users/index.tsx b/x-pack/plugins/security_solution/public/explore/users/components/all_users/index.tsx index 7cf90c41fd7c3a..6948009ebb188b 100644 --- a/x-pack/plugins/security_solution/public/explore/users/components/all_users/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/users/components/all_users/index.tsx @@ -27,9 +27,9 @@ import { usersActions, usersModel, usersSelectors } from '../../store'; import type { User } from '../../../../../common/search_strategy/security_solution/users/all'; import type { SortUsersField } from '../../../../../common/search_strategy/security_solution/users/common'; import type { RiskSeverity } from '../../../../../common/search_strategy'; -import { RiskScoreLevel } from '../../../components/risk_score/severity/common'; +import { RiskScoreLevel } from '../../../../entity_analytics/components/severity/common'; import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; -import { VIEW_USERS_BY_SEVERITY } from '../user_risk_score_table/translations'; +import { VIEW_USERS_BY_SEVERITY } from '../../../../entity_analytics/components/user_risk_score_table/translations'; import { SecurityPageName } from '../../../../app/types'; import { UsersTableType } from '../../store/model'; import { useNavigateTo } from '../../../../common/lib/kibana'; diff --git a/x-pack/plugins/security_solution/public/explore/users/pages/details/details_tabs.tsx b/x-pack/plugins/security_solution/public/explore/users/pages/details/details_tabs.tsx index d2649a33292040..9719dc0844e4ac 100644 --- a/x-pack/plugins/security_solution/public/explore/users/pages/details/details_tabs.tsx +++ b/x-pack/plugins/security_solution/public/explore/users/pages/details/details_tabs.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Routes, Route } from '@kbn/shared-ux-router'; import { TableId } from '@kbn/securitysolution-data-table'; -import { RiskDetailsTabBody } from '../../../components/risk_score/risk_details_tab_body'; +import { RiskDetailsTabBody } from '../../../../entity_analytics/components/risk_details_tab_body'; import { RiskScoreEntity } from '../../../../../common/search_strategy'; import { UsersTableType } from '../../store/model'; import { AnomaliesUserTable } from '../../../../common/components/ml/tables/anomalies_user_table'; diff --git a/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.tsx b/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.tsx index 034ee2a71ab9d7..bc6dd85e21e259 100644 --- a/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.tsx +++ b/x-pack/plugins/security_solution/public/explore/users/pages/users_tabs.tsx @@ -16,7 +16,7 @@ import { AllUsersQueryTabBody, AuthenticationsQueryTabBody } from './navigation' import { AnomaliesQueryTabBody } from '../../../common/containers/anomalies/anomalies_query_tab_body'; import { AnomaliesUserTable } from '../../../common/components/ml/tables/anomalies_user_table'; -import { UserRiskScoreQueryTabBody } from './navigation/user_risk_score_tab_body'; +import { UserRiskScoreQueryTabBody } from '../../../entity_analytics/components/user_risk_score_tab_body'; import { EventsQueryTabBody } from '../../../common/components/events_tab'; import { userNameExistsFilter } from './details/helpers'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/entities_details.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/entities_details.test.tsx index 0a8807b2fb75aa..b6aacd491a0557 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/entities_details.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/entities_details.test.tsx @@ -16,12 +16,12 @@ import { mockContextValue } from '../mocks/mock_context'; import { EXPANDABLE_PANEL_CONTENT_TEST_ID } from '../../../shared/components/test_ids'; import type { Anomalies } from '../../../../common/components/ml/types'; import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; -import { useRiskScore } from '../../../../explore/containers/risk_score'; import { mockAnomalies } from '../../../../common/components/ml/mock'; import { useHostDetails } from '../../../../explore/hosts/containers/hosts/details'; import { useHostRelatedUsers } from '../../../../common/containers/related_entities/related_users'; import { useObservedUserDetails } from '../../../../explore/users/containers/users/observed_details'; import { useUserRelatedHosts } from '../../../../common/containers/related_entities/related_hosts'; +import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score'; jest.mock('react-router-dom', () => { const actual = jest.requireActual('react-router-dom'); @@ -86,7 +86,7 @@ const mockUseHostDetails = useHostDetails as jest.Mock; jest.mock('../../../../common/containers/related_entities/related_users'); const mockUseHostsRelatedUsers = useHostRelatedUsers as jest.Mock; -jest.mock('../../../../explore/containers/risk_score'); +jest.mock('../../../../entity_analytics/api/hooks/use_risk_score'); const mockUseRiskScore = useRiskScore as jest.Mock; jest.mock('../../../../explore/users/containers/users/observed_details'); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.test.tsx index b711e6d3d5f7ed..e8dfa71d0b4c21 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.test.tsx @@ -11,7 +11,6 @@ import type { Anomalies } from '../../../../common/components/ml/types'; import { TestProviders } from '../../../../common/mock'; import { HostDetails } from './host_details'; import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; -import { useRiskScore } from '../../../../explore/containers/risk_score'; import { mockAnomalies } from '../../../../common/components/ml/mock'; import { useHostDetails } from '../../../../explore/hosts/containers/hosts/details'; import { useHostRelatedUsers } from '../../../../common/containers/related_entities/related_users'; @@ -22,6 +21,7 @@ import { HOST_DETAILS_RELATED_USERS_TABLE_TEST_ID, } from './test_ids'; import { EXPANDABLE_PANEL_CONTENT_TEST_ID } from '../../../shared/components/test_ids'; +import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score'; jest.mock('react-router-dom', () => { const actual = jest.requireActual('react-router-dom'); @@ -83,7 +83,7 @@ const mockUseHostDetails = useHostDetails as jest.Mock; jest.mock('../../../../common/containers/related_entities/related_users'); const mockUseHostsRelatedUsers = useHostRelatedUsers as jest.Mock; -jest.mock('../../../../explore/containers/risk_score'); +jest.mock('../../../../entity_analytics/api/hooks/use_risk_score'); const mockUseRiskScore = useRiskScore as jest.Mock; const timestamp = '2022-07-25T08:20:18.966Z'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.tsx index 3f68ef15956ede..711eb2a6500f10 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.tsx @@ -30,7 +30,7 @@ import { AnomalyTableProvider } from '../../../../common/components/ml/anomaly/a import { InspectButton, InspectButtonContainer } from '../../../../common/components/inspect'; import { NetworkDetailsLink } from '../../../../common/components/links'; import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { RiskScoreLevel } from '../../../../explore/components/risk_score/severity/common'; +import { RiskScoreLevel } from '../../../../entity_analytics/components/severity/common'; import { DefaultFieldRenderer } from '../../../../timelines/components/field_renderers/field_renderers'; import { InputsModelId } from '../../../../common/store/inputs/constants'; import { @@ -49,7 +49,7 @@ import { useHostRelatedUsers } from '../../../../common/containers/related_entit import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; import { getEmptyTagValue } from '../../../../common/components/empty_value'; import { HOST_DETAILS_TEST_ID, HOST_DETAILS_RELATED_USERS_TABLE_TEST_ID } from './test_ids'; -import { ENTITY_RISK_LEVEL } from '../../../../explore/components/risk_score/translations'; +import { ENTITY_RISK_LEVEL } from '../../../../entity_analytics/components/risk_score/translations'; import { useHasSecurityCapability } from '../../../../helper_hooks'; const HOST_DETAILS_ID = 'entities-hosts-details'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.test.tsx index 1f2d5b464d4e97..77e42400001f3c 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.test.tsx @@ -11,7 +11,6 @@ import type { Anomalies } from '../../../../common/components/ml/types'; import { TestProviders } from '../../../../common/mock'; import { UserDetails } from './user_details'; import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; -import { useRiskScore } from '../../../../explore/containers/risk_score'; import { mockAnomalies } from '../../../../common/components/ml/mock'; import { useObservedUserDetails } from '../../../../explore/users/containers/users/observed_details'; import { useUserRelatedHosts } from '../../../../common/containers/related_entities/related_hosts'; @@ -22,6 +21,7 @@ import { USER_DETAILS_RELATED_HOSTS_TABLE_TEST_ID, } from './test_ids'; import { EXPANDABLE_PANEL_CONTENT_TEST_ID } from '../../../shared/components/test_ids'; +import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score'; jest.mock('react-router-dom', () => { const actual = jest.requireActual('react-router-dom'); @@ -80,7 +80,7 @@ const mockUseObservedUserDetails = useObservedUserDetails as jest.Mock; jest.mock('../../../../common/containers/related_entities/related_hosts'); const mockUseUsersRelatedHosts = useUserRelatedHosts as jest.Mock; -jest.mock('../../../../explore/containers/risk_score'); +jest.mock('../../../../entity_analytics/api/hooks/use_risk_score'); const mockUseRiskScore = useRiskScore as jest.Mock; const timestamp = '2022-07-25T08:20:18.966Z'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.tsx index 1758bbc5b05d85..0aa2624f202ff1 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.tsx @@ -30,7 +30,7 @@ import { AnomalyTableProvider } from '../../../../common/components/ml/anomaly/a import { InspectButton, InspectButtonContainer } from '../../../../common/components/inspect'; import { NetworkDetailsLink } from '../../../../common/components/links'; import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { RiskScoreLevel } from '../../../../explore/components/risk_score/severity/common'; +import { RiskScoreLevel } from '../../../../entity_analytics/components/severity/common'; import { DefaultFieldRenderer } from '../../../../timelines/components/field_renderers/field_renderers'; import { SecurityCellActions, @@ -49,7 +49,7 @@ import { useUserRelatedHosts } from '../../../../common/containers/related_entit import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; import { getEmptyTagValue } from '../../../../common/components/empty_value'; import { USER_DETAILS_RELATED_HOSTS_TABLE_TEST_ID, USER_DETAILS_TEST_ID } from './test_ids'; -import { ENTITY_RISK_LEVEL } from '../../../../explore/components/risk_score/translations'; +import { ENTITY_RISK_LEVEL } from '../../../../entity_analytics/components/risk_score/translations'; import { useHasSecurityCapability } from '../../../../helper_hooks'; const USER_DETAILS_ID = 'entities-users-details'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/entities_overview.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/entities_overview.test.tsx index 117420358ded54..6388d5f8fb85dc 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/entities_overview.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/entities_overview.test.tsx @@ -15,7 +15,6 @@ import { } from './test_ids'; import { EntitiesOverview } from './entities_overview'; import { TestProviders } from '../../../../common/mock'; -import { useRiskScore } from '../../../../explore/containers/risk_score'; import { useFirstLastSeen } from '../../../../common/containers/use_first_last_seen'; import { useObservedUserDetails } from '../../../../explore/users/containers/users/observed_details'; import { useHostDetails } from '../../../../explore/hosts/containers/hosts/details'; @@ -26,6 +25,7 @@ import { EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID, EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID, } from '../../../shared/components/test_ids'; +import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score'; const from = '2022-04-05T12:00:00.000Z'; const to = '2022-04-08T12:00:00.;000Z'; @@ -49,7 +49,7 @@ const mockUseUserDetails = useObservedUserDetails as jest.Mock; jest.mock('../../../../explore/users/containers/users/observed_details'); const mockUseRiskScore = useRiskScore as jest.Mock; -jest.mock('../../../../explore/containers/risk_score'); +jest.mock('../../../../entity_analytics/api/hooks/use_risk_score'); const mockUseFirstLastSeen = useFirstLastSeen as jest.Mock; jest.mock('../../../../common/containers/use_first_last_seen'); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/host_entity_overview.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/host_entity_overview.test.tsx index 36fb3731943c4a..f7fc4c2a22d90a 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/host_entity_overview.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/host_entity_overview.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { render } from '@testing-library/react'; import { TestProviders } from '../../../../common/mock'; import { HostEntityOverview } from './host_entity_overview'; -import { useRiskScore } from '../../../../explore/containers/risk_score'; import { useHostDetails } from '../../../../explore/hosts/containers/hosts/details'; import { useFirstLastSeen } from '../../../../common/containers/use_first_last_seen'; import { @@ -25,6 +24,7 @@ import type { ExpandableFlyoutContextValue } from '@kbn/expandable-flyout/src/co import { ExpandableFlyoutContext } from '@kbn/expandable-flyout/src/context'; import { LeftPanelInsightsTab, DocumentDetailsLeftPanelKey } from '../../left'; import { ENTITIES_TAB_ID } from '../../left/components/entities_details'; +import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score'; const hostName = 'host'; const osFamily = 'Windows'; @@ -63,7 +63,7 @@ const mockUseHostDetails = useHostDetails as jest.Mock; jest.mock('../../../../explore/hosts/containers/hosts/details'); const mockUseRiskScore = useRiskScore as jest.Mock; -jest.mock('../../../../explore/containers/risk_score'); +jest.mock('../../../../entity_analytics/api/hooks/use_risk_score'); const mockUseFirstLastSeen = useFirstLastSeen as jest.Mock; jest.mock('../../../../common/containers/use_first_last_seen'); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/host_entity_overview.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/host_entity_overview.tsx index a1d42871a42e4f..dd90245a97f707 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/host_entity_overview.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/host_entity_overview.tsx @@ -19,6 +19,7 @@ import { css } from '@emotion/css'; import { getOr } from 'lodash/fp'; import { i18n } from '@kbn/i18n'; import { useExpandableFlyoutContext } from '@kbn/expandable-flyout'; +import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score'; import { useRightPanelContext } from '../context'; import type { DescriptionList } from '../../../../../common/utility_types'; import { @@ -30,10 +31,9 @@ import { getEmptyTagValue } from '../../../../common/components/empty_value'; import { DefaultFieldRenderer } from '../../../../timelines/components/field_renderers/field_renderers'; import { DescriptionListStyled } from '../../../../common/components/page'; import { OverviewDescriptionList } from '../../../../common/components/overview_description_list'; -import { RiskScoreLevel } from '../../../../explore/components/risk_score/severity/common'; +import { RiskScoreLevel } from '../../../../entity_analytics/components/severity/common'; import { useSourcererDataView } from '../../../../common/containers/sourcerer'; import { useGlobalTime } from '../../../../common/containers/use_global_time'; -import { useRiskScore } from '../../../../explore/containers/risk_score'; import { useHostDetails } from '../../../../explore/hosts/containers/hosts/details'; import { FAMILY, diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/insights_section.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/insights_section.test.tsx index bb776547d2a9fe..bef01182954700 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/insights_section.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/insights_section.test.tsx @@ -10,7 +10,6 @@ import { render } from '@testing-library/react'; import { RightPanelContext } from '../context'; import { INSIGHTS_HEADER_TEST_ID } from './test_ids'; import { TestProviders } from '../../../../common/mock'; -import { useRiskScore } from '../../../../explore/containers/risk_score'; import { useFirstLastSeen } from '../../../../common/containers/use_first_last_seen'; import { useObservedUserDetails } from '../../../../explore/users/containers/users/observed_details'; import { useHostDetails } from '../../../../explore/hosts/containers/hosts/details'; @@ -20,6 +19,7 @@ import { mockGetFieldsData } from '../../shared/mocks/mock_get_fields_data'; import { mockDataFormattedForFieldBrowser } from '../../shared/mocks/mock_data_formatted_for_field_browser'; import { InsightsSection } from './insights_section'; import { useAlertPrevalence } from '../../../../common/containers/alerts/use_alert_prevalence'; +import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score'; jest.mock('../../../../common/containers/alerts/use_alert_prevalence'); @@ -69,7 +69,7 @@ const mockUseUserDetails = useObservedUserDetails as jest.Mock; jest.mock('../../../../explore/users/containers/users/observed_details'); const mockUseRiskScore = useRiskScore as jest.Mock; -jest.mock('../../../../explore/containers/risk_score'); +jest.mock('../../../../entity_analytics/api/hooks/use_risk_score'); const mockUseFirstLastSeen = useFirstLastSeen as jest.Mock; jest.mock('../../../../common/containers/use_first_last_seen'); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/user_entity_overview.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/user_entity_overview.test.tsx index c8673f41376f44..b36c21faf3f736 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/user_entity_overview.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/user_entity_overview.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { render } from '@testing-library/react'; import { TestProviders } from '../../../../common/mock'; import { UserEntityOverview } from './user_entity_overview'; -import { useRiskScore } from '../../../../explore/containers/risk_score'; import { useFirstLastSeen } from '../../../../common/containers/use_first_last_seen'; import { ENTITIES_USER_OVERVIEW_DOMAIN_TEST_ID, @@ -25,6 +24,7 @@ import { ExpandableFlyoutContext } from '@kbn/expandable-flyout/src/context'; import { RightPanelContext } from '../context'; import { LeftPanelInsightsTab, DocumentDetailsLeftPanelKey } from '../../left'; import { ENTITIES_TAB_ID } from '../../left/components/entities_details'; +import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score'; const userName = 'user'; const domain = 'n54bg2lfc7'; @@ -63,7 +63,7 @@ const mockUseUserDetails = useObservedUserDetails as jest.Mock; jest.mock('../../../../explore/users/containers/users/observed_details'); const mockUseRiskScore = useRiskScore as jest.Mock; -jest.mock('../../../../explore/containers/risk_score'); +jest.mock('../../../../entity_analytics/api/hooks/use_risk_score'); const mockUseFirstLastSeen = useFirstLastSeen as jest.Mock; jest.mock('../../../../common/containers/use_first_last_seen'); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/user_entity_overview.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/user_entity_overview.tsx index 313719ec1c0bac..34768540e93376 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/user_entity_overview.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/user_entity_overview.tsx @@ -32,10 +32,11 @@ import { getEmptyTagValue } from '../../../../common/components/empty_value'; import { DefaultFieldRenderer } from '../../../../timelines/components/field_renderers/field_renderers'; import { DescriptionListStyled } from '../../../../common/components/page'; import { OverviewDescriptionList } from '../../../../common/components/overview_description_list'; -import { RiskScoreLevel } from '../../../../explore/components/risk_score/severity/common'; +import { RiskScoreLevel } from '../../../../entity_analytics/components/severity/common'; import { useSourcererDataView } from '../../../../common/containers/sourcerer'; import { useGlobalTime } from '../../../../common/containers/use_global_time'; -import { useRiskScore } from '../../../../explore/containers/risk_score'; +import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score'; + import { USER_DOMAIN, LAST_SEEN, diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/content.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/content.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/content.tsx rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/content.tsx diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/header.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/header.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/header.tsx rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/header.tsx diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/index.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/index.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/index.tsx rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/index.tsx diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/tabs.tsx similarity index 84% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs.tsx rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/tabs.tsx index f86dc25ffe2195..61f408a5c0ade3 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/tabs.tsx @@ -9,14 +9,14 @@ import type { ReactElement } from 'react'; import React, { useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; +import { getRiskInputTab } from '../../../entity_analytics/components/entity_details_flyout'; import { UserAssetTableType } from '../../../explore/users/store/model'; import { ManagedUserDatasetKey } from '../../../../common/search_strategy/security_solution/users/managed_details'; import type { ManagedUserHits, ManagedUserHit, } from '../../../../common/search_strategy/security_solution/users/managed_details'; -import { ENTRA_TAB_TEST_ID, OKTA_TAB_TEST_ID, RISK_INPUTS_TAB_TEST_ID } from './test_ids'; -import { RiskInputsTab } from './tabs/risk_inputs'; +import { ENTRA_TAB_TEST_ID, OKTA_TAB_TEST_ID } from './test_ids'; import { AssetDocumentTab } from './tabs/asset_document'; import { RightPanelProvider } from '../../document_details/right/context'; @@ -54,18 +54,6 @@ export const useTabs = (managedUser: ManagedUserHits, alertIds: string[]): LeftP return tabs; }, [alertIds, managedUser]); -const getRiskInputTab = (alertIds: string[]) => ({ - id: UserDetailsLeftPanelTab.RISK_INPUTS, - 'data-test-subj': RISK_INPUTS_TAB_TEST_ID, - name: ( - <FormattedMessage - id="xpack.securitySolution.flyout.entityDetails.userDetails.riskInputs.tabLabel" - defaultMessage="Risk Inputs" - /> - ), - content: <RiskInputsTab alertIds={alertIds} />, -}); - const getOktaTab = (oktaManagedUser: ManagedUserHit) => ({ id: UserDetailsLeftPanelTab.OKTA, 'data-test-subj': OKTA_TAB_TEST_ID, diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/asset_document.test.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/tabs/asset_document.test.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/asset_document.test.tsx rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/tabs/asset_document.test.tsx diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/asset_document.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/tabs/asset_document.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/asset_document.tsx rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/tabs/asset_document.tsx diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/test_ids.ts b/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/tabs/test_ids.ts similarity index 100% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/tabs/test_ids.ts rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/tabs/test_ids.ts diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/test_ids.ts b/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/test_ids.ts similarity index 85% rename from x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/test_ids.ts rename to x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/test_ids.ts index b67efe48dca673..1b1bf00b48401e 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_detais_left/test_ids.ts +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/test_ids.ts @@ -7,6 +7,5 @@ import { PREFIX } from '../../shared/test_ids'; -export const RISK_INPUTS_TAB_TEST_ID = `${PREFIX}RiskInputsTab` as const; export const OKTA_TAB_TEST_ID = `${PREFIX}OktaTab` as const; export const ENTRA_TAB_TEST_ID = `${PREFIX}EntraTab` as const; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx index d782849ce5ee43..9b99c42aeac7a5 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx @@ -8,6 +8,8 @@ import { EuiHorizontalRule } from '@elastic/eui'; import React from 'react'; +import { RiskSummary } from '../../../entity_analytics/components/risk_summary_flyout/risk_summary'; +import type { RiskScoreState } from '../../../entity_analytics/api/hooks/use_risk_score'; import { ManagedUser } from '../../../timelines/components/side_panel/new_user_detail/managed_user'; import type { ManagedUserData, @@ -15,11 +17,9 @@ import type { } from '../../../timelines/components/side_panel/new_user_detail/types'; import { ObservedUser } from '../../../timelines/components/side_panel/new_user_detail/observed_user'; import type { RiskScoreEntity } from '../../../../common/search_strategy'; -import type { RiskScoreState } from '../../../explore/containers/risk_score'; -import { RiskSummary } from '../shared/components/risk_summary'; import { USER_PANEL_RISK_SCORE_QUERY_ID } from '.'; import { FlyoutBody } from '../../shared/components/flyout_body'; -import type { UserDetailsLeftPanelTab } from '../user_detais_left/tabs'; +import type { UserDetailsLeftPanelTab } from '../user_details_left/tabs'; interface UserPanelContentProps { observedUser: ObservedUserData; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.test.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.test.tsx index 5ac5495c3a19f1..1c74e4ed23ea57 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.test.tsx @@ -27,7 +27,7 @@ const mockProps: UserPanelProps = { jest.mock('../../../common/components/visualization_actions/visualization_embeddable'); const mockedUseRiskScore = jest.fn().mockReturnValue(mockRiskScoreState); -jest.mock('../../../explore/containers/risk_score', () => ({ +jest.mock('../../../entity_analytics/api/hooks/use_risk_score', () => ({ useRiskScore: () => mockedUseRiskScore(), })); diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.tsx index fdc4c9fa703520..76168bc01c8421 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.tsx @@ -8,6 +8,7 @@ import React, { useCallback, useMemo } from 'react'; import type { FlyoutPanelProps } from '@kbn/expandable-flyout'; import { useExpandableFlyoutContext } from '@kbn/expandable-flyout'; +import { useRiskScore } from '../../../entity_analytics/api/hooks/use_risk_score'; import { ManagedUserDatasetKey } from '../../../../common/search_strategy/security_solution/users/managed_details'; import { useManagedUser } from '../../../timelines/components/side_panel/new_user_detail/hooks/use_managed_user'; import { useObservedUser } from '../../../timelines/components/side_panel/new_user_detail/hooks/use_observed_user'; @@ -17,14 +18,13 @@ import { getCriteriaFromUsersType } from '../../../common/components/ml/criteria import { useGlobalTime } from '../../../common/containers/use_global_time'; import { AnomalyTableProvider } from '../../../common/components/ml/anomaly/anomaly_table_provider'; import { buildUserNamesFilter } from '../../../../common/search_strategy'; -import { useRiskScore } from '../../../explore/containers/risk_score'; import { RiskScoreEntity } from '../../../../common/entity_analytics/risk_engine'; import { FlyoutLoading } from '../../shared/components/flyout_loading'; import { FlyoutNavigation } from '../../shared/components/flyout_navigation'; import { UserPanelContent } from './content'; import { UserPanelHeader } from './header'; -import { UserDetailsPanelKey } from '../user_detais_left'; -import type { UserDetailsLeftPanelTab } from '../user_detais_left/tabs'; +import { UserDetailsPanelKey } from '../user_details_left'; +import type { UserDetailsLeftPanelTab } from '../user_details_left/tabs'; export interface UserPanelProps extends Record<string, unknown> { contextID: string; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/mocks/index.ts b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/mocks/index.ts index d677f79ca43228..88ab3c10241cb6 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/mocks/index.ts +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/mocks/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { RiskScoreState } from '../../../../explore/containers/risk_score'; +import type { RiskScoreState } from '../../../../entity_analytics/api/hooks/use_risk_score'; import type { RiskScoreEntity, UserRiskScore } from '../../../../../common/search_strategy'; import { RiskSeverity } from '../../../../../common/search_strategy'; import { RiskCategories } from '../../../../../common/entity_analytics/risk_engine'; diff --git a/x-pack/plugins/security_solution/public/flyout/index.tsx b/x-pack/plugins/security_solution/public/flyout/index.tsx index 01c14b3d3ed293..ef7e182324c630 100644 --- a/x-pack/plugins/security_solution/public/flyout/index.tsx +++ b/x-pack/plugins/security_solution/public/flyout/index.tsx @@ -24,8 +24,8 @@ import { PreviewPanel, DocumentDetailsPreviewPanelKey } from './document_details import { PreviewPanelProvider } from './document_details/preview/context'; import type { UserPanelExpandableFlyoutProps } from './entity_details/user_right'; import { UserPanel, UserPanelKey } from './entity_details/user_right'; -import type { UserDetailsPanelProps } from './entity_details/user_detais_left'; -import { UserDetailsPanel, UserDetailsPanelKey } from './entity_details/user_detais_left'; +import type { UserDetailsPanelProps } from './entity_details/user_details_left'; +import { UserDetailsPanel, UserDetailsPanelKey } from './entity_details/user_details_left'; /** * List of all panels that will be used within the document details expandable flyout. * This needs to be passed to the expandable flyout registeredPanels property. diff --git a/x-pack/plugins/security_solution/public/overview/components/common.tsx b/x-pack/plugins/security_solution/public/overview/components/common.tsx index f9068a4507b75c..fcf4072db1afd2 100644 --- a/x-pack/plugins/security_solution/public/overview/components/common.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/common.tsx @@ -8,7 +8,7 @@ import { EuiButtonIcon, EuiPopover, EuiPopoverTitle, EuiText } from '@elastic/eui'; import React, { useCallback, useState } from 'react'; import * as i18n from './translations'; -import { RiskScoreDocLink } from '../../explore/components/risk_score/risk_score_onboarding/risk_score_doc_link'; +import { RiskScoreDocLink } from '../../entity_analytics/components/risk_score_onboarding/risk_score_doc_link'; import type { RiskScoreEntity } from '../../../common/entity_analytics/risk_engine'; export const RiskScoreInfoTooltip: React.FC<{ diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/translations.ts b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/translations.ts deleted file mode 100644 index cc538bedae1eaf..00000000000000 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/translations.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const TOTAL_LABEL = i18n.translate('xpack.securitySolution.entityAnalytics.totalLabel', { - defaultMessage: 'Total', -}); - -export const HOST_RISK_TITLE = i18n.translate( - 'xpack.securitySolution.entityAnalytics.hostsRiskDashboard.title', - { - defaultMessage: 'Host Risk Scores', - } -); - -export const USER_RISK_TITLE = i18n.translate( - 'xpack.securitySolution.entityAnalytics.usersRiskDashboard.title', - { - defaultMessage: 'User Risk Scores', - } -); diff --git a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx index edbb6d03bf9a9d..b1714aace87a51 100644 --- a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx @@ -14,7 +14,7 @@ import { TestProviders } from '../../../common/mock'; import { HostOverview } from '.'; import { mockData } from './mock'; import { mockAnomalies } from '../../../common/components/ml/mock'; -import { useRiskScore } from '../../../explore/containers/risk_score/all'; +import { useRiskScore } from '../../../entity_analytics/api/hooks/use_risk_score'; const defaultProps = { data: undefined, @@ -25,7 +25,7 @@ const defaultProps = { loading: true, }; -jest.mock('../../../explore/containers/risk_score/all'); +jest.mock('../../../entity_analytics/api/hooks/use_risk_score'); const mockUseRiskScore = useRiskScore as jest.Mock; diff --git a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx index 686828412977a8..a6409c587e0a6e 100644 --- a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx @@ -10,6 +10,7 @@ import { euiDarkVars as darkTheme, euiLightVars as lightTheme } from '@kbn/ui-th import { getOr } from 'lodash/fp'; import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; +import { useRiskScore } from '../../../entity_analytics/api/hooks/use_risk_score'; import type { HostItem } from '../../../../common/search_strategy'; import { buildHostNamesFilter, RiskScoreEntity } from '../../../../common/search_strategy'; import { DEFAULT_DARK_MODE } from '../../../../common/constants'; @@ -35,9 +36,8 @@ import { DescriptionListStyled, OverviewWrapper } from '../../../common/componen import * as i18n from './translations'; import { EndpointOverview } from './endpoint_overview'; import { OverviewDescriptionList } from '../../../common/components/overview_description_list'; -import { useRiskScore } from '../../../explore/containers/risk_score'; -import { RiskScoreLevel } from '../../../explore/components/risk_score/severity/common'; -import { RiskScoreHeaderTitle } from '../../../explore/components/risk_score/risk_score_onboarding/risk_score_header_title'; +import { RiskScoreLevel } from '../../../entity_analytics/components/severity/common'; +import { RiskScoreHeaderTitle } from '../../../entity_analytics/components/risk_score_onboarding/risk_score_header_title'; import type { SourcererScopeName } from '../../../common/store/sourcerer/model'; import { RiskScoreDocTooltip } from '../common'; diff --git a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx index 185f2a0fc17b5a..74d78af12fde46 100644 --- a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx @@ -12,7 +12,7 @@ import '../../../common/mock/match_media'; import { TestProviders } from '../../../common/mock'; import { mockAnomalies } from '../../../common/components/ml/mock'; -import { useRiskScore } from '../../../explore/containers/risk_score/all'; +import { useRiskScore } from '../../../entity_analytics/api/hooks/use_risk_score'; import type { UserSummaryProps } from '.'; import { UserOverview } from '.'; @@ -25,7 +25,7 @@ const defaultProps = { loading: false, }; -jest.mock('../../../explore/containers/risk_score/all'); +jest.mock('../../../entity_analytics/api/hooks/use_risk_score'); const mockRiskScore = useRiskScore as jest.Mock; diff --git a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.tsx b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.tsx index 446fe215a695a9..572e4aab7e6dfa 100644 --- a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.tsx @@ -10,6 +10,7 @@ import { euiDarkVars as darkTheme, euiLightVars as lightTheme } from '@kbn/ui-th import { getOr } from 'lodash/fp'; import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; +import { useRiskScore } from '../../../entity_analytics/api/hooks/use_risk_score'; import { buildUserNamesFilter, RiskScoreEntity } from '../../../../common/search_strategy'; import { DEFAULT_DARK_MODE } from '../../../../common/constants'; import type { DescriptionList } from '../../../../common/utility_types'; @@ -32,10 +33,9 @@ import { DescriptionListStyled, OverviewWrapper } from '../../../common/componen import * as i18n from './translations'; import { OverviewDescriptionList } from '../../../common/components/overview_description_list'; -import { useRiskScore } from '../../../explore/containers/risk_score'; -import { RiskScoreLevel } from '../../../explore/components/risk_score/severity/common'; +import { RiskScoreLevel } from '../../../entity_analytics/components/severity/common'; import type { UserItem } from '../../../../common/search_strategy/security_solution/users/common'; -import { RiskScoreHeaderTitle } from '../../../explore/components/risk_score/risk_score_onboarding/risk_score_header_title'; +import { RiskScoreHeaderTitle } from '../../../entity_analytics/components/risk_score_onboarding/risk_score_header_title'; import type { SourcererScopeName } from '../../../common/store/sourcerer/model'; import { RiskScoreDocTooltip } from '../common'; diff --git a/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx b/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx index c98dbc74d5a2cd..b4abb383319521 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx @@ -24,8 +24,8 @@ import { useCtiDashboardLinks } from '../containers/overview_cti_links'; import { useIsExperimentalFeatureEnabled } from '../../common/hooks/use_experimental_features'; import { initialUserPrivilegesState } from '../../common/components/user_privileges/user_privileges_context'; import type { EndpointPrivileges } from '../../../common/endpoint/types'; -import { useRiskScore } from '../../explore/containers/risk_score'; import { mockCasesContract } from '@kbn/cases-plugin/public/mocks'; +import { useRiskScore } from '../../entity_analytics/api/hooks/use_risk_score'; const mockNavigateToApp = jest.fn(); jest.mock('../../common/components/landing_page'); @@ -97,7 +97,7 @@ jest.mock('../containers/overview_cti_links/use_all_ti_data_sources'); const useAllTiDataSourcesMock = useAllTiDataSources as jest.Mock; useAllTiDataSourcesMock.mockReturnValue(mockTiDataSources); -jest.mock('../../explore/containers/risk_score'); +jest.mock('../../entity_analytics/api/hooks/use_risk_score'); const useRiskScoreMock = useRiskScore as jest.Mock; useRiskScoreMock.mockReturnValue({ loading: false, data: [], isModuleEnabled: false }); diff --git a/x-pack/plugins/security_solution/public/overview/routes.tsx b/x-pack/plugins/security_solution/public/overview/routes.tsx index 560daf686242e0..82214b2463bdfa 100644 --- a/x-pack/plugins/security_solution/public/overview/routes.tsx +++ b/x-pack/plugins/security_solution/public/overview/routes.tsx @@ -21,7 +21,7 @@ import { StatefulOverview } from './pages/overview'; import { DataQuality } from './pages/data_quality'; import { DetectionResponse } from './pages/detection_response'; import { PluginTemplateWrapper } from '../common/components/plugin_template_wrapper'; -import { EntityAnalyticsPage } from './pages/entity_analytics'; +import { EntityAnalyticsPage } from '../entity_analytics/pages/entity_analytics_dashboard'; import { SecurityRoutePageWrapper } from '../common/components/security_route_page_wrapper'; import { LandingPage } from './pages/landing'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/index.test.tsx index 3f7702d490e9dc..f50142177ba8b6 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/index.test.tsx @@ -116,7 +116,7 @@ jest.mock( } ); jest.mock('../../../../detections/components/alerts_table/actions'); -jest.mock('../../../../explore/containers/risk_score', () => { +jest.mock('../../../../entity_analytics/api/hooks/use_risk_score', () => { return { useRiskScore: jest.fn().mockReturnValue({ loading: true, diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user.tsx index a208a9ae3f41f1..590f120b196878 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user.tsx @@ -18,7 +18,7 @@ import { import React, { useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { css } from '@emotion/css'; -import type { UserDetailsLeftPanelTab } from '../../../../flyout/entity_details/user_detais_left/tabs'; +import type { UserDetailsLeftPanelTab } from '../../../../flyout/entity_details/user_details_left/tabs'; import { UserAssetTableType } from '../../../../explore/users/store/model'; import type { ManagedUserFields } from '../../../../../common/search_strategy/security_solution/users/managed_details'; import { ManagedUserDatasetKey } from '../../../../../common/search_strategy/security_solution/users/managed_details'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user_accordion.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user_accordion.tsx index 9ae5a6433f0413..a03775f61cf26b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user_accordion.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/managed_user_accordion.tsx @@ -11,7 +11,7 @@ import React from 'react'; import { css } from '@emotion/react'; import { FormattedMessage } from '@kbn/i18n-react'; import { get } from 'lodash/fp'; -import { UserDetailsLeftPanelTab } from '../../../../flyout/entity_details/user_detais_left/tabs'; +import { UserDetailsLeftPanelTab } from '../../../../flyout/entity_details/user_details_left/tabs'; import { ExpandablePanel } from '../../../../flyout/shared/components/expandable_panel'; import type { ManagedUserFields } from '../../../../../common/search_strategy/security_solution/users/managed_details'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/risk_score_field.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/risk_score_field.tsx index 798588928bb777..fab77b92582f67 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/risk_score_field.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/new_user_detail/risk_score_field.tsx @@ -15,8 +15,8 @@ import * as i18n from './translations'; import { RiskScoreEntity } from '../../../../../common/search_strategy'; import { getEmptyTagValue } from '../../../../common/components/empty_value'; -import { RiskScoreLevel } from '../../../../explore/components/risk_score/severity/common'; -import type { RiskScoreState } from '../../../../explore/containers/risk_score'; +import { RiskScoreLevel } from '../../../../entity_analytics/components/severity/common'; +import type { RiskScoreState } from '../../../../entity_analytics/api/hooks/use_risk_score'; import { RiskScoreDocTooltip } from '../../../../overview/components/common'; export const TooltipContainer = styled.div` diff --git a/x-pack/plugins/security_solution/tsconfig.json b/x-pack/plugins/security_solution/tsconfig.json index 2158fe97996dc2..35767b63dab75a 100644 --- a/x-pack/plugins/security_solution/tsconfig.json +++ b/x-pack/plugins/security_solution/tsconfig.json @@ -185,6 +185,7 @@ "@kbn/core-http-common", "@kbn/search-errors", "@kbn/stack-connectors-plugin", - "@kbn/elastic-assistant-common" + "@kbn/elastic-assistant-common", + "@kbn/lens-embeddable-utils" ] } diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 1f97750f40911b..d47d3add7fd8ba 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -34810,7 +34810,6 @@ "xpack.securitySolution.entityAnalytics.hostsRiskDashboard.title": "Scores de risque de l'hôte", "xpack.securitySolution.entityAnalytics.riskDashboard.viewAllLabel": "Afficher tout", "xpack.securitySolution.entityAnalytics.technicalPreviewLabel": "Version d'évaluation technique", - "xpack.securitySolution.entityAnalytics.totalLabel": "Total", "xpack.securitySolution.entityAnalytics.usersRiskDashboard.title": "Scores de risque de l'utilisateur", "xpack.securitySolution.event.module.linkToElasticEndpointSecurityDescription": "Ouvrir dans Endpoint Security", "xpack.securitySolution.event.summary.threat_indicator.modal.allMatches": "Toutes les correspondances d'indicateur", @@ -35969,7 +35968,6 @@ "xpack.securitySolution.riskScore.errorPanel.errors": "Erreurs", "xpack.securitySolution.riskScore.errorPanel.message": "Un problème est survenu. Réessayez plus tard.", "xpack.securitySolution.riskScore.errorPanel.title": "Désolé, une erreur est survenue.", - "xpack.securitySolution.riskScore.errorSearchDescription": "Une erreur s'est produite sur la recherche du score de risque", "xpack.securitySolution.riskScore.failSearchDescription": "Impossible de lancer une recherche sur le score de risque", "xpack.securitySolution.riskScore.hostRiskScoresEnabledTitle": "Scores de risque de l'hôte activés", "xpack.securitySolution.riskScore.hostsDashboardWarningPanelBody": "Nous n’avons pas trouvé de données de score de risque de l’hôte. Vérifiez si vous avez des filtres globaux dans la barre de recherche KQL globale. Si vous venez d’activer le module de risque de l’hôte, le moteur de risque peut mettre une heure à générer les données de score de risque de l’hôte et les afficher dans ce panneau.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 0bcc41300dc7b5..71ebe72b930256 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -34809,7 +34809,6 @@ "xpack.securitySolution.entityAnalytics.hostsRiskDashboard.title": "ホストリスクスコア", "xpack.securitySolution.entityAnalytics.riskDashboard.viewAllLabel": "すべて表示", "xpack.securitySolution.entityAnalytics.technicalPreviewLabel": "テクニカルプレビュー", - "xpack.securitySolution.entityAnalytics.totalLabel": "合計", "xpack.securitySolution.entityAnalytics.usersRiskDashboard.title": "ユーザーリスクスコア", "xpack.securitySolution.event.module.linkToElasticEndpointSecurityDescription": "Endpoint Securityで開く", "xpack.securitySolution.event.summary.threat_indicator.modal.allMatches": "すべてのインジケーター一致", @@ -35968,7 +35967,6 @@ "xpack.securitySolution.riskScore.errorPanel.errors": "エラー", "xpack.securitySolution.riskScore.errorPanel.message": "何か問題が発生しましたしばらくたってから再試行してください。", "xpack.securitySolution.riskScore.errorPanel.title": "申し訳ございません、エラーが発生しました", - "xpack.securitySolution.riskScore.errorSearchDescription": "リスクスコア検索でエラーが発生しました", "xpack.securitySolution.riskScore.failSearchDescription": "リスクスコアで検索を実行できませんでした", "xpack.securitySolution.riskScore.hostRiskScoresEnabledTitle": "ホストリスクスコア有効", "xpack.securitySolution.riskScore.hostsDashboardWarningPanelBody": "ホストリスクスコアデータが見つかりません。グローバルKQL検索バーにグローバルフィルターがあるかどうかを確認してください。ホストリスクモジュールを有効にしたばかりの場合は、リスクエンジンがホストリスクスコアデータを生成し、このパネルに表示するまでに1時間かかることがあります。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 9e283e2a5fe0bb..ff583c718ddf8b 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -34804,7 +34804,6 @@ "xpack.securitySolution.entityAnalytics.hostsRiskDashboard.title": "主机风险分数", "xpack.securitySolution.entityAnalytics.riskDashboard.viewAllLabel": "查看全部", "xpack.securitySolution.entityAnalytics.technicalPreviewLabel": "技术预览", - "xpack.securitySolution.entityAnalytics.totalLabel": "合计", "xpack.securitySolution.entityAnalytics.usersRiskDashboard.title": "用户风险分数", "xpack.securitySolution.event.module.linkToElasticEndpointSecurityDescription": "在 Endpoint Security 中打开", "xpack.securitySolution.event.summary.threat_indicator.modal.allMatches": "所有指标匹配", @@ -35963,7 +35962,6 @@ "xpack.securitySolution.riskScore.errorPanel.errors": "错误", "xpack.securitySolution.riskScore.errorPanel.message": "出问题了。请稍后重试。", "xpack.securitySolution.riskScore.errorPanel.title": "抱歉,有错误", - "xpack.securitySolution.riskScore.errorSearchDescription": "搜索风险分数时发生错误", "xpack.securitySolution.riskScore.failSearchDescription": "无法对风险分数执行搜索", "xpack.securitySolution.riskScore.hostRiskScoresEnabledTitle": "已启用主机风险分数", "xpack.securitySolution.riskScore.hostsDashboardWarningPanelBody": "找不到任何主机风险分数数据。检查全局 KQL 搜索栏中是否具有任何全局筛选。如果刚刚启用了主机风险模块,风险引擎可能需要一小时才能生成并在此面板中显示主机风险分数数据。", From 1a0dcf60fc3f2a8d498ae68f92db53a8de7fd112 Mon Sep 17 00:00:00 2001 From: Sander Philipse <94373878+sphilipse@users.noreply.github.com> Date: Thu, 21 Dec 2023 14:58:25 +0100 Subject: [PATCH 072/116] [Search] Return empty array when checking api keys for unauthorized user (#173823) ## Summary Instead of returning an obnoxious error on every Search page when fetching an unauthorized user's API keys, we just return an empty array. --- .../server/routes/enterprise_search/api_keys.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/api_keys.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/api_keys.ts index 2262879657ec4e..abdac9fb57e0fd 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/api_keys.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/api_keys.ts @@ -54,9 +54,19 @@ export function registerApiKeysRoutes( const { client } = (await context.core).elasticsearch; const user = security.authc.getCurrentUser(request); if (user) { - const apiKeys = await client.asCurrentUser.security.getApiKey({ username: user.username }); - const validKeys = apiKeys.api_keys.filter(({ invalidated }) => !invalidated); - return response.ok({ body: { api_keys: validKeys } }); + try { + const apiKeys = await client.asCurrentUser.security.getApiKey({ + username: user.username, + }); + const validKeys = apiKeys.api_keys.filter(({ invalidated }) => !invalidated); + return response.ok({ body: { api_keys: validKeys } }); + } catch { + // Ideally we check the error response here for unauthorized user + // Unfortunately the error response is not structured enough for us to filter those + // Always returning an empty array should also be fine, and deals with transient errors + + return response.ok({ body: { api_keys: [] } }); + } } return response.customError({ body: 'Could not retrieve current user, security plugin is not ready', From 80edac1d5359079358143cfa791b5ae7c0268fc0 Mon Sep 17 00:00:00 2001 From: Xavier Mouligneau <xavier.mouligneau@elastic.co> Date: Thu, 21 Dec 2023 09:12:58 -0500 Subject: [PATCH 073/116] [RAM] Makes anomaly detection rule visible in Observability (#170451) ## Summary From the rule management page in observability, user will be able to create an anomaly detection rule. <img width="1789" alt="image" src="https://github.com/elastic/kibana/assets/189600/9ce84628-bf1b-44f6-a51b-5bd2ad94d9bd"> <img width="1792" alt="image" src="https://github.com/elastic/kibana/assets/189600/0add536c-2e62-4de5-9e06-2beedd0c0fe2"> --- packages/kbn-rule-data-utils/src/rule_types/index.ts | 3 ++- .../src/rule_types/stack_rules.ts | 1 + x-pack/plugins/infra/server/features.ts | 7 ++++++- x-pack/plugins/ml/common/constants/alerts.ts | 3 ++- x-pack/plugins/ml/common/index.ts | 1 + .../public/hooks/use_get_filtered_rule_types.ts | 8 ++++++-- x-pack/plugins/observability/server/plugin.ts | 2 ++ .../public/application/constants/index.ts | 12 ++++++++++-- .../rule_form/rule_form_consumer_selection.tsx | 1 + 9 files changed, 31 insertions(+), 7 deletions(-) diff --git a/packages/kbn-rule-data-utils/src/rule_types/index.ts b/packages/kbn-rule-data-utils/src/rule_types/index.ts index 6a716a5163dee2..e41ef872848159 100644 --- a/packages/kbn-rule-data-utils/src/rule_types/index.ts +++ b/packages/kbn-rule-data-utils/src/rule_types/index.ts @@ -15,4 +15,5 @@ export type RuleCreationValidConsumer = | typeof AlertConsumers.LOGS | typeof AlertConsumers.INFRASTRUCTURE | typeof AlertConsumers.OBSERVABILITY - | typeof STACK_ALERTS_FEATURE_ID; + | typeof STACK_ALERTS_FEATURE_ID + | 'alerts'; diff --git a/packages/kbn-rule-data-utils/src/rule_types/stack_rules.ts b/packages/kbn-rule-data-utils/src/rule_types/stack_rules.ts index ff426a9069537b..a2bf086d954a60 100644 --- a/packages/kbn-rule-data-utils/src/rule_types/stack_rules.ts +++ b/packages/kbn-rule-data-utils/src/rule_types/stack_rules.ts @@ -8,3 +8,4 @@ export const STACK_ALERTS_FEATURE_ID = 'stackAlerts'; export const ES_QUERY_ID = '.es-query'; +export const ML_ANOMALY_DETECTION_RULE_TYPE_ID = 'xpack.ml.anomaly_detection_alert'; diff --git a/x-pack/plugins/infra/server/features.ts b/x-pack/plugins/infra/server/features.ts index 5e6f809645ac1b..68fe2503ace143 100644 --- a/x-pack/plugins/infra/server/features.ts +++ b/x-pack/plugins/infra/server/features.ts @@ -8,7 +8,10 @@ import { i18n } from '@kbn/i18n'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; import { logViewSavedObjectName } from '@kbn/logs-shared-plugin/server'; -import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils'; +import { + ML_ANOMALY_DETECTION_RULE_TYPE_ID, + OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, +} from '@kbn/rule-data-utils'; import { ES_QUERY_ID } from '@kbn/rule-data-utils'; import { metricsDataSourceSavedObjectName } from '@kbn/metrics-data-access-plugin/server'; import { LOG_DOCUMENT_COUNT_RULE_TYPE_ID } from '../common/alerting/logs/log_threshold/types'; @@ -24,6 +27,7 @@ const metricRuleTypes = [ METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID, ES_QUERY_ID, OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, + ML_ANOMALY_DETECTION_RULE_TYPE_ID, ]; export const METRICS_FEATURE = { @@ -89,6 +93,7 @@ const logsRuleTypes = [ LOG_DOCUMENT_COUNT_RULE_TYPE_ID, ES_QUERY_ID, OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, + ML_ANOMALY_DETECTION_RULE_TYPE_ID, ]; export const LOGS_FEATURE = { diff --git a/x-pack/plugins/ml/common/constants/alerts.ts b/x-pack/plugins/ml/common/constants/alerts.ts index 4582f06b214b6b..81081cd79306af 100644 --- a/x-pack/plugins/ml/common/constants/alerts.ts +++ b/x-pack/plugins/ml/common/constants/alerts.ts @@ -12,11 +12,12 @@ import { ALERT_RULE_NAME, ALERT_START, ALERT_STATUS, + ML_ANOMALY_DETECTION_RULE_TYPE_ID, } from '@kbn/rule-data-utils'; import { JobsHealthTests } from '../types/alerts'; export const ML_ALERT_TYPES = { - ANOMALY_DETECTION: 'xpack.ml.anomaly_detection_alert', + ANOMALY_DETECTION: ML_ANOMALY_DETECTION_RULE_TYPE_ID, AD_JOBS_HEALTH: 'xpack.ml.anomaly_detection_jobs_health', } as const; diff --git a/x-pack/plugins/ml/common/index.ts b/x-pack/plugins/ml/common/index.ts index 1aed6088b79d85..f994ae95682cc8 100644 --- a/x-pack/plugins/ml/common/index.ts +++ b/x-pack/plugins/ml/common/index.ts @@ -9,3 +9,4 @@ export { composeValidators, patternValidator } from './util/validators'; export { getDefaultCapabilities as getDefaultMlCapabilities } from './types/capabilities'; export { DATAFEED_STATE, JOB_STATE } from './constants/states'; export type { MlSummaryJob, SummaryJobState } from './types/anomaly_detection_jobs'; +export { ML_ALERT_TYPES } from './constants/alerts'; diff --git a/x-pack/plugins/observability/public/hooks/use_get_filtered_rule_types.ts b/x-pack/plugins/observability/public/hooks/use_get_filtered_rule_types.ts index 24e8a0fc107fb9..99a448a36405d1 100644 --- a/x-pack/plugins/observability/public/hooks/use_get_filtered_rule_types.ts +++ b/x-pack/plugins/observability/public/hooks/use_get_filtered_rule_types.ts @@ -6,13 +6,17 @@ */ import { useMemo } from 'react'; -import { ES_QUERY_ID } from '@kbn/rule-data-utils'; +import { ES_QUERY_ID, ML_ANOMALY_DETECTION_RULE_TYPE_ID } from '@kbn/rule-data-utils'; import { usePluginContext } from './use_plugin_context'; export function useGetFilteredRuleTypes() { const { observabilityRuleTypeRegistry } = usePluginContext(); return useMemo(() => { - return [ES_QUERY_ID, ...observabilityRuleTypeRegistry.list()]; + return [ + ES_QUERY_ID, + ML_ANOMALY_DETECTION_RULE_TYPE_ID, + ...observabilityRuleTypeRegistry.list(), + ]; }, [observabilityRuleTypeRegistry]); } diff --git a/x-pack/plugins/observability/server/plugin.ts b/x-pack/plugins/observability/server/plugin.ts index 791ddc8108312f..b5be8fb9f622ec 100644 --- a/x-pack/plugins/observability/server/plugin.ts +++ b/x-pack/plugins/observability/server/plugin.ts @@ -28,6 +28,7 @@ import { i18n } from '@kbn/i18n'; import { ApmRuleType, ES_QUERY_ID, + ML_ANOMALY_DETECTION_RULE_TYPE_ID, METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID, OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, } from '@kbn/rule-data-utils'; @@ -89,6 +90,7 @@ const o11yRuleTypes = [ SLO_BURN_RATE_RULE_TYPE_ID, OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, ES_QUERY_ID, + ML_ANOMALY_DETECTION_RULE_TYPE_ID, METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID, ...Object.values(ApmRuleType), ]; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/constants/index.ts b/x-pack/plugins/triggers_actions_ui/public/application/constants/index.ts index bf4cafcf63da96..649af1c9fa07a8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/constants/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/constants/index.ts @@ -6,7 +6,11 @@ */ import { i18n } from '@kbn/i18n'; -import { ES_QUERY_ID, OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils'; +import { + ES_QUERY_ID, + OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, + ML_ANOMALY_DETECTION_RULE_TYPE_ID, +} from '@kbn/rule-data-utils'; export { BASE_ALERTING_API_PATH, INTERNAL_BASE_ALERTING_API_PATH, @@ -120,4 +124,8 @@ export const GLOBAL_CONNECTOR_EXECUTION_DEFAULT_INITIAL_VISIBLE_COLUMNS = [ ...CONNECTOR_LOCKED_COLUMNS, ]; -export const MULTI_CONSUMER_RULE_TYPE_IDS = [OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, ES_QUERY_ID]; +export const MULTI_CONSUMER_RULE_TYPE_IDS = [ + OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, + ES_QUERY_ID, + ML_ANOMALY_DETECTION_RULE_TYPE_ID, +]; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.tsx index 7d62c108d72414..a5bd9bc3420b72 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.tsx @@ -61,6 +61,7 @@ export const VALID_CONSUMERS: RuleCreationValidConsumer[] = [ AlertConsumers.LOGS, AlertConsumers.INFRASTRUCTURE, 'stackAlerts', + 'alerts', ]; export interface RuleFormConsumerSelectionProps { From 574ff80c444fcaa2717f8578ba4af09c5a433c06 Mon Sep 17 00:00:00 2001 From: Steph Milovic <stephanie.milovic@elastic.co> Date: Thu, 21 Dec 2023 08:40:49 -0600 Subject: [PATCH 074/116] [Security solution] Assistant telemetry conversation id fix (#173794) --- .../assistant/assistant_overlay/index.tsx | 17 +++++++------- .../impl/assistant/index.tsx | 9 ++------ .../impl/assistant_context/index.test.tsx | 23 +++++++++++++++++++ .../impl/assistant_context/index.tsx | 15 +++++++++--- 4 files changed, 46 insertions(+), 18 deletions(-) diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.tsx index ac72fc27dd891d..e866cad765456b 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.tsx @@ -33,8 +33,7 @@ export const AssistantOverlay = React.memo(() => { WELCOME_CONVERSATION_TITLE ); const [promptContextId, setPromptContextId] = useState<string | undefined>(); - const { assistantTelemetry, setShowAssistantOverlay, localStorageLastConversationId } = - useAssistantContext(); + const { assistantTelemetry, setShowAssistantOverlay, getConversationId } = useAssistantContext(); // Bind `showAssistantOverlay` in SecurityAssistantContext to this modal instance const showOverlay = useCallback( @@ -44,16 +43,18 @@ export const AssistantOverlay = React.memo(() => { promptContextId: pid, conversationId: cid, }: ShowAssistantOverlayProps) => { + const newConversationId = getConversationId(cid); if (so) assistantTelemetry?.reportAssistantInvoked({ - conversationId: cid ?? 'unknown', + conversationId: newConversationId, invokedBy: 'click', }); + setIsModalVisible(so); setPromptContextId(pid); - setConversationId(cid); + setConversationId(newConversationId); }, - [assistantTelemetry] + [assistantTelemetry, getConversationId] ); useEffect(() => { setShowAssistantOverlay(showOverlay); @@ -63,15 +64,15 @@ export const AssistantOverlay = React.memo(() => { const handleShortcutPress = useCallback(() => { // Try to restore the last conversation on shortcut pressed if (!isModalVisible) { - setConversationId(localStorageLastConversationId ?? WELCOME_CONVERSATION_TITLE); + setConversationId(getConversationId()); assistantTelemetry?.reportAssistantInvoked({ invokedBy: 'shortcut', - conversationId: localStorageLastConversationId ?? WELCOME_CONVERSATION_TITLE, + conversationId: getConversationId(), }); } setIsModalVisible(!isModalVisible); - }, [assistantTelemetry, isModalVisible, localStorageLastConversationId]); + }, [assistantTelemetry, isModalVisible, getConversationId]); // Register keyboard listener to show the modal when cmd + ; is pressed const onKeyDown = useCallback( diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx index 86e0f3a460055d..190eee654bc67e 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx @@ -83,7 +83,7 @@ const AssistantComponent: React.FC<Props> = ({ http, promptContexts, setLastConversationId, - localStorageLastConversationId, + getConversationId, title, allSystemPrompts, } = useAssistantContext(); @@ -113,12 +113,7 @@ const AssistantComponent: React.FC<Props> = ({ ); const [selectedConversationId, setSelectedConversationId] = useState<string>( - isAssistantEnabled - ? // if a conversationId has been provided, use that - // if not, check local storage - // last resort, go to welcome conversation - conversationId ?? localStorageLastConversationId ?? WELCOME_CONVERSATION_TITLE - : WELCOME_CONVERSATION_TITLE + isAssistantEnabled ? getConversationId(conversationId) : WELCOME_CONVERSATION_TITLE ); useEffect(() => { diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.test.tsx index 61f8352e0d3257..84a2ac40a6f248 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.test.tsx @@ -12,7 +12,11 @@ import { AssistantProvider, useAssistantContext } from '.'; import { httpServiceMock } from '@kbn/core-http-browser-mocks'; import { actionTypeRegistryMock } from '@kbn/triggers-actions-ui-plugin/public/application/action_type_registry.mock'; import { AssistantAvailability } from '../..'; +import { useLocalStorage } from 'react-use'; +jest.mock('react-use', () => ({ + useLocalStorage: jest.fn().mockReturnValue(['456', jest.fn()]), +})); const actionTypeRegistry = actionTypeRegistryMock.create(); const mockGetInitialConversations = jest.fn(() => ({})); const mockGetComments = jest.fn(() => []); @@ -70,4 +74,23 @@ describe('AssistantContext', () => { expect(mockHttp.fetch).toBeCalledWith(path); }); + + test('getConversationId defaults to provided id', async () => { + const { result } = renderHook(useAssistantContext, { wrapper: ContextWrapper }); + const id = result.current.getConversationId('123'); + expect(id).toEqual('123'); + }); + + test('getConversationId uses local storage id when no id is provided ', async () => { + const { result } = renderHook(useAssistantContext, { wrapper: ContextWrapper }); + const id = result.current.getConversationId(); + expect(id).toEqual('456'); + }); + + test('getConversationId defaults to Welcome when no local storage id and no id is provided ', async () => { + (useLocalStorage as jest.Mock).mockReturnValue([undefined, jest.fn()]); + const { result } = renderHook(useAssistantContext, { wrapper: ContextWrapper }); + const id = result.current.getConversationId(); + expect(id).toEqual('Welcome'); + }); }); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx index 4d0eec97f2639e..afb785e2025bdd 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx @@ -13,6 +13,7 @@ import type { IToasts } from '@kbn/core-notifications-browser'; import { ActionTypeRegistryContract } from '@kbn/triggers-actions-ui-plugin/public'; import { useLocalStorage } from 'react-use'; import type { DocLinksStart } from '@kbn/core-doc-links-browser'; +import { WELCOME_CONVERSATION_TITLE } from '../assistant/use_conversation/translations'; import { updatePromptContexts } from './helpers'; import type { PromptContext, @@ -136,7 +137,7 @@ export interface UseAssistantContext { }) => EuiCommentProps[]; http: HttpSetup; knowledgeBase: KnowledgeBaseConfig; - localStorageLastConversationId: string | undefined; + getConversationId: (id?: string) => string; promptContexts: Record<string, PromptContext>; modelEvaluatorEnabled: boolean; nameSpace: string; @@ -292,6 +293,14 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({ [setConversations] ); + const getConversationId = useCallback( + // if a conversationId has been provided, use that + // if not, check local storage + // last resort, go to welcome conversation + (id?: string) => id ?? localStorageLastConversationId ?? WELCOME_CONVERSATION_TITLE, + [localStorageLastConversationId] + ); + const value = useMemo( () => ({ actionTypeRegistry, @@ -334,7 +343,7 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({ title, toasts, unRegisterPromptContext, - localStorageLastConversationId, + getConversationId, setLastConversationId: setLocalStorageLastConversationId, }), [ @@ -358,7 +367,7 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({ getComments, http, localStorageKnowledgeBase, - localStorageLastConversationId, + getConversationId, localStorageQuickPrompts, localStorageSystemPrompts, modelEvaluatorEnabled, From f6b7df3d6ef1501d36546ff85bd10b954b95ddad Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin <aleh.zasypkin@elastic.co> Date: Thu, 21 Dec 2023 15:48:53 +0100 Subject: [PATCH 075/116] Unskip `Session Concurrent Limit cleanup` tests. (#173828) ## Summary Unskip `Session Concurrent Limit cleanup` tests. __Flaky Test Runner#1 (no changes, only unskipped tests):__ https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4666 (x100 - :red_circle: 1 out of 100) __Flaky Test Runner#2 (added additional `retry`):__ https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4667 (x200 - all :green_circle:) __Fixes: https://github.com/elastic/kibana/issues/149091__ --- .../tests/session_concurrent_limit/cleanup.ts | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/x-pack/test/security_api_integration/tests/session_concurrent_limit/cleanup.ts b/x-pack/test/security_api_integration/tests/session_concurrent_limit/cleanup.ts index 45d3bfc5b12eae..32f5351b4e4609 100644 --- a/x-pack/test/security_api_integration/tests/session_concurrent_limit/cleanup.ts +++ b/x-pack/test/security_api_integration/tests/session_concurrent_limit/cleanup.ts @@ -150,8 +150,7 @@ export default function ({ getService }: FtrProviderContext) { }); } - // Failing: See https://github.com/elastic/kibana/issues/149091 - describe.skip('Session Concurrent Limit cleanup', () => { + describe('Session Concurrent Limit cleanup', () => { before(async () => { await security.user.create('anonymous_user', { password: 'changeme', @@ -181,7 +180,10 @@ export default function ({ getService }: FtrProviderContext) { await setTimeoutAsync(500); const basicSessionCookieThree = await loginWithBasic(testUser); - expect(await getNumberOfSessionDocuments()).to.be(3); + log.debug('Waiting for all sessions to be persisted...'); + await retry.tryForTime(20000, async () => { + expect(await getNumberOfSessionDocuments()).to.be(3); + }); // Poke the background task to run await runCleanupTaskSoon(); @@ -210,7 +212,10 @@ export default function ({ getService }: FtrProviderContext) { const basicSessionCookieThree = await loginWithBasic(testUser); const samlSessionCookieThree = await loginWithSAML(); - expect(await getNumberOfSessionDocuments()).to.be(6); + log.debug('Waiting for all sessions to be persisted...'); + await retry.tryForTime(20000, async () => { + expect(await getNumberOfSessionDocuments()).to.be(6); + }); // Poke the background task to run await runCleanupTaskSoon(); @@ -243,7 +248,10 @@ export default function ({ getService }: FtrProviderContext) { const basicSessionCookieThree = await loginWithBasic(testUser); const samlSessionCookieThree = await loginWithSAML(); - expect(await getNumberOfSessionDocuments()).to.be(6); + log.debug('Waiting for all sessions to be persisted...'); + await retry.tryForTime(20000, async () => { + expect(await getNumberOfSessionDocuments()).to.be(6); + }); // Remove `createdAt` field from the most recent sessions to emulate legacy sessions. // 1. Get the latest session for every unique credentials. @@ -305,7 +313,10 @@ export default function ({ getService }: FtrProviderContext) { await setTimeoutAsync(500); const basicSessionCookieTwo = await loginWithBasic(testUser); - expect(await getNumberOfSessionDocuments()).to.be(2); + log.debug('Waiting for all sessions to be persisted...'); + await retry.tryForTime(20000, async () => { + expect(await getNumberOfSessionDocuments()).to.be(2); + }); // Poke the background task to run await runCleanupTaskSoon(); @@ -328,7 +339,10 @@ export default function ({ getService }: FtrProviderContext) { const anonymousSessionCookieTwo = await loginWithAnonymous(); const anonymousSessionCookieThree = await loginWithAnonymous(); - expect(await getNumberOfSessionDocuments()).to.be(3); + log.debug('Waiting for all sessions to be persisted...'); + await retry.tryForTime(20000, async () => { + expect(await getNumberOfSessionDocuments()).to.be(3); + }); // Poke the background task to run await runCleanupTaskSoon(); @@ -357,7 +371,10 @@ export default function ({ getService }: FtrProviderContext) { const unauthenticatedSessionTwo = await startSAMLHandshake(); const unauthenticatedSessionThree = await startSAMLHandshake(); - expect(await getNumberOfSessionDocuments()).to.be(3); + log.debug('Waiting for all sessions to be persisted...'); + await retry.tryForTime(20000, async () => { + expect(await getNumberOfSessionDocuments()).to.be(3); + }); // Poke the background task to run await runCleanupTaskSoon(); From 41375d7099c9118998619a31563b743221087517 Mon Sep 17 00:00:00 2001 From: Marco Liberati <dej611@users.noreply.github.com> Date: Thu, 21 Dec 2023 15:56:05 +0100 Subject: [PATCH 076/116] [ES|QL] Fix highlight for multiline #2 (#173827) ## Summary ![esql_syntax_fix](https://github.com/elastic/kibana/assets/924948/263e8cfd-3325-4a28-903f-d55dbb3dfeae) --- .../kbn-monaco/src/esql/lib/monaco/esql_tokens_provider.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/kbn-monaco/src/esql/lib/monaco/esql_tokens_provider.ts b/packages/kbn-monaco/src/esql/lib/monaco/esql_tokens_provider.ts index aa0234c155c336..ce521d1c9dfac2 100644 --- a/packages/kbn-monaco/src/esql/lib/monaco/esql_tokens_provider.ts +++ b/packages/kbn-monaco/src/esql/lib/monaco/esql_tokens_provider.ts @@ -57,7 +57,12 @@ export class ESQLTokensProvider implements monaco.languages.TokensProvider { const tokenTypeName = lexer.vocabulary.getSymbolicName(token.type); if (tokenTypeName) { - const myToken = new ESQLToken(tokenTypeName, token.startIndex, token.stopIndex); + const indexOffset = cleanedLine === line ? 0 : line.length - cleanedLine.length; + const myToken = new ESQLToken( + tokenTypeName, + token.startIndex + indexOffset, + token.stopIndex + indexOffset + ); myTokens.push(myToken); } } From ff0351eb5edd7f57ab856c48f7aa45c6ae95e502 Mon Sep 17 00:00:00 2001 From: Konrad Szwarc <konrad.szwarc@elastic.co> Date: Thu, 21 Dec 2023 15:59:41 +0100 Subject: [PATCH 077/116] [EDR Workflows][Serverless] E2E Endpoint creation fine tuning (#172463) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR addresses 3 known issues with environment setup on Serverless CI pipelines. ### Setup task fails on: ### 1. Host recreation after first failed attempt Test fails on: `AssertionError: Timed out retrying after 60000ms: Expected to find content: 'test-host-2321' but never did.` Failed job from before: [here](https://buildkite.com/elastic/kibana-on-merge/builds/38728#018c219b-c0b2-41a6-9cba-2613fa85382c) Endpoint creation task is successful (host is enrolled with fleet), however, it doesn't appear in kibana. Since we are using /metadata endpoint to list all agents I've added a check in the task to see if the endpoint makes it to the metadata . If it fails to do so I delete the endpoint and do a retry with additional index (.fleet-agents, metadata-current and metadata-unified) search (thanks @joeypoon) Successful job: [here](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4284#018c462c-21ec-44c0-afea-a630253e7717) ### 2. Fleet server not coming up Test fails on: `│ERROR Error: Timed out waiting for fleet server [dev-fleet-server.8284.gns5] to register with Elasticsarch` Failed job from before: [here](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4166#018c368c-2434-4a2a-aaab-ae097ef26843) If first attempt at creating and enrolling fleet server fails we do a retry. Successful job: [here](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4285#018c462c-487d-4a1c-8a37-71ca62915878) ### 3. Package policy creation fails Test fails on: `CypressError: cy.task('indexFleetEndpointPolicy') failed with the following error: Request failed with status code 500` **Couldn't recreate in CI.** Failed job from before: [here](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4204#018c3f17-3a3a-43dd-a31b-6bc5109d4193) Package installation fails with `no_shard_available_action_exception` error. We retry api call. closes https://github.com/elastic/kibana/issues/170482 (agent creation) closes https://github.com/elastic/kibana/issues/172920 (agent creation) closes https://github.com/elastic/kibana/issues/172319 (agent creation) closes https://github.com/elastic/kibana/issues/172326 (package policy) 1000 test runs on single test file (issues were occuring in setup tasks, not test cases itself): https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4496 https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4497 https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4498 https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4499 https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4500 https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4501 https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4502 https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4503 https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4504 https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4505 --- .../index_fleet_endpoint_policy.ts | 64 ++++- .../endpoint}/format_axios_error.ts | 0 .../create_and_enroll_endpoint_host_ci.ts | 12 +- .../cypress/support/data_loaders.ts | 8 +- .../common/endpoint_metadata_services.ts | 25 +- .../fleet_server/fleet_server_services.ts | 224 +++++++++--------- .../scripts/endpoint/common/fleet_services.ts | 41 ++-- .../common/random_policy_id_generator.ts | 2 +- .../endpoint/common/role_and_user_loader.ts | 2 +- .../scripts/endpoint/common/stack_services.ts | 2 +- .../endpoint/sentinelone_host/common.ts | 2 +- 11 files changed, 226 insertions(+), 156 deletions(-) rename x-pack/plugins/security_solution/{scripts/endpoint/common => common/endpoint}/format_axios_error.ts (100%) diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_endpoint_policy.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_endpoint_policy.ts index 558d0a2fa6a503..d122daf52627b4 100644 --- a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_endpoint_policy.ts +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_endpoint_policy.ts @@ -22,17 +22,23 @@ import { API_VERSIONS, } from '@kbn/fleet-plugin/common'; import { memoize } from 'lodash'; +import type { ToolingLog } from '@kbn/tooling-log'; +import { catchAxiosErrorFormatAndThrow } from '../format_axios_error'; import { usageTracker } from './usage_tracker'; import { getEndpointPackageInfo } from '../utils/package'; import type { PolicyData } from '../types'; import { policyFactory as policyConfigFactory } from '../models/policy_config'; -import { wrapErrorAndRejectPromise } from './utils'; +import { RETRYABLE_TRANSIENT_ERRORS, retryOnError, wrapErrorAndRejectPromise } from './utils'; export interface IndexedFleetEndpointPolicyResponse { integrationPolicies: PolicyData[]; agentPolicies: AgentPolicy[]; } +enum TimeoutsInMS { + TEN_SECONDS = 10 * 1000, + FIVE_MINUTES = 5 * 60 * 1000, +} /** * Create an endpoint Integration Policy (and associated Agent Policy) via Fleet * (NOTE: ensure that fleet is setup first before calling this loading function) @@ -43,7 +49,8 @@ export const indexFleetEndpointPolicy = usageTracker.track( kbnClient: KbnClient, policyName: string, endpointPackageVersion?: string, - agentPolicyName?: string + agentPolicyName?: string, + log?: ToolingLog ): Promise<IndexedFleetEndpointPolicyResponse> => { const response: IndexedFleetEndpointPolicyResponse = { integrationPolicies: [], @@ -84,6 +91,7 @@ export const indexFleetEndpointPolicy = usageTracker.track( // Create integration (package) policy const newPackagePolicyData: CreatePackagePolicyRequest['body'] = { name: policyName, + // skip_ensure_installed: true, description: 'Protect the worlds data', policy_id: agentPolicy.data.item.id, enabled: true, @@ -106,18 +114,48 @@ export const indexFleetEndpointPolicy = usageTracker.track( version: packageVersion, }, }; - const packagePolicy = (await kbnClient - .request({ - path: PACKAGE_POLICY_API_ROUTES.CREATE_PATTERN, - method: 'POST', - body: newPackagePolicyData, - headers: { - 'elastic-api-version': API_VERSIONS.public.v1, - }, - }) - .catch(wrapErrorAndRejectPromise)) as AxiosResponse<CreatePackagePolicyResponse>; - response.integrationPolicies.push(packagePolicy.data.item as PolicyData); + const createPackagePolicy = async (): Promise<CreatePackagePolicyResponse> => + kbnClient + .request<CreatePackagePolicyResponse>({ + path: PACKAGE_POLICY_API_ROUTES.CREATE_PATTERN, + method: 'POST', + body: newPackagePolicyData, + headers: { + 'elastic-api-version': API_VERSIONS.public.v1, + }, + }) + .catch(catchAxiosErrorFormatAndThrow) + .then((res) => res.data); + + const started = new Date(); + const hasTimedOut = (): boolean => { + const elapsedTime = Date.now() - started.getTime(); + return elapsedTime > TimeoutsInMS.FIVE_MINUTES; + }; + + let packagePolicy: CreatePackagePolicyResponse | undefined; + log?.debug(`Creating integration policy with name: ${policyName}`); + + while (!packagePolicy && !hasTimedOut()) { + packagePolicy = await retryOnError( + async () => createPackagePolicy(), + [...RETRYABLE_TRANSIENT_ERRORS, 'resource_not_found_exception'], + log + ); + + if (!packagePolicy) { + await new Promise((resolve) => setTimeout(resolve, TimeoutsInMS.TEN_SECONDS)); + } + } + + if (!packagePolicy) { + throw new Error(`Create package policy failed`); + } + + log?.verbose(`Integration policy created:`, JSON.stringify(packagePolicy, null, 2)); + + response.integrationPolicies.push(packagePolicy.item as PolicyData); return response; } diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/format_axios_error.ts b/x-pack/plugins/security_solution/common/endpoint/format_axios_error.ts similarity index 100% rename from x-pack/plugins/security_solution/scripts/endpoint/common/format_axios_error.ts rename to x-pack/plugins/security_solution/common/endpoint/format_axios_error.ts diff --git a/x-pack/plugins/security_solution/public/management/cypress/support/create_and_enroll_endpoint_host_ci.ts b/x-pack/plugins/security_solution/public/management/cypress/support/create_and_enroll_endpoint_host_ci.ts index df3a5cf6d38a07..ef28ebc445e2ad 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/support/create_and_enroll_endpoint_host_ci.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/support/create_and_enroll_endpoint_host_ci.ts @@ -6,6 +6,8 @@ */ import { kibanaPackageJson } from '@kbn/repo-info'; +import type { Client } from '@elastic/elasticsearch'; + import type { ToolingLog } from '@kbn/tooling-log'; import type { KbnClient } from '@kbn/test/src/kbn_client'; import { isFleetServerRunning } from '../../../../scripts/endpoint/common/fleet_server/fleet_server_services'; @@ -28,6 +30,7 @@ import { export interface CreateAndEnrollEndpointHostCIOptions extends Pick<BaseVmCreateOptions, 'disk' | 'cpus' | 'memory'> { + esClient: Client; kbnClient: KbnClient; log: ToolingLog; /** The fleet Agent Policy ID to use for enrolling the agent */ @@ -51,6 +54,7 @@ export interface CreateAndEnrollEndpointHostCIResponse { */ export const createAndEnrollEndpointHostCI = async ({ kbnClient, + esClient, log, agentPolicyId, cpus, @@ -122,7 +126,13 @@ export const createAndEnrollEndpointHostCI = async ({ await hostVm.exec(agentEnrollCommand); - const { id: agentId } = await waitForHostToEnroll(kbnClient, log, hostVm.name, 240000); + const { id: agentId } = await waitForHostToEnroll( + kbnClient, + log, + hostVm.name, + 5 * 60 * 1000, + esClient + ); return { hostname: hostVm.name, diff --git a/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts b/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts index 1c6e50b1cf2f4e..356082f7325da3 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts @@ -169,12 +169,13 @@ export const dataLoaders = ( endpointPackageVersion?: string; agentPolicyName?: string; }) => { - const { kbnClient } = await stackServicesPromise; + const { kbnClient, log } = await stackServicesPromise; return indexFleetEndpointPolicy( kbnClient, policyName, endpointPackageVersion, - agentPolicyName + agentPolicyName, + log ); }, @@ -390,7 +391,7 @@ ${s1Info.status} createEndpointHost: async ( options: Omit<CreateAndEnrollEndpointHostCIOptions, 'log' | 'kbnClient'> ): Promise<CreateAndEnrollEndpointHostCIResponse> => { - const { kbnClient, log } = await stackServicesPromise; + const { kbnClient, log, esClient } = await stackServicesPromise; let retryAttempt = 0; const attemptCreateEndpointHost = @@ -403,6 +404,7 @@ ${s1Info.status} ...options, log, kbnClient, + esClient, }) : await createAndEnrollEndpointHost({ useClosestVersionMatch: true, diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/endpoint_metadata_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/endpoint_metadata_services.ts index a69f348c366ebe..cf0672b113ac70 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/endpoint_metadata_services.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/endpoint_metadata_services.ts @@ -10,7 +10,11 @@ import type { KbnClient } from '@kbn/test'; import type { WriteResponseBase } from '@elastic/elasticsearch/lib/api/types'; import { clone, merge } from 'lodash'; import type { DeepPartial } from 'utility-types'; -import { catchAxiosErrorFormatAndThrow } from './format_axios_error'; +import { + RETRYABLE_TRANSIENT_ERRORS, + retryOnError, +} from '../../../common/endpoint/data_loaders/utils'; +import { catchAxiosErrorFormatAndThrow } from '../../../common/endpoint/format_axios_error'; import type { GetMetadataListRequestQuery } from '../../../common/api/endpoint'; import { resolvePathVariables } from '../../../public/common/utils/resolve_path_variables'; import { @@ -19,6 +23,7 @@ import { METADATA_DATASTREAM, } from '../../../common/endpoint/constants'; import type { HostInfo, HostMetadata, MetadataListResponse } from '../../../common/endpoint/types'; +import { HostStatus } from '../../../common/endpoint/types'; import { EndpointDocGenerator } from '../../../common/endpoint/generate_data'; const endpointGenerator = new EndpointDocGenerator(); @@ -163,15 +168,15 @@ export const waitForEndpointToStreamData = async ( let found: HostInfo | undefined; while (!found && !hasTimedOut()) { - found = await fetchEndpointMetadata(kbnClient, endpointAgentId).catch((error) => { - // Ignore `not found` (404) responses. Endpoint could be new and thus documents might not have - // been streamed yet. - if (error?.response?.status === 404) { - return undefined; - } - - throw error; - }); + found = await retryOnError( + async () => + fetchEndpointMetadataList(kbnClient, { + kuery: `united.endpoint.agent.id: "${endpointAgentId}"`, + }).then((response) => { + return response.data.filter((record) => record.host_status === HostStatus.HEALTHY)[0]; + }), + RETRYABLE_TRANSIENT_ERRORS + ); if (!found) { // sleep and check again diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_server/fleet_server_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_server/fleet_server_services.ts index bb322482feebf2..c9d5b84eb167bf 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_server/fleet_server_services.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_server/fleet_server_services.ts @@ -49,8 +49,8 @@ import { retryOnError, } from '../../../../common/endpoint/data_loaders/utils'; import { isServerlessKibanaFlavor } from '../stack_services'; -import type { FormattedAxiosError } from '../format_axios_error'; -import { catchAxiosErrorFormatAndThrow } from '../format_axios_error'; +import type { FormattedAxiosError } from '../../../../common/endpoint/format_axios_error'; +import { catchAxiosErrorFormatAndThrow } from '../../../../common/endpoint/format_axios_error'; import { ensureFleetSetup, fetchFleetOutputs, @@ -247,113 +247,120 @@ const startFleetServerWithDocker = async ({ let agentVersion = version || (await getAgentVersionMatchingCurrentStack(kbnClient)); const localhostRealIp = getLocalhostRealIp(); const fleetServerUrl = `https://${localhostRealIp}:${port}`; + const isServerless = await isServerlessKibanaFlavor(kbnClient); + const esURL = new URL(await getFleetElasticsearchOutputHost(kbnClient)); + const containerName = `dev-fleet-server.${port}`; log.info( `Starting a new fleet server using Docker\n Agent version: ${agentVersion}\n Server URL: ${fleetServerUrl}` ); - const response: StartedServer = await log.indent(4, async () => { - const isServerless = await isServerlessKibanaFlavor(kbnClient); - const esURL = new URL(await getFleetElasticsearchOutputHost(kbnClient)); - const containerName = `dev-fleet-server.${port}`; - const hostname = `dev-fleet-server.${port}.${Math.random().toString(32).substring(2, 6)}`; - let containerId = ''; - let fleetServerVersionInfo = ''; - - if (isLocalhost(esURL.hostname)) { - esURL.hostname = localhostRealIp; - } + let retryAttempt = isServerless ? 0 : 1; + const attemptServerlessFleetServerSetup = async (): Promise<StartedServer> => { + return log.indent(4, async () => { + const hostname = `dev-fleet-server.${port}.${Math.random().toString(32).substring(2, 6)}`; + let containerId = ''; + let fleetServerVersionInfo = ''; + + if (isLocalhost(esURL.hostname)) { + esURL.hostname = localhostRealIp; + } - if (isServerless) { - log.info(`Kibana running in serverless mode. + if (isServerless) { + log.info(`Kibana running in serverless mode. - will install/run standalone Fleet Server - version adjusted to [latest] from [${agentVersion}]`); - agentVersion = 'latest'; - } else { - assert.ok(!!policyId, '`policyId` is required'); - assert.ok(!!serviceToken, '`serviceToken` is required'); - } - - // Create the `elastic` network to use with all containers - await maybeCreateDockerNetwork(log); + agentVersion = 'latest'; + } else { + assert.ok(!!policyId, '`policyId` is required'); + assert.ok(!!serviceToken, '`serviceToken` is required'); + } - try { - const dockerArgs = isServerless - ? getFleetServerStandAloneDockerArgs({ - containerName, - hostname, - port, - esUrl: esURL.toString(), - agentVersion, + // Create the `elastic` network to use with all containers + await maybeCreateDockerNetwork(log); + try { + const dockerArgs = isServerless + ? getFleetServerStandAloneDockerArgs({ + containerName, + hostname, + port, + esUrl: esURL.toString(), + agentVersion, + }) + : getFleetServerManagedDockerArgs({ + containerName, + hostname, + port, + serviceToken, + policyId, + agentVersion, + esUrl: esURL.toString(), + }); + + await execa('docker', ['kill', containerName]) + .then(() => { + log.info( + `Killed an existing container with name [${containerName}]. New one will be started.` + ); }) - : getFleetServerManagedDockerArgs({ - containerName, - hostname, - port, - serviceToken, - policyId, - agentVersion, - esUrl: esURL.toString(), + .catch((error) => { + if (!/no such container/i.test(error.message)) { + log.verbose(`Attempt to kill currently running fleet-server container with name [${containerName}] was unsuccessful: + ${error}`); + } }); - await execa('docker', ['kill', containerName]) - .then(() => { - log.info( - `Killed an existing container with name [${containerName}]. New one will be started.` - ); - }) - .catch((error) => { - if (!/no such container/i.test(error.message)) { - log.verbose(`Attempt to kill currently running fleet-server container with name [${containerName}] was unsuccessful: - ${error}`); - } - }); + log.verbose(`docker arguments:\n${dockerArgs.join(' ')}`); - log.verbose(`docker arguments:\n${dockerArgs.join(' ')}`); + containerId = (await execa('docker', dockerArgs)).stdout; - containerId = (await execa('docker', dockerArgs)).stdout; + log.info(`Fleet server started`); - log.info(`Fleet server started`); + if (!isServerless) { + await addFleetServerHostToFleetSettings(kbnClient, log, fleetServerUrl); + } - if (!isServerless) { - await addFleetServerHostToFleetSettings(kbnClient, log, fleetServerUrl); - } + await updateFleetElasticsearchOutputHostNames(kbnClient, log); - await updateFleetElasticsearchOutputHostNames(kbnClient, log); + if (isServerless) { + log.info(`Waiting for server [${hostname}] to register with Elasticsearch`); + await waitForFleetServerToRegisterWithElasticsearch(kbnClient, hostname, 180000); + } else { + await waitForHostToEnroll(kbnClient, log, hostname, 120000); + } - if (isServerless) { - log.info(`Waiting for server [${hostname}] to register with Elasticsearch`); + fleetServerVersionInfo = isServerless + ? // `/usr/bin/fleet-server` process does not seem to support a `--version` type of argument + 'Running latest standalone fleet server' + : ( + await execa('docker', [ + 'exec', + containerName, + '/bin/bash', + '-c', + '/usr/share/elastic-agent/elastic-agent version', + ]).catch((err) => { + log.verbose( + `Failed to retrieve agent version information from running instance.`, + err + ); + return { stdout: 'Unable to retrieve version information' }; + }) + ).stdout; + } catch (error) { + if (retryAttempt < 1) { + retryAttempt++; + log.error(`Failed to start fleet server, retrying. Error: ${error.message}`); + log.verbose(dump(error)); + return attemptServerlessFleetServerSetup(); + } - await waitForFleetServerToRegisterWithElasticsearch(kbnClient, hostname, 180000); - } else { - await waitForHostToEnroll(kbnClient, log, hostname, 120000); + log.error(dump(error)); + throw error; } - fleetServerVersionInfo = isServerless - ? // `/usr/bin/fleet-server` process does not seem to support a `--version` type of argument - 'Running latest standalone fleet server' - : ( - await execa('docker', [ - 'exec', - containerName, - '/bin/bash', - '-c', - '/usr/share/elastic-agent/elastic-agent version', - ]).catch((err) => { - log.verbose( - `Failed to retrieve agent version information from running instance.`, - err - ); - return { stdout: 'Unable to retrieve version information' }; - }) - ).stdout; - } catch (error) { - log.error(dump(error)); - throw error; - } - - const info = `Container Name: ${containerName} + const info = `Container Name: ${containerName} Container Id: ${containerId} Fleet-server version: ${fleetServerVersionInfo.replace(/\n/g, '\n ')} @@ -363,26 +370,29 @@ Shell access: ${chalk.cyan(`docker exec -it ${containerName} /bin/bash`) Kill container: ${chalk.cyan(`docker kill ${containerId}`)} `; - return { - type: 'docker', - name: containerName, - id: containerId, - url: fleetServerUrl, - info, - stop: async () => { - log.info( - `Stopping (kill) fleet server. Container name [${containerName}] id [${containerId}]` - ); - await execa('docker', ['kill', containerId]); - }, - stopNow: () => { - log.info( - `Stopping (kill) fleet server. Container name [${containerName}] id [${containerId}]` - ); - execa.sync('docker', ['kill', containerId]); - }, - }; - }); + return { + type: 'docker', + name: containerName, + id: containerId, + url: fleetServerUrl, + info, + stop: async () => { + log.info( + `Stopping (kill) fleet server. Container name [${containerName}] id [${containerId}]` + ); + await execa('docker', ['kill', containerId]); + }, + stopNow: () => { + log.info( + `Stopping (kill) fleet server. Container name [${containerName}] id [${containerId}]` + ); + execa.sync('docker', ['kill', containerId]); + }, + }; + }); + }; + + const response: StartedServer = await attemptServerlessFleetServerSetup(); log.info(`Done. Fleet server up and running`); diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts index 1ca0e3ef12273d..97a9df146c2ac2 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts @@ -9,20 +9,20 @@ import { map, memoize, pick } from 'lodash'; import type { Client, estypes } from '@elastic/elasticsearch'; import type { Agent, + AgentPolicy, AgentStatus, + CreateAgentPolicyRequest, + CreateAgentPolicyResponse, + CreatePackagePolicyRequest, + CreatePackagePolicyResponse, GetAgentPoliciesRequest, GetAgentPoliciesResponse, GetAgentsResponse, + GetInfoResponse, + GetOneAgentPolicyResponse, GetPackagePoliciesRequest, GetPackagePoliciesResponse, - CreateAgentPolicyRequest, - AgentPolicy, - CreateAgentPolicyResponse, - CreatePackagePolicyResponse, - CreatePackagePolicyRequest, PackagePolicy, - GetInfoResponse, - GetOneAgentPolicyResponse, PostFleetSetupResponse, } from '@kbn/fleet-plugin/common'; import { @@ -47,13 +47,13 @@ import { outputRoutesService, } from '@kbn/fleet-plugin/common/services'; import type { + DeleteAgentPolicyResponse, EnrollmentAPIKey, + GenerateServiceTokenResponse, GetAgentsRequest, GetEnrollmentAPIKeysResponse, - PostAgentUnenrollResponse, - GenerateServiceTokenResponse, GetOutputsResponse, - DeleteAgentPolicyResponse, + PostAgentUnenrollResponse, } from '@kbn/fleet-plugin/common/types'; import nodeFetch from 'node-fetch'; import semver from 'semver'; @@ -71,7 +71,7 @@ import { wrapErrorAndRejectPromise, } from '../../../common/endpoint/data_loaders/utils'; import { fetchKibanaStatus } from './stack_services'; -import { catchAxiosErrorFormatAndThrow } from './format_axios_error'; +import { catchAxiosErrorFormatAndThrow } from '../../../common/endpoint/format_axios_error'; import { FleetAgentGenerator } from '../../../common/endpoint/data_generators/fleet_agent_generator'; const fleetGenerator = new FleetAgentGenerator(); @@ -161,12 +161,14 @@ export const fetchFleetAgents = async ( * @param log * @param hostname * @param timeoutMs + * @param esClient */ export const waitForHostToEnroll = async ( kbnClient: KbnClient, log: ToolingLog, hostname: string, - timeoutMs: number = 30000 + timeoutMs: number = 30000, + esClient: Client | undefined = undefined ): Promise<Agent> => { log.info(`Waiting for host [${hostname}] to enroll with fleet`); @@ -212,6 +214,12 @@ export const waitForHostToEnroll = async ( log.debug(`Host [${hostname}] has been enrolled with fleet`); log.verbose(found); + // Workaround for united metadata sometimes being unable to find docs in .fleet-agents index. This + // seems to be a timing issue with the index refresh. + await esClient?.search({ + index: AGENTS_INDEX, + }); + return found; }; @@ -401,9 +409,7 @@ export const getAgentFileName = (agentVersion: string): string => { const downloadArch = { arm64: 'arm64', x64: 'x86_64' }[process.arch as string] ?? `UNSUPPORTED_ARCHITECTURE_${process.arch}`; - const fileName = `elastic-agent-${agentVersion}-linux-${downloadArch}`; - - return fileName; + return `elastic-agent-${agentVersion}-linux-${downloadArch}`; }; interface ElasticArtifactSearchResponse { @@ -560,8 +566,7 @@ export const unEnrollFleetAgent = async ( * Un-enrolls a Fleet agent * * @param kbnClient - * @param agentId - * @param force + * @param policyId */ export const getAgentPolicyEnrollmentKey = async ( kbnClient: KbnClient, @@ -655,7 +660,7 @@ interface EnrollHostVmWithFleetOptions { /** * Installs the Elastic agent on the provided Host VM and enrolls with it Fleet. * - * NOTE: this method assumes that FLeet-Server is already setup and running. + * NOTE: this method assumes that Fleet-Server is already setup and running. * * @param hostVm * @param kbnClient diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/random_policy_id_generator.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/random_policy_id_generator.ts index 3b494d3bfe9cb2..3c58f44b3d266f 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/random_policy_id_generator.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/random_policy_id_generator.ts @@ -12,7 +12,7 @@ import { PACKAGE_POLICY_API_ROUTES, PACKAGE_POLICY_SAVED_OBJECT_TYPE, } from '@kbn/fleet-plugin/common/constants'; -import { catchAxiosErrorFormatAndThrow } from './format_axios_error'; +import { catchAxiosErrorFormatAndThrow } from '../../../common/endpoint/format_axios_error'; import { indexFleetEndpointPolicy } from '../../../common/endpoint/data_loaders/index_fleet_endpoint_policy'; import { setupFleetForEndpoint } from '../../../common/endpoint/data_loaders/setup_fleet_for_endpoint'; import type { GetPolicyListResponse } from '../../../public/management/pages/policy/types'; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/role_and_user_loader.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/role_and_user_loader.ts index f8c51d52550184..eb493e22dafafd 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/role_and_user_loader.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/role_and_user_loader.ts @@ -14,7 +14,7 @@ import { inspect } from 'util'; import type { AxiosError } from 'axios'; import type { EndpointSecurityRoleDefinitions } from './roles_users'; import { getAllEndpointSecurityRoles } from './roles_users'; -import { catchAxiosErrorFormatAndThrow } from './format_axios_error'; +import { catchAxiosErrorFormatAndThrow } from '../../../common/endpoint/format_axios_error'; import { COMMON_API_HEADERS } from './constants'; const ignoreHttp409Error = (error: AxiosError) => { diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/stack_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/stack_services.ts index 13fc2a1a0ffba2..f95ee808408ed7 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/stack_services.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/stack_services.ts @@ -17,7 +17,7 @@ import type { ClientOptions } from '@elastic/elasticsearch/lib/client'; import fs from 'fs'; import { CA_CERT_PATH } from '@kbn/dev-utils'; import { createToolingLogger } from '../../../common/endpoint/data_loaders/utils'; -import { catchAxiosErrorFormatAndThrow } from './format_axios_error'; +import { catchAxiosErrorFormatAndThrow } from '../../../common/endpoint/format_axios_error'; import { isLocalhost } from './is_localhost'; import { getLocalhostRealIp } from './network_services'; import { createSecuritySuperuser } from './security_user_services'; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts b/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts index f15c08ee875002..483bae1c4275e8 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts @@ -14,7 +14,7 @@ import type { S1AgentPackage, S1AgentPackageListApiResponse, } from './types'; -import { catchAxiosErrorFormatAndThrow } from '../common/format_axios_error'; +import { catchAxiosErrorFormatAndThrow } from '../../../common/endpoint/format_axios_error'; import type { HostVm } from '../common/types'; interface S1ClientOptions { From e22ad3648bd990c441728d74efba1d687935db5d Mon Sep 17 00:00:00 2001 From: Paul Tavares <56442535+paul-tavares@users.noreply.github.com> Date: Thu, 21 Dec 2023 10:22:59 -0500 Subject: [PATCH 078/116] [Security Solution][Endpoint] Improve the `run_sentinelone_host` script so that it also creates the Connector and SIEM Rule (#173693) ## Summary Improves the `x-pack/plugins/security_solution/scripts/endpoint/run_sentinelone_host.js` script to also: - Create a Connector for SentinelOne if one is not already created - Create a Detection Engine rule to promote SentinelOne alerts to SIEM Alerts, if one is not already created Co-authored-by: Ash <1849116+ashokaditya@users.noreply.github.com> --- .../endpoint/common/connectors_services.ts | 68 +++++++++++++ .../common/detection_rules_services.ts | 99 +++++++++++++++++++ .../scripts/endpoint/common/fleet_services.ts | 11 +-- .../scripts/endpoint/common/vm_services.ts | 8 +- .../endpoint/sentinelone_host/common.ts | 84 ++++++++++++++++ .../endpoint/sentinelone_host/index.ts | 14 ++- 6 files changed, 272 insertions(+), 12 deletions(-) create mode 100644 x-pack/plugins/security_solution/scripts/endpoint/common/connectors_services.ts create mode 100644 x-pack/plugins/security_solution/scripts/endpoint/common/detection_rules_services.ts diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/connectors_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/connectors_services.ts new file mode 100644 index 00000000000000..e63215005ae9bb --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/connectors_services.ts @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { KbnClient } from '@kbn/test'; +import type { AllConnectorsResponseV1 } from '@kbn/actions-plugin/common/routes/connector/response'; +import type { bodySchema } from '@kbn/actions-plugin/server/routes/create'; +import type { TypeOf } from '@kbn/config-schema'; +import type { Connector } from '@kbn/actions-plugin/server/application/connector/types'; +import { catchAxiosErrorFormatAndThrow } from './format_axios_error'; + +/** + * Retrieve list of configured Connectors + * @param kbnClient + */ +export const fetchConnectorsList = async ( + kbnClient: KbnClient +): Promise<AllConnectorsResponseV1[]> => { + return kbnClient + .request<AllConnectorsResponseV1[]>({ + path: '/api/actions/connectors', + method: 'GET', + }) + .catch(catchAxiosErrorFormatAndThrow) + .then((response) => response.data); +}; + +/** + * Returns the first connector instance (if any) of a given type + * @param kbnClient + * @param connectorTypeId + */ +export const fetchConnectorByType = async ( + kbnClient: KbnClient, + connectorTypeId: string +): Promise<AllConnectorsResponseV1 | undefined> => { + const allConnectors = await fetchConnectorsList(kbnClient); + + for (const connector of allConnectors) { + if (connector.connector_type_id === connectorTypeId) { + return connector; + } + } +}; + +type CreateConnectorBody = TypeOf<typeof bodySchema>; + +/** + * Creates a connector in the stack + * @param kbnClient + * @param createPayload + */ +export const createConnector = async ( + kbnClient: KbnClient, + createPayload: CreateConnectorBody +): Promise<Connector> => { + return kbnClient + .request<Connector>({ + path: '/api/actions/connector', + method: 'POST', + body: createPayload, + }) + .catch(catchAxiosErrorFormatAndThrow) + .then((response) => response.data); +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/detection_rules_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/detection_rules_services.ts new file mode 100644 index 00000000000000..81f343427b3d58 --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/detection_rules_services.ts @@ -0,0 +1,99 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { KbnClient } from '@kbn/test'; +import { catchAxiosErrorFormatAndThrow } from './format_axios_error'; +import { + DETECTION_ENGINE_RULES_URL, + DETECTION_ENGINE_RULES_URL_FIND, +} from '../../../common/constants'; +import type { + CreateRuleRequestBody, + FindRulesRequestQuery, + FindRulesResponse, + RuleResponse, +} from '../../../common/api/detection_engine'; + +/** + * Creates a detection engine rule + * @param kbnClient + * @param payload + */ +export const createRule = async ( + kbnClient: KbnClient, + payload: Partial<CreateRuleRequestBody> = {} +): Promise<RuleResponse> => { + return kbnClient + .request<RuleResponse>({ + path: DETECTION_ENGINE_RULES_URL, + method: 'POST', + body: { + type: 'query', + index: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'traces-apm*', + 'winlogbeat-*', + '-*elastic-cloud-logs-*', + ], + filters: [], + language: 'kuery', + query: '_id:*', + author: [], + false_positives: [], + references: [], + risk_score: 21, + risk_score_mapping: [], + severity: 'low', + severity_mapping: [], + threat: [], + name: `Test rule - ${Math.random().toString(36).substring(2)}`, + description: `Test rule created from: ${__filename}`, + tags: [], + license: '', + interval: '1m', + from: 'now-120s', + to: 'now', + meta: { + from: '1m', + kibana_siem_app_url: kbnClient.resolveUrl('/app/security'), + }, + actions: [], + enabled: true, + throttle: 'no_actions', + + ...payload, + }, + headers: { 'elastic-api-version': '2023-10-31' }, + }) + .catch(catchAxiosErrorFormatAndThrow) + .then((response) => response.data); +}; + +/** + * Query the Detection Rules + * @param kbnClient + * @param query + */ +export const findRules = async ( + kbnClient: KbnClient, + query: Partial<FindRulesRequestQuery> = {} +): Promise<FindRulesResponse> => { + return kbnClient + .request<FindRulesResponse>({ + path: DETECTION_ENGINE_RULES_URL_FIND, + method: 'GET', + headers: { 'elastic-api-version': '2023-10-31' }, + query, + }) + .catch(catchAxiosErrorFormatAndThrow) + .then((response) => response.data); +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts index 97a9df146c2ac2..b1ff5e8464a00d 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts @@ -68,7 +68,6 @@ import { createToolingLogger, RETRYABLE_TRANSIENT_ERRORS, retryOnError, - wrapErrorAndRejectPromise, } from '../../../common/endpoint/data_loaders/utils'; import { fetchKibanaStatus } from './stack_services'; import { catchAxiosErrorFormatAndThrow } from '../../../common/endpoint/format_axios_error'; @@ -777,13 +776,13 @@ export const getOrCreateDefaultAgentPolicy = async ({ }); if (existingPolicy.items[0]) { - log.info(`Re-using existing Fleet test agent policy`); + log.info(`Re-using existing Fleet test agent policy: [${existingPolicy.items[0].name}]`); log.verbose(existingPolicy.items[0]); return existingPolicy.items[0]; } - log.info(`Creating new default test/dev Fleet agent policy`); + log.info(`Creating default test/dev Fleet agent policy with name: [${policyName}]`); const newAgentPolicyData: CreateAgentPolicyRequest['body'] = { name: policyName, @@ -802,7 +801,7 @@ export const getOrCreateDefaultAgentPolicy = async ({ body: newAgentPolicyData, }) .then((response) => response.data.item) - .catch(wrapErrorAndRejectPromise); + .catch(catchAxiosErrorFormatAndThrow); log.verbose(newAgentPolicy); @@ -828,7 +827,7 @@ export const createIntegrationPolicy = async ( }, }) .then((response) => response.data.item) - .catch(wrapErrorAndRejectPromise); + .catch(catchAxiosErrorFormatAndThrow); }; /** @@ -847,7 +846,7 @@ export const fetchPackageInfo = async ( method: 'GET', }) .then((response) => response.data.item) - .catch(wrapErrorAndRejectPromise); + .catch(catchAxiosErrorFormatAndThrow); }; interface AddSentinelOneIntegrationToAgentPolicyOptions { diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/vm_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/vm_services.ts index 17c74b1bf6fc3a..4209b554b2732b 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/vm_services.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/vm_services.ts @@ -178,10 +178,10 @@ export const getMultipassVmCountNotice = async (threshold: number = 1): Promise< if (output.list.length > threshold) { return `----------------------------------------------------------------- ${chalk.red('NOTE:')} ${chalk.bold( - chalk.cyan(`You currently have ${chalk.red(output.list.length)} VMs running.`) - )} Remember to delete those - no longer being used. - View running VMs: ${chalk.bold('multipass list')} + chalk.red(`You currently have ${chalk.red(output.list.length)} VMs running.`) + )} + Remember to delete those no longer being used. + View running VMs: ${chalk.cyan('multipass list')} ----------------------------------------------------------------- `; } diff --git a/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts b/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts index 483bae1c4275e8..fe9053795737a9 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts @@ -8,6 +8,10 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type { AxiosRequestConfig } from 'axios'; import axios from 'axios'; +import type { KbnClient } from '@kbn/test'; +import { SENTINELONE_CONNECTOR_ID } from '@kbn/stack-connectors-plugin/common/sentinelone/constants'; +import { type RuleResponse } from '../../../common/api/detection_engine'; +import { dump } from '../endpoint_agent_runner/utils'; import { createToolingLogger } from '../../../common/endpoint/data_loaders/utils'; import type { S1SitesListApiResponse, @@ -17,6 +21,9 @@ import type { import { catchAxiosErrorFormatAndThrow } from '../../../common/endpoint/format_axios_error'; import type { HostVm } from '../common/types'; +import { createConnector, fetchConnectorByType } from '../common/connectors_services'; +import { createRule, findRules } from '../common/detection_rules_services'; + interface S1ClientOptions { /** The base URL for SentinelOne */ url: string; @@ -200,6 +207,13 @@ export const installSentinelOneAgent = async ({ const status = (await hostVm.exec(`sudo ${installPath} control status`)).stdout; + try { + // Generate an alert in SentinelOne + await hostVm.exec('nslookup amazon.com'); + } catch (e) { + log?.warning(`Attempted to generate an alert on SentinelOne host failed: ${e.message}`); + } + log.info('done'); return { @@ -208,3 +222,73 @@ export const installSentinelOneAgent = async ({ }; }); }; + +interface CreateSentinelOneStackConnectorIfNeededOptions { + kbnClient: KbnClient; + log: ToolingLog; + s1Url: string; + s1ApiToken: string; + name?: string; +} + +export const createSentinelOneStackConnectorIfNeeded = async ({ + kbnClient, + log, + s1ApiToken, + s1Url, + name = 'SentinelOne Dev instance', +}: CreateSentinelOneStackConnectorIfNeededOptions): Promise<void> => { + const connector = await fetchConnectorByType(kbnClient, SENTINELONE_CONNECTOR_ID); + + if (connector) { + log.debug(`Nothing to do. A connector for SentinelOne is already configured`); + log.verbose(dump(connector)); + return; + } + + log.info(`Creating SentinelOne Connector with name: ${name}`); + + await createConnector(kbnClient, { + name, + config: { + url: s1Url, + }, + secrets: { + token: s1ApiToken, + }, + connector_type_id: SENTINELONE_CONNECTOR_ID, + }); +}; + +export const createDetectionEngineSentinelOneRuleIfNeeded = async ( + kbnClient: KbnClient, + log: ToolingLog +): Promise<RuleResponse> => { + const ruleName = 'Promote SentinelOne alerts'; + const sentinelOneAlertsIndexPattern = 'logs-sentinel_one.alert'; + const ruleQueryValue = 'observer.serial_number:*'; + + const { data } = await findRules(kbnClient, { + filter: `(alert.attributes.params.query: "${ruleQueryValue}" AND alert.attributes.params.index: ${sentinelOneAlertsIndexPattern})`, + }); + + if (data.length) { + log.info( + `Detection engine rule for SentinelOne alerts already exists [${data[0].name}]. No need to create a new one.` + ); + + return data[0]; + } + + log.info(`Creating new detection engine rule named [${ruleName}] for SentinelOne`); + + const createdRule = await createRule(kbnClient, { + index: [sentinelOneAlertsIndexPattern], + query: ruleQueryValue, + from: 'now-3660s', + }); + + log.verbose(dump(createdRule)); + + return createdRule; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/index.ts b/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/index.ts index 3fad8bf0223bb7..3416b8d4e51b6f 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/index.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/index.ts @@ -21,7 +21,12 @@ import { fetchAgentPolicy, getOrCreateDefaultAgentPolicy, } from '../common/fleet_services'; -import { installSentinelOneAgent, S1Client } from './common'; +import { + createDetectionEngineSentinelOneRuleIfNeeded, + createSentinelOneStackConnectorIfNeeded, + installSentinelOneAgent, + S1Client, +} from './common'; import { createVm, generateVmName, getMultipassVmCountNotice } from '../common/vm_services'; import { createKbnClient } from '../common/stack_services'; @@ -157,11 +162,16 @@ const runCli: RunFn = async ({ log, flags }) => { agentPolicyId, }); } else { - log.info( + log.debug( `No host VM created for Fleet agent policy [${agentPolicyName}]. It already shows to have [${agents}] enrolled` ); } + await Promise.all([ + createSentinelOneStackConnectorIfNeeded({ kbnClient, log, s1ApiToken, s1Url }), + createDetectionEngineSentinelOneRuleIfNeeded(kbnClient, log), + ]); + log.info(`Done! ${hostVm.info()} From 85245e13e6aba610a5a336b3528888c712f24d71 Mon Sep 17 00:00:00 2001 From: Paul Tavares <56442535+paul-tavares@users.noreply.github.com> Date: Thu, 21 Dec 2023 10:37:44 -0500 Subject: [PATCH 079/116] [Security Solution][Endpoint] Add support for agent type to response action APIs (#172322) ## Summary PR builds towards being able to support sending response actions against 3rd party EDR systems - with focus on SentinelOne for the next release. The framework puts in place a standard interface for systems that we will support response actions for - Elastic Defend `endpoint` being the existing one, and SentinelOne being the next one to be supported. - Adds `agent_type` to all Response Actions APIs (`isolate`, `unisolate`, etc...) - attribute is optional and defaults to `endpoint` when not defined (backwards compatible) - Adds support for `agent_type` of `sentinel_one` - Currently only allowed when `responseActionsSentinelOneV1Enabled` experimental feature flag is enabled - Adds response actions client for SentinelOne - Only `isolate` has been implemented. All other response actions, if called via API, will receive a `405` HTTP error code - Only the Action Request internal document is currently written to ES, thus the action will appear in the UI (action history log) as pending - Updates to the Action History Log API are not included in this PR, thus some things might not be displayed correctly --- .../api/endpoint/actions/common/base.ts | 8 + .../service/response_actions/constants.ts | 4 + .../common/endpoint/types/actions.ts | 3 +- .../common/endpoint/types/utility_types.ts | 7 + .../common/experimental_features.ts | 5 + .../endpoint/endpoint_app_context_services.ts | 10 + .../response_actions/base_actions_provider.ts | 86 --- .../server/endpoint/mocks.ts | 3 + .../routes/actions/response_actions.test.ts | 113 +++- .../routes/actions/response_actions.ts | 59 +- .../actions/action_details_by_id.test.ts | 6 +- .../services/actions/action_details_by_id.ts | 12 +- .../clients/endpoint_actions_client.ts | 35 +- .../services/actions/clients/errors.ts | 46 ++ .../get_response_actions_client.test.ts | 39 ++ .../clients/get_response_actions_client.ts | 40 ++ .../services/actions/clients/index.ts | 6 +- .../lib/base_response_actions_client.test.ts | 515 ++++++++++++++++++ .../lib/base_response_actions_client.ts | 366 +++++++++++++ .../actions/clients/lib}/types.ts | 6 +- .../services/actions/clients/mocks.ts | 209 +++++++ .../sentinel_one_actions_client.test.ts | 167 ++++++ .../sentinel_one_actions_client.ts | 148 +++++ .../actions/create/write_action_to_indices.ts | 20 +- .../server/endpoint/services/actions/index.ts | 1 + .../server/endpoint/utils/dump.ts | 18 + .../security_solution/server/plugin.ts | 1 + .../server/utils/custom_http_request_error.ts | 7 +- .../plugins/security_solution/tsconfig.json | 1 + .../agent_type_support.ts | 34 ++ .../apis/index.ts | 1 + 31 files changed, 1825 insertions(+), 151 deletions(-) delete mode 100644 x-pack/plugins/security_solution/server/endpoint/lib/response_actions/base_actions_provider.ts create mode 100644 x-pack/plugins/security_solution/server/endpoint/services/actions/clients/errors.ts create mode 100644 x-pack/plugins/security_solution/server/endpoint/services/actions/clients/get_response_actions_client.test.ts create mode 100644 x-pack/plugins/security_solution/server/endpoint/services/actions/clients/get_response_actions_client.ts create mode 100644 x-pack/plugins/security_solution/server/endpoint/services/actions/clients/lib/base_response_actions_client.test.ts create mode 100644 x-pack/plugins/security_solution/server/endpoint/services/actions/clients/lib/base_response_actions_client.ts rename x-pack/plugins/security_solution/server/endpoint/{lib/response_actions => services/actions/clients/lib}/types.ts (93%) create mode 100644 x-pack/plugins/security_solution/server/endpoint/services/actions/clients/mocks.ts create mode 100644 x-pack/plugins/security_solution/server/endpoint/services/actions/clients/sentinelone/sentinel_one_actions_client.test.ts create mode 100644 x-pack/plugins/security_solution/server/endpoint/services/actions/clients/sentinelone/sentinel_one_actions_client.ts create mode 100644 x-pack/plugins/security_solution/server/endpoint/utils/dump.ts create mode 100644 x-pack/test/security_solution_endpoint_api_int/apis/endpoint_response_actions/agent_type_support.ts diff --git a/x-pack/plugins/security_solution/common/api/endpoint/actions/common/base.ts b/x-pack/plugins/security_solution/common/api/endpoint/actions/common/base.ts index 9adc5f7289dc5a..755361902eaa1d 100644 --- a/x-pack/plugins/security_solution/common/api/endpoint/actions/common/base.ts +++ b/x-pack/plugins/security_solution/common/api/endpoint/actions/common/base.ts @@ -7,6 +7,7 @@ import type { TypeOf } from '@kbn/config-schema'; import { schema } from '@kbn/config-schema'; +import { RESPONSE_ACTION_AGENT_TYPE } from '../../../../endpoint/service/response_actions/constants'; export const BaseActionRequestSchema = { /** A list of endpoint IDs whose hosts will be isolated (Fleet Agent IDs will be retrieved for these) */ @@ -42,6 +43,13 @@ export const BaseActionRequestSchema = { ), comment: schema.maybe(schema.string()), parameters: schema.maybe(schema.object({})), + agent_type: schema.maybe( + schema.oneOf( + // @ts-expect-error TS2769: No overload matches this call + RESPONSE_ACTION_AGENT_TYPE.map((agentType) => schema.literal(agentType)), + { defaultValue: 'endpoint' } + ) + ), }; export const NoParametersRequestSchema = { diff --git a/x-pack/plugins/security_solution/common/endpoint/service/response_actions/constants.ts b/x-pack/plugins/security_solution/common/endpoint/service/response_actions/constants.ts index 14d1272add26ba..67a29b7a185a21 100644 --- a/x-pack/plugins/security_solution/common/endpoint/service/response_actions/constants.ts +++ b/x-pack/plugins/security_solution/common/endpoint/service/response_actions/constants.ts @@ -11,6 +11,10 @@ export type ResponseActionStatus = typeof RESPONSE_ACTION_STATUS[number]; export const RESPONSE_ACTION_TYPE = ['automated', 'manual'] as const; export type ResponseActionType = typeof RESPONSE_ACTION_TYPE[number]; + +export const RESPONSE_ACTION_AGENT_TYPE = ['endpoint', 'sentinel_one'] as const; +export type ResponseActionAgentType = typeof RESPONSE_ACTION_AGENT_TYPE[number]; + /** * The Command names that are used in the API payload for the `{ command: '' }` attribute */ diff --git a/x-pack/plugins/security_solution/common/endpoint/types/actions.ts b/x-pack/plugins/security_solution/common/endpoint/types/actions.ts index 98fb9b0f16b0c1..f2393c02c3b41d 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/actions.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/actions.ts @@ -17,6 +17,7 @@ import type { import type { ResponseActionStatus, ResponseActionsApiCommandNames, + ResponseActionAgentType, } from '../service/response_actions/constants'; export type ISOLATION_ACTIONS = 'isolate' | 'unisolate'; @@ -104,7 +105,7 @@ interface EndpointActionFields< interface ActionRequestFields { expiration: string; type: 'INPUT_ACTION'; - input_type: 'endpoint'; + input_type: ResponseActionAgentType; } interface ActionResponseFields { diff --git a/x-pack/plugins/security_solution/common/endpoint/types/utility_types.ts b/x-pack/plugins/security_solution/common/endpoint/types/utility_types.ts index 92880d93221914..a70c8e124eb842 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/utility_types.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/utility_types.ts @@ -10,3 +10,10 @@ export type PromiseResolvedValue<T extends Promise<any>> = T extends Promise<infer Value> ? Value : never; + +/** + * Deeply convert a immutable type (those with `readonly` properties) to a mutable type + */ +export type DeepMutable<T> = T extends Record<any, any> + ? { -readonly [K in keyof T]: DeepMutable<T[K]> } + : T; diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index 8c16307ab5b8c5..4a84e25f692d79 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -71,6 +71,11 @@ export const allowedExperimentalValues = Object.freeze({ */ responseActionUploadEnabled: true, + /** + * Enables the ability to send Response actions to SentinelOne + */ + responseActionsSentinelOneV1Enabled: false, + /** * Enables top charts on Alerts Page */ diff --git a/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts b/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts index 3fb28c1c5099db..4a1c1332916db0 100644 --- a/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts +++ b/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts @@ -9,6 +9,7 @@ import type { ElasticsearchClient, KibanaRequest, Logger, + LoggerFactory, SavedObjectsClientContract, } from '@kbn/core/server'; import type { ExceptionListClient, ListsServerExtensionRegistrar } from '@kbn/lists-plugin/server'; @@ -52,6 +53,7 @@ import type { AppFeaturesService } from '../lib/app_features_service/app_feature export interface EndpointAppContextServiceSetupContract { securitySolutionRequestContextFactory: IRequestContextFactory; cloud: CloudSetup; + loggerFactory: LoggerFactory; } export interface EndpointAppContextServiceStartContract { @@ -172,6 +174,14 @@ export class EndpointAppContextService { return this.startDependencies.fleetAuthzService; } + public createLogger(...contextParts: string[]) { + if (!this.setupDependencies?.loggerFactory) { + throw new EndpointAppContentServicesNotStartedError(); + } + + return this.setupDependencies.loggerFactory.get(...contextParts); + } + public async getEndpointAuthz(request: KibanaRequest): Promise<EndpointAuthz> { const fleetAuthz = await this.getFleetAuthzService().fromRequest(request); const userRoles = this.security?.authc.getCurrentUser(request)?.roles ?? []; diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/response_actions/base_actions_provider.ts b/x-pack/plugins/security_solution/server/endpoint/lib/response_actions/base_actions_provider.ts deleted file mode 100644 index 906402b877e0e0..00000000000000 --- a/x-pack/plugins/security_solution/server/endpoint/lib/response_actions/base_actions_provider.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; -import type { CasesClient } from '@kbn/cases-plugin/server'; -import type { Logger } from '@kbn/logging'; -import type { EndpointAppContext } from '../../types'; -import type { ResponseActionsProvider } from './types'; -import type { - ActionDetails, - GetProcessesActionOutputContent, - KillOrSuspendProcessRequestBody, - KillProcessActionOutputContent, - ResponseActionExecuteOutputContent, - ResponseActionGetFileOutputContent, - ResponseActionGetFileParameters, - ResponseActionParametersWithPidOrEntityId, - ResponseActionsExecuteParameters, - ResponseActionUploadOutputContent, - ResponseActionUploadParameters, - SuspendProcessActionOutputContent, -} from '../../../../common/endpoint/types'; -import type { - IsolationRouteRequestBody, - ExecuteActionRequestBody, - GetProcessesRequestBody, - ResponseActionGetFileRequestBody, - UploadActionApiRequestBody, -} from '../../../../common/api/endpoint'; - -export interface BaseActionsProviderOptions { - endpointContext: EndpointAppContext; - esClient: ElasticsearchClient; - casesClient?: CasesClient; - /** Username that will be stored along with the action's ES documents */ - username: string; -} - -export abstract class BaseResponseActionsClient implements ResponseActionsProvider { - protected readonly log: Logger; - - constructor(protected readonly options: BaseActionsProviderOptions) { - this.log = options.endpointContext.logFactory.get(this.constructor.name ?? 'ActionsProvider'); - } - - // TODO:PT implement a generic way to update cases without relying on the Attachments being endpoint agents - // protected async updateCases(): Promise<void> { - // throw new Error('Method not yet implemented'); - // } - - public abstract isolate(options: IsolationRouteRequestBody): Promise<ActionDetails>; - - public abstract release(options: IsolationRouteRequestBody): Promise<ActionDetails>; - - public abstract killProcess( - options: KillOrSuspendProcessRequestBody - ): Promise< - ActionDetails<KillProcessActionOutputContent, ResponseActionParametersWithPidOrEntityId> - >; - - public abstract suspendProcess( - options: KillOrSuspendProcessRequestBody - ): Promise< - ActionDetails<SuspendProcessActionOutputContent, ResponseActionParametersWithPidOrEntityId> - >; - - public abstract runningProcesses( - options: GetProcessesRequestBody - ): Promise<ActionDetails<GetProcessesActionOutputContent>>; - - public abstract getFile( - options: ResponseActionGetFileRequestBody - ): Promise<ActionDetails<ResponseActionGetFileOutputContent, ResponseActionGetFileParameters>>; - - public abstract execute( - options: ExecuteActionRequestBody - ): Promise<ActionDetails<ResponseActionExecuteOutputContent, ResponseActionsExecuteParameters>>; - - public abstract upload( - options: UploadActionApiRequestBody - ): Promise<ActionDetails<ResponseActionUploadOutputContent, ResponseActionUploadParameters>>; -} diff --git a/x-pack/plugins/security_solution/server/endpoint/mocks.ts b/x-pack/plugins/security_solution/server/endpoint/mocks.ts index 6376bf45540415..477d1e70be966d 100644 --- a/x-pack/plugins/security_solution/server/endpoint/mocks.ts +++ b/x-pack/plugins/security_solution/server/endpoint/mocks.ts @@ -101,6 +101,7 @@ export const createMockEndpointAppContextService = ( const fleetFromHostFilesClientMock = createFleetFromHostFilesClientMock(); const fleetToHostFilesClientMock = createFleetToHostFilesClientMock(); const fleetActionsClientMock = createFleetActionsClientMock(); + const loggerFactory = loggingSystemMock.create(); return { start: jest.fn(), @@ -108,6 +109,7 @@ export const createMockEndpointAppContextService = ( experimentalFeatures: { ...allowedExperimentalValues, }, + createLogger: jest.fn((...parts) => loggerFactory.get(...parts)), getManifestManager: jest.fn().mockReturnValue(mockManifestManager ?? jest.fn()), getEndpointMetadataService: jest.fn(() => mockEndpointMetadataContext.endpointMetadataService), getInternalFleetServices: jest.fn(() => mockEndpointMetadataContext.fleetServices), @@ -133,6 +135,7 @@ export const createMockEndpointAppContextServiceSetupContract = return { securitySolutionRequestContextFactory: requestContextFactoryMock.create(), cloud: cloudMock.createSetup(), + loggerFactory: loggingSystemMock.create(), }; }; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.test.ts index 8f7682c83daadf..055ef330cb08fa 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.test.ts @@ -62,13 +62,30 @@ import * as ActionDetailsService from '../../services/actions/action_details_by_ import { CaseStatuses } from '@kbn/cases-components'; import { getEndpointAuthzInitialStateMock } from '../../../../common/endpoint/service/authz/mocks'; import { actionCreateService } from '../../services/actions'; +import { getResponseActionsClient as _getResponseActionsClient } from '../../services'; import type { UploadActionApiRequestBody } from '../../../../common/api/endpoint'; import type { FleetToHostFileClientInterface } from '@kbn/fleet-plugin/server'; import type { HapiReadableStream, SecuritySolutionRequestHandlerContext } from '../../../types'; import { createHapiReadableStreamMock } from '../../services/actions/mocks'; import { EndpointActionGenerator } from '../../../../common/endpoint/data_generators/endpoint_action_generator'; import { CustomHttpRequestError } from '../../../utils/custom_http_request_error'; -import { omit } from 'lodash'; +import { omit, set } from 'lodash'; +import type { ResponseActionAgentType } from '../../../../common/endpoint/service/response_actions/constants'; +import { responseActionsClientMock } from '../../services/actions/clients/mocks'; +import type { ActionsApiRequestHandlerContext } from '@kbn/actions-plugin/server'; + +jest.mock('../../services', () => { + const realModule = jest.requireActual('../../services'); + + return { + ...realModule, + getResponseActionsClient: jest.fn((...args) => { + return realModule.getResponseActionsClient(...args); + }), + }; +}); + +const getResponseActionsClientMock = _getResponseActionsClient; interface CallRouteInterface { body?: ResponseActionRequestBody; @@ -1085,7 +1102,7 @@ describe('Response actions', () => { }); afterEach(() => { - jest.resetAllMocks(); + jest.clearAllMocks(); }); it('should create a file', async () => { @@ -1147,4 +1164,96 @@ describe('Response actions', () => { }); }); }); + + describe('and `responseActionsSentinelOneV1Enabled` feature flag is enabled', () => { + let testSetup: HttpApiTestSetupMock; + let httpRequestMock: ReturnType<HttpApiTestSetupMock['createRequestMock']>; + let httpHandlerContextMock: HttpApiTestSetupMock['httpHandlerContextMock']; + let httpResponseMock: HttpApiTestSetupMock['httpResponseMock']; + let callHandler: () => ReturnType<RequestHandler>; + + beforeEach(async () => { + testSetup = createHttpApiTestSetupMock(); + + ({ httpHandlerContextMock, httpResponseMock } = testSetup); + httpRequestMock = testSetup.createRequestMock(); + + testSetup.endpointAppContextMock.experimentalFeatures = { + ...testSetup.endpointAppContextMock.experimentalFeatures, + responseActionsSentinelOneV1Enabled: true, + }; + + httpHandlerContextMock.actions = Promise.resolve({ + getActionsClient: () => responseActionsClientMock.createConnectorActionsClient(), + } as unknown as jest.Mocked<ActionsApiRequestHandlerContext>); + + // Set the esClient to be used in the handler context + // eslint-disable-next-line require-atomic-updates + httpHandlerContextMock.core = Promise.resolve( + set( + await httpHandlerContextMock.core, + 'elasticsearch.client.asInternalUser', + responseActionsClientMock.createConstructorOptions().esClient + ) + ); + + httpRequestMock = testSetup.createRequestMock({ + body: { + endpoint_ids: ['123-456'], + }, + }); + registerResponseActionRoutes(testSetup.routerMock, testSetup.endpointAppContextMock); + + (testSetup.endpointAppContextMock.service.getEndpointMetadataService as jest.Mock) = jest + .fn() + .mockReturnValue({ + getMetadataForEndpoints: jest.fn().mockResolvedValue([ + { + elastic: { + agent: { + id: '123-456', + }, + }, + }, + ]), + }); + + const handler = testSetup.getRegisteredVersionedRoute( + 'post', + ISOLATE_HOST_ROUTE_V2, + '2023-10-31' + ).routeHandler as RequestHandler; + + callHandler = () => handler(httpHandlerContextMock, httpRequestMock, httpResponseMock); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it.each([ + ['undefined', undefined], + ['blank value', ''], + ['endpoint', 'endpoint'], + ])( + 'should use endpoint response actions client when agentType is: %s', + async (_, agentTypeValue) => { + if (agentTypeValue !== undefined) { + httpRequestMock.body.agent_type = agentTypeValue as ResponseActionAgentType; + } + await callHandler(); + + expect(getResponseActionsClientMock).toHaveBeenCalledWith('endpoint', expect.anything()); + expect(httpResponseMock.ok).toHaveBeenCalled(); + } + ); + + it('should use SentinelOne response actions client when agent type is sentinel_one', async () => { + httpRequestMock.body.agent_type = 'sentinel_one'; + await callHandler(); + + expect(getResponseActionsClientMock).toHaveBeenCalledWith('sentinel_one', expect.anything()); + expect(httpResponseMock.ok).toHaveBeenCalled(); + }); + }); }); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.ts index c8669869833fe4..4e8fdc997572af 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.ts @@ -7,8 +7,10 @@ import type { RequestHandler } from '@kbn/core/server'; import type { TypeOf } from '@kbn/config-schema'; +import { dump } from '../../utils/dump'; +import { getResponseActionsClient } from '../../services'; +import type { ResponseActionsClient } from '../../services/actions/clients/lib/types'; import { CustomHttpRequestError } from '../../../utils/custom_http_request_error'; -import { EndpointActionsClient } from '../../services/actions/clients'; import type { NoParametersRequestSchema, ResponseActionsRequestBody, @@ -290,50 +292,77 @@ function responseActionRequestHandler<T extends EndpointActionDataParameterTypes const logger = endpointContext.logFactory.get('responseActionsHandler'); return async (context, req, res) => { + logger.debug(`response action [${command}]:\n${dump(req.body)}`); + + // Note: because our API schemas are defined as module static variables (as opposed to a + // `getter` function), we need to include this additional validation here, since + // `agent_type` is included in the schema independent of the feature flag + if ( + req.body.agent_type && + !endpointContext.experimentalFeatures.responseActionsSentinelOneV1Enabled + ) { + return errorHandler( + logger, + res, + new CustomHttpRequestError(`[request body.agent_type]: feature is disabled`, 400) + ); + } + const user = endpointContext.service.security?.authc.getCurrentUser(req); const esClient = (await context.core).elasticsearch.client.asInternalUser; const casesClient = await endpointContext.service.getCasesClient(req); - const actionsClient = new EndpointActionsClient({ - esClient, - casesClient, - endpointContext, - username: user?.username ?? 'unknown', - }); + const connectorActions = (await context.actions).getActionsClient(); + const responseActionsClient: ResponseActionsClient = getResponseActionsClient( + req.body.agent_type || 'endpoint', + { + esClient, + casesClient, + endpointService: endpointContext.service, + username: user?.username || 'unknown', + connectorActions, + } + ); try { let action: ActionDetails; switch (command) { case 'isolate': - action = await actionsClient.isolate(req.body); + action = await responseActionsClient.isolate(req.body); break; case 'unisolate': - action = await actionsClient.release(req.body); + action = await responseActionsClient.release(req.body); break; case 'running-processes': - action = await actionsClient.runningProcesses(req.body); + action = await responseActionsClient.runningProcesses(req.body); break; case 'execute': - action = await actionsClient.execute(req.body as ExecuteActionRequestBody); + action = await responseActionsClient.execute(req.body as ExecuteActionRequestBody); break; case 'suspend-process': - action = await actionsClient.suspendProcess(req.body as KillOrSuspendProcessRequestBody); + action = await responseActionsClient.suspendProcess( + req.body as KillOrSuspendProcessRequestBody + ); break; case 'kill-process': - action = await actionsClient.killProcess(req.body as KillOrSuspendProcessRequestBody); + action = await responseActionsClient.killProcess( + req.body as KillOrSuspendProcessRequestBody + ); break; case 'get-file': - action = await actionsClient.getFile(req.body as ResponseActionGetFileRequestBody); + action = await responseActionsClient.getFile( + req.body as ResponseActionGetFileRequestBody + ); break; case 'upload': - action = await actionsClient.upload(req.body as UploadActionApiRequestBody); + action = await responseActionsClient.upload(req.body as UploadActionApiRequestBody); break; default: diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.test.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.test.ts index 452bf46316d603..54d536e314edd7 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.test.ts @@ -127,11 +127,7 @@ describe('When using `getActionDetailsById()', () => { body: { query: { bool: { - filter: [ - { term: { action_id: '123' } }, - { term: { input_type: 'endpoint' } }, - { term: { type: 'INPUT_ACTION' } }, - ], + filter: [{ term: { action_id: '123' } }], }, }, }, diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.ts index 9c85a193d712d8..8e3d6ddad12b87 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.ts @@ -31,11 +31,11 @@ import { NotFoundError } from '../../errors'; import { ACTION_RESPONSE_INDICES, ACTIONS_SEARCH_PAGE_SIZE } from './constants'; import type { EndpointMetadataService } from '../metadata'; -export const getActionDetailsById = async ( +export const getActionDetailsById = async <T extends ActionDetails = ActionDetails>( esClient: ElasticsearchClient, metadataService: EndpointMetadataService, actionId: string -): Promise<ActionDetails> => { +): Promise<T> => { let actionRequestsLogEntries: EndpointActivityLogAction[]; let normalizedActionRequest: ReturnType<typeof mapToNormalizedActionRequest> | undefined; @@ -52,11 +52,7 @@ export const getActionDetailsById = async ( body: { query: { bool: { - filter: [ - { term: { action_id: actionId } }, - { term: { input_type: 'endpoint' } }, - { term: { type: 'INPUT_ACTION' } }, - ], + filter: [{ term: { action_id: actionId } }], }, }, }, @@ -148,5 +144,5 @@ export const getActionDetailsById = async ( parameters: normalizedActionRequest.parameters, }; - return actionDetails; + return actionDetails as T; }; diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/endpoint_actions_client.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/endpoint_actions_client.ts index 2b5813fa6c909e..a999659f2273a7 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/endpoint_actions_client.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/endpoint_actions_client.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { dump } from '../../../utils/dump'; import type { HapiReadableStream } from '../../../../types'; import type { ResponseActionsApiCommandNames } from '../../../../../common/endpoint/service/response_actions/constants'; import { updateCases } from '../create/update_cases'; @@ -17,7 +18,7 @@ import type { UploadActionApiRequestBody, ResponseActionsRequestBody, } from '../../../../../common/api/endpoint'; -import { BaseResponseActionsClient } from '../../../lib/response_actions/base_actions_provider'; +import { ResponseActionsClientImpl } from './lib/base_response_actions_client'; import type { ActionDetails, HostMetadata, @@ -32,18 +33,16 @@ import type { ResponseActionUploadOutputContent, ResponseActionUploadParameters, SuspendProcessActionOutputContent, - HostMetadataInterface, - ImmutableObject, } from '../../../../../common/endpoint/types'; -export class EndpointActionsClient extends BaseResponseActionsClient { +export class EndpointActionsClient extends ResponseActionsClientImpl { private async checkAgentIds(ids: string[]): Promise<{ valid: string[]; invalid: string[]; allValid: boolean; hosts: HostMetadata[]; }> { - const foundEndpointHosts = await this.options.endpointContext.service + const foundEndpointHosts = await this.options.endpointService .getEndpointMetadataService() .getMetadataForEndpoints(this.options.esClient, [...new Set(ids)]); const validIds = foundEndpointHosts.map((endpoint: HostMetadata) => endpoint.elastic.agent.id); @@ -72,26 +71,24 @@ export class EndpointActionsClient extends BaseResponseActionsClient { user: { username: this.options.username }, }; - const response = await this.options.endpointContext.service + const response = await this.options.endpointService .getActionCreateService() .createAction(createPayload, agentIds.valid); - await this.updateCases(createPayload, agentIds.hosts); + try { + await updateCases({ + casesClient: this.options.casesClient, + endpointData: agentIds.hosts, + createActionPayload: createPayload, + }); + } catch (err) { + // failures during update of cases should not cause the response action to fail. Just log error + this.log.warn(`failed to update cases: ${err.message}\n${dump(err)}`); + } return response as TResponse; } - protected async updateCases( - createActionPayload: CreateActionPayload, - endpointData: Array<ImmutableObject<HostMetadataInterface>> - ): Promise<void> { - return updateCases({ - casesClient: this.options.casesClient, - createActionPayload, - endpointData, - }); - } - async isolate(options: IsolationRouteRequestBody): Promise<ActionDetails> { return this.handleResponseAction<IsolationRouteRequestBody, ActionDetails>('isolate', options); } @@ -155,7 +152,7 @@ export class EndpointActionsClient extends BaseResponseActionsClient { async upload( options: UploadActionApiRequestBody ): Promise<ActionDetails<ResponseActionUploadOutputContent, ResponseActionUploadParameters>> { - const fleetFiles = await this.options.endpointContext.service.getFleetToHostFilesClient(); + const fleetFiles = await this.options.endpointService.getFleetToHostFilesClient(); const fileStream = options.file as HapiReadableStream; const { file: _, parameters: userParams, ...actionPayload } = options; const uploadParameters: ResponseActionUploadParameters = { diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/errors.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/errors.ts new file mode 100644 index 00000000000000..300f2fa56cade1 --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/errors.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* eslint-disable max-classes-per-file */ + +import type { ResponseActionsApiCommandNames } from '../../../../../common/endpoint/service/response_actions/constants'; +import { dump } from '../../../utils/dump'; +import { CustomHttpRequestError } from '../../../../utils/custom_http_request_error'; + +/** + * Errors associated with Response Actions clients + */ +export class ResponseActionsClientError extends CustomHttpRequestError { + toJSON() { + return { + message: this.message, + statusCode: this.statusCode, + meta: this.meta, + stack: this.stack, + }; + } + + toString() { + return JSON.stringify(dump(this.toJSON()), null, 2); + } +} + +export class ResponseActionsNotSupportedError extends ResponseActionsClientError { + constructor( + responseAction?: ResponseActionsApiCommandNames, + statusCode: number = 405, + meta?: unknown + ) { + super(`Action ${responseAction ? `[${responseAction}] ` : ''}not supported`, statusCode, meta); + } +} + +export class UnsupportedResponseActionsAgentTypeError extends ResponseActionsClientError { + constructor(message: string, statusCode = 501, meta?: unknown) { + super(message, statusCode, meta); + } +} diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/get_response_actions_client.test.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/get_response_actions_client.test.ts new file mode 100644 index 00000000000000..f0cee2a616462b --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/get_response_actions_client.test.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { GetResponseActionsClientConstructorOptions } from '../..'; +import { responseActionsClientMock } from './mocks'; +import { RESPONSE_ACTION_AGENT_TYPE } from '../../../../../common/endpoint/service/response_actions/constants'; +import { getResponseActionsClient } from '../..'; +import { ResponseActionsClientImpl } from './lib/base_response_actions_client'; +import { UnsupportedResponseActionsAgentTypeError } from './errors'; + +describe('getResponseActionsClient()', () => { + let options: GetResponseActionsClientConstructorOptions; + + beforeEach(() => { + options = { + ...responseActionsClientMock.createConstructorOptions(), + connectorActions: responseActionsClientMock.createConnectorActionsClient(), + }; + }); + + it.each(RESPONSE_ACTION_AGENT_TYPE)( + 'should return a response actions client for agentType: %s', + (agentType) => { + expect(getResponseActionsClient(agentType, options)).toBeInstanceOf( + ResponseActionsClientImpl + ); + } + ); + + it(`should throw error if agentType is not supported`, () => { + expect(() => getResponseActionsClient('foo', options)).toThrow( + UnsupportedResponseActionsAgentTypeError + ); + }); +}); diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/get_response_actions_client.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/get_response_actions_client.ts new file mode 100644 index 00000000000000..b60e9419208b97 --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/get_response_actions_client.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { SentinelOneActionsClientOptions } from './sentinelone/sentinel_one_actions_client'; +import type { ResponseActionsClient } from './lib/types'; +import type { ResponseActionsClientOptions } from './lib/base_response_actions_client'; +import { EndpointActionsClient } from './endpoint_actions_client'; +import { SentinelOneActionsClient } from './sentinelone/sentinel_one_actions_client'; +import { UnsupportedResponseActionsAgentTypeError } from './errors'; +import type { ResponseActionAgentType } from '../../../../../common/endpoint/service/response_actions/constants'; + +export type GetResponseActionsClientConstructorOptions = ResponseActionsClientOptions & + SentinelOneActionsClientOptions; + +/** + * Retrieve a response actions client for an agent type + * @param agentType + * @param constructorOptions + * + * @throws UnsupportedResponseActionsAgentTypeError + */ +export const getResponseActionsClient = ( + agentType: string | ResponseActionAgentType, + constructorOptions: GetResponseActionsClientConstructorOptions +): ResponseActionsClient => { + switch (agentType) { + case 'endpoint': + return new EndpointActionsClient(constructorOptions); + case 'sentinel_one': + return new SentinelOneActionsClient(constructorOptions); + } + + throw new UnsupportedResponseActionsAgentTypeError( + `Agent type [${agentType}] does not support response actions` + ); +}; diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/index.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/index.ts index 83a11352dfe950..dba0f0771de1f8 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/index.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/index.ts @@ -5,4 +5,8 @@ * 2.0. */ -export { EndpointActionsClient } from './endpoint_actions_client'; +export * from './endpoint_actions_client'; +export * from './sentinelone/sentinel_one_actions_client'; +export * from './get_response_actions_client'; + +export * from './lib/types'; diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/lib/base_response_actions_client.test.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/lib/base_response_actions_client.test.ts new file mode 100644 index 00000000000000..7b6d991e28f0bc --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/lib/base_response_actions_client.test.ts @@ -0,0 +1,515 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ResponseActionsClient } from './types'; +import type { + ResponseActionsClientUpdateCasesOptions, + ResponseActionsClientWriteActionRequestToEndpointIndexOptions, + ResponseActionsClientWriteActionResponseToEndpointIndexOptions, +} from './base_response_actions_client'; +import { ResponseActionsClientImpl } from './base_response_actions_client'; +import type { + ActionDetails, + LogsEndpointAction, + LogsEndpointActionResponse, +} from '../../../../../../common/endpoint/types'; +import type { EndpointAppContextService } from '../../../../endpoint_app_context_services'; +import type { ElasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; +import { ResponseActionsClientError, ResponseActionsNotSupportedError } from '../errors'; +import type { CasesClientMock } from '@kbn/cases-plugin/server/client/mocks'; +import type { CasesByAlertIDParams } from '@kbn/cases-plugin/server/client/cases/get'; +import type { Logger } from '@kbn/logging'; +import { getActionDetailsById as _getActionDetailsById } from '../../action_details_by_id'; +import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { TransportResult } from '@elastic/elasticsearch'; +import { ENDPOINT_ACTIONS_INDEX } from '../../../../../../common/endpoint/constants'; +import type { DeepMutable } from '../../../../../../common/endpoint/types/utility_types'; +import { set } from 'lodash'; +import { responseActionsClientMock } from '../mocks'; + +jest.mock('../../action_details_by_id', () => { + const original = jest.requireActual('../../action_details_by_id'); + + return { + ...original, + getActionDetailsById: jest.fn(original.getActionDetailsById), + }; +}); + +const getActionDetailsByIdMock = _getActionDetailsById as jest.Mock; + +describe('ResponseActionsClientImpl base class', () => { + let esClient: ElasticsearchClientMock; + let endpointAppContextService: EndpointAppContextService; + let baseClassMock: MockClassWithExposedProtectedMembers; + let casesClient: CasesClientMock; + let logger: Logger; + + beforeEach(async () => { + const constructorOptions = responseActionsClientMock.createConstructorOptions(); + + esClient = constructorOptions.esClient; + casesClient = constructorOptions.casesClient; + endpointAppContextService = constructorOptions.endpointService; + logger = endpointAppContextService.createLogger(); + baseClassMock = new MockClassWithExposedProtectedMembers(constructorOptions); + }); + + afterEach(() => { + getActionDetailsByIdMock.mockClear(); + }); + + describe('Public methods', () => { + const methods: Array<keyof ResponseActionsClient> = [ + 'isolate', + 'release', + 'killProcess', + 'suspendProcess', + 'runningProcesses', + 'getFile', + 'execute', + 'upload', + ]; + + it.each(methods)('should throw Not Supported error for %s()', async (method) => { + // @ts-expect-error ignoring input type to method since they all should throw + const responsePromise = baseClassMock[method]({}); + + await expect(responsePromise).rejects.toBeInstanceOf(ResponseActionsNotSupportedError); + await expect(responsePromise).rejects.toHaveProperty('statusCode', 405); + }); + }); + + describe('#updateCases()', () => { + const KNOWN_ALERT_ID_1 = 'alert-1'; + const KNOWN_ALERT_ID_2 = 'alert-2'; + const KNOWN_ALERT_ID_3 = 'alert-3'; + + let updateCasesOptions: Required<ResponseActionsClientUpdateCasesOptions>; + + beforeEach(async () => { + (casesClient.cases.getCasesByAlertID as jest.Mock).mockImplementation( + async ({ alertID }: CasesByAlertIDParams) => { + if (alertID === KNOWN_ALERT_ID_1) { + return [{ id: 'case-1' }, { id: 'case-2' }, { id: 'case-3' }]; + } + + if (alertID === KNOWN_ALERT_ID_2) { + return [{ id: 'case-3' }]; + } + + if (alertID === KNOWN_ALERT_ID_3) { + return []; + } + + throw new Error('test: alert id not found'); + } + ); + + updateCasesOptions = { + command: 'isolate', + caseIds: ['case-999'], + alertIds: [KNOWN_ALERT_ID_1, KNOWN_ALERT_ID_2, KNOWN_ALERT_ID_3], + comment: 'this is a case comment', + hosts: [ + { + hostId: '1-2-3', + hostname: 'foo-one', + }, + { + hostId: '4-5-6', + hostname: 'foo-two', + }, + ], + }; + }); + + it('should do nothing if no caseIds nor alertIds are provided', async () => { + updateCasesOptions.caseIds.length = 0; + updateCasesOptions.alertIds.length = 0; + await baseClassMock.updateCases(updateCasesOptions); + + expect(casesClient.cases.getCasesByAlertID).not.toHaveBeenCalled(); + expect(casesClient.attachments.bulkCreate).not.toHaveBeenCalled(); + expect(logger.debug).toHaveBeenCalledWith( + "Nothing to do. 'caseIds' and 'alertIds' are empty" + ); + }); + + it('should do nothing if no hosts were provided', async () => { + updateCasesOptions.hosts.length = 0; + await baseClassMock.updateCases(updateCasesOptions); + + expect(casesClient.cases.getCasesByAlertID).not.toHaveBeenCalled(); + expect(casesClient.attachments.bulkCreate).not.toHaveBeenCalled(); + expect(logger.debug).toHaveBeenCalledWith("Nothing to do. 'hosts' is empty"); + }); + + it('should do nothing if cases client was not provided', async () => { + const mockInstance = new MockClassWithExposedProtectedMembers({ + esClient, + endpointService: endpointAppContextService, + username: 'foo', + }); + await mockInstance.updateCases(updateCasesOptions); + + expect(casesClient.cases.getCasesByAlertID).not.toHaveBeenCalled(); + expect(casesClient.attachments.bulkCreate).not.toHaveBeenCalled(); + expect(logger.debug).toHaveBeenCalledWith( + 'No CasesClient available. Skipping updates to Cases!' + ); + }); + + it('should retrieve caseIds from alerts if alertIds was provided', async () => { + await baseClassMock.updateCases(updateCasesOptions); + + expect(casesClient.cases.getCasesByAlertID).toHaveBeenCalledTimes(3); + }); + + it('should not error is retrieving case id for alert fails', async () => { + updateCasesOptions.alertIds.push('invalid-alert-id'); + await baseClassMock.updateCases(updateCasesOptions); + + expect(casesClient.cases.getCasesByAlertID).toHaveBeenCalledTimes(4); + expect(logger.warn).toHaveBeenCalledWith( + expect.stringContaining('Attempt to get cases for alertID [invalid-alert-id]') + ); + }); + + it('should do nothing if alertIDs were not associated with any cases', async () => { + updateCasesOptions.caseIds.length = 0; + updateCasesOptions.alertIds = [KNOWN_ALERT_ID_3]; + await baseClassMock.updateCases(updateCasesOptions); + + expect(logger.debug).toHaveBeenCalledWith(`Nothing to do. Alert IDs are not tied to Cases`); + }); + + it('should update cases with an attachment for each host', async () => { + const updateResponse = await baseClassMock.updateCases(updateCasesOptions); + + expect(updateResponse).toBeUndefined(); + expect(casesClient.attachments.bulkCreate).toHaveBeenCalledTimes(4); + expect(casesClient.attachments.bulkCreate).toHaveBeenLastCalledWith({ + attachments: [ + { + actions: { + targets: [ + { + endpointId: '1-2-3', + hostname: 'foo-one', + }, + { + endpointId: '4-5-6', + hostname: 'foo-two', + }, + ], + type: 'isolate', + }, + comment: 'this is a case comment', + owner: 'securitySolution', + type: 'actions', + }, + { + actions: { + targets: [ + { + endpointId: '1-2-3', + hostname: 'foo-one', + }, + { + endpointId: '4-5-6', + hostname: 'foo-two', + }, + ], + type: 'isolate', + }, + comment: 'this is a case comment', + owner: 'securitySolution', + type: 'actions', + }, + { + actions: { + targets: [ + { + endpointId: '1-2-3', + hostname: 'foo-one', + }, + { + endpointId: '4-5-6', + hostname: 'foo-two', + }, + ], + type: 'isolate', + }, + comment: 'this is a case comment', + owner: 'securitySolution', + type: 'actions', + }, + { + actions: { + targets: [ + { + endpointId: '1-2-3', + hostname: 'foo-one', + }, + { + endpointId: '4-5-6', + hostname: 'foo-two', + }, + ], + type: 'isolate', + }, + comment: 'this is a case comment', + owner: 'securitySolution', + type: 'actions', + }, + ], + caseId: 'case-3', + }); + }); + + it('should not error if update to a case fails', async () => { + (casesClient.attachments.bulkCreate as jest.Mock).mockImplementation(async (options) => { + if (options.caseId === 'case-2') { + throw new Error('update filed to case-2'); + } + }); + await baseClassMock.updateCases(updateCasesOptions); + + expect(logger.warn).toHaveBeenCalledWith( + expect.stringContaining('Attempt to update case ID [case-2] failed:') + ); + }); + }); + + describe('#fetchActionDetails()', () => { + it('should retrieve action details', async () => { + await baseClassMock.fetchActionDetails('one').catch(() => { + // just ignoring error + }); + + expect(getActionDetailsByIdMock).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + 'one' + ); + }); + }); + + describe('#writeActionRequestToEndpointIndex()', () => { + let esIndexDocResponse: TransportResult<estypes.IndexResponse, unknown>; + let indexDocOptions: DeepMutable<ResponseActionsClientWriteActionRequestToEndpointIndexOptions>; + let expectedIndexDoc: LogsEndpointAction; + + beforeEach(() => { + esIndexDocResponse = { + body: { + result: 'created', + _id: '123', + _index: ENDPOINT_ACTIONS_INDEX, + _version: 1, + }, + statusCode: 201, + headers: {}, + meta: {}, + warnings: null, + } as TransportResult<estypes.IndexResponse, unknown>; + + indexDocOptions = { + command: 'isolate', + agent_type: 'endpoint', + endpoint_ids: ['one'], + comment: 'test comment', + rule_name: undefined, + rule_id: undefined, + alert_ids: undefined, + case_ids: undefined, + hosts: undefined, + parameters: undefined, + file: undefined, + }; + + expectedIndexDoc = { + '@timestamp': expect.any(String), + EndpointActions: { + action_id: expect.any(String), + data: { + command: 'isolate', + comment: 'test comment', + }, + expiration: expect.any(String), + input_type: 'endpoint', + type: 'INPUT_ACTION', + }, + agent: { + id: ['one'], + }, + user: { + id: 'foo', + }, + }; + + // @ts-expect-error TS2345: Argument of type... Due to the fact that the method definition is overloaded + esClient.index.mockResolvedValue(esIndexDocResponse); + }); + + it('should return indexed record on success', async () => { + await expect( + baseClassMock.writeActionRequestToEndpointIndex(indexDocOptions) + ).resolves.toEqual(expectedIndexDoc); + }); + + it('should set `EndpointActions.input_type` to the correct value', async () => { + indexDocOptions.agent_type = 'sentinel_one'; + set(expectedIndexDoc, 'EndpointActions.input_type', 'sentinel_one'); + + await expect( + baseClassMock.writeActionRequestToEndpointIndex(indexDocOptions) + ).resolves.toEqual(expectedIndexDoc); + }); + + it('should include alert_ids if any were provided', async () => { + indexDocOptions.alert_ids = ['one', 'two']; + set(expectedIndexDoc, 'EndpointActions.data.alert_id', indexDocOptions.alert_ids); + + await expect( + baseClassMock.writeActionRequestToEndpointIndex(indexDocOptions) + ).resolves.toEqual(expectedIndexDoc); + }); + + it('should include hosts if any where provided', async () => { + indexDocOptions.hosts = { hostA: { name: 'host a' } }; + set(expectedIndexDoc, 'EndpointActions.data.hosts', indexDocOptions.hosts); + + await expect( + baseClassMock.writeActionRequestToEndpointIndex(indexDocOptions) + ).resolves.toEqual(expectedIndexDoc); + }); + + it('should include Rule information if rule_id and rule_name were provided', async () => { + indexDocOptions.rule_id = '1-2-3'; + indexDocOptions.rule_name = 'rule 123'; + expectedIndexDoc.rule = { + name: indexDocOptions.rule_name, + id: indexDocOptions.rule_id, + }; + + await expect( + baseClassMock.writeActionRequestToEndpointIndex(indexDocOptions) + ).resolves.toEqual(expectedIndexDoc); + }); + + it('should NOT include Rule information if rule_id or rule_name are missing', async () => { + indexDocOptions.rule_id = '1-2-3'; + + await expect( + baseClassMock.writeActionRequestToEndpointIndex(indexDocOptions) + ).resolves.toEqual(expectedIndexDoc); + }); + + it('should error if index of document did not return a 201', async () => { + esIndexDocResponse.statusCode = 200; + const responsePromise = baseClassMock.writeActionRequestToEndpointIndex(indexDocOptions); + + await expect(responsePromise).rejects.toBeInstanceOf(ResponseActionsClientError); + await expect(responsePromise).rejects.toHaveProperty('statusCode', 500); + }); + + it('should throw ResponseActionsClientError if operation fails', async () => { + esClient.index.mockImplementation(async () => { + throw new Error('test error'); + }); + const responsePromise = baseClassMock.writeActionRequestToEndpointIndex(indexDocOptions); + + await expect(responsePromise).rejects.toBeInstanceOf(ResponseActionsClientError); + await expect(responsePromise).rejects.toHaveProperty('statusCode', 500); + await expect(responsePromise).rejects.toHaveProperty( + 'message', + expect.stringContaining('Failed to create action request document:') + ); + }); + }); + + describe('#writeActionResponseToEndpointIndex()', () => { + let actionResponseOptions: ResponseActionsClientWriteActionResponseToEndpointIndexOptions; + + beforeEach(() => { + actionResponseOptions = { + actionId: '1-2-3', + agentId: '123', + error: { message: 'test error' }, + data: { + command: 'isolate', + comment: 'some comment', + output: undefined, + }, + }; + }); + + it('should return indexed record on success', async () => { + await expect( + baseClassMock.writeActionResponseToEndpointIndex(actionResponseOptions) + ).resolves.toEqual({ + '@timestamp': expect.any(String), + EndpointActions: { + action_id: '1-2-3', + completed_at: expect.any(String), + data: { + command: 'isolate', + comment: 'some comment', + }, + started_at: expect.any(String), + }, + agent: { + id: '123', + }, + error: { + message: 'test error', + }, + }); + }); + + it('should throw ResponseActionsClientError if operation fails', async () => { + esClient.index.mockImplementation(async () => { + throw new Error('oh oh'); + }); + const responsePromise = + baseClassMock.writeActionResponseToEndpointIndex(actionResponseOptions); + + await expect(responsePromise).rejects.toBeInstanceOf(ResponseActionsClientError); + await expect(responsePromise).rejects.toHaveProperty( + 'message', + expect.stringContaining('Failed to create action response document: ') + ); + await expect(responsePromise).rejects.toHaveProperty('statusCode', 500); + }); + }); +}); + +class MockClassWithExposedProtectedMembers extends ResponseActionsClientImpl { + public async updateCases(options: ResponseActionsClientUpdateCasesOptions): Promise<void> { + return super.updateCases(options); + } + + public async fetchActionDetails<T extends ActionDetails = ActionDetails>( + actionId: string + ): Promise<T> { + return super.fetchActionDetails(actionId); + } + + public async writeActionRequestToEndpointIndex( + actionRequest: ResponseActionsClientWriteActionRequestToEndpointIndexOptions + ): Promise<LogsEndpointAction> { + return super.writeActionRequestToEndpointIndex(actionRequest); + } + + public async writeActionResponseToEndpointIndex<TOutputContent extends object = object>( + options: ResponseActionsClientWriteActionResponseToEndpointIndexOptions<TOutputContent> + ): Promise<LogsEndpointActionResponse<TOutputContent>> { + return super.writeActionResponseToEndpointIndex<TOutputContent>(options); + } +} diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/lib/base_response_actions_client.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/lib/base_response_actions_client.ts new file mode 100644 index 00000000000000..cea80bd3f9bcda --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/lib/base_response_actions_client.ts @@ -0,0 +1,366 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; +import type { CasesClient } from '@kbn/cases-plugin/server'; +import type { Logger } from '@kbn/logging'; +import { v4 as uuidv4 } from 'uuid'; +import { AttachmentType } from '@kbn/cases-plugin/common'; +import type { BulkCreateArgs } from '@kbn/cases-plugin/server/client/attachments/types'; +import type { EndpointAppContextService } from '../../../../endpoint_app_context_services'; +import { APP_ID } from '../../../../../../common'; +import type { ResponseActionsApiCommandNames } from '../../../../../../common/endpoint/service/response_actions/constants'; +import { getActionDetailsById } from '../../action_details_by_id'; +import { ResponseActionsClientError, ResponseActionsNotSupportedError } from '../errors'; +import { + addRuleInfoToAction, + getActionParameters, + getActionRequestExpiration, +} from '../../create/write_action_to_indices'; +import { + ENDPOINT_ACTION_RESPONSES_INDEX, + ENDPOINT_ACTIONS_INDEX, +} from '../../../../../../common/endpoint/constants'; +import type { ResponseActionsClient } from './types'; +import type { + ActionDetails, + GetProcessesActionOutputContent, + KillOrSuspendProcessRequestBody, + KillProcessActionOutputContent, + ResponseActionExecuteOutputContent, + ResponseActionGetFileOutputContent, + ResponseActionGetFileParameters, + ResponseActionParametersWithPidOrEntityId, + ResponseActionsExecuteParameters, + ResponseActionUploadOutputContent, + ResponseActionUploadParameters, + SuspendProcessActionOutputContent, + LogsEndpointAction, + EndpointActionDataParameterTypes, + LogsEndpointActionResponse, +} from '../../../../../../common/endpoint/types'; +import type { + IsolationRouteRequestBody, + ExecuteActionRequestBody, + GetProcessesRequestBody, + ResponseActionGetFileRequestBody, + UploadActionApiRequestBody, + ResponseActionsRequestBody, +} from '../../../../../../common/api/endpoint'; +import type { CreateActionPayload } from '../../create/types'; +import { dump } from '../../../../utils/dump'; + +export interface ResponseActionsClientOptions { + endpointService: EndpointAppContextService; + esClient: ElasticsearchClient; + casesClient?: CasesClient; + /** Username that will be stored along with the action's ES documents */ + username: string; +} + +export interface ResponseActionsClientUpdateCasesOptions { + /** The Response Action that was taken */ + command: ResponseActionsApiCommandNames; + /** the list of hosts that received the response action `command` */ + hosts: Array<{ + hostname: string; + hostId: string; + }>; + caseIds?: string[]; + /** If defined, any case that the alert is included in will also receive an update */ + alertIds?: string[]; + /** Comment to include in the Case attachment */ + comment?: string; +} + +export type ResponseActionsClientWriteActionRequestToEndpointIndexOptions = + ResponseActionsRequestBody & + Pick<CreateActionPayload, 'command' | 'hosts' | 'rule_id' | 'rule_name'>; + +export type ResponseActionsClientWriteActionResponseToEndpointIndexOptions< + TOutputContent extends object = object +> = { + agentId: LogsEndpointActionResponse['agent']['id']; + actionId: string; +} & Pick<LogsEndpointActionResponse, 'error'> & + Pick<LogsEndpointActionResponse<TOutputContent>['EndpointActions'], 'data'>; + +/** + * Base class for a Response Actions client + */ +export class ResponseActionsClientImpl implements ResponseActionsClient { + protected readonly log: Logger; + + constructor(protected readonly options: ResponseActionsClientOptions) { + this.log = options.endpointService.createLogger( + this.constructor.name ?? 'ResponseActionsClient' + ); + } + + /** + * Update cases with information about the hosts that received a response action. + * + * **NOTE:** Failures during update will not cause this operation to fail - it will only log the errors + * @protected + */ + protected async updateCases({ + command, + hosts, + caseIds = [], + alertIds = [], + comment = '', + }: ResponseActionsClientUpdateCasesOptions): Promise<void> { + if (caseIds.length === 0 && alertIds.length === 0) { + this.log.debug(`Nothing to do. 'caseIds' and 'alertIds' are empty`); + return; + } + + if (hosts.length === 0) { + this.log.debug(`Nothing to do. 'hosts' is empty`); + return; + } + + const casesClient = this.options.casesClient; + + if (!casesClient) { + this.log.debug(`No CasesClient available. Skipping updates to Cases!`); + return; + } + + const casesFromAlertIds = await Promise.all( + alertIds.map((alertID) => { + return casesClient.cases + .getCasesByAlertID({ alertID, options: { owner: APP_ID } }) + .then((casesFound) => { + return casesFound.map((caseInfo) => caseInfo.id); + }) + .catch((err) => { + this.log.warn( + `Attempt to get cases for alertID [${alertID}][owner: ${APP_ID}] failed with: ${err.message}` + ); + + // We don't fail everything here. Just log it and keep going + return [] as string[]; + }); + }) + ).then((results) => { + return results.flat(); + }); + + const allCases = [...new Set([...caseIds, ...casesFromAlertIds])]; + + if (allCases.length === 0) { + this.log.debug(`Nothing to do. Alert IDs are not tied to Cases`); + return; + } + + this.log.debug(`Updating cases:\n${dump(allCases)}`); + + // Create an attachment for each case that includes info. about the response actions taken against the hosts + const attachments = allCases.map(() => ({ + type: AttachmentType.actions, + comment, + actions: { + targets: hosts.map(({ hostId: endpointId, hostname }) => ({ endpointId, hostname })), + type: command, + }, + owner: APP_ID, + })) as BulkCreateArgs['attachments']; + + const casesUpdateResponse = await Promise.all( + allCases.map((caseId) => + casesClient.attachments + .bulkCreate({ + caseId, + attachments, + }) + .catch((err) => { + // Log any error, BUT: do not fail execution + this.log.warn( + `Attempt to update case ID [${caseId}] failed: ${err.message}\n${dump(err)}` + ); + return null; + }) + ) + ); + + this.log.debug(`Update to cases done:\n${dump(casesUpdateResponse)}`); + } + + /** + * Returns the action details for a given response action id + * @param actionId + * @protected + */ + protected async fetchActionDetails<T extends ActionDetails = ActionDetails>( + actionId: string + ): Promise<T> { + return getActionDetailsById( + this.options.esClient, + this.options.endpointService.getEndpointMetadataService(), + actionId + ); + } + + /** + * Creates a Response Action request document in the Endpoint index (`.logs-endpoint.actions-default`) + * @protected + */ + protected async writeActionRequestToEndpointIndex( + actionRequest: ResponseActionsClientWriteActionRequestToEndpointIndexOptions + ): Promise<LogsEndpointAction> { + const doc: LogsEndpointAction = { + '@timestamp': new Date().toISOString(), + agent: { + id: actionRequest.endpoint_ids, + }, + EndpointActions: { + action_id: uuidv4(), + expiration: getActionRequestExpiration(), + type: 'INPUT_ACTION', + input_type: actionRequest.agent_type ?? 'endpoint', + data: { + command: actionRequest.command, + comment: actionRequest.comment ?? undefined, + ...(actionRequest.alert_ids ? { alert_id: actionRequest.alert_ids } : {}), + ...(actionRequest.hosts ? { hosts: actionRequest.hosts } : {}), + parameters: getActionParameters(actionRequest) as EndpointActionDataParameterTypes, + }, + }, + user: { + id: this.options.username, + }, + ...addRuleInfoToAction(actionRequest), + }; + + try { + const logsEndpointActionsResult = await this.options.esClient.index<LogsEndpointAction>( + { + index: ENDPOINT_ACTIONS_INDEX, + document: doc, + refresh: 'wait_for', + }, + { meta: true } + ); + + if (logsEndpointActionsResult.statusCode !== 201) { + throw new ResponseActionsClientError( + `Failed to create (index) action request document. StatusCode: [${logsEndpointActionsResult.statusCode}] Result: ${logsEndpointActionsResult.body.result}`, + 500, + logsEndpointActionsResult + ); + } + + return doc; + } catch (err) { + if (!(err instanceof ResponseActionsClientError)) { + throw new ResponseActionsClientError( + `Failed to create action request document: ${err.message}`, + 500, + err + ); + } + + throw err; + } + } + + /** + * Writes a Response Action response document to the Endpoint index + * @param options + * @protected + */ + protected async writeActionResponseToEndpointIndex<TOutputContent extends object = object>({ + actionId, + error, + agentId, + data, + }: ResponseActionsClientWriteActionResponseToEndpointIndexOptions<TOutputContent>): Promise< + LogsEndpointActionResponse<TOutputContent> + > { + const timestamp = new Date().toISOString(); + const doc: LogsEndpointActionResponse<TOutputContent> = { + '@timestamp': timestamp, + agent: { + id: agentId, + }, + EndpointActions: { + action_id: actionId, + started_at: timestamp, + completed_at: timestamp, + data, + }, + error, + }; + + this.log.debug(`Writing response action response:\n${dump(doc)}`); + + await this.options.esClient + .index<LogsEndpointActionResponse>({ + index: ENDPOINT_ACTION_RESPONSES_INDEX, + document: doc, + refresh: 'wait_for', + }) + .catch((err) => { + throw new ResponseActionsClientError( + `Failed to create action response document: ${err.message}`, + err.statusCode ?? 500, + err + ); + }); + + return doc; + } + + public async isolate(options: IsolationRouteRequestBody): Promise<ActionDetails> { + throw new ResponseActionsNotSupportedError('isolate'); + } + + public async release(options: IsolationRouteRequestBody): Promise<ActionDetails> { + throw new ResponseActionsNotSupportedError('unisolate'); + } + + public async killProcess( + options: KillOrSuspendProcessRequestBody + ): Promise< + ActionDetails<KillProcessActionOutputContent, ResponseActionParametersWithPidOrEntityId> + > { + throw new ResponseActionsNotSupportedError('kill-process'); + } + + public async suspendProcess( + options: KillOrSuspendProcessRequestBody + ): Promise< + ActionDetails<SuspendProcessActionOutputContent, ResponseActionParametersWithPidOrEntityId> + > { + throw new ResponseActionsNotSupportedError('suspend-process'); + } + + public async runningProcesses( + options: GetProcessesRequestBody + ): Promise<ActionDetails<GetProcessesActionOutputContent>> { + throw new ResponseActionsNotSupportedError('running-processes'); + } + + public async getFile( + options: ResponseActionGetFileRequestBody + ): Promise<ActionDetails<ResponseActionGetFileOutputContent, ResponseActionGetFileParameters>> { + throw new ResponseActionsNotSupportedError('get-file'); + } + + public async execute( + options: ExecuteActionRequestBody + ): Promise<ActionDetails<ResponseActionExecuteOutputContent, ResponseActionsExecuteParameters>> { + throw new ResponseActionsNotSupportedError('execute'); + } + + public async upload( + options: UploadActionApiRequestBody + ): Promise<ActionDetails<ResponseActionUploadOutputContent, ResponseActionUploadParameters>> { + throw new ResponseActionsNotSupportedError('upload'); + } +} diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/response_actions/types.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/lib/types.ts similarity index 93% rename from x-pack/plugins/security_solution/server/endpoint/lib/response_actions/types.ts rename to x-pack/plugins/security_solution/server/endpoint/services/actions/clients/lib/types.ts index 5578128cf4248c..c6407dceae9ddb 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/response_actions/types.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/lib/types.ts @@ -18,19 +18,19 @@ import type { ResponseActionsExecuteParameters, ResponseActionUploadOutputContent, ResponseActionUploadParameters, -} from '../../../../common/endpoint/types'; +} from '../../../../../../common/endpoint/types'; import type { IsolationRouteRequestBody, GetProcessesRequestBody, ResponseActionGetFileRequestBody, ExecuteActionRequestBody, UploadActionApiRequestBody, -} from '../../../../common/api/endpoint'; +} from '../../../../../../common/api/endpoint'; /** * The interface required for a Response Actions provider */ -export interface ResponseActionsProvider { +export interface ResponseActionsClient { isolate: (options: IsolationRouteRequestBody) => Promise<ActionDetails>; release: (options: IsolationRouteRequestBody) => Promise<ActionDetails>; diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/mocks.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/mocks.ts new file mode 100644 index 00000000000000..27773a898b9329 --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/mocks.ts @@ -0,0 +1,209 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ActionsClientMock } from '@kbn/actions-plugin/server/actions_client/actions_client.mock'; +import { actionsClientMock } from '@kbn/actions-plugin/server/actions_client/actions_client.mock'; +import type { ConnectorWithExtraFindData } from '@kbn/actions-plugin/server/application/connector/types'; +import { SENTINELONE_CONNECTOR_ID } from '@kbn/stack-connectors-plugin/common/sentinelone/constants'; +import type { DeepPartial } from 'utility-types'; +import type { ActionTypeExecutorResult } from '@kbn/actions-plugin/common'; +import type { ElasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; +import type { CasesClientMock } from '@kbn/cases-plugin/server/client/mocks'; +import { createCasesClientMock } from '@kbn/cases-plugin/server/client/mocks'; +import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; +import { merge } from 'lodash'; +import type * as esTypes from '@elastic/elasticsearch/lib/api/types'; +import type { TransportResult } from '@elastic/elasticsearch'; +import type { AttachmentsSubClient } from '@kbn/cases-plugin/server/client/attachments/client'; +import { BaseDataGenerator } from '../../../../../common/endpoint/data_generators/base_data_generator'; +import { + createActionRequestsEsSearchResultsMock, + createActionResponsesEsSearchResultsMock, +} from '../mocks'; +import { + ENDPOINT_ACTION_RESPONSES_INDEX, + ENDPOINT_ACTIONS_INDEX, +} from '../../../../../common/endpoint/constants'; +import type { DeepMutable } from '../../../../../common/endpoint/types/utility_types'; +import { EndpointAppContextService } from '../../../endpoint_app_context_services'; +import { + createMockEndpointAppContextServiceSetupContract, + createMockEndpointAppContextServiceStartContract, +} from '../../../mocks'; +import type { IsolationRouteRequestBody } from '../../../../../common/api/endpoint'; +import type { ResponseActionsClientOptions } from './lib/base_response_actions_client'; +import { ACTION_RESPONSE_INDICES } from '../constants'; + +export interface ResponseActionsClientOptionsMock extends ResponseActionsClientOptions { + esClient: ElasticsearchClientMock; + casesClient?: CasesClientMock; +} + +const createConstructorOptionsMock = (): Required<ResponseActionsClientOptionsMock> => { + const esClient = elasticsearchServiceMock.createScopedClusterClient().asInternalUser; + const casesClient = createCasesClientMock(); + const endpointService = new EndpointAppContextService(); + + esClient.index.mockImplementation((async (payload) => { + switch (payload.index) { + case ENDPOINT_ACTIONS_INDEX: + case ENDPOINT_ACTION_RESPONSES_INDEX: + return createEsIndexTransportResponseMock({ body: { _index: payload.index } }); + default: + throw new Error(`no esClient.index() mock defined for index ${payload.index}`); + } + }) as typeof esClient.index); + + esClient.search.mockImplementation(async (payload) => { + if (payload) { + switch (payload.index) { + case ENDPOINT_ACTIONS_INDEX: + return createActionRequestsEsSearchResultsMock(); + case ACTION_RESPONSE_INDICES: + return createActionResponsesEsSearchResultsMock(); + } + } + + return BaseDataGenerator.toEsSearchResponse([]); + }); + + (casesClient.attachments.bulkCreate as jest.Mock).mockImplementation( + (async () => {}) as unknown as jest.Mocked<AttachmentsSubClient>['bulkCreate'] + ); + + endpointService.setup(createMockEndpointAppContextServiceSetupContract()); + endpointService.start(createMockEndpointAppContextServiceStartContract()); + + return { + esClient, + casesClient, + endpointService, + username: 'foo', + }; +}; + +const createEsIndexTransportResponseMock = ( + overrides: DeepPartial<TransportResult<esTypes.IndexResponse, unknown>> = {} +): TransportResult<esTypes.IndexResponse, unknown> => { + const responseDoc: TransportResult<esTypes.IndexResponse, unknown> = { + body: { + _id: 'indexed-1-2-3', + _index: 'some-index', + _primary_term: 1, + result: 'created', + _seq_no: 1, + _shards: { + failed: 0, + successful: 1, + total: 1, + }, + _version: 1, + }, + statusCode: 201, + headers: {}, + warnings: null, + meta: { + context: {}, + name: 'foo', + request: { + params: { + method: 'GET', + path: 'some/path', + }, + options: {}, + id: 'some-id', + }, + connection: null, + attempts: 1, + aborted: false, + }, + }; + + return merge(responseDoc, overrides); +}; + +const createIsolateOptionsMock = ( + overrides: Partial<IsolationRouteRequestBody> = {} +): DeepMutable<IsolationRouteRequestBody> => { + const isolateOptions: IsolationRouteRequestBody = { + agent_type: 'endpoint', + endpoint_ids: ['1-2-3'], + comment: 'test comment', + }; + + return merge(isolateOptions, overrides); +}; + +const createConnectorActionsClientMock = (): ActionsClientMock => { + const client = actionsClientMock.create(); + + // Mock result of retrieving list of connectors + (client.getAll as jest.Mock).mockImplementation(async () => { + const result: ConnectorWithExtraFindData[] = [ + // SentinelOne connector + createConnectorMock({ + actionTypeId: SENTINELONE_CONNECTOR_ID, + id: 's1-connector-instance-id', + }), + ]; + + return result; + }); + + (client.execute as jest.Mock).mockImplementation(async () => { + return createConnectorAcitonExecuteResponseMock(); + }); + + return client; +}; + +const createConnectorMock = ( + overrides: DeepPartial<ConnectorWithExtraFindData> = {} +): ConnectorWithExtraFindData => { + return merge( + { + id: 'connector-mock-id-1', + actionTypeId: '.some-type', + name: 'some mock name', + isMissingSecrets: false, + config: {}, + isPreconfigured: false, + isDeprecated: false, + isSystemAction: false, + referencedByCount: 0, + }, + overrides + ); +}; + +const createConnectorAcitonExecuteResponseMock = ( + overrides: DeepPartial<ActionTypeExecutorResult<{}>> = {} +): ActionTypeExecutorResult<{}> => { + const result: ActionTypeExecutorResult<{}> = { + actionId: 'execute-response-mock-1', + data: undefined, + message: 'some mock message', + serviceMessage: 'some mock service message', + retry: true, + status: 'ok', + }; + + return merge(result, overrides); +}; + +export const responseActionsClientMock = Object.freeze({ + createConstructorOptions: createConstructorOptionsMock, + createIsolateOptions: createIsolateOptionsMock, + createReleaseOptions: createIsolateOptionsMock, + // TODO:PT add more methods to get option mocks for other class methods + + createIndexedResponse: createEsIndexTransportResponseMock, + + createConnectorActionsClient: createConnectorActionsClientMock, + createConnector: createConnectorMock, + createConnectorActionExecuteResponse: createConnectorAcitonExecuteResponseMock, +}); diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/sentinelone/sentinel_one_actions_client.test.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/sentinelone/sentinel_one_actions_client.test.ts new file mode 100644 index 00000000000000..a56b54ce2e65fa --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/sentinelone/sentinel_one_actions_client.test.ts @@ -0,0 +1,167 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ResponseActionsClient } from '../lib/types'; +import { responseActionsClientMock } from '../mocks'; +import type { SentinelOneActionsClientOptions } from '../../..'; +import { SentinelOneActionsClient } from '../../..'; +import { getActionDetailsById as _getActionDetailsById } from '../../action_details_by_id'; +import { ResponseActionsClientError, ResponseActionsNotSupportedError } from '../errors'; +import type { ActionsClientMock } from '@kbn/actions-plugin/server/actions_client/actions_client.mock'; + +jest.mock('../../action_details_by_id', () => { + const originalMod = jest.requireActual('../../action_details_by_id'); + + return { + ...originalMod, + getActionDetailsById: jest.fn(originalMod.getActionDetailsById), + }; +}); + +const getActionDetailsByIdMock = _getActionDetailsById as jest.Mock; + +describe('SentinelOneActionsClient class', () => { + let classConstructorOptions: SentinelOneActionsClientOptions; + let s1ActionsClient: ResponseActionsClient; + let connectorActionsMock: ActionsClientMock; + + const createS1IsolateOptions = () => + responseActionsClientMock.createIsolateOptions({ agent_type: 'sentinel_one' }); + + beforeEach(() => { + connectorActionsMock = responseActionsClientMock.createConnectorActionsClient(); + + connectorActionsMock.getAll(); + + classConstructorOptions = { + ...responseActionsClientMock.createConstructorOptions(), + connectorActions: connectorActionsMock, + }; + s1ActionsClient = new SentinelOneActionsClient(classConstructorOptions); + }); + + it.each([ + 'release', + 'killProcess', + 'suspendProcess', + 'runningProcesses', + 'getFile', + 'execute', + 'upload', + ] as Array<keyof ResponseActionsClient>)( + 'should throw an un-supported error for %s', + async (methodName) => { + // @ts-expect-error Purposely passing in empty object for options + await expect(s1ActionsClient[methodName]({})).rejects.toBeInstanceOf( + ResponseActionsNotSupportedError + ); + } + ); + + it('should error if unable to retrieve list of connectors', async () => { + connectorActionsMock.getAll.mockImplementation(async () => { + throw new Error('oh oh'); + }); + const responsePromise = s1ActionsClient.isolate(createS1IsolateOptions()); + + await expect(responsePromise).rejects.toBeInstanceOf(ResponseActionsClientError); + await expect(responsePromise).rejects.toHaveProperty( + 'message', + expect.stringContaining('Unable to retrieve list of stack connectors:') + ); + await expect(responsePromise).rejects.toHaveProperty('statusCode', 400); + }); + + it('should error if retrieving connectors fails', async () => { + (connectorActionsMock.getAll as jest.Mock).mockImplementation(async () => { + throw new Error('oh oh'); + }); + + await expect(s1ActionsClient.isolate(createS1IsolateOptions())).rejects.toMatchObject({ + message: `Unable to retrieve list of stack connectors: oh oh`, + statusCode: 400, + }); + }); + + it.each([ + ['no connector defined', async () => []], + [ + 'deprecated connector', + async () => [responseActionsClientMock.createConnector({ isDeprecated: true })], + ], + [ + 'missing secrets', + async () => [responseActionsClientMock.createConnector({ isMissingSecrets: true })], + ], + ])('should error if: %s', async (_, getAllImplementation) => { + (connectorActionsMock.getAll as jest.Mock).mockImplementation(getAllImplementation); + + await expect(s1ActionsClient.isolate(createS1IsolateOptions())).rejects.toMatchObject({ + message: `No SentinelOne stack connector found`, + statusCode: 400, + }); + }); + + it('should error if multiple agent ids are received', async () => { + const payload = createS1IsolateOptions(); + payload.endpoint_ids.push('second-host-id'); + + await expect(s1ActionsClient.isolate(payload)).rejects.toMatchObject({ + message: `[body.endpoint_ids]: Multiple agents IDs not currently supported for SentinelOne`, + statusCode: 400, + }); + }); + + describe(`#isolate()`, () => { + it('should send action to sentinelone', async () => { + await s1ActionsClient.isolate(createS1IsolateOptions()); + + expect(connectorActionsMock.execute as jest.Mock).toHaveBeenCalledWith({ + actionId: 's1-connector-instance-id', + params: { + subAction: 'isolateHost', + subActionParams: { + uuid: '1-2-3', + }, + }, + }); + }); + + it('should write action request and response to endpoint indexes', async () => { + await s1ActionsClient.isolate(createS1IsolateOptions()); + + expect(classConstructorOptions.esClient.index).toHaveBeenCalledTimes(1); + // FIXME:PT once we start writing the Response, check above should be removed and new assertion added for it + expect(classConstructorOptions.esClient.index).toHaveBeenNthCalledWith( + 1, + { + document: { + '@timestamp': expect.any(String), + EndpointActions: { + action_id: expect.any(String), + data: { command: 'isolate', comment: 'test comment', parameters: undefined }, + expiration: expect.any(String), + input_type: 'sentinel_one', + type: 'INPUT_ACTION', + }, + agent: { id: ['1-2-3'] }, + user: { id: 'foo' }, + }, + index: '.logs-endpoint.actions-default', + refresh: 'wait_for', + }, + { meta: true } + ); + }); + + it('should return action details', async () => { + await s1ActionsClient.isolate(createS1IsolateOptions()); + + expect(getActionDetailsByIdMock).toHaveBeenCalled(); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/sentinelone/sentinel_one_actions_client.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/sentinelone/sentinel_one_actions_client.ts new file mode 100644 index 00000000000000..4837f427a926b6 --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/clients/sentinelone/sentinel_one_actions_client.ts @@ -0,0 +1,148 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ActionsClient } from '@kbn/actions-plugin/server'; +import { + SENTINELONE_CONNECTOR_ID, + SUB_ACTION, +} from '@kbn/stack-connectors-plugin/common/sentinelone/constants'; +import type { ConnectorWithExtraFindData } from '@kbn/actions-plugin/server/application/connector/types'; +import { once } from 'lodash'; +import type { ActionTypeExecutorResult } from '@kbn/actions-plugin/common'; +import { dump } from '../../../../utils/dump'; +import { ResponseActionsClientError } from '../errors'; +import type { ActionDetails } from '../../../../../../common/endpoint/types'; +import type { + IsolationRouteRequestBody, + BaseActionRequestBody, +} from '../../../../../../common/api/endpoint'; +import type { ResponseActionsClientOptions } from '../lib/base_response_actions_client'; +import { ResponseActionsClientImpl } from '../lib/base_response_actions_client'; + +export type SentinelOneActionsClientOptions = ResponseActionsClientOptions & { + connectorActions: ActionsClient; +}; + +export class SentinelOneActionsClient extends ResponseActionsClientImpl { + private readonly connectorActionsClient: ActionsClient; + private readonly getConnector: () => Promise<ConnectorWithExtraFindData>; + + constructor({ connectorActions, ...options }: SentinelOneActionsClientOptions) { + super(options); + this.connectorActionsClient = connectorActions; + + this.getConnector = once(async () => { + let connectorList: ConnectorWithExtraFindData[] = []; + + try { + connectorList = await this.connectorActionsClient.getAll(); + } catch (err) { + throw new ResponseActionsClientError( + `Unable to retrieve list of stack connectors: ${err.message}`, + // failure here is likely due to Authz, but because we don't have a good way to determine that, + // the `statusCode` below is set to `400` instead of `401`. + 400, + err + ); + } + const connector = connectorList.find(({ actionTypeId, isDeprecated, isMissingSecrets }) => { + return actionTypeId === SENTINELONE_CONNECTOR_ID && !isDeprecated && !isMissingSecrets; + }); + + if (!connector) { + throw new ResponseActionsClientError( + `No SentinelOne stack connector found`, + 400, + connectorList + ); + } + + this.log.debug(`Using SentinelOne stack connector: ${connector.name} (${connector.id})`); + + return connector; + }); + } + + /** + * Sends actions to SentinelOne directly + * @private + */ + private async sendAction( + actionType: SUB_ACTION, + actionParams: object + // FIXME:PT type properly the options above once PR 168441 for 8.12 merges + ): Promise<ActionTypeExecutorResult<unknown>> { + const { id: connectorId } = await this.getConnector(); + const executeOptions: Parameters<typeof this.connectorActionsClient.execute>[0] = { + actionId: connectorId, + params: { + subAction: actionType, + subActionParams: actionParams, + }, + }; + + this.log.debug( + `calling connector actions 'execute()' for SentinelOne with:\n${dump(executeOptions)}` + ); + + const actionSendResponse = await this.connectorActionsClient.execute(executeOptions); + + if (actionSendResponse.status === 'error') { + this.log.error(dump(actionSendResponse)); + + throw new ResponseActionsClientError( + `Attempt to send [${actionType}] to SentinelOne failed: ${ + actionSendResponse.serviceMessage || actionSendResponse.message + }`, + 500, + actionSendResponse + ); + } + + this.log.debug(`Response:\n${dump(actionSendResponse)}`); + + return actionSendResponse; + } + + private async validateRequest(payload: BaseActionRequestBody): Promise<void> { + if (payload.endpoint_ids.length > 1) { + throw new ResponseActionsClientError( + `[body.endpoint_ids]: Multiple agents IDs not currently supported for SentinelOne`, + 400 + ); + } + } + + async isolate(options: IsolationRouteRequestBody): Promise<ActionDetails> { + // TODO:PT support multiple agents + await this.validateRequest(options); + + const agentUUID = options.endpoint_ids[0]; + + await this.sendAction(SUB_ACTION.ISOLATE_HOST, { + uuid: agentUUID, + }); + + // FIXME:PT need to grab data from the response above and store it with the Request or Response documents on our side + + const actionRequestDoc = await this.writeActionRequestToEndpointIndex({ + ...options, + command: 'isolate', + }); + + // TODO: un-comment code below once we have proper authz given to `kibana_system` account (security issue #8190) + // await this.writeActionResponseToEndpointIndex({ + // actionId: actionRequestDoc.EndpointActions.action_id, + // agentId: actionRequestDoc.agent.id, + // data: { + // command: actionRequestDoc.EndpointActions.data.command, + // }, + // }); + + return this.fetchActionDetails(actionRequestDoc.EndpointActions.action_id); + } +} diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/create/write_action_to_indices.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/create/write_action_to_indices.ts index 6df43004acb1a7..b502ec082c69b7 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/actions/create/write_action_to_indices.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/create/write_action_to_indices.ts @@ -179,20 +179,18 @@ const createFailedActionResponseEntry = async ({ } }; -const addRuleInfoToAction = ( - payload: CreateActionPayload -): - | { - rule: { id: string; name: string }; - } - | undefined => { +export const addRuleInfoToAction = ( + payload: Pick<CreateActionPayload, 'rule_id' | 'rule_name'> +): Pick<LogsEndpointAction, 'rule'> => { if (payload.rule_id && payload.rule_name) { return { rule: { id: payload.rule_id, name: payload.rule_name } }; } + + return {}; }; -const getActionParameters = ( - action: CreateActionPayload +export const getActionParameters = ( + action: Pick<CreateActionPayload, 'command' | 'parameters'> ): ResponseActionsExecuteParameters | Readonly<{}> | undefined => { // set timeout to 4h (if not specified or when timeout is specified as 0) when command is `execute` if (action.command === 'execute') { @@ -206,3 +204,7 @@ const getActionParameters = ( // for all other commands return the parameters as is return action.parameters ?? undefined; }; + +export const getActionRequestExpiration = (): string => { + return moment().add(2, 'weeks').toISOString(); +}; diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/index.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/index.ts index 67a8167ad5fa1e..49f8a89944d372 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/actions/index.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/index.ts @@ -11,3 +11,4 @@ export { getActionList, getActionListByStatus } from './action_list'; export { getPendingActionsSummary } from './pending_actions_summary'; export { validateActionId } from './validate_action_id'; export * from './create'; +export * from './clients'; diff --git a/x-pack/plugins/security_solution/server/endpoint/utils/dump.ts b/x-pack/plugins/security_solution/server/endpoint/utils/dump.ts new file mode 100644 index 00000000000000..ae05b73fac05a4 --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/utils/dump.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { inspect } from 'util'; + +/** + * Safely traverse some content (object, array, etc) and stringify it + * @param content + * @param depth + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const dump = (content: any, depth = 8): string => { + return inspect(content, { depth }); +}; diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index 227a7ea7e1439d..53141fc1751ceb 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -211,6 +211,7 @@ export class Plugin implements ISecuritySolutionPlugin { this.endpointAppContextService.setup({ securitySolutionRequestContextFactory: requestContextFactory, cloud: plugins.cloud, + loggerFactory: this.pluginContext.logger, }); initUsageCollectors({ diff --git a/x-pack/plugins/security_solution/server/utils/custom_http_request_error.ts b/x-pack/plugins/security_solution/server/utils/custom_http_request_error.ts index 0146912d78c6ca..9ce131a9182efa 100644 --- a/x-pack/plugins/security_solution/server/utils/custom_http_request_error.ts +++ b/x-pack/plugins/security_solution/server/utils/custom_http_request_error.ts @@ -5,10 +5,13 @@ * 2.0. */ export class CustomHttpRequestError extends Error { - constructor(message: string, public readonly statusCode: number = 500, meta?: unknown) { + constructor( + message: string, + public readonly statusCode: number = 500, + public readonly meta?: unknown + ) { super(message); // For debugging - capture name of subclasses this.name = this.constructor.name; - this.message = message; } } diff --git a/x-pack/plugins/security_solution/tsconfig.json b/x-pack/plugins/security_solution/tsconfig.json index 35767b63dab75a..92f062103e7597 100644 --- a/x-pack/plugins/security_solution/tsconfig.json +++ b/x-pack/plugins/security_solution/tsconfig.json @@ -186,6 +186,7 @@ "@kbn/search-errors", "@kbn/stack-connectors-plugin", "@kbn/elastic-assistant-common", + "@kbn/core-elasticsearch-server-mocks", "@kbn/lens-embeddable-utils" ] } diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/endpoint_response_actions/agent_type_support.ts b/x-pack/test/security_solution_endpoint_api_int/apis/endpoint_response_actions/agent_type_support.ts new file mode 100644 index 00000000000000..696c48183624a4 --- /dev/null +++ b/x-pack/test/security_solution_endpoint_api_int/apis/endpoint_response_actions/agent_type_support.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ISOLATE_HOST_ROUTE_V2 } from '@kbn/security-solution-plugin/common/endpoint/constants'; +import { FtrProviderContext } from '../../ftr_provider_context'; +import { targetTags } from '../../../security_solution_endpoint/target_tags'; + +export default function ({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + + describe('Response Actions support for agentType', function () { + targetTags(this, ['@ess', '@serverless']); + + describe('and the "responseActionsSentinelOneV1Enabled" feature flag is disabled', () => { + // When feature flag is enabled, this entire `describe()` block should be removed + it('should return an error', async () => { + await supertest + .post(ISOLATE_HOST_ROUTE_V2) + .set('kbn-xsrf', 'true') + .set('Elastic-Api-Version', '2023-10-31') + .send({ endpoint_ids: ['test'], agent_type: 'endpoint' }) + .expect(400, { + statusCode: 400, + error: 'Bad Request', + message: '[request body.agent_type]: feature is disabled', + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/index.ts b/x-pack/test/security_solution_endpoint_api_int/apis/index.ts index c0668612907a76..b4f4bb4b46063a 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/index.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/index.ts @@ -57,6 +57,7 @@ export default function endpointAPIIntegrationTests(providerContext: FtrProvider loadTestFile(require.resolve('./package')); loadTestFile(require.resolve('./endpoint_authz')); loadTestFile(require.resolve('./endpoint_response_actions/execute')); + loadTestFile(require.resolve('./endpoint_response_actions/agent_type_support')); loadTestFile(require.resolve('./endpoint_artifacts/trusted_apps')); loadTestFile(require.resolve('./endpoint_artifacts/event_filters')); loadTestFile(require.resolve('./endpoint_artifacts/host_isolation_exceptions')); From f1deae8bd62ecaf97d41a3078bc5c85f4df17b70 Mon Sep 17 00:00:00 2001 From: Vitalii Dmyterko <92328789+vitaliidm@users.noreply.github.com> Date: Thu, 21 Dec 2023 15:41:52 +0000 Subject: [PATCH 080/116] [Security Solution][Detection Engine] removes threshold alert suppression feature flag (#173762) ## Summary - removes threshold alert suppression experimental feature flag introduced in https://github.com/elastic/kibana/pull/171423 - docs [issue](https://github.com/elastic/security-docs/issues/4315) for reference --- .../common/experimental_features.ts | 5 ---- .../rule_details/rule_definition_section.tsx | 28 +++++++------------ .../rules/step_define_rule/index.tsx | 7 +---- .../rule_types/threshold/threshold.ts | 6 +--- .../config/ess/config.base.ts | 1 - .../configs/serverless.config.ts | 3 -- .../test/security_solution_cypress/config.ts | 1 - .../rule_creation/threshold_rule.cy.ts | 9 ------ ...threshold_rule_serverless_essentials.cy.ts | 5 ---- .../rule_edit/threshold_rule.cy.ts | 9 ------ .../serverless_config.ts | 3 -- 11 files changed, 12 insertions(+), 65 deletions(-) diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index 4a84e25f692d79..85525ff82bc1ec 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -130,11 +130,6 @@ export const allowedExperimentalValues = Object.freeze({ */ protectionUpdatesEnabled: true, - /** - * Enables alerts suppression for threshold rules - */ - alertSuppressionForThresholdRuleEnabled: false, - /** * Disables the timeline save tour. * This flag is used to disable the tour in cypress tests. diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_definition_section.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_definition_section.tsx index c2c85fca93f031..cb37caa661fdac 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_definition_section.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_definition_section.tsx @@ -54,7 +54,6 @@ import { TechnicalPreviewBadge } from '../../../../detections/components/rules/t import { BadgeList } from './badge_list'; import { DEFAULT_DESCRIPTION_LIST_COLUMN_WIDTHS } from './constants'; import * as i18n from './translations'; -import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import type { ExperimentalFeatures } from '../../../../../common/experimental_features'; interface SavedQueryNameProps { @@ -427,7 +426,7 @@ const prepareDefinitionSectionListItems = ( rule: Partial<RuleResponse>, isInteractive: boolean, savedQuery: SavedQuery | undefined, - { alertSuppressionForThresholdRuleEnabled }: Partial<ExperimentalFeatures> + experimentalFeatures?: Partial<ExperimentalFeatures> ): EuiDescriptionListProps['listItems'] => { const definitionSectionListItems: EuiDescriptionListProps['listItems'] = []; @@ -669,16 +668,14 @@ const prepareDefinitionSectionListItems = ( }); } - if (rule.type !== 'threshold' || alertSuppressionForThresholdRuleEnabled) { - definitionSectionListItems.push({ - title: ( - <span data-test-subj="alertSuppressionDurationPropertyTitle"> - <AlertSuppressionTitle title={i18n.SUPPRESS_ALERTS_DURATION_FIELD_LABEL} /> - </span> - ), - description: <SuppressAlertsDuration duration={rule.alert_suppression.duration} />, - }); - } + definitionSectionListItems.push({ + title: ( + <span data-test-subj="alertSuppressionDurationPropertyTitle"> + <AlertSuppressionTitle title={i18n.SUPPRESS_ALERTS_DURATION_FIELD_LABEL} /> + </span> + ), + description: <SuppressAlertsDuration duration={rule.alert_suppression.duration} />, + }); if ('missing_fields_strategy' in rule.alert_suppression) { definitionSectionListItems.push({ @@ -741,15 +738,10 @@ export const RuleDefinitionSection = ({ ruleType: rule.type, }); - const alertSuppressionForThresholdRuleEnabled = useIsExperimentalFeatureEnabled( - 'alertSuppressionForThresholdRuleEnabled' - ); - const definitionSectionListItems = prepareDefinitionSectionListItems( rule, isInteractive, - savedQuery, - { alertSuppressionForThresholdRuleEnabled } + savedQuery ); return ( diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx index 2d6234f225b3ac..809fb97eb260c3 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx @@ -83,7 +83,6 @@ import { useLicense } from '../../../../common/hooks/use_license'; import { AlertSuppressionMissingFieldsStrategyEnum } from '../../../../../common/api/detection_engine/model/rule_schema'; import { DurationInput } from '../duration_input'; import { MINIMUM_LICENSE_FOR_SUPPRESSION } from '../../../../../common/detection_engine/constants'; -import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { useUpsellingMessage } from '../../../../common/hooks/use_upselling'; const CommonUseField = getUseField({ component: Field }); @@ -182,9 +181,6 @@ const StepDefineRuleComponent: FC<StepDefineRuleProps> = ({ const esqlQueryRef = useRef<DefineStepRule['queryBar'] | undefined>(undefined); - const isAlertSuppressionForThresholdRuleFeatureEnabled = useIsExperimentalFeatureEnabled( - 'alertSuppressionForThresholdRuleEnabled' - ); const isAlertSuppressionLicenseValid = license.isAtLeast(MINIMUM_LICENSE_FOR_SUPPRESSION); const isThresholdRule = getIsThresholdRule(ruleType); @@ -808,8 +804,7 @@ const StepDefineRuleComponent: FC<StepDefineRuleProps> = ({ [isUpdateView, mlCapabilities] ); - const isAlertSuppressionEnabled = - isQueryRule(ruleType) || (isThresholdRule && isAlertSuppressionForThresholdRuleFeatureEnabled); + const isAlertSuppressionEnabled = isQueryRule(ruleType) || isThresholdRule; return ( <> diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts index 41ede6563524ca..70c554231a0e12 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts @@ -156,11 +156,7 @@ export const thresholdExecutor = async ({ let createResult: GenericBulkCreateResponse<BaseFieldsLatest>; let newSignalHistory: ThresholdSignalHistory; - if ( - alertSuppression?.duration && - runOpts?.experimentalFeatures?.alertSuppressionForThresholdRuleEnabled && - hasPlatinumLicense - ) { + if (alertSuppression?.duration && hasPlatinumLicense) { const suppressedResults = await bulkCreateSuppressedThresholdAlerts({ buckets, completeRule, diff --git a/x-pack/test/security_solution_api_integration/config/ess/config.base.ts b/x-pack/test/security_solution_api_integration/config/ess/config.base.ts index b7f08d5180bbe8..b4fbdba6de4c46 100644 --- a/x-pack/test/security_solution_api_integration/config/ess/config.base.ts +++ b/x-pack/test/security_solution_api_integration/config/ess/config.base.ts @@ -81,7 +81,6 @@ export function createTestConfig(options: CreateTestConfigOptions, testFiles?: s 'previewTelemetryUrlEnabled', 'riskScoringPersistence', 'riskScoringRoutesEnabled', - 'alertSuppressionForThresholdRuleEnabled', ])}`, '--xpack.task_manager.poll_interval=1000', `--xpack.actions.preconfigured=${JSON.stringify({ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/configs/serverless.config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/configs/serverless.config.ts index c01c3a74e61cfd..7bcb663699d68f 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/configs/serverless.config.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/configs/serverless.config.ts @@ -16,8 +16,5 @@ export default createTestConfig({ 'testing_ignored.constant', '/testing_regex*/', ])}`, // See tests within the file "ignore_fields.ts" which use these values in "alertIgnoreFields" - `--xpack.securitySolution.enableExperimental=${JSON.stringify([ - 'alertSuppressionForThresholdRuleEnabled', - ])}`, ], }); diff --git a/x-pack/test/security_solution_cypress/config.ts b/x-pack/test/security_solution_cypress/config.ts index 4fe61b660f1a4f..fb34362f7fb9b5 100644 --- a/x-pack/test/security_solution_cypress/config.ts +++ b/x-pack/test/security_solution_cypress/config.ts @@ -46,7 +46,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { '--xpack.ruleRegistry.unsafe.legacyMultiTenancy.enabled=true', `--xpack.securitySolution.enableExperimental=${JSON.stringify([ 'chartEmbeddablesEnabled', - 'alertSuppressionForThresholdRuleEnabled', ])}`, // mock cloud to enable the guided onboarding tour in e2e tests '--xpack.cloud.id=test', diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/threshold_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/threshold_rule.cy.ts index fa925131892e15..3a09073b71f388 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/threshold_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/threshold_rule.cy.ts @@ -72,15 +72,6 @@ describe( 'Threshold rules', { tags: ['@ess', '@serverless'], - env: { - ftrConfig: { - kbnServerArgs: [ - `--xpack.securitySolution.enableExperimental=${JSON.stringify([ - 'alertSuppressionForThresholdRuleEnabled', - ])}`, - ], - }, - }, }, () => { const rule = getNewThresholdRule(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/threshold_rule_serverless_essentials.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/threshold_rule_serverless_essentials.cy.ts index 5b8ec27e2c8910..c26954ea7e37b3 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/threshold_rule_serverless_essentials.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_creation/threshold_rule_serverless_essentials.cy.ts @@ -23,11 +23,6 @@ describe( { product_line: 'security', product_tier: 'essentials' }, { product_line: 'endpoint', product_tier: 'essentials' }, ], - kbnServerArgs: [ - `--xpack.securitySolution.enableExperimental=${JSON.stringify([ - 'alertSuppressionForThresholdRuleEnabled', - ])}`, - ], }, }, }, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_edit/threshold_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_edit/threshold_rule.cy.ts index 5eed825f99ada0..8d4bdf2d349766 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_edit/threshold_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/rule_edit/threshold_rule.cy.ts @@ -41,15 +41,6 @@ describe( 'Detection threshold rules, edit', { tags: ['@ess', '@serverless'], - env: { - ftrConfig: { - kbnServerArgs: [ - `--xpack.securitySolution.enableExperimental=${JSON.stringify([ - 'alertSuppressionForThresholdRuleEnabled', - ])}`, - ], - }, - }, }, () => { describe('without suppression', () => { diff --git a/x-pack/test/security_solution_cypress/serverless_config.ts b/x-pack/test/security_solution_cypress/serverless_config.ts index 8eb8d2efdefdc9..d0ee1613f6e4cc 100644 --- a/x-pack/test/security_solution_cypress/serverless_config.ts +++ b/x-pack/test/security_solution_cypress/serverless_config.ts @@ -34,9 +34,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { { product_line: 'endpoint', product_tier: 'complete' }, { product_line: 'cloud', product_tier: 'complete' }, ])}`, - `--xpack.securitySolution.enableExperimental=${JSON.stringify([ - 'alertSuppressionForThresholdRuleEnabled', - ])}`, ], }, testRunner: SecuritySolutionConfigurableCypressTestRunner, From b793a2e9b12da62512e3531905cb4353455faa7c Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski <jon@elastic.co> Date: Thu, 21 Dec 2023 09:41:25 -0600 Subject: [PATCH 081/116] Revert "[Security Solution][Endpoint] Improve the `run_sentinelone_host` script so that it also creates the Connector and SIEM Rule (#173693)" This reverts commit e22ad3648bd990c441728d74efba1d687935db5d. --- .../endpoint/common/connectors_services.ts | 68 ------------- .../common/detection_rules_services.ts | 99 ------------------- .../scripts/endpoint/common/fleet_services.ts | 11 ++- .../scripts/endpoint/common/vm_services.ts | 8 +- .../endpoint/sentinelone_host/common.ts | 84 ---------------- .../endpoint/sentinelone_host/index.ts | 14 +-- 6 files changed, 12 insertions(+), 272 deletions(-) delete mode 100644 x-pack/plugins/security_solution/scripts/endpoint/common/connectors_services.ts delete mode 100644 x-pack/plugins/security_solution/scripts/endpoint/common/detection_rules_services.ts diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/connectors_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/connectors_services.ts deleted file mode 100644 index e63215005ae9bb..00000000000000 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/connectors_services.ts +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { KbnClient } from '@kbn/test'; -import type { AllConnectorsResponseV1 } from '@kbn/actions-plugin/common/routes/connector/response'; -import type { bodySchema } from '@kbn/actions-plugin/server/routes/create'; -import type { TypeOf } from '@kbn/config-schema'; -import type { Connector } from '@kbn/actions-plugin/server/application/connector/types'; -import { catchAxiosErrorFormatAndThrow } from './format_axios_error'; - -/** - * Retrieve list of configured Connectors - * @param kbnClient - */ -export const fetchConnectorsList = async ( - kbnClient: KbnClient -): Promise<AllConnectorsResponseV1[]> => { - return kbnClient - .request<AllConnectorsResponseV1[]>({ - path: '/api/actions/connectors', - method: 'GET', - }) - .catch(catchAxiosErrorFormatAndThrow) - .then((response) => response.data); -}; - -/** - * Returns the first connector instance (if any) of a given type - * @param kbnClient - * @param connectorTypeId - */ -export const fetchConnectorByType = async ( - kbnClient: KbnClient, - connectorTypeId: string -): Promise<AllConnectorsResponseV1 | undefined> => { - const allConnectors = await fetchConnectorsList(kbnClient); - - for (const connector of allConnectors) { - if (connector.connector_type_id === connectorTypeId) { - return connector; - } - } -}; - -type CreateConnectorBody = TypeOf<typeof bodySchema>; - -/** - * Creates a connector in the stack - * @param kbnClient - * @param createPayload - */ -export const createConnector = async ( - kbnClient: KbnClient, - createPayload: CreateConnectorBody -): Promise<Connector> => { - return kbnClient - .request<Connector>({ - path: '/api/actions/connector', - method: 'POST', - body: createPayload, - }) - .catch(catchAxiosErrorFormatAndThrow) - .then((response) => response.data); -}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/detection_rules_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/detection_rules_services.ts deleted file mode 100644 index 81f343427b3d58..00000000000000 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/detection_rules_services.ts +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { KbnClient } from '@kbn/test'; -import { catchAxiosErrorFormatAndThrow } from './format_axios_error'; -import { - DETECTION_ENGINE_RULES_URL, - DETECTION_ENGINE_RULES_URL_FIND, -} from '../../../common/constants'; -import type { - CreateRuleRequestBody, - FindRulesRequestQuery, - FindRulesResponse, - RuleResponse, -} from '../../../common/api/detection_engine'; - -/** - * Creates a detection engine rule - * @param kbnClient - * @param payload - */ -export const createRule = async ( - kbnClient: KbnClient, - payload: Partial<CreateRuleRequestBody> = {} -): Promise<RuleResponse> => { - return kbnClient - .request<RuleResponse>({ - path: DETECTION_ENGINE_RULES_URL, - method: 'POST', - body: { - type: 'query', - index: [ - 'apm-*-transaction*', - 'auditbeat-*', - 'endgame-*', - 'filebeat-*', - 'logs-*', - 'packetbeat-*', - 'traces-apm*', - 'winlogbeat-*', - '-*elastic-cloud-logs-*', - ], - filters: [], - language: 'kuery', - query: '_id:*', - author: [], - false_positives: [], - references: [], - risk_score: 21, - risk_score_mapping: [], - severity: 'low', - severity_mapping: [], - threat: [], - name: `Test rule - ${Math.random().toString(36).substring(2)}`, - description: `Test rule created from: ${__filename}`, - tags: [], - license: '', - interval: '1m', - from: 'now-120s', - to: 'now', - meta: { - from: '1m', - kibana_siem_app_url: kbnClient.resolveUrl('/app/security'), - }, - actions: [], - enabled: true, - throttle: 'no_actions', - - ...payload, - }, - headers: { 'elastic-api-version': '2023-10-31' }, - }) - .catch(catchAxiosErrorFormatAndThrow) - .then((response) => response.data); -}; - -/** - * Query the Detection Rules - * @param kbnClient - * @param query - */ -export const findRules = async ( - kbnClient: KbnClient, - query: Partial<FindRulesRequestQuery> = {} -): Promise<FindRulesResponse> => { - return kbnClient - .request<FindRulesResponse>({ - path: DETECTION_ENGINE_RULES_URL_FIND, - method: 'GET', - headers: { 'elastic-api-version': '2023-10-31' }, - query, - }) - .catch(catchAxiosErrorFormatAndThrow) - .then((response) => response.data); -}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts index b1ff5e8464a00d..97a9df146c2ac2 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts @@ -68,6 +68,7 @@ import { createToolingLogger, RETRYABLE_TRANSIENT_ERRORS, retryOnError, + wrapErrorAndRejectPromise, } from '../../../common/endpoint/data_loaders/utils'; import { fetchKibanaStatus } from './stack_services'; import { catchAxiosErrorFormatAndThrow } from '../../../common/endpoint/format_axios_error'; @@ -776,13 +777,13 @@ export const getOrCreateDefaultAgentPolicy = async ({ }); if (existingPolicy.items[0]) { - log.info(`Re-using existing Fleet test agent policy: [${existingPolicy.items[0].name}]`); + log.info(`Re-using existing Fleet test agent policy`); log.verbose(existingPolicy.items[0]); return existingPolicy.items[0]; } - log.info(`Creating default test/dev Fleet agent policy with name: [${policyName}]`); + log.info(`Creating new default test/dev Fleet agent policy`); const newAgentPolicyData: CreateAgentPolicyRequest['body'] = { name: policyName, @@ -801,7 +802,7 @@ export const getOrCreateDefaultAgentPolicy = async ({ body: newAgentPolicyData, }) .then((response) => response.data.item) - .catch(catchAxiosErrorFormatAndThrow); + .catch(wrapErrorAndRejectPromise); log.verbose(newAgentPolicy); @@ -827,7 +828,7 @@ export const createIntegrationPolicy = async ( }, }) .then((response) => response.data.item) - .catch(catchAxiosErrorFormatAndThrow); + .catch(wrapErrorAndRejectPromise); }; /** @@ -846,7 +847,7 @@ export const fetchPackageInfo = async ( method: 'GET', }) .then((response) => response.data.item) - .catch(catchAxiosErrorFormatAndThrow); + .catch(wrapErrorAndRejectPromise); }; interface AddSentinelOneIntegrationToAgentPolicyOptions { diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/vm_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/vm_services.ts index 4209b554b2732b..17c74b1bf6fc3a 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/vm_services.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/vm_services.ts @@ -178,10 +178,10 @@ export const getMultipassVmCountNotice = async (threshold: number = 1): Promise< if (output.list.length > threshold) { return `----------------------------------------------------------------- ${chalk.red('NOTE:')} ${chalk.bold( - chalk.red(`You currently have ${chalk.red(output.list.length)} VMs running.`) - )} - Remember to delete those no longer being used. - View running VMs: ${chalk.cyan('multipass list')} + chalk.cyan(`You currently have ${chalk.red(output.list.length)} VMs running.`) + )} Remember to delete those + no longer being used. + View running VMs: ${chalk.bold('multipass list')} ----------------------------------------------------------------- `; } diff --git a/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts b/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts index fe9053795737a9..483bae1c4275e8 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts @@ -8,10 +8,6 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type { AxiosRequestConfig } from 'axios'; import axios from 'axios'; -import type { KbnClient } from '@kbn/test'; -import { SENTINELONE_CONNECTOR_ID } from '@kbn/stack-connectors-plugin/common/sentinelone/constants'; -import { type RuleResponse } from '../../../common/api/detection_engine'; -import { dump } from '../endpoint_agent_runner/utils'; import { createToolingLogger } from '../../../common/endpoint/data_loaders/utils'; import type { S1SitesListApiResponse, @@ -21,9 +17,6 @@ import type { import { catchAxiosErrorFormatAndThrow } from '../../../common/endpoint/format_axios_error'; import type { HostVm } from '../common/types'; -import { createConnector, fetchConnectorByType } from '../common/connectors_services'; -import { createRule, findRules } from '../common/detection_rules_services'; - interface S1ClientOptions { /** The base URL for SentinelOne */ url: string; @@ -207,13 +200,6 @@ export const installSentinelOneAgent = async ({ const status = (await hostVm.exec(`sudo ${installPath} control status`)).stdout; - try { - // Generate an alert in SentinelOne - await hostVm.exec('nslookup amazon.com'); - } catch (e) { - log?.warning(`Attempted to generate an alert on SentinelOne host failed: ${e.message}`); - } - log.info('done'); return { @@ -222,73 +208,3 @@ export const installSentinelOneAgent = async ({ }; }); }; - -interface CreateSentinelOneStackConnectorIfNeededOptions { - kbnClient: KbnClient; - log: ToolingLog; - s1Url: string; - s1ApiToken: string; - name?: string; -} - -export const createSentinelOneStackConnectorIfNeeded = async ({ - kbnClient, - log, - s1ApiToken, - s1Url, - name = 'SentinelOne Dev instance', -}: CreateSentinelOneStackConnectorIfNeededOptions): Promise<void> => { - const connector = await fetchConnectorByType(kbnClient, SENTINELONE_CONNECTOR_ID); - - if (connector) { - log.debug(`Nothing to do. A connector for SentinelOne is already configured`); - log.verbose(dump(connector)); - return; - } - - log.info(`Creating SentinelOne Connector with name: ${name}`); - - await createConnector(kbnClient, { - name, - config: { - url: s1Url, - }, - secrets: { - token: s1ApiToken, - }, - connector_type_id: SENTINELONE_CONNECTOR_ID, - }); -}; - -export const createDetectionEngineSentinelOneRuleIfNeeded = async ( - kbnClient: KbnClient, - log: ToolingLog -): Promise<RuleResponse> => { - const ruleName = 'Promote SentinelOne alerts'; - const sentinelOneAlertsIndexPattern = 'logs-sentinel_one.alert'; - const ruleQueryValue = 'observer.serial_number:*'; - - const { data } = await findRules(kbnClient, { - filter: `(alert.attributes.params.query: "${ruleQueryValue}" AND alert.attributes.params.index: ${sentinelOneAlertsIndexPattern})`, - }); - - if (data.length) { - log.info( - `Detection engine rule for SentinelOne alerts already exists [${data[0].name}]. No need to create a new one.` - ); - - return data[0]; - } - - log.info(`Creating new detection engine rule named [${ruleName}] for SentinelOne`); - - const createdRule = await createRule(kbnClient, { - index: [sentinelOneAlertsIndexPattern], - query: ruleQueryValue, - from: 'now-3660s', - }); - - log.verbose(dump(createdRule)); - - return createdRule; -}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/index.ts b/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/index.ts index 3416b8d4e51b6f..3fad8bf0223bb7 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/index.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/index.ts @@ -21,12 +21,7 @@ import { fetchAgentPolicy, getOrCreateDefaultAgentPolicy, } from '../common/fleet_services'; -import { - createDetectionEngineSentinelOneRuleIfNeeded, - createSentinelOneStackConnectorIfNeeded, - installSentinelOneAgent, - S1Client, -} from './common'; +import { installSentinelOneAgent, S1Client } from './common'; import { createVm, generateVmName, getMultipassVmCountNotice } from '../common/vm_services'; import { createKbnClient } from '../common/stack_services'; @@ -162,16 +157,11 @@ const runCli: RunFn = async ({ log, flags }) => { agentPolicyId, }); } else { - log.debug( + log.info( `No host VM created for Fleet agent policy [${agentPolicyName}]. It already shows to have [${agents}] enrolled` ); } - await Promise.all([ - createSentinelOneStackConnectorIfNeeded({ kbnClient, log, s1ApiToken, s1Url }), - createDetectionEngineSentinelOneRuleIfNeeded(kbnClient, log), - ]); - log.info(`Done! ${hostVm.info()} From faa3d8f42fd0b3523b14a63691eaf715050cd911 Mon Sep 17 00:00:00 2001 From: Ido Cohen <90558359+CohenIdo@users.noreply.github.com> Date: Thu, 21 Dec 2023 17:53:44 +0200 Subject: [PATCH 082/116] [Cloud Security] Mute detection rules --- .../common/types/rules/v3.ts | 15 +- .../common/utils/detection_rules.test.ts | 113 ++++++++ .../common/utils/detection_rules.ts | 58 ++++ .../cloud_security_posture/kibana.jsonc | 3 +- .../api/use_fetch_detection_rules_by_tags.ts | 7 +- .../findings_detection_rule_counter.tsx | 8 +- .../create_detection_rule_from_finding.ts | 40 +-- .../bulk_action/bulk_action.test.ts | 36 --- .../bulk_action/bulk_action.ts | 32 ++- .../benchmark_rules/bulk_action/utils.ts | 110 ++++++- .../routes/benchmark_rules/bulk_action/v1.ts | 42 ++- .../cloud_security_posture/server/types.ts | 4 + .../cloud_security_posture/tsconfig.json | 1 + .../routes/csp_benchmark_rules_bulk_update.ts | 270 +++++++++++++----- 14 files changed, 553 insertions(+), 186 deletions(-) create mode 100644 x-pack/plugins/cloud_security_posture/common/utils/detection_rules.test.ts create mode 100644 x-pack/plugins/cloud_security_posture/common/utils/detection_rules.ts delete mode 100644 x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.test.ts diff --git a/x-pack/plugins/cloud_security_posture/common/types/rules/v3.ts b/x-pack/plugins/cloud_security_posture/common/types/rules/v3.ts index cef3e445b91a89..4c4b6ee026b7eb 100644 --- a/x-pack/plugins/cloud_security_posture/common/types/rules/v3.ts +++ b/x-pack/plugins/cloud_security_posture/common/types/rules/v3.ts @@ -6,7 +6,7 @@ */ import { schema, TypeOf } from '@kbn/config-schema'; - +import type { SavedObjectsUpdateResponse } from '@kbn/core-saved-objects-api-server'; import { CSPM_POLICY_TEMPLATE, KSPM_POLICY_TEMPLATE } from '../../constants'; const DEFAULT_BENCHMARK_RULES_PER_PAGE = 25; @@ -132,9 +132,7 @@ export interface FindCspBenchmarkRuleResponse { export const cspBenchmarkRules = schema.arrayOf( schema.object({ - benchmark_id: schema.string(), - benchmark_version: schema.string(), - rule_number: schema.string(), + rule_id: schema.string(), }) ); @@ -153,6 +151,10 @@ const rulesStates = schema.recordOf( schema.string(), schema.object({ muted: schema.boolean(), + benchmark_id: schema.string(), + benchmark_version: schema.string(), + rule_number: schema.string(), + rule_id: schema.string(), }) ); @@ -162,3 +164,8 @@ export const cspSettingsSchema = schema.object({ export type CspBenchmarkRulesStates = TypeOf<typeof rulesStates>; export type CspSettings = TypeOf<typeof cspSettingsSchema>; + +export interface BulkActionBenchmarkRulesResponse { + newCspSettings: SavedObjectsUpdateResponse<CspSettings>; + disabledRulesCounter: number; +} diff --git a/x-pack/plugins/cloud_security_posture/common/utils/detection_rules.test.ts b/x-pack/plugins/cloud_security_posture/common/utils/detection_rules.test.ts new file mode 100644 index 00000000000000..f2a35944f0825f --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/common/utils/detection_rules.test.ts @@ -0,0 +1,113 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CspBenchmarkRuleMetadata } from '../types'; +import { + convertRuleTagsToKQL, + generateBenchmarkRuleTags, + getFindingsDetectionRuleSearchTags, +} from './detection_rules'; + +describe('Detection rules utils', () => { + it('should convert tags to KQL format', () => { + const inputTags = ['tag1', 'tag2', 'tag3']; + + const result = convertRuleTagsToKQL(inputTags); + + const expectedKQL = 'alert.attributes.tags:("tag1" AND "tag2" AND "tag3")'; + expect(result).toBe(expectedKQL); + }); + + it('Should convert tags to KQL format', () => { + const inputTags = [] as string[]; + + const result = convertRuleTagsToKQL(inputTags); + + const expectedKQL = 'alert.attributes.tags:()'; + expect(result).toBe(expectedKQL); + }); + + it('Should generate search tags for a CSP benchmark rule', () => { + const cspBenchmarkRule = { + benchmark: { + id: 'cis_gcp', + rule_number: '1.1', + }, + } as unknown as CspBenchmarkRuleMetadata; + + const result = getFindingsDetectionRuleSearchTags(cspBenchmarkRule); + + const expectedTags = ['CIS', 'GCP', 'CIS GCP 1.1']; + expect(result).toEqual(expectedTags); + }); + + it('Should handle undefined benchmark object gracefully', () => { + const cspBenchmarkRule = { benchmark: {} } as any; + const expectedTags: string[] = []; + const result = getFindingsDetectionRuleSearchTags(cspBenchmarkRule); + expect(result).toEqual(expectedTags); + }); + + it('Should handle undefined rule number gracefully', () => { + const cspBenchmarkRule = { + benchmark: { + id: 'cis_gcp', + }, + } as unknown as CspBenchmarkRuleMetadata; + const result = getFindingsDetectionRuleSearchTags(cspBenchmarkRule); + const expectedTags = ['CIS', 'GCP', 'CIS GCP']; + expect(result).toEqual(expectedTags); + }); + + it('Should generate tags for a CSPM benchmark rule', () => { + const cspBenchmarkRule = { + benchmark: { + id: 'cis_gcp', + rule_number: '1.1', + posture_type: 'cspm', + }, + } as unknown as CspBenchmarkRuleMetadata; + + const result = generateBenchmarkRuleTags(cspBenchmarkRule); + + const expectedTags = [ + 'Cloud Security', + 'Use Case: Configuration Audit', + 'CIS', + 'GCP', + 'CIS GCP 1.1', + 'CSPM', + 'Data Source: CSPM', + 'Domain: Cloud', + ]; + expect(result).toEqual(expectedTags); + }); + + it('Should generate tags for a KSPM benchmark rule', () => { + const cspBenchmarkRule = { + benchmark: { + id: 'cis_gcp', + rule_number: '1.1', + posture_type: 'kspm', + }, + } as unknown as CspBenchmarkRuleMetadata; + + const result = generateBenchmarkRuleTags(cspBenchmarkRule); + + const expectedTags = [ + 'Cloud Security', + 'Use Case: Configuration Audit', + 'CIS', + 'GCP', + 'CIS GCP 1.1', + 'KSPM', + 'Data Source: KSPM', + 'Domain: Container', + ]; + expect(result).toEqual(expectedTags); + }); +}); diff --git a/x-pack/plugins/cloud_security_posture/common/utils/detection_rules.ts b/x-pack/plugins/cloud_security_posture/common/utils/detection_rules.ts new file mode 100644 index 00000000000000..42ea7561286c16 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/common/utils/detection_rules.ts @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CspBenchmarkRuleMetadata } from '../types/latest'; + +const CSP_RULE_TAG = 'Cloud Security'; +const CSP_RULE_TAG_USE_CASE = 'Use Case: Configuration Audit'; +const CSP_RULE_TAG_DATA_SOURCE_PREFIX = 'Data Source: '; + +const STATIC_RULE_TAGS = [CSP_RULE_TAG, CSP_RULE_TAG_USE_CASE]; + +export const convertRuleTagsToKQL = (tags: string[]): string => { + const TAGS_FIELD = 'alert.attributes.tags'; + return `${TAGS_FIELD}:(${tags.map((tag) => `"${tag}"`).join(' AND ')})`; +}; + +/* + * Returns an array of CspFinding tags that can be used to search and filter a detection rule + */ +export const getFindingsDetectionRuleSearchTags = ( + cspBenchmarkRule: CspBenchmarkRuleMetadata +): string[] => { + if (!cspBenchmarkRule.benchmark || !cspBenchmarkRule.benchmark.id) { + // Return an empty array if benchmark ID is undefined + return []; + } + + // ex: cis_gcp to ['CIS', 'GCP'] + const benchmarkIdTags = cspBenchmarkRule.benchmark.id.split('_').map((tag) => tag.toUpperCase()); + + // ex: 'CIS GCP 1.1' + const benchmarkRuleNumberTag = cspBenchmarkRule.benchmark.rule_number + ? `${cspBenchmarkRule.benchmark.id.replace('_', ' ').toUpperCase()} ${ + cspBenchmarkRule.benchmark.rule_number + }` + : cspBenchmarkRule.benchmark.id.replace('_', ' ').toUpperCase(); + + return benchmarkIdTags.concat([benchmarkRuleNumberTag]); +}; + +export const generateBenchmarkRuleTags = (rule: CspBenchmarkRuleMetadata) => { + return [STATIC_RULE_TAGS] + .concat(getFindingsDetectionRuleSearchTags(rule)) + .concat( + rule.benchmark.posture_type + ? [ + rule.benchmark.posture_type.toUpperCase(), + `${CSP_RULE_TAG_DATA_SOURCE_PREFIX}${rule.benchmark.posture_type.toUpperCase()}`, + ] + : [] + ) + .concat(rule.benchmark.posture_type === 'cspm' ? ['Domain: Cloud'] : ['Domain: Container']) + .flat(); +}; diff --git a/x-pack/plugins/cloud_security_posture/kibana.jsonc b/x-pack/plugins/cloud_security_posture/kibana.jsonc index 9237ed70104ad2..56ea8549629acb 100644 --- a/x-pack/plugins/cloud_security_posture/kibana.jsonc +++ b/x-pack/plugins/cloud_security_posture/kibana.jsonc @@ -21,7 +21,8 @@ "cloud", "licensing", "share", - "kibanaUtils" + "kibanaUtils", + "alerting" ], "optionalPlugins": ["usageCollection"], "requiredBundles": ["kibanaReact", "usageCollection"] diff --git a/x-pack/plugins/cloud_security_posture/public/common/api/use_fetch_detection_rules_by_tags.ts b/x-pack/plugins/cloud_security_posture/public/common/api/use_fetch_detection_rules_by_tags.ts index 309698f4219d98..dfd6f13e386921 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/api/use_fetch_detection_rules_by_tags.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/api/use_fetch_detection_rules_by_tags.ts @@ -11,6 +11,7 @@ import { useQuery } from '@tanstack/react-query'; import { DETECTION_RULE_RULES_API_CURRENT_VERSION } from '../../../common/constants'; import { RuleResponse } from '../types'; import { DETECTION_ENGINE_RULES_KEY } from '../constants'; +import { convertRuleTagsToKQL } from '../../../common/utils/detection_rules'; /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one @@ -26,16 +27,10 @@ export interface FetchRulesResponse { data: RuleResponse[]; } -export const TAGS_FIELD = 'alert.attributes.tags'; - const DETECTION_ENGINE_URL = '/api/detection_engine' as const; const DETECTION_ENGINE_RULES_URL = `${DETECTION_ENGINE_URL}/rules` as const; export const DETECTION_ENGINE_RULES_URL_FIND = `${DETECTION_ENGINE_RULES_URL}/_find` as const; -export function convertRuleTagsToKQL(tags: string[]): string { - return `${TAGS_FIELD}:(${tags.map((tag) => `"${tag}"`).join(' AND ')})`; -} - export const useFetchDetectionRulesByTags = (tags: string[]) => { const { http } = useKibana<CoreStart>().services; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_detection_rule_counter.tsx b/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_detection_rule_counter.tsx index f39379f8c4ddd8..24ef238cf57748 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_detection_rule_counter.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_detection_rule_counter.tsx @@ -9,10 +9,8 @@ import type { HttpSetup } from '@kbn/core/public'; import React from 'react'; import { CspFinding } from '../../../../common/schemas/csp_finding'; import { DetectionRuleCounter } from '../../../components/detection_rule_counter'; -import { - createDetectionRuleFromFinding, - getFindingsDetectionRuleSearchTags, -} from '../utils/create_detection_rule_from_finding'; +import { createDetectionRuleFromFinding } from '../utils/create_detection_rule_from_finding'; +import { getFindingsDetectionRuleSearchTags } from '../../../../common/utils/detection_rules'; export const FindingsDetectionRuleCounter = ({ finding }: { finding: CspFinding }) => { const createMisconfigurationRuleFn = async (http: HttpSetup) => @@ -20,7 +18,7 @@ export const FindingsDetectionRuleCounter = ({ finding }: { finding: CspFinding return ( <DetectionRuleCounter - tags={getFindingsDetectionRuleSearchTags(finding)} + tags={getFindingsDetectionRuleSearchTags(finding.rule)} createRuleFn={createMisconfigurationRuleFn} /> ); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/create_detection_rule_from_finding.ts b/x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/create_detection_rule_from_finding.ts index b06246e6605e9b..ca0e03460c3406 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/create_detection_rule_from_finding.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/create_detection_rule_from_finding.ts @@ -12,6 +12,7 @@ import { LATEST_FINDINGS_RETENTION_POLICY, } from '../../../../common/constants'; import { createDetectionRule } from '../../../common/api/create_detection_rule'; +import { generateBenchmarkRuleTags } from '../../../../common/utils/detection_rules'; const DEFAULT_RULE_RISK_SCORE = 0; const DEFAULT_RULE_SEVERITY = 'low'; @@ -47,43 +48,6 @@ const convertReferencesLinksToArray = (input: string | undefined) => { return matches.map((link) => link.replace(/^\d+\. /, '').replace(/\n/g, '')); }; -const CSP_RULE_TAG = 'Cloud Security'; -const CSP_RULE_TAG_USE_CASE = 'Use Case: Configuration Audit'; -const CSP_RULE_TAG_DATA_SOURCE_PREFIX = 'Data Source: '; - -const STATIC_RULE_TAGS = [CSP_RULE_TAG, CSP_RULE_TAG_USE_CASE]; - -/* - * Returns an array of CspFinding tags that can be used to search and filter a detection rule - */ -export const getFindingsDetectionRuleSearchTags = ({ rule }: CspFinding) => { - // ex: cis_gcp to ['CIS', 'GCP'] - const benchmarkIdTags = rule.benchmark.id.split('_').map((tag) => tag.toUpperCase()); - // ex: 'CIS GCP 1.1' - const benchmarkRuleNumberTag = `${rule.benchmark.id.replace('_', ' ').toUpperCase()} ${ - rule.benchmark.rule_number - }`; - - return benchmarkIdTags.concat([benchmarkRuleNumberTag]); -}; - -const generateFindingsTags = (finding: CspFinding) => { - return [STATIC_RULE_TAGS] - .concat(getFindingsDetectionRuleSearchTags(finding)) - .concat( - finding.rule.benchmark.posture_type - ? [ - finding.rule.benchmark.posture_type.toUpperCase(), - `${CSP_RULE_TAG_DATA_SOURCE_PREFIX}${finding.rule.benchmark.posture_type.toUpperCase()}`, - ] - : [] - ) - .concat( - finding.rule.benchmark.posture_type === 'cspm' ? ['Domain: Cloud'] : ['Domain: Container'] - ) - .flat(); -}; - const generateFindingsRuleQuery = (finding: CspFinding) => { const currentTimestamp = new Date().toISOString(); @@ -128,7 +92,7 @@ export const createDetectionRuleFromFinding = async (http: HttpSetup, finding: C references: convertReferencesLinksToArray(finding.rule.references), name: finding.rule.name, description: finding.rule.rationale, - tags: generateFindingsTags(finding), + tags: generateBenchmarkRuleTags(finding.rule), investigation_fields: DEFAULT_INVESTIGATION_FIELDS, note: finding.rule.remediation, }, diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.test.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.test.ts deleted file mode 100644 index 1bb2232d2834d1..00000000000000 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.test.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import expect from 'expect'; -import { setRulesStates, buildRuleKey } from './utils'; - -describe('CSP Rule State Management', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should set rules states correctly', () => { - const ruleIds = ['rule1', 'rule3']; - const newState = true; - - const updatedRulesStates = setRulesStates(ruleIds, newState); - - expect(updatedRulesStates).toEqual({ - rule1: { muted: true }, - rule3: { muted: true }, - }); - }); - - it('should build a rule key with the provided benchmarkId, benchmarkVersion, and ruleNumber', () => { - const benchmarkId = 'randomId'; - const benchmarkVersion = 'v1'; - const ruleNumber = '001'; - - const result = buildRuleKey(benchmarkId, benchmarkVersion, ruleNumber); - - expect(result).toBe(`${benchmarkId};${benchmarkVersion};${ruleNumber}`); - }); -}); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.ts index a87df39341741b..1b033867c03fd6 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/bulk_action.ts @@ -16,6 +16,26 @@ import { CspRouter } from '../../../types'; import { CSP_BENCHMARK_RULES_BULK_ACTION_ROUTE_PATH } from '../../../../common/constants'; import { bulkActionBenchmarkRulesHandler } from './v1'; +/** + This API allows bulk actions (mute or unmute) on CSP benchmark rules. + Request: + { + action: 'mute' | 'unmute'; // Specify the bulk action type (mute or unmute) + rules: [ + { + rule_id: string; // Unique identifier for the rule + }, + // ... (additional benchmark rules) + ]; + } + + Response: + { + updated_benchmark_rules: CspBenchmarkRulesStates; Benchmark rules object that were affected + detection_rules: string; // Status message indicating the number of detection rules affected + message: string; // Success message + } + */ export const defineBulkActionCspBenchmarkRulesRoute = (router: CspRouter) => router.versioned .post({ @@ -42,16 +62,24 @@ export const defineBulkActionCspBenchmarkRulesRoute = (router: CspRouter) => const benchmarkRulesToUpdate = requestBody.rules; + const detectionRulesClient = (await context.alerting).getRulesClient(); + const handlerResponse = await bulkActionBenchmarkRulesHandler( + cspContext.soClient, cspContext.encryptedSavedObjects, + detectionRulesClient, benchmarkRulesToUpdate, - requestBody.action + requestBody.action, + cspContext.logger ); - const updatedBenchmarkRules: CspBenchmarkRulesStates = handlerResponse; + const updatedBenchmarkRules: CspBenchmarkRulesStates = + handlerResponse.newCspSettings.attributes.rules!; + return response.ok({ body: { updated_benchmark_rules: updatedBenchmarkRules, + detection_rules: `disabled ${handlerResponse.disabledRulesCounter} detections rules.`, message: 'The bulk operation has been executed successfully.', }, }); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/utils.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/utils.ts index 3442b3f050b90c..2f03af30c58b5e 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/utils.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/utils.ts @@ -9,13 +9,99 @@ import type { SavedObjectsClientContract, SavedObjectsUpdateResponse, } from '@kbn/core-saved-objects-api-server'; -import { CspBenchmarkRulesStates, CspSettings } from '../../../../common/types/rules/v3'; +import type { FindResult, RulesClient } from '@kbn/alerting-plugin/server'; +import type { RuleParams } from '@kbn/alerting-plugin/server/application/rule/types'; +import type { + CspBenchmarkRule, + CspBenchmarkRulesStates, + CspSettings, +} from '../../../../common/types/rules/v3'; +import { + convertRuleTagsToKQL, + generateBenchmarkRuleTags, +} from '../../../../common/utils/detection_rules'; import { + CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE, INTERNAL_CSP_SETTINGS_SAVED_OBJECT_ID, INTERNAL_CSP_SETTINGS_SAVED_OBJECT_TYPE, } from '../../../../common/constants'; +export const getRuleIdsToDisable = async (detectionRules: Array<FindResult<RuleParams>>) => { + const idsToDisable = detectionRules + .map((detectionRule) => { + return detectionRule.data.map((data) => data.id); + }) + .flat(); + return idsToDisable; +}; + +const disableDetectionRules = async ( + detectionRulesClient: RulesClient, + detectionRules: Array<FindResult<RuleParams>> +) => { + const idsToDisable = await getRuleIdsToDisable(detectionRules); + if (!idsToDisable.length) return; + return await detectionRulesClient.bulkDisableRules({ ids: idsToDisable }); +}; + +export const getDetectionRules = async ( + detectionRulesClient: RulesClient, + rulesTags: string[][] +): Promise<Array<FindResult<RuleParams>>> => { + const detectionRules = Promise.all( + rulesTags.map(async (ruleTags) => { + return detectionRulesClient.find({ + excludeFromPublicApi: false, + options: { + filter: convertRuleTagsToKQL(ruleTags), + searchFields: ['tags'], + page: 1, + per_page: 1, + }, + }); + }) + ); + + return detectionRules; +}; + +export const getBenchmarkRules = async ( + soClient: SavedObjectsClientContract, + ruleIds: string[] +): Promise<Array<CspBenchmarkRule | undefined>> => { + const bulkGetObject = ruleIds.map((ruleId) => ({ + id: ruleId, + type: CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE, + })); + const cspBenchmarkRulesSo = await soClient.bulkGet<CspBenchmarkRule>(bulkGetObject); + + const benchmarkRules = cspBenchmarkRulesSo.saved_objects.map( + (cspBenchmarkRule) => cspBenchmarkRule.attributes + ); + return benchmarkRules; +}; + +export const muteDetectionRules = async ( + soClient: SavedObjectsClientContract, + detectionRulesClient: RulesClient, + rulesIds: string[] +): Promise<number> => { + const benchmarkRules = await getBenchmarkRules(soClient, rulesIds); + if (benchmarkRules.includes(undefined)) { + throw new Error('At least one of the provided benchmark rule IDs does not exist'); + } + const benchmarkRulesTags = benchmarkRules.map((benchmarkRule) => + generateBenchmarkRuleTags(benchmarkRule!.metadata) + ); + + const detectionRules = await getDetectionRules(detectionRulesClient, benchmarkRulesTags); + + const disabledDetectionRules = await disableDetectionRules(detectionRulesClient, detectionRules); + + return disabledDetectionRules ? disabledDetectionRules.rules.length : 0; +}; + export const updateRulesStates = async ( encryptedSoClient: SavedObjectsClientContract, newRulesStates: CspBenchmarkRulesStates @@ -29,14 +115,26 @@ export const updateRulesStates = async ( ); }; -export const setRulesStates = (ruleIds: string[], state: boolean): CspBenchmarkRulesStates => { +export const setRulesStates = ( + ruleIds: string[], + state: boolean, + benchmarkRules: CspBenchmarkRule[] +): CspBenchmarkRulesStates => { const rulesStates: CspBenchmarkRulesStates = {}; - ruleIds.forEach((ruleId) => { - rulesStates[ruleId] = { muted: state }; + ruleIds.forEach((ruleId, index) => { + const benchmarkRule = benchmarkRules[index]; + rulesStates[ruleId] = { + muted: state, + benchmark_id: benchmarkRule.metadata.benchmark.id, + benchmark_version: benchmarkRule.metadata.benchmark.version, + rule_number: benchmarkRule.metadata.benchmark.rule_number || '', + rule_id: benchmarkRule.metadata.id, + }; }); return rulesStates; }; -export const buildRuleKey = (benchmarkId: string, benchmarkVersion: string, ruleNumber: string) => { - return `${benchmarkId};${benchmarkVersion};${ruleNumber}`; +export const buildRuleKey = (benchmarkRule: CspBenchmarkRule) => { + const ruleNumber = benchmarkRule.metadata.benchmark.rule_number; + return `${benchmarkRule.metadata.benchmark.id};${benchmarkRule.metadata.benchmark.version};${ruleNumber}`; }; diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/v1.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/v1.ts index 42895b5eb694d1..907b8cea3d73ce 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/v1.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmark_rules/bulk_action/v1.ts @@ -5,8 +5,20 @@ * 2.0. */ import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { CspBenchmarkRules, CspBenchmarkRulesStates } from '../../../../common/types/rules/v3'; -import { buildRuleKey, setRulesStates, updateRulesStates } from './utils'; +import { Logger } from '@kbn/core/server'; +import type { RulesClient } from '@kbn/alerting-plugin/server'; +import { + buildRuleKey, + getBenchmarkRules, + muteDetectionRules, + setRulesStates, + updateRulesStates, +} from './utils'; +import type { + BulkActionBenchmarkRulesResponse, + CspBenchmarkRule, + CspBenchmarkRules, +} from '../../../../common/types/rules/v3'; const muteStatesMap = { mute: true, @@ -14,17 +26,29 @@ const muteStatesMap = { }; export const bulkActionBenchmarkRulesHandler = async ( + soClient: SavedObjectsClientContract, encryptedSoClient: SavedObjectsClientContract, + detectionRulesClient: RulesClient, rulesToUpdate: CspBenchmarkRules, - action: 'mute' | 'unmute' -): Promise<CspBenchmarkRulesStates> => { - const ruleKeys = rulesToUpdate.map((rule) => - buildRuleKey(rule.benchmark_id, rule.benchmark_version, rule.rule_number) - ); + action: 'mute' | 'unmute', + logger: Logger +): Promise<BulkActionBenchmarkRulesResponse> => { + const rulesIds = rulesToUpdate.map((rule) => rule.rule_id); + + const benchmarkRules = await getBenchmarkRules(soClient, rulesIds); + if (benchmarkRules.includes(undefined)) + throw new Error('At least one of the provided benchmark rule IDs does not exist'); - const newRulesStates = setRulesStates(ruleKeys, muteStatesMap[action]); + const rulesKeys = benchmarkRules.map((benchmarkRule) => buildRuleKey(benchmarkRule!)); + const newRulesStates = setRulesStates( + rulesKeys, + muteStatesMap[action], + benchmarkRules as CspBenchmarkRule[] + ); const newCspSettings = await updateRulesStates(encryptedSoClient, newRulesStates); + const disabledRulesCounter = + action === 'mute' ? await muteDetectionRules(soClient, detectionRulesClient, rulesIds) : 0; - return newCspSettings.attributes.rules!; + return { newCspSettings, disabledRulesCounter }; }; diff --git a/x-pack/plugins/cloud_security_posture/server/types.ts b/x-pack/plugins/cloud_security_posture/server/types.ts index b6e83939b6ca74..15dee7c9941d0c 100644 --- a/x-pack/plugins/cloud_security_posture/server/types.ts +++ b/x-pack/plugins/cloud_security_posture/server/types.ts @@ -34,6 +34,8 @@ import type { import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server'; import type { FleetStartContract, FleetRequestHandlerContext } from '@kbn/fleet-plugin/server'; import { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; +import type { AlertingApiRequestHandlerContext } from '@kbn/alerting-plugin/server'; +import type { AlertingPluginSetup } from '@kbn/alerting-plugin/public/plugin'; import { CspStatusCode, IndexDetails } from '../common/types_old'; // eslint-disable-next-line @typescript-eslint/no-empty-interface @@ -47,6 +49,7 @@ export interface CspServerPluginSetupDeps { taskManager: TaskManagerSetupContract; security: SecurityPluginSetup; cloud: CloudSetup; + alerting: AlertingPluginSetup; // optional usageCollection?: UsageCollectionSetup; } @@ -80,6 +83,7 @@ export interface CspApiRequestHandlerContext { export type CspRequestHandlerContext = CustomRequestHandlerContext<{ csp: CspApiRequestHandlerContext; fleet: FleetRequestHandlerContext['fleet']; + alerting: AlertingApiRequestHandlerContext; }>; /** diff --git a/x-pack/plugins/cloud_security_posture/tsconfig.json b/x-pack/plugins/cloud_security_posture/tsconfig.json index ad1a97748967f9..e6e0879f774190 100755 --- a/x-pack/plugins/cloud_security_posture/tsconfig.json +++ b/x-pack/plugins/cloud_security_posture/tsconfig.json @@ -61,6 +61,7 @@ "@kbn/field-formats-plugin", "@kbn/data-view-field-editor-plugin", "@kbn/securitysolution-grouping", + "@kbn/alerting-plugin" ], "exclude": ["target/**/*"] } diff --git a/x-pack/test/cloud_security_posture_api/routes/csp_benchmark_rules_bulk_update.ts b/x-pack/test/cloud_security_posture_api/routes/csp_benchmark_rules_bulk_update.ts index dad7845e60e317..fd08e1cae3f3a6 100644 --- a/x-pack/test/cloud_security_posture_api/routes/csp_benchmark_rules_bulk_update.ts +++ b/x-pack/test/cloud_security_posture_api/routes/csp_benchmark_rules_bulk_update.ts @@ -12,14 +12,16 @@ import { ELASTIC_HTTP_VERSION_HEADER, X_ELASTIC_INTERNAL_ORIGIN_REQUEST, } from '@kbn/core-http-common'; +import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; +import { + CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE, + DETECTION_RULE_RULES_API_CURRENT_VERSION, +} from '@kbn/cloud-security-posture-plugin/common/constants'; +import type { CspBenchmarkRule } from '@kbn/cloud-security-posture-plugin/common/types/latest'; +// eslint-disable @kbn/imports/no_boundary_crossing +import { generateBenchmarkRuleTags } from '@kbn/cloud-security-posture-plugin/common/utils/detection_rules'; import type { FtrProviderContext } from '../ftr_provider_context'; -interface RuleIdentifier { - benchmarkId: string; - benchmarkVersion: string; - ruleNumber: string; -} - // eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const retry = getService('retry'); @@ -27,24 +29,52 @@ export default function ({ getService }: FtrProviderContext) { const log = getService('log'); const kibanaServer = getService('kibanaServer'); - const generateRuleKey = (ruleParams: RuleIdentifier): string => { - return `${ruleParams.benchmarkId};${ruleParams.benchmarkVersion};${ruleParams.ruleNumber}`; + const generateRuleKey = (rule: CspBenchmarkRule): string => { + return `${rule.metadata.benchmark.id};${rule.metadata.benchmark.version};${rule.metadata.benchmark.rule_number}`; + }; + + const getRandomCspBenchmarkRule = async () => { + const cspBenchmarkRules = await kibanaServer.savedObjects.find<CspBenchmarkRule>({ + type: CSP_BENCHMARK_RULE_SAVED_OBJECT_TYPE, + }); + + expect(cspBenchmarkRules.saved_objects.length).greaterThan(0); + + const randomIndex = Math.floor(Math.random() * cspBenchmarkRules.saved_objects.length); + return cspBenchmarkRules.saved_objects[randomIndex].attributes; }; - const generateRandomRule = (): RuleIdentifier => { - const majorVersionNumber = Math.floor(Math.random() * 10); // Random major number between 0 and 9 - const minorVersionNumber = Math.floor(Math.random() * 10); - const benchmarksIds = ['cis_aws', 'cis_k8s', 'cis_k8s']; - const benchmarksVersions = ['v2.0.0', 'v2.0.1', 'v2.0.3', 'v3.0.0']; - const randomBenchmarkId = benchmarksIds[Math.floor(Math.random() * benchmarksIds.length)]; - const randomBenchmarkVersion = - benchmarksVersions[Math.floor(Math.random() * benchmarksVersions.length)]; - - return { - benchmarkId: randomBenchmarkId, - benchmarkVersion: randomBenchmarkVersion, - ruleNumber: `${majorVersionNumber}.${minorVersionNumber}`, - }; + const createDetectionRule = async (rule: CspBenchmarkRule) => { + await supertest + .post(DETECTION_ENGINE_RULES_URL) + .set('version', DETECTION_RULE_RULES_API_CURRENT_VERSION) + .set('kbn-xsrf', 'xxxx') + .send({ + type: 'query', + language: 'kuery', + license: 'Elastic', + author: ['Elastic License v2'], + filters: [], + false_positives: [], + risk_score: 0, + risk_score_mapping: [], + severity: 'low', + severity_mapping: [], + threat: [], + interval: '1h', + from: 'now-26h', + to: 'now', + max_signals: 100, + timestamp_override: 'event.ingested', + timestamp_override_fallback_disabled: false, + actions: [], + enabled: true, + index: ['logs-cloud_security_posture.findings-default*'], + query: 'rule.benchmark.rule_number: foo', + name: rule.metadata.name, + description: rule.metadata.rationale, + tags: generateBenchmarkRuleTags(rule.metadata), + }); }; /** @@ -66,15 +96,15 @@ export default function ({ getService }: FtrProviderContext) { await waitForPluginInitialized(); }); - afterEach(async () => { + beforeEach(async () => { await kibanaServer.savedObjects.clean({ types: ['cloud-security-posture-settings'], }); }); - it('mute rules successfully', async () => { - const rule1 = generateRandomRule(); - const rule2 = generateRandomRule(); + it('mute benchmark rules successfully', async () => { + const rule1 = await getRandomCspBenchmarkRule(); + const rule2 = await getRandomCspBenchmarkRule(); const { body } = await supertest .post(`/internal/cloud_security_posture/rules/_bulk_action`) @@ -85,14 +115,10 @@ export default function ({ getService }: FtrProviderContext) { action: 'mute', rules: [ { - benchmark_id: rule1.benchmarkId, - benchmark_version: rule1.benchmarkVersion, - rule_number: rule1.ruleNumber, + rule_id: rule1.metadata.id, }, { - benchmark_id: rule2.benchmarkId, - benchmark_version: rule2.benchmarkVersion, - rule_number: rule2.ruleNumber, + rule_id: rule2.metadata.id, }, ], }) @@ -100,16 +126,33 @@ export default function ({ getService }: FtrProviderContext) { expectExpect(body.updated_benchmark_rules).toEqual( expectExpect.objectContaining({ - [generateRuleKey(rule1)]: { muted: true }, - [generateRuleKey(rule2)]: { muted: true }, + [generateRuleKey(rule1)]: { + muted: true, + benchmark_id: rule1.metadata.benchmark.id, + benchmark_version: rule1.metadata.benchmark.version, + rule_number: rule1.metadata.benchmark.rule_number + ? rule1.metadata.benchmark.rule_number + : '', + rule_id: rule1.metadata.id, + }, + [generateRuleKey(rule2)]: { + muted: true, + benchmark_id: rule2.metadata.benchmark.id, + benchmark_version: rule2.metadata.benchmark.version, + rule_number: rule2.metadata.benchmark.rule_number + ? rule2.metadata.benchmark.rule_number + : '', + rule_id: rule2.metadata.id, + }, }) ); + expectExpect(body.detection_rules).toEqual('disabled 0 detections rules.'); }); it('unmute rules successfully', async () => { - const rule1 = generateRandomRule(); - const rule2 = generateRandomRule(); - + const rule1 = await getRandomCspBenchmarkRule(); + const rule2 = await getRandomCspBenchmarkRule(); + // getRandomCspBenchmarkRule(); const { body } = await supertest .post(`/internal/cloud_security_posture/rules/_bulk_action`) .set(ELASTIC_HTTP_VERSION_HEADER, '1') @@ -119,14 +162,10 @@ export default function ({ getService }: FtrProviderContext) { action: 'unmute', rules: [ { - benchmark_id: rule1.benchmarkId, - benchmark_version: rule1.benchmarkVersion, - rule_number: rule1.ruleNumber, + rule_id: rule1.metadata.id, }, { - benchmark_id: rule2.benchmarkId, - benchmark_version: rule2.benchmarkVersion, - rule_number: rule2.ruleNumber, + rule_id: rule2.metadata.id, }, ], }) @@ -134,19 +173,35 @@ export default function ({ getService }: FtrProviderContext) { expectExpect(body.updated_benchmark_rules).toEqual( expectExpect.objectContaining({ - [generateRuleKey(rule1)]: { muted: false }, - [generateRuleKey(rule2)]: { muted: false }, + [generateRuleKey(rule1)]: { + muted: false, + benchmark_id: rule1.metadata.benchmark.id, + benchmark_version: rule1.metadata.benchmark.version, + rule_number: rule1.metadata.benchmark.rule_number + ? rule1.metadata.benchmark.rule_number + : '', + rule_id: rule1.metadata.id, + }, + [generateRuleKey(rule2)]: { + muted: false, + benchmark_id: rule2.metadata.benchmark.id, + benchmark_version: rule2.metadata.benchmark.version, + rule_number: rule2.metadata.benchmark.rule_number + ? rule2.metadata.benchmark.rule_number + : '', + rule_id: rule2.metadata.id, + }, }) ); }); it('verify new rules are added and existing rules are set.', async () => { - const rule1 = generateRandomRule(); - const rule2 = generateRandomRule(); - const rule3 = generateRandomRule(); + const rule1 = await getRandomCspBenchmarkRule(); + const rule2 = await getRandomCspBenchmarkRule(); + const rule3 = await getRandomCspBenchmarkRule(); // unmute rule1 and rule2 - const cspSettingsResponse = await supertest + const { body } = await supertest .post(`/internal/cloud_security_posture/rules/_bulk_action`) .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') @@ -155,28 +210,40 @@ export default function ({ getService }: FtrProviderContext) { action: 'unmute', rules: [ { - benchmark_id: rule1.benchmarkId, - benchmark_version: rule1.benchmarkVersion, - rule_number: rule1.ruleNumber, + rule_id: rule1.metadata.id, }, { - benchmark_id: rule2.benchmarkId, - benchmark_version: rule2.benchmarkVersion, - rule_number: rule2.ruleNumber, + rule_id: rule2.metadata.id, }, ], }) .expect(200); - expectExpect(cspSettingsResponse.body.updated_benchmark_rules).toEqual( + expectExpect(body.updated_benchmark_rules).toEqual( expectExpect.objectContaining({ - [generateRuleKey(rule1)]: { muted: false }, - [generateRuleKey(rule2)]: { muted: false }, + [generateRuleKey(rule1)]: { + muted: false, + benchmark_id: rule1.metadata.benchmark.id, + benchmark_version: rule1.metadata.benchmark.version, + rule_number: rule1.metadata.benchmark.rule_number + ? rule1.metadata.benchmark.rule_number + : '', + rule_id: rule1.metadata.id, + }, + [generateRuleKey(rule2)]: { + muted: false, + benchmark_id: rule2.metadata.benchmark.id, + benchmark_version: rule2.metadata.benchmark.version, + rule_number: rule2.metadata.benchmark.rule_number + ? rule2.metadata.benchmark.rule_number + : '', + rule_id: rule2.metadata.id, + }, }) ); // mute rule1 and rule3 - const updatedCspSettingsResponse = await supertest + const { body: body2 } = await supertest .post(`/internal/cloud_security_posture/rules/_bulk_action`) .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') @@ -185,29 +252,43 @@ export default function ({ getService }: FtrProviderContext) { action: 'mute', rules: [ { - benchmark_id: rule1.benchmarkId, - benchmark_version: rule1.benchmarkVersion, - rule_number: rule1.ruleNumber, + rule_id: rule1.metadata.id, }, { - benchmark_id: rule3.benchmarkId, - benchmark_version: rule3.benchmarkVersion, - rule_number: rule3.ruleNumber, + rule_id: rule3.metadata.id, }, ], }) .expect(200); - expectExpect(updatedCspSettingsResponse.body.updated_benchmark_rules).toEqual( + expectExpect(body2.updated_benchmark_rules).toEqual( expectExpect.objectContaining({ - [generateRuleKey(rule1)]: { muted: true }, - [generateRuleKey(rule3)]: { muted: true }, + [generateRuleKey(rule1)]: { + muted: true, + benchmark_id: rule1.metadata.benchmark.id, + benchmark_version: rule1.metadata.benchmark.version, + rule_number: rule1.metadata.benchmark.rule_number + ? rule1.metadata.benchmark.rule_number + : '', + rule_id: rule1.metadata.id, + }, + [generateRuleKey(rule3)]: { + muted: true, + benchmark_id: rule3.metadata.benchmark.id, + benchmark_version: rule3.metadata.benchmark.version, + rule_number: rule3.metadata.benchmark.rule_number + ? rule3.metadata.benchmark.rule_number + : '', + rule_id: rule3.metadata.id, + }, }) ); }); - it('set wrong action input', async () => { - const rule1 = generateRandomRule(); + it('mute detection rule successfully', async () => { + const rule1 = await getRandomCspBenchmarkRule(); + + await createDetectionRule(rule1); const { body } = await supertest .post(`/internal/cloud_security_posture/rules/_bulk_action`) @@ -215,21 +296,24 @@ export default function ({ getService }: FtrProviderContext) { .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .set('kbn-xsrf', 'xxxx') .send({ - action: 'foo', + action: 'mute', rules: [ { - benchmark_id: rule1.benchmarkId, - benchmark_version: rule1.benchmarkVersion, - rule_number: rule1.ruleNumber, + rule_id: rule1.metadata.id, }, ], - }); + }) + .expect(200); - expect(body.error).to.eql('Bad Request'); - expect(body.statusCode).to.eql(400); + expectExpect(body.detection_rules).toEqual('disabled 1 detections rules.'); }); - it('set wrong rule ids input', async () => { + it('Expect to two benchmark rules and one detection rule', async () => { + const rule1 = await getRandomCspBenchmarkRule(); + const rule2 = await getRandomCspBenchmarkRule(); + + await createDetectionRule(rule1); + const { body } = await supertest .post(`/internal/cloud_security_posture/rules/_bulk_action`) .set(ELASTIC_HTTP_VERSION_HEADER, '1') @@ -237,7 +321,35 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'xxxx') .send({ action: 'mute', - rule_ids: ['invalid_rule_structure'], + rules: [ + { + rule_id: rule1.metadata.id, + }, + { + rule_id: rule2.metadata.id, + }, + ], + }) + .expect(200); + + expectExpect(body.detection_rules).toEqual('disabled 1 detections rules.'); + }); + + it('set wrong action input', async () => { + const rule1 = await getRandomCspBenchmarkRule(); + + const { body } = await supertest + .post(`/internal/cloud_security_posture/rules/_bulk_action`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .set('kbn-xsrf', 'xxxx') + .send({ + action: 'foo', + rules: [ + { + rule_id: rule1.metadata.id, + }, + ], }); expect(body.error).to.eql('Bad Request'); From 3781a0dcd185550e2beaa2701c1ec95ad4f19915 Mon Sep 17 00:00:00 2001 From: Ash <1849116+ashokaditya@users.noreply.github.com> Date: Thu, 21 Dec 2023 16:56:31 +0100 Subject: [PATCH 083/116] [Security Solution][Endpoint] Map `unisolate` to `release` and `running-processes` to `processes` commands on response actions history output tray (#173831) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Shows `release` instead of `unisolate` and `processes` instead of `running-processes` on the response actions history output tray. **with this change** ![Screenshot 2023-12-21 at 2 40 03 PM](https://github.com/elastic/kibana/assets/1849116/3fb0ffe5-4f8b-4caa-9238-380d39f199bf) ![Screenshot 2023-12-21 at 3 43 57 PM](https://github.com/elastic/kibana/assets/1849116/1d3e67f4-d2f9-49a3-8a7b-01979e7ecbcd) closes elastic/kibana/issues/168779 ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [x] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) --- .../components/action_log_expanded_tray.tsx | 5 +++-- .../response_actions_log.test.tsx | 17 +++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/action_log_expanded_tray.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/action_log_expanded_tray.tsx index 7920bae8b22d79..b70a74d839bc98 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/action_log_expanded_tray.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/action_log_expanded_tray.tsx @@ -6,7 +6,7 @@ */ import React, { memo, useMemo } from 'react'; -import { EuiCodeBlock, EuiFlexGroup, EuiFlexItem, EuiDescriptionList } from '@elastic/eui'; +import { EuiCodeBlock, EuiDescriptionList, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { css, euiStyled } from '@kbn/kibana-react-plugin/common'; import { map } from 'lodash'; import { EndpointUploadActionResult } from '../../endpoint_upload_action_result'; @@ -96,7 +96,8 @@ const OutputContent = memo<{ action: MaybeImmutable<ActionDetails>; 'data-test-s canAccessEndpointActionsLogManagement, } = useUserPrivileges().endpointPrivileges; - const { command, isCompleted, isExpired, wasSuccessful, errors } = action; + const { command: _command, isCompleted, isExpired, wasSuccessful, errors } = action; + const command = getUiCommand(_command); if (errors?.length) { return ( diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx index 1e835e34ac7ef3..93e6719db3569a 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/integration_tests/response_actions_log.test.tsx @@ -34,6 +34,7 @@ import { getEndpointAuthzInitialStateMock } from '../../../../../common/endpoint import { useGetEndpointActionList as _useGetEndpointActionList } from '../../../hooks/response_actions/use_get_endpoint_action_list'; import { OUTPUT_MESSAGES } from '../translations'; import { EndpointActionGenerator } from '../../../../../common/endpoint/data_generators/endpoint_action_generator'; +import { getUiCommand } from '../components/hooks'; const useGetEndpointActionListMock = _useGetEndpointActionList as jest.Mock; @@ -981,10 +982,12 @@ describe('Response actions history', () => { render(); + const outputCommand = getUiCommand(command); + const outputs = expandRows(); expect(outputs.map((n) => n.textContent)).toEqual([ - expect.stringContaining(`${command} completed successfully`), - expect.stringContaining(`${command} completed successfully`), + expect.stringContaining(`${outputCommand} completed successfully`), + expect.stringContaining(`${outputCommand} completed successfully`), ]); expect( renderResult.getAllByTestId(`${testPrefix}-column-status`).map((n) => n.textContent) @@ -1006,10 +1009,11 @@ describe('Response actions history', () => { }); render(); + const outputCommand = getUiCommand(command); const outputs = expandRows(); expect(outputs.map((n) => n.textContent)).toEqual([ - `${command} failed`, - `${command} failed`, + `${outputCommand} failed`, + `${outputCommand} failed`, ]); expect( renderResult.getAllByTestId(`${testPrefix}-column-status`).map((n) => n.textContent) @@ -1032,10 +1036,11 @@ describe('Response actions history', () => { }); render(); + const outputCommand = getUiCommand(command); const outputs = expandRows(); expect(outputs.map((n) => n.textContent)).toEqual([ - `${command} failed: action expired`, - `${command} failed: action expired`, + `${outputCommand} failed: action expired`, + `${outputCommand} failed: action expired`, ]); expect( renderResult.getAllByTestId(`${testPrefix}-column-status`).map((n) => n.textContent) From 3def20e8dcb0ac4edf95a6b092ec11d23bff41e5 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski <jon@elastic.co> Date: Thu, 21 Dec 2023 09:59:08 -0600 Subject: [PATCH 084/116] Revert "Replace deprecated node-sass with sass (#161813)" This reverts commit 87d5d6be262068d52d7125a6d75670d4c2c09ea2. --- WORKSPACE.bazel | 1 + kbn_pm/src/lib/bazel.mjs | 2 + package.json | 4 +- .../kbn-dom-drag-drop/src/sass/drag_drop.scss | 2 +- .../src/worker/webpack.config.ts | 8 +- packages/kbn-storybook/src/webpack.config.ts | 3 +- .../field_list_sidebar.scss | 2 +- renovate.json | 4 +- .../build/tasks/install_dependencies_task.ts | 2 + src/dev/license_checker/config.ts | 1 - src/plugins/console/public/styles/_app.scss | 2 +- .../options_list/components/options_list.scss | 4 +- .../components/doc_table/_doc_table.scss | 2 +- .../public/markdown/_markdown.scss | 2 +- .../filter_bar/filter_item/filter_item.scss | 8 +- .../saved_query_management_list.scss | 4 +- .../public/_agg_params.scss | 2 +- .../components/_vis_with_splits.scss | 2 +- .../visualizations/views/_metric.scss | 2 +- .../public/vislib/lib/layout/_layout.scss | 2 +- .../shareable_runtime/webpack.config.js | 4 +- .../canvas/storybook/canvas_webpack.ts | 2 +- .../field_data_row/column_chart.scss | 2 +- .../guidance_panel/_guidance_panel.scss | 2 +- .../editor_frame/suggestion_panel.scss | 4 +- .../layer_toc/toc_entry/_toc_entry.scss | 2 +- .../influencers_list/_influencers_list.scss | 4 +- .../components/rule_editor/_rule_editor.scss | 2 +- .../explorer_charts/_explorer_chart.scss | 2 +- .../_timeseriesexplorer_annotations.scss | 8 +- .../shard_allocation/shard_allocation.scss | 2 +- .../components/status_icon/_status_icon.scss | 2 +- .../components/policy_form/_policy_form.scss | 4 +- .../_restore_snapshot_form.scss | 4 +- .../_deprecation_logging_toggle.scss | 2 +- yarn.lock | 452 +++++++++++++----- 36 files changed, 391 insertions(+), 166 deletions(-) diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index 49623728f1afe9..e614bdff172f99 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel @@ -60,6 +60,7 @@ yarn_install( "GECKODRIVER_CDNURL": "https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache", "CHROMEDRIVER_CDNURL": "https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache", "CHROMEDRIVER_CDNBINARIESURL": "https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache", + "SASS_BINARY_SITE": "https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-sass", "RE2_DOWNLOAD_MIRROR": "https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2", "CYPRESS_DOWNLOAD_MIRROR": "https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/cypress", } diff --git a/kbn_pm/src/lib/bazel.mjs b/kbn_pm/src/lib/bazel.mjs index 022447ded129c1..2ec27b359f1533 100644 --- a/kbn_pm/src/lib/bazel.mjs +++ b/kbn_pm/src/lib/bazel.mjs @@ -150,6 +150,8 @@ export async function installYarnDeps(log, opts = undefined) { offline: opts?.offline, quiet: opts?.quiet, env: { + SASS_BINARY_SITE: + 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-sass', RE2_DOWNLOAD_MIRROR: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2', }, diff --git a/package.json b/package.json index 972f7df2bc0f7c..2553521b662be4 100644 --- a/package.json +++ b/package.json @@ -1597,6 +1597,7 @@ "mutation-observer": "^1.0.3", "native-hdr-histogram": "^1.0.0", "nock": "12.0.3", + "node-sass": "^8.0.0", "null-loader": "^3.0.0", "nyc": "^15.1.0", "oboe": "^2.1.4", @@ -1624,8 +1625,7 @@ "regenerate": "^1.4.0", "resolve": "^1.22.0", "rxjs-marbles": "^7.0.1", - "sass-embedded": "^1.69.5", - "sass-loader": "^10.5.0", + "sass-loader": "^10.4.1", "selenium-webdriver": "^4.16.0", "simple-git": "^3.16.0", "sinon": "^7.4.2", diff --git a/packages/kbn-dom-drag-drop/src/sass/drag_drop.scss b/packages/kbn-dom-drag-drop/src/sass/drag_drop.scss index c68ae0c0d6f1e0..c26bb6c49b6cff 100644 --- a/packages/kbn-dom-drag-drop/src/sass/drag_drop.scss +++ b/packages/kbn-dom-drag-drop/src/sass/drag_drop.scss @@ -99,7 +99,7 @@ $reorderItemMargin: $euiSizeS; position: absolute; width: 100%; top: 0; - height: calc(100% + #{calc($reorderItemMargin / 2)}); + height: calc(100% + #{$reorderItemMargin / 2}); } .domDragDrop-translatableDrop { diff --git a/packages/kbn-optimizer/src/worker/webpack.config.ts b/packages/kbn-optimizer/src/worker/webpack.config.ts index 7b4a5b27b78c7a..189ca29072afe6 100644 --- a/packages/kbn-optimizer/src/worker/webpack.config.ts +++ b/packages/kbn-optimizer/src/worker/webpack.config.ts @@ -185,12 +185,12 @@ export function getWebpackConfig( ) )};\n${content}`; }, - implementation: require('sass-embedded'), + webpackImporter: false, + implementation: require('node-sass'), sassOptions: { - outputStyle: worker.dist ? 'compressed' : 'expanded', + outputStyle: worker.dist ? 'compressed' : 'nested', includePaths: [Path.resolve(worker.repoRoot, 'node_modules')], - sourceMap: true, - quietDeps: true, + sourceMapRoot: `/${bundle.type}:${bundle.id}`, }, }, }, diff --git a/packages/kbn-storybook/src/webpack.config.ts b/packages/kbn-storybook/src/webpack.config.ts index 282a41dcbd4532..35bda9718d7cb6 100644 --- a/packages/kbn-storybook/src/webpack.config.ts +++ b/packages/kbn-storybook/src/webpack.config.ts @@ -115,10 +115,9 @@ export default ({ config: storybookConfig }: { config: Configuration }) => { resolve(REPO_ROOT, 'src/core/public/styles/core_app/_globals_v8light.scss') )};\n${content}`; }, - implementation: require('sass-embedded'), + implementation: require('node-sass'), sassOptions: { includePaths: [resolve(REPO_ROOT, 'node_modules')], - quietDeps: true, }, }, }, diff --git a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.scss b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.scss index 08402941bf74b5..48fb44f1663e37 100644 --- a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.scss +++ b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.scss @@ -53,7 +53,7 @@ .unifiedFieldListSidebar .unifiedFieldListItemButton { &.kbnFieldButton { - margin-bottom: calc($euiSizeXS / 2); + margin-bottom: $euiSizeXS / 2; } &.domDragDrop-isDraggable { diff --git a/renovate.json b/renovate.json index 7fb5b9020388c4..4a725ce80a5f5d 100644 --- a/renovate.json +++ b/renovate.json @@ -362,7 +362,7 @@ { "groupName": "scss", "packageNames": [ - "sass-embedded" + "node-sass" ], "reviewers": [ "team:kibana-operations" @@ -673,4 +673,4 @@ "enabled": true } ] -} +} \ No newline at end of file diff --git a/src/dev/build/tasks/install_dependencies_task.ts b/src/dev/build/tasks/install_dependencies_task.ts index 0eebadec5ca791..59c9e389112435 100644 --- a/src/dev/build/tasks/install_dependencies_task.ts +++ b/src/dev/build/tasks/install_dependencies_task.ts @@ -32,6 +32,8 @@ export const InstallDependencies: Task = { { cwd: build.resolvePath(), env: { + SASS_BINARY_SITE: + 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-sass', RE2_DOWNLOAD_MIRROR: 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-re2', }, diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index 6ba5deb6408acc..b0919d0ab61415 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -88,5 +88,4 @@ export const LICENSE_OVERRIDES = { '@elastic/eui@91.0.0-backport.0': ['SSPL-1.0 OR Elastic License 2.0'], 'language-subtag-registry@0.3.21': ['CC-BY-4.0'], // retired ODC‑By license https://github.com/mattcg/language-subtag-registry 'buffers@0.1.1': ['MIT'], // license in importing module https://www.npmjs.com/package/binary - '@bufbuild/protobuf@1.2.1': ['Apache-2.0'], // license (Apache-2.0 AND BSD-3-Clause) }; diff --git a/src/plugins/console/public/styles/_app.scss b/src/plugins/console/public/styles/_app.scss index 2f4340f1de0ab1..9cbe6437220477 100644 --- a/src/plugins/console/public/styles/_app.scss +++ b/src/plugins/console/public/styles/_app.scss @@ -42,7 +42,7 @@ padding: 0 $euiSizeS; display: inline-block; text-decoration: none; - border-radius: calc($euiBorderRadius / 2); + border-radius: $euiBorderRadius / 2; white-space: nowrap; vertical-align: middle; cursor: default; diff --git a/src/plugins/controls/public/options_list/components/options_list.scss b/src/plugins/controls/public/options_list/components/options_list.scss index e0c749441ff6af..ff4014d0cc41d5 100644 --- a/src/plugins/controls/public/options_list/components/options_list.scss +++ b/src/plugins/controls/public/options_list/components/options_list.scss @@ -65,7 +65,7 @@ } .optionsList__actionsRow { - margin: calc($euiSizeS / 2) 0 !important; + margin: ($euiSizeS / 2) 0 !important; .optionsList__actionBarDivider { height: $euiSize; @@ -97,4 +97,4 @@ color: $euiTextSubduedColor; padding: $euiSizeM; } -} +} \ No newline at end of file diff --git a/src/plugins/discover/public/components/doc_table/_doc_table.scss b/src/plugins/discover/public/components/doc_table/_doc_table.scss index 67de9cfae42e1f..8a9b629a9694bc 100644 --- a/src/plugins/discover/public/components/doc_table/_doc_table.scss +++ b/src/plugins/discover/public/components/doc_table/_doc_table.scss @@ -69,7 +69,7 @@ dt { background-color: transparentize(shade($euiColorPrimary, 20%), .9); color: $euiTextColor; - padding: calc($euiSizeXS / 2) $euiSizeXS; + padding: ($euiSizeXS / 2) $euiSizeXS; margin-right: $euiSizeXS; word-break: normal; border-radius: $euiBorderRadius; diff --git a/src/plugins/kibana_react/public/markdown/_markdown.scss b/src/plugins/kibana_react/public/markdown/_markdown.scss index a3bba38509bcdb..c11aefe1f4d97c 100644 --- a/src/plugins/kibana_react/public/markdown/_markdown.scss +++ b/src/plugins/kibana_react/public/markdown/_markdown.scss @@ -14,7 +14,7 @@ $kbnDefaultFontSize: 14px; @function canvasToEm($size) { - @return #{calc($size / $kbnDefaultFontSize)}em; + @return #{$size / $kbnDefaultFontSize}em; } .kbnMarkdown__body { diff --git a/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.scss b/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.scss index 362aec7264983e..1c16adbfc8c133 100644 --- a/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.scss +++ b/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.scss @@ -8,8 +8,8 @@ line-height: $euiSize; border: none; color: $euiTextColor; - padding-top: calc($euiSizeM / 2) + 1px; - padding-bottom: calc($euiSizeM / 2) + 1px; + padding-top: $euiSizeM / 2 + 1px; + padding-bottom: $euiSizeM / 2 + 1px; white-space: normal; /* 1 */ &:not(.globalFilterItem-isDisabled) { @@ -54,8 +54,8 @@ left: 0; width: $euiSizeXS; background-color: $kbnGlobalFilterItemBorderColor; - border-top-left-radius: calc($euiBorderRadius / 2); - border-bottom-left-radius: calc($euiBorderRadius / 2); + border-top-left-radius: $euiBorderRadius / 2; + border-bottom-left-radius: $euiBorderRadius / 2; } } diff --git a/src/plugins/unified_search/public/saved_query_management/saved_query_management_list.scss b/src/plugins/unified_search/public/saved_query_management/saved_query_management_list.scss index 2e6f639ea792d7..7ce304310ae56a 100644 --- a/src/plugins/unified_search/public/saved_query_management/saved_query_management_list.scss +++ b/src/plugins/unified_search/public/saved_query_management/saved_query_management_list.scss @@ -5,7 +5,7 @@ } .kbnSavedQueryManagement__text { - padding: $euiSizeM $euiSizeM calc($euiSizeM / 2) $euiSizeM; + padding: $euiSizeM $euiSizeM ($euiSizeM / 2) $euiSizeM; } .kbnSavedQueryManagement__list { @@ -13,5 +13,5 @@ max-height: inherit; // Fixes overflow for applied max-height // Left/Right padding is calculated to match the left alignment of the // popover text and buttons - padding: calc($euiSizeM / 2) $euiSizeXS !important; // Override flush + padding: ($euiSizeM / 2) $euiSizeXS !important; // Override flush } diff --git a/src/plugins/vis_default_editor/public/_agg_params.scss b/src/plugins/vis_default_editor/public/_agg_params.scss index c56ef94c3a4baf..81faa06681c0d9 100644 --- a/src/plugins/vis_default_editor/public/_agg_params.scss +++ b/src/plugins/vis_default_editor/public/_agg_params.scss @@ -1,7 +1,7 @@ .visEditorAggParam--half { margin: $euiSize 0; display: inline-block; - width: calc(50% - #{calc($euiSizeS / 2)}); + width: calc(50% - #{$euiSizeS / 2}); } .visEditorAggParam--half-size { diff --git a/src/plugins/vis_types/timeseries/public/application/components/_vis_with_splits.scss b/src/plugins/vis_types/timeseries/public/application/components/_vis_with_splits.scss index 036cf3f6a8fbdc..9e09a6c3477f3c 100644 --- a/src/plugins/vis_types/timeseries/public/application/components/_vis_with_splits.scss +++ b/src/plugins/vis_types/timeseries/public/application/components/_vis_with_splits.scss @@ -20,7 +20,7 @@ > .tvbVis { // Apply the minimum height on the vis itself so it doesn't interfere with flex calculations // Gauges are not completely square, so the height is just slightly less than the width - min-height: calc($euiSize * 12 / 1.25); + min-height: $euiSize * 12 / 1.25; } } diff --git a/src/plugins/vis_types/timeseries/public/application/visualizations/views/_metric.scss b/src/plugins/vis_types/timeseries/public/application/visualizations/views/_metric.scss index d5eb056dd172e4..bc2ce4f1a9e441 100644 --- a/src/plugins/vis_types/timeseries/public/application/visualizations/views/_metric.scss +++ b/src/plugins/vis_types/timeseries/public/application/visualizations/views/_metric.scss @@ -101,7 +101,7 @@ .tvbVisMetric__label--additional { @include euiTextTruncate; font-size: .25em; /* 1 */ - padding: calc($euiSizeXS / 2) 0 0; + padding: ($euiSizeXS / 2) 0 0; text-align: center; color: $tvbValueColor; line-height: 1.2; // Ensure the descenders don't get cut off diff --git a/src/plugins/vis_types/vislib/public/vislib/lib/layout/_layout.scss b/src/plugins/vis_types/vislib/public/vislib/lib/layout/_layout.scss index 8b92af5a4fdcf9..4612602d93f1cc 100644 --- a/src/plugins/vis_types/vislib/public/vislib/lib/layout/_layout.scss +++ b/src/plugins/vis_types/vislib/public/vislib/lib/layout/_layout.scss @@ -203,7 +203,7 @@ } .slice { - stroke-width: calc($euiSizeXS / 2); + stroke-width: $euiSizeXS / 2; stroke: $euiColorEmptyShade; &:hover { diff --git a/x-pack/plugins/canvas/shareable_runtime/webpack.config.js b/x-pack/plugins/canvas/shareable_runtime/webpack.config.js index ccc04a846236eb..c60230c6bd6848 100644 --- a/x-pack/plugins/canvas/shareable_runtime/webpack.config.js +++ b/x-pack/plugins/canvas/shareable_runtime/webpack.config.js @@ -110,7 +110,7 @@ module.exports = { { loader: 'sass-loader', options: { - implementation: require('sass-embedded'), + implementation: require('node-sass'), sourceMap: !isProd, }, }, @@ -147,7 +147,7 @@ module.exports = { path.resolve(KIBANA_ROOT, 'src/core/public/styles/core_app/_globals_v8light.scss') )};\n${content}`; }, - implementation: require('sass-embedded'), + implementation: require('node-sass'), webpackImporter: false, sassOptions: { outputStyle: 'nested', diff --git a/x-pack/plugins/canvas/storybook/canvas_webpack.ts b/x-pack/plugins/canvas/storybook/canvas_webpack.ts index c6ae4a9dbaa950..946b6c5b78ceca 100644 --- a/x-pack/plugins/canvas/storybook/canvas_webpack.ts +++ b/x-pack/plugins/canvas/storybook/canvas_webpack.ts @@ -38,7 +38,7 @@ export const canvasWebpack = { { loader: 'sass-loader', options: { - implementation: require('sass-embedded'), + implementation: require('node-sass'), }, }, ], diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_row/column_chart.scss b/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_row/column_chart.scss index a98eb200f022e7..8a0b9cc992c3ec 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_row/column_chart.scss +++ b/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_row/column_chart.scss @@ -16,7 +16,7 @@ font-weight: normal; text-align: left; line-height: 1.1; - font-size: #{calc($euiFontSizeL / 2)}; // 10px + font-size: #{$euiFontSizeL / 2}; // 10px } .dataGridChart__legend--numeric { diff --git a/x-pack/plugins/graph/public/components/guidance_panel/_guidance_panel.scss b/x-pack/plugins/graph/public/components/guidance_panel/_guidance_panel.scss index 28e05afe0c7816..add1d0bdf8aa33 100644 --- a/x-pack/plugins/graph/public/components/guidance_panel/_guidance_panel.scss +++ b/x-pack/plugins/graph/public/components/guidance_panel/_guidance_panel.scss @@ -28,7 +28,7 @@ .gphGuidancePanel__itemIcon { position: absolute; left: 0; - top: -(calc($euiSizeXS / 2)); + top: -($euiSizeXS / 2); width: $euiSizeL; height: $euiSizeL; padding: $euiSizeXS; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.scss index 35606c67382d58..cd2ee706c1e18e 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.scss +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.scss @@ -25,8 +25,8 @@ flex: 0 0 auto; height: $lnsSuggestionHeight; margin-right: $euiSizeS; - margin-left: calc($euiSizeXS / 2); - margin-bottom: calc($euiSizeXS / 2); + margin-left: $euiSizeXS / 2; + margin-bottom: $euiSizeXS / 2; padding: 0 $euiSizeS; box-shadow: none !important; // sass-lint:disable-line no-important diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss index 7f1c61801a4f3c..c88f343f7dbfa1 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss @@ -128,7 +128,7 @@ background-color: $euiColorEmptyShade; border: $euiBorderThin; color: $euiTextColor; - border-radius: calc($euiBorderRadius / 2); + border-radius: $euiBorderRadius / 2; height: $euiSize; width: $euiSizeXL; line-height: $euiSize; diff --git a/x-pack/plugins/ml/public/application/components/influencers_list/_influencers_list.scss b/x-pack/plugins/ml/public/application/components/influencers_list/_influencers_list.scss index 1b091e4046c502..e33811aa9a8ccc 100644 --- a/x-pack/plugins/ml/public/application/components/influencers_list/_influencers_list.scss +++ b/x-pack/plugins/ml/public/application/components/influencers_list/_influencers_list.scss @@ -28,7 +28,7 @@ } .progress-bar { - height: calc($euiSizeXS / 2); + height: $euiSizeXS / 2; margin-top: $euiSizeM; text-align: right; line-height: 18px; // SASSTODO: Calc proper value @@ -96,7 +96,7 @@ font-size: 11px; line-height: 14px; border-radius: $euiBorderRadius; - padding: calc($euiSizeXS / 2); + padding: $euiSizeXS / 2; margin-top: $euiSizeXS; display: inline-block; border: $euiBorderThin; diff --git a/x-pack/plugins/ml/public/application/components/rule_editor/_rule_editor.scss b/x-pack/plugins/ml/public/application/components/rule_editor/_rule_editor.scss index 09605c4016565d..03eca2842c3002 100644 --- a/x-pack/plugins/ml/public/application/components/rule_editor/_rule_editor.scss +++ b/x-pack/plugins/ml/public/application/components/rule_editor/_rule_editor.scss @@ -41,7 +41,7 @@ // SASSTODO: Dangerous EUI overwrite .scope-field-checkbox { - margin-right: calc($euiSizeXS / 2); + margin-right: $euiSizeXS / 2; .euiCheckbox { margin-top: $euiSizeXS; diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/_explorer_chart.scss b/x-pack/plugins/ml/public/application/explorer/explorer_charts/_explorer_chart.scss index 29967e8db9b3f0..55ebfe8ab3edb9 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/_explorer_chart.scss +++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/_explorer_chart.scss @@ -15,7 +15,7 @@ rect.selected-interval { fill: rgba(200, 200, 200, .1); stroke: $euiColorDarkShade; - stroke-width: calc($euiSizeXS / 2); + stroke-width: $euiSizeXS / 2; stroke-opacity: .8; } diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/_timeseriesexplorer_annotations.scss b/x-pack/plugins/ml/public/application/timeseriesexplorer/_timeseriesexplorer_annotations.scss index 656f38590d3a5e..a7186597b41356 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/_timeseriesexplorer_annotations.scss +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/_timeseriesexplorer_annotations.scss @@ -40,10 +40,10 @@ $mlAnnotationRectDefaultFillOpacity: .05; } .mlAnnotationRect-isBlur { - stroke-opacity: calc($mlAnnotationRectDefaultStrokeOpacity / 2); + stroke-opacity: $mlAnnotationRectDefaultStrokeOpacity / 2; transition: stroke-opacity $euiAnimSpeedFast; - fill-opacity: calc($mlAnnotationRectDefaultFillOpacity / 2); + fill-opacity: $mlAnnotationRectDefaultFillOpacity / 2; transition: fill-opacity $euiAnimSpeedFast; } @@ -95,9 +95,9 @@ $mlAnnotationRectDefaultFillOpacity: .05; } .mlContextAnnotationRect-isBlur { - stroke-opacity: calc($mlAnnotationRectDefaultStrokeOpacity / 2); + stroke-opacity: $mlAnnotationRectDefaultStrokeOpacity / 2; transition: stroke-opacity $euiAnimSpeedFast; - fill-opacity: calc($mlAnnotationRectDefaultFillOpacity / 2); + fill-opacity: $mlAnnotationRectDefaultFillOpacity / 2; transition: fill-opacity $euiAnimSpeedFast; } diff --git a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/shard_allocation.scss b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/shard_allocation.scss index 961e0350ccc85f..c46d7a048b93ba 100644 --- a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/shard_allocation.scss +++ b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/shard_allocation.scss @@ -22,7 +22,7 @@ margin: $euiSizeS; border: 1px solid $euiColorMediumShade; border-radius: $euiSizeXS; - padding: calc($euiSizeXS / 2) 0; + padding: $euiSizeXS / 2 0; &.monChild--index { border-left: $euiSizeXS solid $euiColorSuccess; diff --git a/x-pack/plugins/monitoring/public/components/status_icon/_status_icon.scss b/x-pack/plugins/monitoring/public/components/status_icon/_status_icon.scss index 50c705f80650ef..2d36e7fc90f225 100644 --- a/x-pack/plugins/monitoring/public/components/status_icon/_status_icon.scss +++ b/x-pack/plugins/monitoring/public/components/status_icon/_status_icon.scss @@ -1,7 +1,7 @@ .monStatusIcon { display: inline-block; margin-left: $euiSizeXS; - padding: calc($euiSizeXS / 2) $euiSizeS; + padding: ($euiSizeXS / 2) $euiSizeS; border-radius: $euiBorderRadius; color: $euiColorGhost; min-width: 1.9em; diff --git a/x-pack/plugins/snapshot_restore/public/application/components/policy_form/_policy_form.scss b/x-pack/plugins/snapshot_restore/public/application/components/policy_form/_policy_form.scss index 389e925f392c27..0a5187908f8542 100644 --- a/x-pack/plugins/snapshot_restore/public/application/components/policy_form/_policy_form.scss +++ b/x-pack/plugins/snapshot_restore/public/application/components/policy_form/_policy_form.scss @@ -4,7 +4,7 @@ .snapshotRestore__policyForm__stepSettings { .euiFormRow--hasEmptyLabelSpace { min-height: auto; - margin-top: $euiFontSizeXS + $euiSizeS + calc($euiSizeXXL / 4); + margin-top: $euiFontSizeXS + $euiSizeS + ($euiSizeXXL / 4); } } @@ -13,4 +13,4 @@ */ .snapshotRestore__policyForm__stepSettings__indicesFieldWrapper .euiFormLabel { width: 100%; -} +} \ No newline at end of file diff --git a/x-pack/plugins/snapshot_restore/public/application/components/restore_snapshot_form/_restore_snapshot_form.scss b/x-pack/plugins/snapshot_restore/public/application/components/restore_snapshot_form/_restore_snapshot_form.scss index ec680472edf465..6a8f0b951c99fe 100644 --- a/x-pack/plugins/snapshot_restore/public/application/components/restore_snapshot_form/_restore_snapshot_form.scss +++ b/x-pack/plugins/snapshot_restore/public/application/components/restore_snapshot_form/_restore_snapshot_form.scss @@ -5,7 +5,7 @@ .snapshotRestore__restoreForm__stepSettings { .euiFormRow--hasEmptyLabelSpace { min-height: auto; - margin-top: $euiFontSizeXS + $euiSizeS + calc($euiSizeXXL / 4); + margin-top: $euiFontSizeXS + $euiSizeS + ($euiSizeXXL / 4); } } @@ -14,4 +14,4 @@ */ .snapshotRestore__restoreForm__stepLogistics__indicesFieldWrapper .euiFormLabel { width: 100%; -} +} \ No newline at end of file diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecation_logs/fix_deprecation_logs/deprecation_logging_toggle/_deprecation_logging_toggle.scss b/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecation_logs/fix_deprecation_logs/deprecation_logging_toggle/_deprecation_logging_toggle.scss index abcc87b75cd081..e8b6ec06ed7c99 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecation_logs/fix_deprecation_logs/deprecation_logging_toggle/_deprecation_logging_toggle.scss +++ b/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecation_logs/fix_deprecation_logs/deprecation_logging_toggle/_deprecation_logging_toggle.scss @@ -3,5 +3,5 @@ // them. With this selector we offset the difference so that the content // of the page doesnt jump when toggling between states. .upgToggleLoading > .upgLoadingItem { - margin: calc($euiSizeM / 2); + margin: $euiSizeM / 2; } diff --git a/yarn.lock b/yarn.lock index e7bf86c9eb972c..7b2754c8719c8f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1321,11 +1321,6 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@bufbuild/protobuf@^1.0.0": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@bufbuild/protobuf/-/protobuf-1.2.1.tgz#f8b1fbbe79726a4eafa9772ddde147b57f85d177" - integrity sha512-cwwGvLGqvoaOZmoP5+i4v/rbW+rHkguvTehuZyM2p/xpmaNSdT2h3B7kHw33aiffv35t1XrYHIkdJSEkSEMJuA== - "@cbor-extract/cbor-extract-darwin-arm64@2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.0.0.tgz#cf0667e4c22111c9d45e16c29964892b12460a76" @@ -2248,7 +2243,7 @@ pngjs "7.0.0" sharp "0.32.1" -"@gar/promisify@^1.0.1": +"@gar/promisify@^1.0.1", "@gar/promisify@^1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== @@ -6791,6 +6786,14 @@ "@gar/promisify" "^1.0.1" semver "^7.3.5" +"@npmcli/fs@^2.1.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-2.1.2.tgz#a9e2541a4a2fec2e69c29b35e6060973da79b865" + integrity sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ== + dependencies: + "@gar/promisify" "^1.1.3" + semver "^7.3.5" + "@npmcli/fs@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e" @@ -6805,6 +6808,14 @@ dependencies: mkdirp "^1.0.4" +"@npmcli/move-file@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-2.0.1.tgz#26f6bdc379d87f75e55739bab89db525b06100e4" + integrity sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + "@octokit/auth-token@^2.4.0": version "2.4.4" resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.4.4.tgz#ee31c69b01d0378c12fd3ffe406030f3d94d3b56" @@ -8542,6 +8553,11 @@ dependencies: "@babel/runtime" "^7.12.5" +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" @@ -10873,7 +10889,7 @@ after-all-results@^2.0.0: resolved "https://registry.yarnpkg.com/after-all-results/-/after-all-results-2.0.0.tgz#6ac2fc202b500f88da8f4f5530cfa100f4c6a2d0" integrity sha1-asL8ICtQD4jaj09VMM+hAPTGotA= -agent-base@6: +agent-base@6, agent-base@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== @@ -11234,6 +11250,14 @@ are-we-there-yet@^2.0.0: delegates "^1.0.0" readable-stream "^3.6.0" +are-we-there-yet@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz#ba20bd6b553e31d62fc8c31bd23d22b95734390d" + integrity sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + arg@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" @@ -11535,6 +11559,11 @@ async-cache@^1.1.0: dependencies: lru-cache "^4.0.0" +async-foreach@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" + integrity sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI= + async-value-promise@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/async-value-promise/-/async-value-promise-1.1.1.tgz#68957819e3eace804f3b4b69477e2bd276c15378" @@ -12374,11 +12403,6 @@ btoa-lite@^1.0.0: resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" integrity sha1-M3dm2hWAEhD92VbCLpxokaudAzc= -buffer-builder@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/buffer-builder/-/buffer-builder-0.2.0.tgz#3322cd307d8296dab1f604618593b261a3fade8f" - integrity sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg== - buffer-crc32@^0.2.1, buffer-crc32@^0.2.13, buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" @@ -12505,7 +12529,7 @@ cacache@^12.0.2: unique-filename "^1.1.1" y18n "^4.0.0" -cacache@^15.0.4, cacache@^15.0.5: +cacache@^15.0.4, cacache@^15.0.5, cacache@^15.2.0: version "15.3.0" resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== @@ -12529,6 +12553,30 @@ cacache@^15.0.4, cacache@^15.0.5: tar "^6.0.2" unique-filename "^1.1.1" +cacache@^16.1.0: + version "16.1.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.3.tgz#a02b9f34ecfaf9a78c9f4bc16fceb94d5d67a38e" + integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ== + dependencies: + "@npmcli/fs" "^2.1.0" + "@npmcli/move-file" "^2.0.0" + chownr "^2.0.0" + fs-minipass "^2.1.0" + glob "^8.0.1" + infer-owner "^1.0.4" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + mkdirp "^1.0.4" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^9.0.0" + tar "^6.1.11" + unique-filename "^2.0.0" + cacache@^18.0.0: version "18.0.0" resolved "https://registry.yarnpkg.com/cacache/-/cacache-18.0.0.tgz#17a9ecd6e1be2564ebe6cdca5f7cfed2bfeb6ddc" @@ -12948,9 +12996,9 @@ ci-info@^2.0.0: integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== ci-info@^3.2.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" - integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + version "3.3.1" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.1.tgz#58331f6f472a25fe3a50a351ae3052936c2c7f32" + integrity sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg== cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" @@ -14461,7 +14509,7 @@ debug@3.X, debug@^3.0.0, debug@^3.1.0, debug@^3.2.7: dependencies: ms "^2.1.1" -debug@4, debug@4.3.4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: +debug@4, debug@4.3.4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -15485,7 +15533,7 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.13: +encoding@^0.1.12, encoding@^0.1.13: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== @@ -17263,7 +17311,7 @@ fs-extra@^9.0.0, fs-extra@^9.0.1, fs-extra@^9.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-minipass@^2.0.0: +fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== @@ -17365,6 +17413,28 @@ gauge@^3.0.0: strip-ansi "^6.0.1" wide-align "^1.1.2" +gauge@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.2.tgz#c3777652f542b6ef62797246e8c7caddecb32cc7" + integrity sha512-aSPRm2CvA9R8QyU5eXMFPd+cYkyxLsXHd2l5/FOH2V/eml//M04G6KZOmTap07O1PvEwNcl2NndyLfK8g3QrKA== + dependencies: + ansi-regex "^5.0.1" + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.3" + console-control-strings "^1.1.0" + has-unicode "^2.0.1" + signal-exit "^3.0.7" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.5" + +gaze@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" + integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== + dependencies: + globule "^1.0.0" + geckodriver@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/geckodriver/-/geckodriver-4.3.0.tgz#8586e80ddd23e5d5cd47382d9f6897051ca12ea3" @@ -17618,7 +17688,7 @@ glob@7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@8.1.0, glob@^8.0.3: +glob@8.1.0, glob@^8.0.1, glob@^8.0.3: version "8.1.0" resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== @@ -17652,6 +17722,18 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, gl once "^1.3.0" path-is-absolute "^1.0.0" +glob@~7.1.1: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + global-dirs@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" @@ -17784,6 +17866,15 @@ globjoin@^0.1.4: resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43" integrity sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM= +globule@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d" + integrity sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ== + dependencies: + glob "~7.1.1" + lodash "~4.17.10" + minimatch "~3.0.2" + gonzales-pe@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.3.0.tgz#fe9dec5f3c557eead09ff868c65826be54d067b3" @@ -18441,7 +18532,7 @@ htmlparser2@^8.0.1: domutils "^3.0.1" entities "^4.4.0" -http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.1: +http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0, http-cache-semantics@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== @@ -18489,6 +18580,15 @@ http-parser-js@>=0.5.1: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg== +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -18548,7 +18648,7 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -https-proxy-agent@^5.0.1: +https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== @@ -18659,11 +18759,6 @@ immer@^9.0.15, immer@^9.0.7: resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.15.tgz#0b9169e5b1d22137aba7d43f8a81a495dd1b62dc" integrity sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ== -immutable@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.1.0.tgz#f795787f0db780183307b9eb2091fcac1f6fafef" - integrity sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ== - import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -20319,6 +20414,11 @@ jquery@^3.5.0: resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw== +js-base64@^2.4.9: + version "2.5.2" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.2.tgz#313b6274dda718f714d00b3330bbae6e38e90209" + integrity sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ== + js-beautify@1.10.3: version "1.10.3" resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.10.3.tgz#c73fa10cf69d3dfa52d8ed624f23c64c0a6a94c1" @@ -21253,7 +21353,7 @@ lodash.uniq@4.5.0, lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@>4.17.4, lodash@^4.0.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21: +lodash@>4.17.4, lodash@^4.0.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@~4.17.10: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -21422,7 +21522,7 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^7.14.1: +lru-cache@^7.14.1, lru-cache@^7.7.1: version "7.18.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== @@ -21481,6 +21581,28 @@ make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +make-fetch-happen@^10.0.4: + version "10.2.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" + integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== + dependencies: + agentkeepalive "^4.2.1" + cacache "^16.1.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-fetch "^2.0.3" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + socks-proxy-agent "^7.0.0" + ssri "^9.0.0" + make-fetch-happen@^13.0.0: version "13.0.0" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-13.0.0.tgz#705d6f6cbd7faecb8eac2432f551e49475bfedf0" @@ -21498,6 +21620,28 @@ make-fetch-happen@^13.0.0: promise-retry "^2.0.1" ssri "^10.0.0" +make-fetch-happen@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" + integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== + dependencies: + agentkeepalive "^4.1.3" + cacache "^15.2.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^6.0.0" + minipass "^3.1.3" + minipass-collect "^1.0.2" + minipass-fetch "^1.3.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.2" + promise-retry "^2.0.1" + socks-proxy-agent "^6.0.0" + ssri "^8.0.0" + makeerror@1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" @@ -22104,7 +22248,7 @@ minimatch@5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2, minimatch@~3.0.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -22146,6 +22290,28 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" +minipass-fetch@^1.3.2: + version "1.3.4" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.3.4.tgz#63f5af868a38746ca7b33b03393ddf8c291244fe" + integrity sha512-TielGogIzbUEtd1LsjZFs47RWuHHfhl6TiCx1InVxApBAmQ8bL0dL5ilkLGcRvuyW/A9nE+Lvn855Ewz8S0PnQ== + dependencies: + minipass "^3.1.0" + minipass-sized "^1.0.3" + minizlib "^2.0.0" + optionalDependencies: + encoding "^0.1.12" + +minipass-fetch@^2.0.3: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.2.tgz#95560b50c472d81a3bc76f20ede80eaed76d8add" + integrity sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA== + dependencies: + minipass "^3.1.6" + minipass-sized "^1.0.3" + minizlib "^2.1.2" + optionalDependencies: + encoding "^0.1.13" + minipass-fetch@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.3.tgz#d9df70085609864331b533c960fd4ffaa78d15ce" @@ -22178,7 +22344,7 @@ minipass-sized@^1.0.3: dependencies: minipass "^3.0.0" -minipass@^3.0.0, minipass@^3.1.1: +minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3, minipass@^3.1.6: version "3.3.6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== @@ -22202,7 +22368,7 @@ minipass@^5.0.0: resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== -minizlib@^2.1.1, minizlib@^2.1.2: +minizlib@^2.0.0, minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== @@ -22577,7 +22743,7 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nan@^2.18.0: +nan@^2.17.0, nan@^2.18.0: version "2.18.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.18.0.tgz#26a6faae7ffbeb293a39660e88a76b82e30b7554" integrity sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w== @@ -22658,7 +22824,7 @@ nearley@^2.7.10: randexp "0.4.6" semver "^5.4.1" -negotiator@0.6.3, negotiator@^0.6.3: +negotiator@0.6.3, negotiator@^0.6.2, negotiator@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== @@ -22825,6 +22991,22 @@ node-gyp@^10.0.1: tar "^6.1.2" which "^4.0.0" +node-gyp@^8.4.1: + version "8.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" + integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^9.1.0" + nopt "^5.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -22886,6 +23068,26 @@ node-releases@^2.0.6: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== +node-sass@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-8.0.0.tgz#c80d52148db0ce88610bcf1e1d112027393c13e1" + integrity sha512-jPzqCF2/e6JXw6r3VxfIqYc8tKQdkj5Z/BDATYyG6FL6b/LuYBNFGFVhus0mthcWifHm/JzBpKAd+3eXsWeK/A== + dependencies: + async-foreach "^0.1.3" + chalk "^4.1.2" + cross-spawn "^7.0.3" + gaze "^1.0.0" + get-stdin "^4.0.1" + glob "^7.0.3" + lodash "^4.17.15" + make-fetch-happen "^10.0.4" + meow "^9.0.0" + nan "^2.17.0" + node-gyp "^8.4.1" + sass-graph "^4.0.1" + stdout-stream "^1.4.0" + "true-case-path" "^2.2.1" + node-source-walk@^6.0.0, node-source-walk@^6.0.1, node-source-walk@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/node-source-walk/-/node-source-walk-6.0.2.tgz#ba81bc4bc0f6f05559b084bea10be84c3f87f211" @@ -22906,6 +23108,13 @@ nopt@^4.0.1, nopt@~4.0.1: abbrev "1" osenv "^0.1.4" +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + nopt@^7.0.0: version "7.2.0" resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.0.tgz#067378c68116f602f552876194fd11f1292503d7" @@ -22996,6 +23205,16 @@ npmlog@^5.0.1: gauge "^3.0.0" set-blocking "^2.0.0" +npmlog@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.1.tgz#06f1344a174c06e8de9c6c70834cfba2964bba17" + integrity sha512-BTHDvY6nrRHuRfyjt1MAufLxYdVXZfd099H4+i1f0lPywNQyI4foeNXJRObB/uy+TYqUW0vAD9gbdSOXPst7Eg== + dependencies: + are-we-there-yet "^3.0.0" + console-control-strings "^1.1.0" + gauge "^4.0.0" + set-blocking "^2.0.0" + nth-check@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" @@ -23275,9 +23494,9 @@ onetime@^5.1.0, onetime@^5.1.2: mimic-fn "^2.1.0" open@^7.0.3: - version "7.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" - integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + version "7.1.0" + resolved "https://registry.yarnpkg.com/open/-/open-7.1.0.tgz#68865f7d3cb238520fa1225a63cf28bcf8368a1c" + integrity sha512-lLPI5KgOwEYCDKXf4np7y1PBEkj7HYIyP2DY8mVDRnx0VIIu6bNrRB0R66TuO7Mack6EnTNLm4uvcl1UoklTpA== dependencies: is-docker "^2.0.0" is-wsl "^2.1.1" @@ -26680,10 +26899,10 @@ rxjs@^6.3.3, rxjs@^6.4.0, rxjs@^6.5.1, rxjs@^6.6.0, rxjs@^6.6.7: dependencies: tslib "^1.9.0" -rxjs@^7.0.0, rxjs@^7.4.0, rxjs@^7.5.5: - version "7.8.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" - integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== +rxjs@^7.0.0, rxjs@^7.5.5: + version "7.5.5" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.5.tgz#2ebad89af0f560f460ad5cc4213219e1f7dd4e9f" + integrity sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw== dependencies: tslib "^2.1.0" @@ -26765,71 +26984,20 @@ sane@^4.0.3: minimist "^1.1.1" walker "~1.0.5" -sass-embedded-darwin-arm64@1.69.5: - version "1.69.5" - resolved "https://registry.yarnpkg.com/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.69.5.tgz#69e246d4a6875184a593906dfd7b84a21eb6eeb2" - integrity sha512-zVuXJzgT54t24E4QPP/iteHsw/cawZE8gAXGEm20cP2DKsIQBF7bvSTk0zzY0bS01YFtJviYM13HcGUe4q7/7w== - -sass-embedded-darwin-x64@1.69.5: - version "1.69.5" - resolved "https://registry.yarnpkg.com/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.69.5.tgz#82c2a659dafa93b54d2690f08f7aac9b2447c43f" - integrity sha512-HcA9YER3Ax7lMnHouxnIY462gnst5lNL56QXkZaTQmg9nH7oqR2bMfWbckEQL+mHIXGSM/QfX0aD59VOm5iKZw== - -sass-embedded-linux-arm64@1.69.5: - version "1.69.5" - resolved "https://registry.yarnpkg.com/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.69.5.tgz#8585bbcc6996ba04d8aa4216a2bf65de2e6592ea" - integrity sha512-HWCjdFSLGh0dMUNLNh+slc2j9koSZnfTEO9qQR6WEIuC+We6vYKJugGPo1V9pFbBeoW6VAJGYdlqsRPquteCZw== - -sass-embedded-linux-arm@1.69.5: - version "1.69.5" - resolved "https://registry.yarnpkg.com/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.69.5.tgz#ded653fe37d6b07d778c5f414cba5f28107dc438" - integrity sha512-m0NxVkrfcS3UsF33q0FgItMWIz/F1FZdfVZpjp+dP6qd0KLeTuoPUCh2GSize0DAU5T0Zj24b2mXeowDKv463g== - -sass-embedded-linux-ia32@1.69.5: - version "1.69.5" - resolved "https://registry.yarnpkg.com/sass-embedded-linux-ia32/-/sass-embedded-linux-ia32-1.69.5.tgz#61ad8b3b43be563f6fcd6ff04d0e121b195ecc2a" - integrity sha512-0taR6AJDb+eLOBTEMc1nfX2fI1hgRF9M+Hmv+wwGrxfBu/MkASk6fmR9B8MDw9hPHIqGVUkTVizjOh50O7nIKg== - -sass-embedded-linux-x64@1.69.5: - version "1.69.5" - resolved "https://registry.yarnpkg.com/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.69.5.tgz#3d490f520200d596b2b6072d6d3f4460b7114241" - integrity sha512-gN9yLTbKC0hUHukx4mdRs4V39WD719PM2GhWQBUA+3Z8qr9ywywi7LiU2atWrKESRF34V+eqF9lYiYVQxtTHZw== - -sass-embedded-win32-ia32@1.69.5: - version "1.69.5" - resolved "https://registry.yarnpkg.com/sass-embedded-win32-ia32/-/sass-embedded-win32-ia32-1.69.5.tgz#e84a053d25aec1176fac485bee65a384f39dfa9e" - integrity sha512-9OgSaufHP53b33gaH1Y5NZ/Im3druCHIQvLUEqJBCFuOzly47g/hZGrO+dBDiWgYGYKbSYI7Z4/PBtQoK5Vkxg== - -sass-embedded-win32-x64@1.69.5: - version "1.69.5" - resolved "https://registry.yarnpkg.com/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.69.5.tgz#8d803e99cccc0e8105dde50e49a2fd7839e360ec" - integrity sha512-p1PsOJnpwXdPfiRbX6QdRa4PnL2QXPpIRy8fkeAZpQFYZ278ZIlwemC2MukKMVLcE3iQ5lBulbC8IYm91rod6Q== - -sass-embedded@^1.69.5: - version "1.69.5" - resolved "https://registry.yarnpkg.com/sass-embedded/-/sass-embedded-1.69.5.tgz#ae217d4b17b0fb07e5ed146917c9c9de0c4383c6" - integrity sha512-0YNcRcbSpgGd4AnE+mm3a3g4S97puFLIZ0cYJgbwdD4iGz/hiOzE+yh72XS+u1LMhE+pQfNeC9MNnRsc8n1yRg== - dependencies: - "@bufbuild/protobuf" "^1.0.0" - buffer-builder "^0.2.0" - immutable "^4.0.0" - rxjs "^7.4.0" - supports-color "^8.1.1" - varint "^6.0.0" - optionalDependencies: - sass-embedded-darwin-arm64 "1.69.5" - sass-embedded-darwin-x64 "1.69.5" - sass-embedded-linux-arm "1.69.5" - sass-embedded-linux-arm64 "1.69.5" - sass-embedded-linux-ia32 "1.69.5" - sass-embedded-linux-x64 "1.69.5" - sass-embedded-win32-ia32 "1.69.5" - sass-embedded-win32-x64 "1.69.5" - -sass-loader@^10.5.0: - version "10.5.0" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.5.0.tgz#011c92ea529029e296aea37508e034b94f7dd2dc" - integrity sha512-VsU71W7VR6SChMJZUqtrfLeMSA8ns7QTHbnA7cfevtjb3c392mX93lr0Dmr4uU1ch5uIbEmfmHjdrDYcXXkQ7w== +sass-graph@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-4.0.1.tgz#2ff8ca477224d694055bf4093f414cf6cfad1d2e" + integrity sha512-5YCfmGBmxoIRYHnKK2AKzrAkCoQ8ozO+iumT8K4tXJXRVCPf+7s1/9KxTSW3Rbvf+7Y7b4FR3mWyLnQr3PHocA== + dependencies: + glob "^7.0.0" + lodash "^4.17.11" + scss-tokenizer "^0.4.3" + yargs "^17.2.1" + +sass-loader@^10.4.1: + version "10.4.1" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.4.1.tgz#bea4e173ddf512c9d7f53e9ec686186146807cbf" + integrity sha512-aX/iJZTTpNUNx/OSYzo2KsjIUQHqvWsAhhUijFjAPdZTEhstjZI9zTNvkTTwsx+uNUJqUwOw5gacxQMx4hJxGQ== dependencies: klona "^2.0.4" loader-utils "^2.0.0" @@ -26927,6 +27095,14 @@ screenfull@^5.0.0: resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.0.0.tgz#5c2010c0e84fd4157bf852877698f90b8cbe96f6" integrity sha512-yShzhaIoE9OtOhWVyBBffA6V98CDCoyHTsp8228blmqYy1Z5bddzE/4FPiJKlr8DVR4VBiiUyfPzIQPIYDkeMA== +scss-tokenizer@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.4.3.tgz#1058400ee7d814d71049c29923d2b25e61dc026c" + integrity sha512-raKLgf1LI5QMQnG+RxHz6oK0sL3x3I4FN2UDLqgLOGO8hodECNnNh5BXn7fAyBxrA8zVzdQizQ6XjNJQ+uBwMw== + dependencies: + js-base64 "^2.4.9" + source-map "^0.7.3" + secure-json-parse@^2.4.0: version "2.6.0" resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.6.0.tgz#95d89f84adf32d76ff7800e68a673b129fe918b0" @@ -27427,6 +27603,24 @@ sockjs@^0.3.24: uuid "^8.3.2" websocket-driver "^0.7.4" +socks-proxy-agent@^6.0.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz#e664e8f1aaf4e1fb3df945f09e3d94f911137f87" + integrity sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew== + dependencies: + agent-base "^6.0.2" + debug "^4.3.1" + socks "^2.6.1" + +socks-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" + integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== + dependencies: + agent-base "^6.0.2" + debug "^4.3.3" + socks "^2.6.2" + socks-proxy-agent@^8.0.1, socks-proxy-agent@^8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz#5acbd7be7baf18c46a3f293a840109a430a640ad" @@ -27436,7 +27630,7 @@ socks-proxy-agent@^8.0.1, socks-proxy-agent@^8.0.2: debug "^4.3.4" socks "^2.7.1" -socks@^2.7.1: +socks@^2.6.1, socks@^2.6.2, socks@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== @@ -27770,13 +27964,20 @@ ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" -ssri@^8.0.1: +ssri@^8.0.0, ssri@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== dependencies: minipass "^3.1.1" +ssri@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" + integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== + dependencies: + minipass "^3.1.1" + stable@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" @@ -27885,6 +28086,13 @@ stats-lite@^2.2.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= +stdout-stream@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.0.tgz#a2c7c8587e54d9427ea9edb3ac3f2cd522df378b" + integrity sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s= + dependencies: + readable-stream "^2.0.1" + store2@^2.12.0: version "2.12.0" resolved "https://registry.yarnpkg.com/store2/-/store2-2.12.0.tgz#e1f1b7e1a59b6083b2596a8d067f6ee88fd4d3cf" @@ -29014,6 +29222,11 @@ trough@^1.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.1.tgz#a9fd8b0394b0ae8fff82e0633a0a36ccad5b5f86" integrity sha1-qf2LA5Swro//guBjOgo2zK1bX4Y= +"true-case-path@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-2.2.1.tgz#c5bf04a5bbec3fd118be4084461b3a27c4d796bf" + integrity sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q== + ts-algebra@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/ts-algebra/-/ts-algebra-1.2.0.tgz#f91c481207a770f0d14d055c376cbee040afdfc9" @@ -29458,6 +29671,13 @@ unique-filename@^1.1.1: dependencies: unique-slug "^2.0.0" +unique-filename@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" + integrity sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A== + dependencies: + unique-slug "^3.0.0" + unique-filename@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" @@ -29472,6 +29692,13 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" +unique-slug@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-3.0.0.tgz#6d347cf57c8a7a7a6044aabd0e2d74e4d76dc7c9" + integrity sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w== + dependencies: + imurmurhash "^0.1.4" + unique-slug@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" @@ -29912,11 +30139,6 @@ variable-diff@1.1.0: chalk "^1.1.1" object-assign "^4.0.1" -varint@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0" - integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg== - vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -30825,7 +31047,7 @@ which@^1.2.9, which@^1.3.1: dependencies: isexe "^2.0.0" -which@^2.0.1: +which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== @@ -30839,7 +31061,7 @@ which@^4.0.0: dependencies: isexe "^3.1.1" -wide-align@^1.1.2: +wide-align@^1.1.2, wide-align@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== From 45210fb5e2d2ce1000ca43ea34324e3832df9cb7 Mon Sep 17 00:00:00 2001 From: Rickyanto Ang <rickyangwyn@gmail.com> Date: Thu, 21 Dec 2023 08:09:32 -0800 Subject: [PATCH 085/116] [Cloud Security][Dashboard][CNVM]Sub components that shows Cloud Regions data now shows Cloud Accounts instead (#173796) ## Summary This PR is part of Quick wins. This PR addresses issue where instead of showing number of cloud regions on cnvm dashboard, we should instead show number of accounts as this information is more valuable for the users **Before:** <img width="321" alt="Screenshot 2023-12-20 at 3 53 20 PM" src="https://github.com/elastic/kibana/assets/8703149/968112e9-df88-49f9-80ac-e0256a0bfe54"> **After:** <img width="553" alt="Screenshot 2023-12-20 at 3 52 27 PM" src="https://github.com/elastic/kibana/assets/8703149/e123e097-9011-427d-8214-1f6d2fc2846e"> --- x-pack/plugins/cloud_security_posture/common/types_old.ts | 2 +- .../_mocks_/vulnerability_dashboard.mock.ts | 2 +- .../vulnerability_dashboard/vulnerability_statistics.tsx | 4 ++-- .../get_vulnerabilities_statistics.ts | 8 ++++---- .../routes/vulnerabilities_dashboard.ts | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/cloud_security_posture/common/types_old.ts b/x-pack/plugins/cloud_security_posture/common/types_old.ts index d3706c51469f81..617f9dce122e80 100644 --- a/x-pack/plugins/cloud_security_posture/common/types_old.ts +++ b/x-pack/plugins/cloud_security_posture/common/types_old.ts @@ -181,7 +181,7 @@ export interface CnvmStatistics { highCount: number | undefined; mediumCount: number | undefined; resourcesScanned: number | undefined; - cloudRegions: number | undefined; + cloudAccounts: number | undefined; } export interface CnvmDashboardData { diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/_mocks_/vulnerability_dashboard.mock.ts b/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/_mocks_/vulnerability_dashboard.mock.ts index 0148105bbc83a5..7811f2c29892be 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/_mocks_/vulnerability_dashboard.mock.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/_mocks_/vulnerability_dashboard.mock.ts @@ -13,7 +13,7 @@ export const mockCnvmDashboardData: CnvmDashboardData = { highCount: 4715, mediumCount: 10537, resourcesScanned: 81, - cloudRegions: 1, + cloudAccounts: 1, }, vulnTrends: [ { diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/vulnerability_statistics.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/vulnerability_statistics.tsx index 1552ed2821bb85..adfca7f2f02052 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/vulnerability_statistics.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerability_dashboard/vulnerability_statistics.tsx @@ -84,11 +84,11 @@ export const VulnerabilityStatistics = () => { id: 'cloud-regions-stat', title: ( <CompactFormattedNumber - number={getVulnerabilityDashboard.data?.cnvmStatistics.cloudRegions} + number={getVulnerabilityDashboard.data?.cnvmStatistics.cloudAccounts} /> ), description: i18n.translate('xpack.csp.cnvmDashboard.statistics.cloudRegionTitle', { - defaultMessage: 'Cloud Regions', + defaultMessage: 'Cloud Accounts', }), }, { diff --git a/x-pack/plugins/cloud_security_posture/server/routes/vulnerabilities_dashboard/get_vulnerabilities_statistics.ts b/x-pack/plugins/cloud_security_posture/server/routes/vulnerabilities_dashboard/get_vulnerabilities_statistics.ts index 8458d66817f82d..530090c326766c 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/vulnerabilities_dashboard/get_vulnerabilities_statistics.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/vulnerabilities_dashboard/get_vulnerabilities_statistics.ts @@ -25,7 +25,7 @@ export interface VulnerabilitiesStatisticsQueryResult { resources_scanned: { value: number; }; - cloud_regions: { + cloud_accounts: { value: number; }; } @@ -51,9 +51,9 @@ export const getVulnerabilitiesStatisticsQuery = (): SearchRequest => ({ field: 'resource.id', }, }, - cloud_regions: { + cloud_accounts: { cardinality: { - field: 'cloud.region', + field: 'cloud.account.id', }, }, }, @@ -69,6 +69,6 @@ export const getVulnerabilitiesStatistics = async (esClient: ElasticsearchClient highCount: queryResult.aggregations?.high.doc_count, mediumCount: queryResult.aggregations?.medium.doc_count, resourcesScanned: queryResult.aggregations?.resources_scanned.value, - cloudRegions: queryResult.aggregations?.cloud_regions.value, + cloudAccounts: queryResult.aggregations?.cloud_accounts.value, }; }; diff --git a/x-pack/test/cloud_security_posture_api/routes/vulnerabilities_dashboard.ts b/x-pack/test/cloud_security_posture_api/routes/vulnerabilities_dashboard.ts index 7f15daf653478f..892d31e4bc04bb 100644 --- a/x-pack/test/cloud_security_posture_api/routes/vulnerabilities_dashboard.ts +++ b/x-pack/test/cloud_security_posture_api/routes/vulnerabilities_dashboard.ts @@ -19,7 +19,7 @@ export interface CnvmStatistics { highCount?: number; mediumCount?: number; resourcesScanned?: number; - cloudRegions?: number; + cloudAccounts?: number; } export interface AccountVulnStats { @@ -211,7 +211,7 @@ export default function ({ getService }: FtrProviderContext) { highCount: 1, mediumCount: 1, resourcesScanned: 2, - cloudRegions: 1, + cloudAccounts: 1, }, vulnTrends: [ { From 68883b37686cb428d66004166faeb0dc982ae97b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 17:11:50 +0100 Subject: [PATCH 086/116] Update dependency @elastic/charts to v61.2.0 (main) (#173329) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@elastic/charts](https://togithub.com/elastic/elastic-charts) | [`61.0.3` -> `61.2.0`](https://renovatebot.com/diffs/npm/@elastic%2fcharts/61.0.3/61.2.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@elastic%2fcharts/61.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@elastic%2fcharts/61.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@elastic%2fcharts/61.0.3/61.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@elastic%2fcharts/61.0.3/61.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>elastic/elastic-charts (@​elastic/charts)</summary> ### [61.2.0](https://github.com/elastic/elastic-charts/compare/v61.1.0...v61.2.0) (2023-12-19) ##### Bug Fixes * **deps:** update dependency @elastic/eui to ^91.1.0 ([#2267](https://github.com/elastic/elastic-charts/issues/2267)) ([308e974](https://github.com/elastic/elastic-charts/commit/308e97429c6d69fc3b902ed557c322c1d2e6bfa8)) * **deps:** update dependency @elastic/eui to ^91.2.0 ([#2268](https://github.com/elastic/elastic-charts/issues/2268)) ([29cdcb3](https://github.com/elastic/elastic-charts/commit/29cdcb360740a535710f1a4d08a1dd44c5cb569b)) * **metric:** background colors and sparkline rendering ([#2255](https://github.com/elastic/elastic-charts/issues/2255)) ([5abddfc](https://github.com/elastic/elastic-charts/commit/5abddfc67fe284d1a483deb4f8f6bc51e7cfedbc)) * **partition:** rendering with small radius ([#2273](https://github.com/elastic/elastic-charts/issues/2273)) ([95a8537](https://github.com/elastic/elastic-charts/commit/95a8537248eff8e72db21f960852b20ccd64fa62)) * **partition:** zero value sectors cause max stack call ([#2260](https://github.com/elastic/elastic-charts/issues/2260)) ([4b30db7](https://github.com/elastic/elastic-charts/commit/4b30db72981af3baed78ad72c7ab679324a767f6)) * **theme:** legacy margins ([#2262](https://github.com/elastic/elastic-charts/issues/2262)) ([299c869](https://github.com/elastic/elastic-charts/commit/299c869fec254c16fea169cc32b319c2bc79ee71)) ##### Features * increase tooltip width to 500px and truncate items to 2 lines ([#2261](https://github.com/elastic/elastic-charts/issues/2261)) ([afdef1c](https://github.com/elastic/elastic-charts/commit/afdef1c0142d954dd72a5833d6b9f0abce064f4a)) ### [`v61.1.0`](https://togithub.com/elastic/elastic-charts/blob/HEAD/CHANGELOG.md#6110-2023-11-20) [Compare Source](https://togithub.com/elastic/elastic-charts/compare/v61.0.3...v61.1.0) ##### Bug Fixes - **deps:** update dependency [@​elastic/eui](https://togithub.com/elastic/eui) to v91 ([#​2233](https://togithub.com/elastic/elastic-charts/issues/2233)) ([e89f623](https://togithub.com/elastic/elastic-charts/commit/e89f623792312c4f6b609ebb975de0800f3c297e)) - **metric:** add option to set empty cell background color ([#​2247](https://togithub.com/elastic/elastic-charts/issues/2247)) ([6a9fb86](https://togithub.com/elastic/elastic-charts/commit/6a9fb86bee5212a47060c5070f260961097014b4)) - **metric:** background color for bar with interactions ([#​2248](https://togithub.com/elastic/elastic-charts/issues/2248)) ([dcb56fa](https://togithub.com/elastic/elastic-charts/commit/dcb56fa08540631a9b3b0e588352ee6daf3d54a0)) ##### Features - **bullet:** improve header layout and positioning ([#​2243](https://togithub.com/elastic/elastic-charts/issues/2243)) ([b3a95d2](https://togithub.com/elastic/elastic-charts/commit/b3a95d24fb02690ca6599622352c743c04624690)) - **bullet:** new design style and implementation ([#​2156](https://togithub.com/elastic/elastic-charts/issues/2156)) ([fca6cdd](https://togithub.com/elastic/elastic-charts/commit/fca6cdd5bc34a65c0792dbab7d756404bf43501b)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/elastic/kibana). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy44Ny4yIiwidXBkYXRlZEluVmVyIjoiMzcuMTAzLjEiLCJ0YXJnZXRCcmFuY2giOiJtYWluIn0=--> --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Marco Vettorello <marco.vettorello@elastic.co> --- package.json | 2 +- .../gauge_component.test.tsx.snap | 15 +- .../partition_vis_component.test.tsx.snap | 90 ++++++++++- .../__snapshots__/xy_chart.test.tsx.snap | 150 ++++++++++++++++-- .../__snapshots__/donut_chart.test.tsx.snap | 15 +- yarn.lock | 10 +- 6 files changed, 258 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index 2553521b662be4..998d54ad9eb79a 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "@dnd-kit/utilities": "^2.0.0", "@elastic/apm-rum": "^5.15.0", "@elastic/apm-rum-react": "^2.0.1", - "@elastic/charts": "61.0.3", + "@elastic/charts": "61.2.0", "@elastic/datemath": "5.0.3", "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@8.9.1-canary.1", "@elastic/ems-client": "8.5.1", diff --git a/src/plugins/chart_expressions/expression_gauge/public/components/__snapshots__/gauge_component.test.tsx.snap b/src/plugins/chart_expressions/expression_gauge/public/components/__snapshots__/gauge_component.test.tsx.snap index afd6ce21ad36f7..f797f9ba344e07 100644 --- a/src/plugins/chart_expressions/expression_gauge/public/components/__snapshots__/gauge_component.test.tsx.snap +++ b/src/plugins/chart_expressions/expression_gauge/public/components/__snapshots__/gauge_component.test.tsx.snap @@ -191,6 +191,19 @@ exports[`GaugeComponent renders the chart 1`] = ` "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -510,7 +523,7 @@ exports[`GaugeComponent renders the chart 1`] = ` "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap b/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap index 241e2ac6f4fafa..f7c57d6e765df0 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap +++ b/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap @@ -421,6 +421,19 @@ exports[`PartitionVisComponent should render correct structure for donut 1`] = ` "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -740,7 +753,7 @@ exports[`PartitionVisComponent should render correct structure for donut 1`] = ` "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } @@ -1324,6 +1337,19 @@ exports[`PartitionVisComponent should render correct structure for mosaic 1`] = "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -1643,7 +1669,7 @@ exports[`PartitionVisComponent should render correct structure for mosaic 1`] = "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } @@ -2287,6 +2313,19 @@ exports[`PartitionVisComponent should render correct structure for multi-metric "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -2606,7 +2645,7 @@ exports[`PartitionVisComponent should render correct structure for multi-metric "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } @@ -3252,6 +3291,19 @@ exports[`PartitionVisComponent should render correct structure for pie 1`] = ` "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -3571,7 +3623,7 @@ exports[`PartitionVisComponent should render correct structure for pie 1`] = ` "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } @@ -4155,6 +4207,19 @@ exports[`PartitionVisComponent should render correct structure for treemap 1`] = "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -4474,7 +4539,7 @@ exports[`PartitionVisComponent should render correct structure for treemap 1`] = "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } @@ -5013,6 +5078,19 @@ exports[`PartitionVisComponent should render correct structure for waffle 1`] = "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -5332,7 +5410,7 @@ exports[`PartitionVisComponent should render correct structure for waffle 1`] = "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } diff --git a/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap b/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap index 7f5aeab32335a7..267833cba170dd 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap +++ b/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap @@ -763,6 +763,19 @@ exports[`XYChart component it renders area 1`] = ` "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -1082,7 +1095,7 @@ exports[`XYChart component it renders area 1`] = ` "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } @@ -2286,6 +2299,19 @@ exports[`XYChart component it renders bar 1`] = ` "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -2605,7 +2631,7 @@ exports[`XYChart component it renders bar 1`] = ` "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } @@ -3809,6 +3835,19 @@ exports[`XYChart component it renders horizontal bar 1`] = ` "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -4128,7 +4167,7 @@ exports[`XYChart component it renders horizontal bar 1`] = ` "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } @@ -5332,6 +5371,19 @@ exports[`XYChart component it renders line 1`] = ` "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -5651,7 +5703,7 @@ exports[`XYChart component it renders line 1`] = ` "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } @@ -6855,6 +6907,19 @@ exports[`XYChart component it renders stacked area 1`] = ` "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -7174,7 +7239,7 @@ exports[`XYChart component it renders stacked area 1`] = ` "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } @@ -8378,6 +8443,19 @@ exports[`XYChart component it renders stacked bar 1`] = ` "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -8697,7 +8775,7 @@ exports[`XYChart component it renders stacked bar 1`] = ` "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } @@ -9901,6 +9979,19 @@ exports[`XYChart component it renders stacked horizontal bar 1`] = ` "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -10220,7 +10311,7 @@ exports[`XYChart component it renders stacked horizontal bar 1`] = ` "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } @@ -11454,6 +11545,19 @@ exports[`XYChart component split chart should render split chart if both, splitR "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -11773,7 +11877,7 @@ exports[`XYChart component split chart should render split chart if both, splitR "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } @@ -13215,6 +13319,19 @@ exports[`XYChart component split chart should render split chart if splitColumnA "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -13534,7 +13651,7 @@ exports[`XYChart component split chart should render split chart if splitColumnA "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } @@ -14969,6 +15086,19 @@ exports[`XYChart component split chart should render split chart if splitRowAcce "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -15288,7 +15418,7 @@ exports[`XYChart component split chart should render split chart if splitRowAcce "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } diff --git a/x-pack/plugins/uptime/public/legacy_uptime/components/common/charts/__snapshots__/donut_chart.test.tsx.snap b/x-pack/plugins/uptime/public/legacy_uptime/components/common/charts/__snapshots__/donut_chart.test.tsx.snap index acf41bdf93448f..6f9a8644bb706c 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/components/common/charts/__snapshots__/donut_chart.test.tsx.snap +++ b/x-pack/plugins/uptime/public/legacy_uptime/components/common/charts/__snapshots__/donut_chart.test.tsx.snap @@ -204,6 +204,19 @@ exports[`DonutChart component passes correct props without errors for valid prop "visible": true, }, }, + "bulletGraph": Object { + "angularTickLabelPadding": 10, + "barBackground": "#343741", + "border": "#EDF0F5", + "colorBands": Array [ + "#D9C6EF", + "#AA87D1", + ], + "fallbackBandColor": "#98A2B3", + "minHeight": 64, + "nonFiniteText": "N/A", + "textColor": "#343741", + }, "chartMargins": Object { "bottom": 0, "left": 0, @@ -523,7 +536,7 @@ exports[`DonutChart component passes correct props without errors for valid prop "tooltip": Object { "defaultDotColor": "black", "maxTableHeight": 120, - "maxWidth": 260, + "maxWidth": 500, }, } } diff --git a/yarn.lock b/yarn.lock index 7b2754c8719c8f..bf07d32acc0c74 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1544,14 +1544,14 @@ dependencies: object-hash "^1.3.0" -"@elastic/charts@61.0.3": - version "61.0.3" - resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-61.0.3.tgz#77a2e1f18a39dd4b421a91edfd30f19cde740594" - integrity sha512-TY7hUieULTchNFgvpi6Rt7wMxrYMCmuZ4bbS6szOGBIY4WKJvZCgMfgZ2kUdC5MVG/jEzd8Qu+Xixce7GDpRxw== +"@elastic/charts@61.2.0": + version "61.2.0" + resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-61.2.0.tgz#fa065b85324d5660e4b6355390cca8699ef0d6ff" + integrity sha512-LBmZ+6wSR9/BCR+go5eIBy51Jpxr0cbK/a7vslZNYIGCdpHsWxGZgcqG3KgshFxOmUvcP7kj9LEEmeCTEGhbUQ== dependencies: "@popperjs/core" "^2.11.8" bezier-easing "^2.1.0" - chroma-js "^2.1.0" + chroma-js "^2.4.2" classnames "^2.2.6" d3-array "^1.2.4" d3-cloud "^1.2.5" From 5fceb91fb3a4d6a8df58bc79ca9b074249468886 Mon Sep 17 00:00:00 2001 From: Maryam Saeidi <maryam.saeidi@elastic.co> Date: Thu, 21 Dec 2023 17:39:46 +0100 Subject: [PATCH 087/116] [Custom threshold] Add view in app URL to the recovered alerts plus testing (#173652) Closes #172436 ## Summary This PR adds a functional test and unit tests for the viewInApp URL. I also added this URL to the recovered alerts. --- .../locators/redirect/parse_search_params.ts | 6 +- .../get_view_in_app_url.test.ts | 157 ++++++++++++++++++ .../get_view_in_app_url.ts | 32 ++-- .../pages/alerts/helpers/parse_alert.ts | 9 +- .../register_observability_rule_types.ts | 10 +- .../custom_threshold_executor.test.ts | 66 +++++++- .../custom_threshold_executor.ts | 22 ++- .../custom_threshold_rule/avg_pct_fired.ts | 22 ++- .../custom_threshold_rule/avg_pct_no_data.ts | 18 +- .../custom_threshold_rule/constants.ts | 8 + .../documents_count_fired.ts | 31 +++- .../custom_threshold_rule/typings.ts | 10 ++ 12 files changed, 351 insertions(+), 40 deletions(-) create mode 100644 x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.test.ts create mode 100644 x-pack/test/alerting_api_integration/observability/custom_threshold_rule/constants.ts diff --git a/src/plugins/share/common/url_service/locators/redirect/parse_search_params.ts b/src/plugins/share/common/url_service/locators/redirect/parse_search_params.ts index a4711c30db5d09..c66bf56b1858fc 100644 --- a/src/plugins/share/common/url_service/locators/redirect/parse_search_params.ts +++ b/src/plugins/share/common/url_service/locators/redirect/parse_search_params.ts @@ -22,7 +22,9 @@ import type { RedirectOptions } from './types'; * @param urlSearch Search part of URL path. * @returns Parsed out locator ID, version, and locator params. */ -export function parseSearchParams(urlSearch: string): RedirectOptions { +export function parseSearchParams<P extends SerializableRecord = unknown & SerializableRecord>( + urlSearch: string +): RedirectOptions<P> { const search = new URLSearchParams(urlSearch); const id = search.get('l'); @@ -66,7 +68,7 @@ export function parseSearchParams(urlSearch: string): RedirectOptions { throw new Error(message); } - let params: unknown & SerializableRecord; + let params: P; try { params = JSON.parse(paramsJson); } catch { diff --git a/x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.test.ts b/x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.test.ts new file mode 100644 index 00000000000000..6971ff2d33c2db --- /dev/null +++ b/x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.test.ts @@ -0,0 +1,157 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DiscoverAppLocatorParams } from '@kbn/discover-plugin/common'; +import { Aggregators } from './types'; +import { LocatorPublic } from '@kbn/share-plugin/common'; +import { getViewInAppUrl, GetViewInAppUrlArgs } from './get_view_in_app_url'; + +describe('getViewInAppUrl', () => { + const logExplorerLocator = { + getRedirectUrl: jest.fn(() => 'mockedGetRedirectUrl'), + } as unknown as LocatorPublic<DiscoverAppLocatorParams>; + const startedAt = '2023-12-07T16:30:15.403Z'; + const endedAt = '2023-12-07T20:30:15.403Z'; + const returnedTimeRange = { + // Duration 4 hour, time range will be extended it with 30 minutes from each side + from: '2023-12-07T16:00:15.403Z', + to: '2023-12-07T21:00:15.403Z', + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('Should return empty string if logExplorerLocator is not provided', () => { + const args: GetViewInAppUrlArgs = { + metrics: [], + startedAt, + endedAt, + }; + + expect(getViewInAppUrl(args)).toBe(''); + }); + + it('should call getRedirectUrl with data view, time range and filters', () => { + const args: GetViewInAppUrlArgs = { + metrics: [ + { + name: 'A', + aggType: Aggregators.COUNT, + filter: 'mockedCountFilter', + }, + ], + logExplorerLocator, + startedAt, + endedAt, + filter: 'mockedFilter', + dataViewId: 'mockedDataViewId', + }; + + expect(getViewInAppUrl(args)).toBe('mockedGetRedirectUrl'); + expect(logExplorerLocator.getRedirectUrl).toHaveBeenCalledWith({ + dataset: args.dataViewId, + timeRange: returnedTimeRange, + query: { + query: 'mockedFilter and mockedCountFilter', + language: 'kuery', + }, + }); + }); + + it('should call getRedirectUrl with only count filter', () => { + const args: GetViewInAppUrlArgs = { + metrics: [ + { + name: 'A', + aggType: Aggregators.COUNT, + filter: 'mockedCountFilter', + }, + ], + logExplorerLocator, + startedAt, + endedAt, + }; + + expect(getViewInAppUrl(args)).toBe('mockedGetRedirectUrl'); + expect(logExplorerLocator.getRedirectUrl).toHaveBeenCalledWith({ + dataset: undefined, + timeRange: returnedTimeRange, + query: { + query: 'mockedCountFilter', + language: 'kuery', + }, + }); + }); + + it('should call getRedirectUrl with only filter', () => { + const args: GetViewInAppUrlArgs = { + logExplorerLocator, + startedAt, + endedAt, + filter: 'mockedFilter', + }; + + expect(getViewInAppUrl(args)).toBe('mockedGetRedirectUrl'); + expect(logExplorerLocator.getRedirectUrl).toHaveBeenCalledWith({ + dataset: undefined, + timeRange: returnedTimeRange, + query: { + query: 'mockedFilter', + language: 'kuery', + }, + }); + }); + + it('should call getRedirectUrl with empty query if metrics and filter are not not provided', () => { + const args: GetViewInAppUrlArgs = { + logExplorerLocator, + startedAt, + endedAt, + }; + + expect(getViewInAppUrl(args)).toBe('mockedGetRedirectUrl'); + expect(logExplorerLocator.getRedirectUrl).toHaveBeenCalledWith({ + dataset: undefined, + timeRange: returnedTimeRange, + query: { + query: '', + language: 'kuery', + }, + }); + }); + + it('should call getRedirectUrl with empty if there are multiple metrics', () => { + const args: GetViewInAppUrlArgs = { + metrics: [ + { + name: 'A', + aggType: Aggregators.COUNT, + filter: 'mockedCountFilter', + }, + { + name: 'A', + aggType: Aggregators.AVERAGE, + field: 'mockedAvgField', + }, + ], + logExplorerLocator, + startedAt, + endedAt, + }; + + expect(getViewInAppUrl(args)).toBe('mockedGetRedirectUrl'); + expect(logExplorerLocator.getRedirectUrl).toHaveBeenCalledWith({ + dataset: undefined, + timeRange: returnedTimeRange, + query: { + query: '', + language: 'kuery', + }, + }); + }); +}); diff --git a/x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.ts b/x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.ts index 658d1debe0a94b..27efa730dccb77 100644 --- a/x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.ts +++ b/x-pack/plugins/observability/common/custom_threshold_rule/get_view_in_app_url.ts @@ -11,21 +11,27 @@ import type { TimeRange } from '@kbn/es-query'; import type { LocatorPublic } from '@kbn/share-plugin/common'; import type { CustomThresholdExpressionMetric } from './types'; -export const getViewInAppUrl = ( - metrics: CustomThresholdExpressionMetric[], - startedAt?: string, - logExplorerLocator?: LocatorPublic<DiscoverAppLocatorParams>, - filter?: string, - dataViewId?: string, - endedAt?: string -) => { +export interface GetViewInAppUrlArgs { + dataViewId?: string; + endedAt?: string; + startedAt?: string; + filter?: string; + logExplorerLocator?: LocatorPublic<DiscoverAppLocatorParams>; + metrics?: CustomThresholdExpressionMetric[]; +} + +export const getViewInAppUrl = ({ + dataViewId, + endedAt, + startedAt = new Date().toISOString(), + filter, + logExplorerLocator, + metrics = [], +}: GetViewInAppUrlArgs) => { if (!logExplorerLocator) return ''; - let timeRange: TimeRange | undefined; - if (startedAt) { - timeRange = getPaddedAlertTimeRange(startedAt, endedAt); - timeRange.to = endedAt ? timeRange.to : 'now'; - } + const timeRange: TimeRange | undefined = getPaddedAlertTimeRange(startedAt, endedAt); + timeRange.to = endedAt ? timeRange.to : 'now'; const query = { query: '', diff --git a/x-pack/plugins/observability/public/pages/alerts/helpers/parse_alert.ts b/x-pack/plugins/observability/public/pages/alerts/helpers/parse_alert.ts index 33cff33c663a17..2ffea657998676 100644 --- a/x-pack/plugins/observability/public/pages/alerts/helpers/parse_alert.ts +++ b/x-pack/plugins/observability/public/pages/alerts/helpers/parse_alert.ts @@ -38,10 +38,17 @@ export const parseAlert = }; const formatter = observabilityRuleTypeRegistry.getFormatter(parsedFields[ALERT_RULE_TYPE_ID]!); + let formattedFields = {}; + try { + formattedFields = + formatter?.({ fields: parsedFields, formatters: { asDuration, asPercent } }) ?? {}; + } catch (error) { + // Ignore formatted fields if there is a formatting error + } const formatted = { link: undefined, reason: parsedFields[ALERT_REASON] ?? parsedFields[ALERT_RULE_NAME] ?? '', - ...(formatter?.({ fields: parsedFields, formatters: { asDuration, asPercent } }) ?? {}), + ...formattedFields, }; return { diff --git a/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts b/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts index 643d5ffd4f337d..c9079991bdf4d3 100644 --- a/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts +++ b/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts @@ -145,13 +145,13 @@ export const registerObservabilityRuleTypes = async ( const dataViewId = getDataViewId(searchConfiguration); return { reason: fields[ALERT_REASON] ?? '-', - link: getViewInAppUrl( + link: getViewInAppUrl({ metrics, - fields[ALERT_START], + startedAt: fields[ALERT_START], logExplorerLocator, - (searchConfiguration?.query as { query: string }).query, - dataViewId - ), + filter: (searchConfiguration?.query as { query: string }).query, + dataViewId, + }), hasBasePath: true, }; }, diff --git a/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.test.ts b/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.test.ts index b769f5f32b73bb..f581236e229250 100644 --- a/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.test.ts +++ b/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.test.ts @@ -27,10 +27,11 @@ import { CustomMetricExpressionParams, CustomThresholdExpressionMetric, } from '../../../../common/custom_threshold_rule/types'; +import { getViewInAppUrl } from '../../../../common/custom_threshold_rule/get_view_in_app_url'; jest.mock('./lib/evaluate_rule', () => ({ evaluateRule: jest.fn() })); jest.mock('../../../../common/custom_threshold_rule/get_view_in_app_url', () => ({ - getViewInAppUrl: () => 'mockedViewInApp', + getViewInAppUrl: jest.fn().mockReturnValue('mockedViewInApp'), })); interface AlertTestInstance { @@ -67,6 +68,7 @@ const logger = { const STARTED_AT_MOCK_DATE = new Date(); +const mockQuery = 'mockQuery'; const mockOptions = { executionId: '', startedAt: STARTED_AT_MOCK_DATE, @@ -74,7 +76,7 @@ const mockOptions = { params: { searchConfiguration: { query: { - query: '', + query: mockQuery, language: 'kuery', }, }, @@ -1058,6 +1060,7 @@ describe('The custom threshold alert type', () => { ); }); }); + describe('querying with the count aggregator', () => { afterAll(() => clearInstances()); const instanceID = '*'; @@ -1196,6 +1199,63 @@ describe('The custom threshold alert type', () => { }); }); }); + + describe('querying recovered alert with a count aggregator', () => { + afterAll(() => clearInstances()); + const execute = (comparator: Comparator, threshold: number[], sourceId: string = 'default') => + executor({ + ...mockOptions, + services, + params: { + ...mockOptions.params, + sourceId, + criteria: [ + { + ...customThresholdCountCriterion, + comparator, + threshold, + }, + ], + }, + }); + test('alerts based on the doc_count value instead of the aggregatedValue', async () => { + setEvaluationResults([ + { + '*': { + ...customThresholdCountCriterion, + comparator: Comparator.GT, + threshold: [0.9], + currentValue: 1, + timestamp: new Date().toISOString(), + shouldFire: true, + isNoData: false, + bucketKey: { groupBy0: 'a' }, + }, + }, + ]); + const mockedSetContext = jest.fn(); + services.alertFactory.done.mockImplementation(() => { + return { + getRecoveredAlerts: jest.fn().mockReturnValue([ + { + setContext: mockedSetContext, + getId: jest.fn().mockReturnValue('mockedId'), + }, + ]), + }; + }); + await execute(Comparator.GT, [0.9]); + const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/; + expect(getViewInAppUrl).toBeCalledWith({ + dataViewId: 'c34a7c79-a88b-4b4a-ad19-72f6d24104e4', + filter: mockQuery, + logExplorerLocator: undefined, + metrics: customThresholdCountCriterion.metrics, + startedAt: expect.stringMatching(ISO_DATE_REGEX), + }); + }); + }); + describe("querying a metric that hasn't reported data", () => { afterAll(() => clearInstances()); const instanceID = '*'; @@ -1901,12 +1961,14 @@ const customThresholdNonCountCriterion: CustomMetricExpressionParams = { threshold: [0], }; +const mockedCountFilter = 'mockedCountFilter'; const customThresholdCountCriterion: CustomMetricExpressionParams = { comparator: Comparator.GT, metrics: [ { aggType: Aggregators.COUNT, name: 'A', + filter: mockedCountFilter, }, ], timeSize: 1, diff --git a/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.ts b/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.ts index 2aa9ee09a073db..1be464f0fbbc39 100644 --- a/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.ts +++ b/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.ts @@ -295,13 +295,13 @@ export const createCustomThresholdExecutor = ({ } return formatAlertResult(evaluation).currentValue; }), - viewInAppUrl: getViewInAppUrl( - alertResults.length === 1 ? alertResults[0][group].metrics : [], - indexedStartedAt, + viewInAppUrl: getViewInAppUrl({ + dataViewId: params.searchConfiguration?.index?.title ?? dataViewId, + filter: params.searchConfiguration.query.query, logExplorerLocator, - params.searchConfiguration.query.query, - params.searchConfiguration?.index?.title ?? dataViewId - ), + metrics: alertResults.length === 1 ? alertResults[0][group].metrics : [], + startedAt: indexedStartedAt, + }), ...additionalContext, }); } @@ -321,6 +321,7 @@ export const createCustomThresholdExecutor = ({ const alertUuid = getAlertUuid(recoveredAlertId); const timestamp = startedAt.toISOString(); const indexedStartedAt = getAlertStartedDate(recoveredAlertId) ?? timestamp; + const group = groupByKeysObjectForRecovered[recoveredAlertId]; const alertHits = alertUuid ? await getAlertByAlertUuid(alertUuid) : undefined; const additionalContext = getContextForRecoveredAlerts(alertHits); @@ -333,8 +334,15 @@ export const createCustomThresholdExecutor = ({ alertsLocator, basePath.publicBaseUrl ), - group: groupByKeysObjectForRecovered[recoveredAlertId], + group, timestamp: startedAt.toISOString(), + viewInAppUrl: getViewInAppUrl({ + dataViewId: params.searchConfiguration?.index?.title ?? dataViewId, + filter: params.searchConfiguration.query.query, + logExplorerLocator, + metrics: params.criteria[0]?.metrics, + startedAt: indexedStartedAt, + }), ...additionalContext, }); } diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_fired.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_fired.ts index 90998bc55623b2..d2f29896575833 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_fired.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_fired.ts @@ -6,6 +6,7 @@ */ import moment from 'moment'; +import { omit } from 'lodash'; import { cleanup, generate } from '@kbn/infra-forge'; import { Aggregators, @@ -14,6 +15,7 @@ import { import { FIRED_ACTIONS_ID } from '@kbn/observability-plugin/server/lib/rules/custom_threshold/constants'; import expect from '@kbn/expect'; import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils'; +import { parseSearchParams } from '@kbn/share-plugin/common/url_service'; import { createIndexConnector, createRule } from '../helpers/alerting_api_helper'; import { waitForAlertInIndex, @@ -21,7 +23,8 @@ import { waitForRuleStatus, } from '../helpers/alerting_wait_for_helpers'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { ActionDocument } from './typings'; +import { ActionDocument, LogExplorerLocatorParsedParams } from './typings'; +import { ISO_DATE_REGEX } from './constants'; // eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { @@ -35,12 +38,12 @@ export default function ({ getService }: FtrProviderContext) { const ALERT_ACTION_INDEX = 'alert-action-threshold'; // DATE_VIEW should match the index template: // x-pack/packages/kbn-infra-forge/src/data_sources/composable/template.json - const DATE_VIEW = 'kbn-data-forge-fake_hosts'; + const DATE_VIEW_TITLE = 'kbn-data-forge-fake_hosts'; const DATE_VIEW_NAME = 'ad-hoc-data-view-name'; const DATA_VIEW_ID = 'data-view-id'; const MOCKED_AD_HOC_DATA_VIEW = { id: DATA_VIEW_ID, - title: DATE_VIEW, + title: DATE_VIEW_TITLE, timeFieldName: '@timestamp', sourceFilters: [], fieldFormats: {}, @@ -122,6 +125,7 @@ export default function ({ getService }: FtrProviderContext) { reason: '{{context.reason}}', value: '{{context.value}}', host: '{{context.host}}', + viewInAppUrl: '{{context.viewInAppUrl}}', }, ], }, @@ -218,6 +222,18 @@ export default function ({ getService }: FtrProviderContext) { `Average system.cpu.user.pct is 250%, above the threshold of 50%. (duration: 5 mins, data view: ${DATE_VIEW_NAME})` ); expect(resp.hits.hits[0]._source?.value).eql('250%'); + + const parsedViewInAppUrl = parseSearchParams<LogExplorerLocatorParsedParams>( + new URL(resp.hits.hits[0]._source?.viewInAppUrl || '').search + ); + + expect(resp.hits.hits[0]._source?.viewInAppUrl).contain('LOG_EXPLORER_LOCATOR'); + expect(omit(parsedViewInAppUrl.params, 'timeRange.from')).eql({ + dataset: DATE_VIEW_TITLE, + timeRange: { to: 'now' }, + query: { query: '', language: 'kuery' }, + }); + expect(parsedViewInAppUrl.params.timeRange.from).match(ISO_DATE_REGEX); }); }); }); diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_no_data.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_no_data.ts index ae3689fbb49e3b..e1d029f375c92e 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_no_data.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_no_data.ts @@ -5,12 +5,14 @@ * 2.0. */ +import { omit } from 'lodash'; import moment from 'moment'; import { Aggregators, Comparator, } from '@kbn/observability-plugin/common/custom_threshold_rule/types'; import { NO_DATA_ACTIONS_ID } from '@kbn/observability-plugin/server/lib/rules/custom_threshold/constants'; +import { parseSearchParams } from '@kbn/share-plugin/common/url_service'; import expect from '@kbn/expect'; import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils'; @@ -22,7 +24,8 @@ import { waitForRuleStatus, } from '../helpers/alerting_wait_for_helpers'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { ActionDocument } from './typings'; +import { ISO_DATE_REGEX } from './constants'; +import { ActionDocument, LogExplorerLocatorParsedParams } from './typings'; // eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { @@ -114,6 +117,7 @@ export default function ({ getService }: FtrProviderContext) { alertDetailsUrl: '{{context.alertDetailsUrl}}', reason: '{{context.reason}}', value: '{{context.value}}', + viewInAppUrl: '{{context.viewInAppUrl}}', }, ], }, @@ -210,6 +214,18 @@ export default function ({ getService }: FtrProviderContext) { 'Average system.cpu.user.pct reported no data in the last 5m' ); expect(resp.hits.hits[0]._source?.value).eql('[NO DATA]'); + + const parsedViewInAppUrl = parseSearchParams<LogExplorerLocatorParsedParams>( + new URL(resp.hits.hits[0]._source?.viewInAppUrl || '').search + ); + + expect(resp.hits.hits[0]._source?.viewInAppUrl).contain('LOG_EXPLORER_LOCATOR'); + expect(omit(parsedViewInAppUrl.params, 'timeRange.from')).eql({ + dataset: DATA_VIEW_ID, + timeRange: { to: 'now' }, + query: { query: '', language: 'kuery' }, + }); + expect(parsedViewInAppUrl.params.timeRange.from).match(ISO_DATE_REGEX); }); }); }); diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/constants.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/constants.ts new file mode 100644 index 00000000000000..5cf1e0b4d66145 --- /dev/null +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/constants.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/; diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/documents_count_fired.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/documents_count_fired.ts index 361ca1d05b225d..5bad9470f5d75c 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/documents_count_fired.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/documents_count_fired.ts @@ -5,15 +5,17 @@ * 2.0. */ +import { omit } from 'lodash'; import moment from 'moment'; +import expect from '@kbn/expect'; import { cleanup, generate } from '@kbn/infra-forge'; import { Aggregators, Comparator, } from '@kbn/observability-plugin/common/custom_threshold_rule/types'; import { FIRED_ACTIONS_ID } from '@kbn/observability-plugin/server/lib/rules/custom_threshold/constants'; -import expect from '@kbn/expect'; import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils'; +import { parseSearchParams } from '@kbn/share-plugin/common/url_service'; import { createIndexConnector, createRule } from '../helpers/alerting_api_helper'; import { createDataView, deleteDataView } from '../helpers/data_view'; import { @@ -22,7 +24,8 @@ import { waitForRuleStatus, } from '../helpers/alerting_wait_for_helpers'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { ActionDocument } from './typings'; +import { ISO_DATE_REGEX } from './constants'; +import { ActionDocument, LogExplorerLocatorParsedParams } from './typings'; // eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { @@ -95,14 +98,14 @@ export default function ({ getService }: FtrProviderContext) { threshold: [1, 2], timeSize: 1, timeUnit: 'm', - metrics: [{ name: 'A', filter: '', aggType: Aggregators.COUNT }], + metrics: [{ name: 'A', filter: 'container.id:*', aggType: Aggregators.COUNT }], }, ], alertOnNoData: true, alertOnGroupDisappear: true, searchConfiguration: { query: { - query: '', + query: 'host.name:*', language: 'kuery', }, index: DATA_VIEW_ID, @@ -119,6 +122,7 @@ export default function ({ getService }: FtrProviderContext) { alertDetailsUrl: '{{context.alertDetailsUrl}}', reason: '{{context.reason}}', value: '{{context.value}}', + viewInAppUrl: '{{context.viewInAppUrl}}', }, ], }, @@ -190,12 +194,15 @@ export default function ({ getService }: FtrProviderContext) { threshold: [1, 2], timeSize: 1, timeUnit: 'm', - metrics: [{ name: 'A', filter: '', aggType: 'count' }], + metrics: [{ name: 'A', filter: 'container.id:*', aggType: 'count' }], }, ], alertOnNoData: true, alertOnGroupDisappear: true, - searchConfiguration: { index: 'data-view-id', query: { query: '', language: 'kuery' } }, + searchConfiguration: { + index: 'data-view-id', + query: { query: 'host.name:*', language: 'kuery' }, + }, }); }); @@ -214,6 +221,18 @@ export default function ({ getService }: FtrProviderContext) { `Document count is 3, not between the threshold of 1 and 2. (duration: 1 min, data view: ${DATE_VIEW_NAME})` ); expect(resp.hits.hits[0]._source?.value).eql('3'); + + const parsedViewInAppUrl = parseSearchParams<LogExplorerLocatorParsedParams>( + new URL(resp.hits.hits[0]._source?.viewInAppUrl || '').search + ); + + expect(resp.hits.hits[0]._source?.viewInAppUrl).contain('LOG_EXPLORER_LOCATOR'); + expect(omit(parsedViewInAppUrl.params, 'timeRange.from')).eql({ + dataset: DATA_VIEW_ID, + timeRange: { to: 'now' }, + query: { query: 'host.name:* and container.id:*', language: 'kuery' }, + }); + expect(parsedViewInAppUrl.params.timeRange.from).match(ISO_DATE_REGEX); }); }); }); diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/typings.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/typings.ts index 83894e6cf24a2f..a0cfb54fff1577 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/typings.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/typings.ts @@ -5,11 +5,21 @@ * 2.0. */ +import { Query, TimeRange } from '@kbn/es-query'; +import { SerializableRecord } from '@kbn/utility-types'; + export interface ActionDocument { ruleType: string; alertDetailsUrl: string; reason: string; value: string; + viewInAppUrl: string; host?: string; group?: string; } + +export interface LogExplorerLocatorParsedParams extends SerializableRecord { + dataset: string; + timeRange: TimeRange; + query: Query; +} From 93c26b931b29a968654e846a433bf6debcba781b Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet <pierre.gayvallet@elastic.co> Date: Thu, 21 Dec 2023 18:50:36 +0100 Subject: [PATCH 088/116] Use theme instead of UISettings for darkMode access (#173639) ## Summary Part of https://github.com/elastic/kibana/issues/173529 Adapt most of the theme access based on `uiSettings.get('theme:darkMode')` with the correct approach of using `core.theme` --- .../landing_page/guide/guide_filters.tsx | 3 + .../public/application/components/home.tsx | 2 +- .../components/sample_data/index.tsx | 2 +- .../components/tutorial/instruction.js | 6 +- .../public/vis_controller.tsx | 2 +- .../kibana_react/public/dark_mode/index.ts | 9 +++ .../public/dark_mode/use_dark_mode.test.tsx | 81 +++++++++++++++++++ .../public/dark_mode/use_dark_mode.ts | 26 ++++++ src/plugins/kibana_react/public/index.ts | 3 + .../application/maintenance_windows.tsx | 2 +- .../components/routing/app_root/index.tsx | 4 +- .../public/application/index.tsx | 2 +- .../exploratory_view/embeddable/index.tsx | 4 +- .../kubernetes_security/public/test/index.tsx | 5 +- .../monitoring/public/application/index.tsx | 10 +-- .../public/application/index.tsx | 2 +- .../components/expression_chart.tsx | 4 +- .../ux/core_web_vitals/palette_legends.tsx | 5 +- .../e2e/cypress/e2e/home.cy.ts | 1 + .../public/application/app.tsx | 5 +- .../session_view/public/test/index.tsx | 5 +- .../public/apps/synthetics/render_app.tsx | 10 +-- .../public/hooks/use_base_chart_theme.ts | 5 +- .../components/table/cell_renderer.tsx | 8 +- .../public/application/app.tsx | 9 +-- .../public/application/connectors_app.tsx | 7 +- .../public/legacy_uptime/app/render_app.tsx | 10 +-- .../hooks/use_base_chart_theme.ts | 4 +- .../plugins/ux/public/application/ux_app.tsx | 5 +- 29 files changed, 173 insertions(+), 68 deletions(-) create mode 100644 src/plugins/kibana_react/public/dark_mode/index.ts create mode 100644 src/plugins/kibana_react/public/dark_mode/use_dark_mode.test.tsx create mode 100644 src/plugins/kibana_react/public/dark_mode/use_dark_mode.ts diff --git a/packages/kbn-guided-onboarding/src/components/landing_page/guide/guide_filters.tsx b/packages/kbn-guided-onboarding/src/components/landing_page/guide/guide_filters.tsx index 28314f7f08bf20..c5132cc1fd146d 100644 --- a/packages/kbn-guided-onboarding/src/components/landing_page/guide/guide_filters.tsx +++ b/packages/kbn-guided-onboarding/src/components/landing_page/guide/guide_filters.tsx @@ -69,6 +69,7 @@ export const GuideFilters = ({ <EuiButton onClick={onSelectFilter} data-filter-id="search" + data-test-subj="guide-filter-search" color="text" css={[filterButtonCss, activeFilter === 'search' && activeFilterFill]} > @@ -82,6 +83,7 @@ export const GuideFilters = ({ <EuiButton onClick={onSelectFilter} data-filter-id="observability" + data-test-subj="guide-filter-observability" color="text" css={[filterButtonCss, activeFilter === 'observability' && activeFilterFill]} > @@ -95,6 +97,7 @@ export const GuideFilters = ({ <EuiButton onClick={onSelectFilter} data-filter-id="security" + data-test-subj="guide-filter-security" color="text" css={[filterButtonCss, activeFilter === 'security' && activeFilterFill]} > diff --git a/src/plugins/home/public/application/components/home.tsx b/src/plugins/home/public/application/components/home.tsx index 176b620430a56b..a69f222c93e586 100644 --- a/src/plugins/home/public/application/components/home.tsx +++ b/src/plugins/home/public/application/components/home.tsx @@ -129,7 +129,7 @@ export class Home extends Component<HomeProps, State> { private renderNormal() { const { addBasePath, solutions, isCloudEnabled } = this.props; const { application, trackUiMetric } = getServices(); - const isDarkMode = getServices().uiSettings?.get('theme:darkMode') || false; + const isDarkMode = getServices().theme?.getTheme().darkMode ?? false; const devTools = this.findDirectoryById('console'); const manageDataFeatures = this.getFeaturesByCategory('admin'); diff --git a/src/plugins/home/public/application/components/sample_data/index.tsx b/src/plugins/home/public/application/components/sample_data/index.tsx index 316ba615ce8188..c1ebf4178186ef 100644 --- a/src/plugins/home/public/application/components/sample_data/index.tsx +++ b/src/plugins/home/public/application/components/sample_data/index.tsx @@ -29,7 +29,7 @@ interface Props { } export function SampleDataCard({ urlBasePath, onDecline, onConfirm }: Props) { - const IS_DARK_THEME = getServices().uiSettings.get('theme:darkMode'); + const IS_DARK_THEME = getServices().theme.getTheme().darkMode; const cardGraphicFile = !IS_DARK_THEME ? 'illustration_integrations_lightmode.png' : 'illustration_integrations_darkmode.png'; diff --git a/src/plugins/home/public/application/components/tutorial/instruction.js b/src/plugins/home/public/application/components/tutorial/instruction.js index 68360c86d2edeb..e1aaeae274fe02 100644 --- a/src/plugins/home/public/application/components/tutorial/instruction.js +++ b/src/plugins/home/public/application/components/tutorial/instruction.js @@ -24,7 +24,7 @@ export function Instruction({ variantId, isCloudEnabled, }) { - const { tutorialService, http, uiSettings, getBasePath, kibanaVersion } = getServices(); + const { tutorialService, http, theme, getBasePath, kibanaVersion } = getServices(); let pre; if (textPre) { @@ -67,6 +67,8 @@ export function Instruction({ ); } + const darkTheme = theme?.getTheme().darkMode ?? false; + return ( <div> {pre} @@ -78,7 +80,7 @@ export function Instruction({ <EuiErrorBoundary> <LazyCustomComponent basePath={getBasePath()} - isDarkTheme={uiSettings.get('theme:darkMode')} + isDarkTheme={darkTheme} http={http} variantId={variantId} isCloudEnabled={isCloudEnabled} diff --git a/src/plugins/input_control_vis/public/vis_controller.tsx b/src/plugins/input_control_vis/public/vis_controller.tsx index e13b29d41a6e9a..0bf6f0d0754a9f 100644 --- a/src/plugins/input_control_vis/public/vis_controller.tsx +++ b/src/plugins/input_control_vis/public/vis_controller.tsx @@ -61,7 +61,7 @@ export const createInputControlVisController = ( } }); - this.isDarkMode = deps.core.uiSettings.get('theme:darkMode'); + this.isDarkMode = deps.core.theme.getTheme().darkMode; } async render(visParams: InputControlVisParams) { diff --git a/src/plugins/kibana_react/public/dark_mode/index.ts b/src/plugins/kibana_react/public/dark_mode/index.ts new file mode 100644 index 00000000000000..8ec62fbeef6153 --- /dev/null +++ b/src/plugins/kibana_react/public/dark_mode/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { useDarkMode } from './use_dark_mode'; diff --git a/src/plugins/kibana_react/public/dark_mode/use_dark_mode.test.tsx b/src/plugins/kibana_react/public/dark_mode/use_dark_mode.test.tsx new file mode 100644 index 00000000000000..7308207c817778 --- /dev/null +++ b/src/plugins/kibana_react/public/dark_mode/use_dark_mode.test.tsx @@ -0,0 +1,81 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { act } from 'react-dom/test-utils'; +import { useDarkMode } from './use_dark_mode'; +import { createKibanaReactContext } from '../context'; +import { KibanaServices } from '../context/types'; +import { BehaviorSubject } from 'rxjs'; +import { CoreTheme } from '@kbn/core/public'; +import { coreMock } from '@kbn/core/public/mocks'; + +describe('useDarkMode', () => { + let container: HTMLDivElement | null; + + beforeEach(() => { + container = document.createElement('div'); + document.body.appendChild(container); + }); + + afterEach(() => { + document.body.removeChild(container!); + container = null; + }); + + const TestConsumer: React.FC = () => { + const darkMode = useDarkMode(); + return <div>{String(darkMode)}</div>; + }; + + const mock = (): [KibanaServices, BehaviorSubject<CoreTheme>] => { + const core = coreMock.createStart(); + const subject = new BehaviorSubject<CoreTheme>({ darkMode: false }); + core.theme.theme$ = subject.asObservable(); + + return [core, subject]; + }; + + test('returns the value from the theme', () => { + const [core] = mock(); + const { Provider } = createKibanaReactContext(core); + + ReactDOM.render( + <Provider> + <TestConsumer /> + </Provider>, + container + ); + + const div = container!.querySelector('div'); + expect(div!.textContent).toBe('false'); + }); + + test('value changes if the theme changes', () => { + const [core, subject] = mock(); + const { Provider } = createKibanaReactContext(core); + + ReactDOM.render( + <Provider> + <TestConsumer /> + </Provider>, + container + ); + + let div = container!.querySelector('div'); + expect(div!.textContent).toBe('false'); + + act(() => { + subject.next({ darkMode: true }); + }); + + div = container!.querySelector('div'); + expect(div!.textContent).toBe('true'); + }); +}); diff --git a/src/plugins/kibana_react/public/dark_mode/use_dark_mode.ts b/src/plugins/kibana_react/public/dark_mode/use_dark_mode.ts new file mode 100644 index 00000000000000..c53a7b8687aad6 --- /dev/null +++ b/src/plugins/kibana_react/public/dark_mode/use_dark_mode.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import useObservable from 'react-use/lib/useObservable'; +import { useKibana } from '../context'; + +export const useDarkMode = (defaultValue?: boolean): boolean => { + const { + services: { theme }, + } = useKibana(); + + if (!theme) { + if (defaultValue !== undefined) { + return defaultValue; + } + throw new TypeError('theme service not available in kibana-react context.'); + } + + const currentTheme = useObservable(theme.theme$, theme.getTheme()); + return currentTheme.darkMode; +}; diff --git a/src/plugins/kibana_react/public/index.ts b/src/plugins/kibana_react/public/index.ts index 05abdbd84e91c6..5b4e8a9bcbae0c 100644 --- a/src/plugins/kibana_react/public/index.ts +++ b/src/plugins/kibana_react/public/index.ts @@ -42,6 +42,8 @@ export { useGlobalUiSetting$, } from './ui_settings'; +export { useDarkMode } from './dark_mode'; + export { useExecutionContext } from './use_execution_context'; export { reactRouterNavigate, reactRouterOnClickHandler } from './react_router_navigate'; @@ -79,6 +81,7 @@ export { KibanaThemeProvider, wrapWithTheme, type KibanaThemeProviderProps } fro export function plugin() { return new (class KibanaReactPlugin { setup() {} + start() {} })(); } diff --git a/x-pack/plugins/alerting/public/application/maintenance_windows.tsx b/x-pack/plugins/alerting/public/application/maintenance_windows.tsx index 6bbe3a080943e7..bb2ba1847abac3 100644 --- a/x-pack/plugins/alerting/public/application/maintenance_windows.tsx +++ b/x-pack/plugins/alerting/public/application/maintenance_windows.tsx @@ -78,7 +78,7 @@ export const renderApp = ({ }) => { const { element, history, theme$ } = mountParams; const i18nCore = core.i18n; - const isDarkMode = core.uiSettings.get('theme:darkMode'); + const isDarkMode = core.theme.getTheme().darkMode; const queryClient = new QueryClient(); diff --git a/x-pack/plugins/apm/public/components/routing/app_root/index.tsx b/x-pack/plugins/apm/public/components/routing/app_root/index.tsx index 85df672363ce16..ea1440c91706c3 100644 --- a/x-pack/plugins/apm/public/components/routing/app_root/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/app_root/index.tsx @@ -8,7 +8,7 @@ import { APP_WRAPPER_CLASS } from '@kbn/core/public'; import { KibanaContextProvider, - useUiSetting$, + useDarkMode, } from '@kbn/kibana-react-plugin/public'; import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app'; import { Storage } from '@kbn/kibana-utils-plugin/public'; @@ -132,7 +132,7 @@ function MountApmHeaderActionMenu() { } export function ApmThemeProvider({ children }: { children: React.ReactNode }) { - const [darkMode] = useUiSetting$<boolean>('theme:darkMode'); + const darkMode = useDarkMode(false); return ( <ThemeProvider diff --git a/x-pack/plugins/exploratory_view/public/application/index.tsx b/x-pack/plugins/exploratory_view/public/application/index.tsx index f3189e7cf660b4..d496af2b23fb95 100644 --- a/x-pack/plugins/exploratory_view/public/application/index.tsx +++ b/x-pack/plugins/exploratory_view/public/application/index.tsx @@ -52,7 +52,7 @@ export const renderApp = ({ }) => { const { element, history, theme$ } = appMountParameters; const i18nCore = core.i18n; - const isDarkMode = core.uiSettings.get('theme:darkMode'); + const isDarkMode = core.theme.getTheme().darkMode; core.chrome.setHelpExtension({ appName: i18n.translate('xpack.exploratoryView.feedbackMenu.appName', { diff --git a/x-pack/plugins/exploratory_view/public/components/shared/exploratory_view/embeddable/index.tsx b/x-pack/plugins/exploratory_view/public/components/shared/exploratory_view/embeddable/index.tsx index d5cb78b84f6428..8fe530c0b5bdf3 100644 --- a/x-pack/plugins/exploratory_view/public/components/shared/exploratory_view/embeddable/index.tsx +++ b/x-pack/plugins/exploratory_view/public/components/shared/exploratory_view/embeddable/index.tsx @@ -33,7 +33,7 @@ function ExploratoryViewEmbeddable(props: ExploratoryEmbeddableComponentProps) { export function getExploratoryViewEmbeddable( services: CoreStart & ExploratoryViewPublicPluginsStart ) { - const { lens, dataViews: dataViewsService, uiSettings } = services; + const { lens, dataViews: dataViewsService, theme } = services; const dataViewCache: Record<string, DataView> = {}; @@ -70,7 +70,7 @@ export function getExploratoryViewEmbeddable( const series = attributes[0]; - const isDarkMode = uiSettings?.get('theme:darkMode'); + const isDarkMode = theme?.getTheme().darkMode ?? false; const { data: lensHelper, loading: lensLoading } = useFetcher(async () => { if (lenStateHelperPromise) { diff --git a/x-pack/plugins/kubernetes_security/public/test/index.tsx b/x-pack/plugins/kubernetes_security/public/test/index.tsx index 1ca31c8e0baf00..a267169e6cf18a 100644 --- a/x-pack/plugins/kubernetes_security/public/test/index.tsx +++ b/x-pack/plugins/kubernetes_security/public/test/index.tsx @@ -11,7 +11,6 @@ import { render as reactRender, RenderOptions, RenderResult } from '@testing-lib import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { Router } from '@kbn/shared-ux-router'; import { History } from 'history'; -import useObservable from 'react-use/lib/useObservable'; import { I18nProvider } from '@kbn/i18n-react'; import { CoreStart } from '@kbn/core/public'; import { coreMock } from '@kbn/core/public/mocks'; @@ -65,8 +64,8 @@ const AppRootProvider = memo<{ history: History; coreStart: CoreStart; children: ReactNode | ReactNode[]; -}>(({ history, coreStart: { http, notifications, uiSettings, application }, children }) => { - const isDarkMode = useObservable<boolean>(uiSettings.get$('theme:darkMode')); +}>(({ history, coreStart: { http, notifications, theme, application }, children }) => { + const isDarkMode = useMemo(() => theme.getTheme().darkMode, [theme]); const services = useMemo( () => ({ http, notifications, application }), [application, http, notifications] diff --git a/x-pack/plugins/monitoring/public/application/index.tsx b/x-pack/plugins/monitoring/public/application/index.tsx index f34cde08370500..b9fd25f60c3675 100644 --- a/x-pack/plugins/monitoring/public/application/index.tsx +++ b/x-pack/plugins/monitoring/public/application/index.tsx @@ -8,11 +8,10 @@ import { AppMountParameters, CoreStart, CoreTheme, MountPoint } from '@kbn/core/public'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; -import React, { useMemo } from 'react'; +import React from 'react'; import ReactDOM from 'react-dom'; import { Redirect } from 'react-router-dom'; import { Router, Routes, Route } from '@kbn/shared-ux-router'; -import useObservable from 'react-use/lib/useObservable'; import { Observable } from 'rxjs'; import { CODE_PATH_APM, @@ -100,12 +99,7 @@ const MonitoringApp: React.FC<{ theme$: Observable<CoreTheme>; }> = ({ core, plugins, externalConfig, setHeaderActionMenu, theme$ }) => { const history = createPreserveQueryHistory(); - - const darkModeObservable: Observable<boolean> = useMemo( - () => core.uiSettings!.get$('theme:darkMode'), - [core.uiSettings] - ); - const darkMode = useObservable(darkModeObservable, core.uiSettings!.get('theme:darkMode')); + const darkMode = core.theme.getTheme().darkMode; return ( <KibanaContextProvider services={{ ...core, ...plugins }}> diff --git a/x-pack/plugins/observability/public/application/index.tsx b/x-pack/plugins/observability/public/application/index.tsx index 7b01bc1f8eeb1d..23a0952ed91db4 100644 --- a/x-pack/plugins/observability/public/application/index.tsx +++ b/x-pack/plugins/observability/public/application/index.tsx @@ -67,7 +67,7 @@ export const renderApp = ({ }) => { const { element, history, theme$ } = appMountParameters; const i18nCore = core.i18n; - const isDarkMode = core.uiSettings.get('theme:darkMode'); + const isDarkMode = core.theme.getTheme().darkMode; core.chrome.setHelpExtension({ appName: i18n.translate('xpack.observability.feedbackMenu.appName', { diff --git a/x-pack/plugins/observability/public/components/custom_threshold/components/expression_chart.tsx b/x-pack/plugins/observability/public/components/custom_threshold/components/expression_chart.tsx index 010642acdf551f..fb90056b5193e6 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/components/expression_chart.tsx +++ b/x-pack/plugins/observability/public/components/custom_threshold/components/expression_chart.tsx @@ -67,7 +67,7 @@ export function ExpressionChart({ timeRange, timeFieldName, }: Props) { - const { charts, uiSettings } = useKibana().services; + const { charts, uiSettings, theme } = useKibana().services; const { isLoading, data } = useExpressionChartData( expression, derivedIndexPattern, @@ -90,7 +90,7 @@ export function ExpressionChart({ return <NoDataState />; } - const isDarkMode = uiSettings?.get('theme:darkMode') || false; + const isDarkMode = theme?.getTheme().darkMode ?? false; const firstSeries = first(first(data.pages)!.series); // Creating a custom series where the ID is changed to 0 // so that we can get a proper domain diff --git a/x-pack/plugins/observability/public/pages/overview/components/sections/ux/core_web_vitals/palette_legends.tsx b/x-pack/plugins/observability/public/pages/overview/components/sections/ux/core_web_vitals/palette_legends.tsx index 1887f203200854..20f7d47e08d23c 100644 --- a/x-pack/plugins/observability/public/pages/overview/components/sections/ux/core_web_vitals/palette_legends.tsx +++ b/x-pack/plugins/observability/public/pages/overview/components/sections/ux/core_web_vitals/palette_legends.tsx @@ -17,7 +17,7 @@ import { import styled from 'styled-components'; import { FormattedMessage } from '@kbn/i18n-react'; import { euiLightVars, euiDarkVars } from '@kbn/ui-theme'; -import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; +import { useDarkMode } from '@kbn/kibana-react-plugin/public'; import { getCoreVitalTooltipMessage, Thresholds } from './core_vital_item'; import { LEGEND_NEEDS_IMPROVEMENT_LABEL, @@ -50,8 +50,7 @@ interface Props { } export function PaletteLegends({ ranks, title, onItemHover, thresholds, isCls }: Props) { - const [darkMode] = useUiSetting$<boolean>('theme:darkMode'); - + const darkMode = useDarkMode(false); const palette = euiPaletteForStatus(3); const labels = [LEGEND_GOOD_LABEL, LEGEND_NEEDS_IMPROVEMENT_LABEL, LEGEND_POOR_LABEL]; diff --git a/x-pack/plugins/observability_onboarding/e2e/cypress/e2e/home.cy.ts b/x-pack/plugins/observability_onboarding/e2e/cypress/e2e/home.cy.ts index 8c7d433f48a4da..3c1e123b494526 100644 --- a/x-pack/plugins/observability_onboarding/e2e/cypress/e2e/home.cy.ts +++ b/x-pack/plugins/observability_onboarding/e2e/cypress/e2e/home.cy.ts @@ -13,6 +13,7 @@ describe('[Observability onboarding] Landing page', () => { describe('Entry point', () => { it('when clicking on the logs card the user is navigated to the observability onboarding page', () => { cy.getByTestSubj('guideButtonRedirect').click(); + cy.getByTestSubj('guide-filter-observability').click(); cy.getByTestSubj('onboarding--observability--logs').click(); cy.url().should('include', '/app/observabilityOnboarding'); diff --git a/x-pack/plugins/observability_onboarding/public/application/app.tsx b/x-pack/plugins/observability_onboarding/public/application/app.tsx index 6142f7acd45cb3..7a6143c9954cb1 100644 --- a/x-pack/plugins/observability_onboarding/public/application/app.tsx +++ b/x-pack/plugins/observability_onboarding/public/application/app.tsx @@ -16,7 +16,7 @@ import { i18n } from '@kbn/i18n'; import { KibanaContextProvider, KibanaThemeProvider, - useUiSetting$, + useDarkMode, } from '@kbn/kibana-react-plugin/public'; import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app'; import { HeaderMenuPortal } from '@kbn/observability-shared-plugin/public'; @@ -112,8 +112,7 @@ function App() { } function ObservabilityOnboardingApp() { - const [darkMode] = useUiSetting$<boolean>('theme:darkMode'); - + const darkMode = useDarkMode(false); return ( <ThemeProvider theme={(outerTheme?: Theme) => ({ diff --git a/x-pack/plugins/session_view/public/test/index.tsx b/x-pack/plugins/session_view/public/test/index.tsx index 277917e44ccafc..23f5fe8b25ce1c 100644 --- a/x-pack/plugins/session_view/public/test/index.tsx +++ b/x-pack/plugins/session_view/public/test/index.tsx @@ -11,7 +11,6 @@ import { render as reactRender, RenderOptions, RenderResult } from '@testing-lib import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { Router } from '@kbn/shared-ux-router'; import { History } from 'history'; -import useObservable from 'react-use/lib/useObservable'; import { I18nProvider } from '@kbn/i18n-react'; import { CoreStart } from '@kbn/core/public'; import { coreMock } from '@kbn/core/public/mocks'; @@ -68,8 +67,8 @@ const AppRootProvider = memo<{ history: History; coreStart: CoreStart; children: ReactNode | ReactNode[]; -}>(({ history, coreStart: { http, notifications, uiSettings, application }, children }) => { - const isDarkMode = useObservable<boolean>(uiSettings.get$('theme:darkMode')); +}>(({ history, coreStart: { http, notifications, theme, application }, children }) => { + const isDarkMode = theme.getTheme().darkMode; const services = useMemo( () => ({ http, notifications, application }), [application, http, notifications] diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/render_app.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/render_app.tsx index 23e82f6f2c6dc8..d7f3b79ef53cbc 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/render_app.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/render_app.tsx @@ -11,11 +11,7 @@ import { i18n as i18nFormatter } from '@kbn/i18n'; import { AppMountParameters, CoreStart } from '@kbn/core/public'; import { SyntheticsAppProps } from './contexts'; import { getIntegratedAppAvailability } from './utils/adapters'; -import { - DEFAULT_DARK_MODE, - DEFAULT_TIMEPICKER_QUICK_RANGES, - INTEGRATED_SOLUTIONS, -} from '../../../common/constants'; +import { DEFAULT_TIMEPICKER_QUICK_RANGES, INTEGRATED_SOLUTIONS } from '../../../common/constants'; import { SyntheticsApp } from './synthetics_app'; import { ClientPluginsSetup, ClientPluginsStart } from '../../plugin'; @@ -32,6 +28,7 @@ export function renderApp( docLinks, http: { basePath }, i18n, + theme, } = core; const { apm, infrastructure, logs } = getIntegratedAppAvailability( @@ -40,6 +37,7 @@ export function renderApp( ); const canSave = (capabilities.uptime.save ?? false) as boolean; // TODO: Determine for synthetics + const darkMode = theme.getTheme().darkMode; const props: SyntheticsAppProps = { isDev, @@ -49,7 +47,7 @@ export function renderApp( i18n, startPlugins, basePath: basePath.get(), - darkMode: core.uiSettings.get(DEFAULT_DARK_MODE), + darkMode, commonlyUsedRanges: core.uiSettings.get(DEFAULT_TIMEPICKER_QUICK_RANGES), isApmAvailable: apm, isInfraAvailable: infrastructure, diff --git a/x-pack/plugins/synthetics/public/hooks/use_base_chart_theme.ts b/x-pack/plugins/synthetics/public/hooks/use_base_chart_theme.ts index be10a050905e6a..413081b998aecf 100644 --- a/x-pack/plugins/synthetics/public/hooks/use_base_chart_theme.ts +++ b/x-pack/plugins/synthetics/public/hooks/use_base_chart_theme.ts @@ -7,10 +7,11 @@ import { DARK_THEME, LIGHT_THEME, Theme } from '@elastic/charts'; import { useMemo } from 'react'; -import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; +import { useDarkMode } from '@kbn/kibana-react-plugin/public'; export const useBaseChartTheme = (): Theme => { - const [darkMode] = useUiSetting$<boolean>('theme:darkMode'); + const darkMode = useDarkMode(false); + return useMemo(() => { return darkMode ? DARK_THEME : LIGHT_THEME; }, [darkMode]); diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/cell_renderer.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/cell_renderer.tsx index 520a9d69c4f2a5..6ac03f591eb5fa 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/cell_renderer.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/table/cell_renderer.tsx @@ -8,8 +8,8 @@ import { EuiDataGridCellValueElementProps } from '@elastic/eui'; import React, { useContext, useEffect } from 'react'; import { euiDarkVars as themeDark, euiLightVars as themeLight } from '@kbn/ui-theme'; +import { useDarkMode } from '@kbn/kibana-react-plugin/public'; import { useStyles } from './styles'; -import { useKibana } from '../../../../hooks/use_kibana'; import { Indicator } from '../../../../../common/types/indicator'; import { IndicatorFieldValue } from '../common/field_value'; import { IndicatorsTableContext } from '../../hooks/use_table_context'; @@ -25,11 +25,7 @@ export const cellRendererFactory = (from: number) => { throw new Error('this can only be used inside indicators table'); } - const { - services: { uiSettings }, - } = useKibana(); - - const darkMode = uiSettings.get('theme:darkMode'); + const darkMode = useDarkMode(); const { indicators, expanded } = indicatorsTableContext; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/app.tsx b/x-pack/plugins/triggers_actions_ui/public/application/app.tsx index 62eaf684e97dad..585f65954254ae 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/app.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/app.tsx @@ -11,7 +11,6 @@ import { Router, Routes, Route } from '@kbn/shared-ux-router'; import { ChromeBreadcrumb, CoreStart, CoreTheme, ScopedHistory } from '@kbn/core/public'; import { render, unmountComponentAtNode } from 'react-dom'; import { I18nProvider } from '@kbn/i18n-react'; -import useObservable from 'react-use/lib/useObservable'; import { Observable } from 'rxjs'; import { KibanaFeature } from '@kbn/features-plugin/common'; import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; @@ -86,17 +85,17 @@ export const renderApp = (deps: TriggersAndActionsUiServices) => { }; export const App = ({ deps }: { deps: TriggersAndActionsUiServices }) => { - const { dataViews, uiSettings, theme$ } = deps; + const { dataViews, theme } = deps; const sections: Section[] = ['rules', 'logs', 'alerts']; - const isDarkMode = useObservable<boolean>(uiSettings.get$('theme:darkMode')); + const isDarkMode = theme.getTheme().darkMode; const sectionsRegex = sections.join('|'); setDataViewsService(dataViews); return ( <I18nProvider> <EuiThemeProvider darkMode={isDarkMode}> - <KibanaThemeProvider theme$={theme$}> - <KibanaContextProvider services={{ ...deps, theme: { theme$ } }}> + <KibanaThemeProvider theme$={theme.theme$}> + <KibanaContextProvider services={{ ...deps }}> <Router history={deps.history}> <QueryClientProvider client={queryClient}> <AppWithoutRouter sectionsRegex={sectionsRegex} /> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/connectors_app.tsx b/x-pack/plugins/triggers_actions_ui/public/application/connectors_app.tsx index 876c8a26b00ec7..089908dcbbdbcc 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/connectors_app.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/connectors_app.tsx @@ -11,7 +11,6 @@ import { Router, Routes, Route } from '@kbn/shared-ux-router'; import { ChromeBreadcrumb, CoreStart, CoreTheme, ScopedHistory } from '@kbn/core/public'; import { render, unmountComponentAtNode } from 'react-dom'; import { I18nProvider } from '@kbn/i18n-react'; -import useObservable from 'react-use/lib/useObservable'; import { Observable } from 'rxjs'; import { KibanaFeature } from '@kbn/features-plugin/common'; import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; @@ -74,8 +73,8 @@ export const renderApp = (deps: TriggersAndActionsUiServices) => { }; export const App = ({ deps }: { deps: TriggersAndActionsUiServices }) => { - const { dataViews, uiSettings, theme$ } = deps; - const isDarkMode = useObservable<boolean>(uiSettings.get$('theme:darkMode')); + const { dataViews, theme } = deps; + const isDarkMode = theme.getTheme().darkMode; const sections: Section[] = ['connectors', 'logs']; const sectionsRegex = sections.join('|'); @@ -83,7 +82,7 @@ export const App = ({ deps }: { deps: TriggersAndActionsUiServices }) => { return ( <I18nProvider> <EuiThemeProvider darkMode={isDarkMode}> - <KibanaThemeProvider theme$={theme$}> + <KibanaThemeProvider theme$={theme.theme$}> <KibanaContextProvider services={{ ...deps }}> <Router history={deps.history}> <AppWithoutRouter sectionsRegex={sectionsRegex} /> diff --git a/x-pack/plugins/uptime/public/legacy_uptime/app/render_app.tsx b/x-pack/plugins/uptime/public/legacy_uptime/app/render_app.tsx index d0c6a2f550e4eb..1a9d5aac398abe 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/app/render_app.tsx +++ b/x-pack/plugins/uptime/public/legacy_uptime/app/render_app.tsx @@ -10,11 +10,7 @@ import ReactDOM from 'react-dom'; import { i18n as i18nFormatter } from '@kbn/i18n'; import { AppMountParameters, CoreStart } from '@kbn/core/public'; import { getIntegratedAppAvailability } from '../lib/adapters/framework/capabilities_adapter'; -import { - DEFAULT_DARK_MODE, - DEFAULT_TIMEPICKER_QUICK_RANGES, - INTEGRATED_SOLUTIONS, -} from '../../../common/constants'; +import { DEFAULT_TIMEPICKER_QUICK_RANGES, INTEGRATED_SOLUTIONS } from '../../../common/constants'; import { UptimeApp, UptimeAppProps } from './uptime_app'; import { ClientPluginsSetup, ClientPluginsStart } from '../../plugin'; @@ -31,6 +27,7 @@ export function renderApp( docLinks, http: { basePath }, i18n, + theme, } = core; const { apm, infrastructure, logs } = getIntegratedAppAvailability( @@ -39,6 +36,7 @@ export function renderApp( ); const canSave = (capabilities.uptime.save ?? false) as boolean; + const darkMode = theme.getTheme().darkMode; const props: UptimeAppProps = { isDev, @@ -48,7 +46,7 @@ export function renderApp( i18n, startPlugins, basePath: basePath.get(), - darkMode: core.uiSettings.get(DEFAULT_DARK_MODE), + darkMode, commonlyUsedRanges: core.uiSettings.get(DEFAULT_TIMEPICKER_QUICK_RANGES), isApmAvailable: apm, isInfraAvailable: infrastructure, diff --git a/x-pack/plugins/uptime/public/legacy_uptime/hooks/use_base_chart_theme.ts b/x-pack/plugins/uptime/public/legacy_uptime/hooks/use_base_chart_theme.ts index f8cb8dfd4134f9..007d463c63e1b0 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/hooks/use_base_chart_theme.ts +++ b/x-pack/plugins/uptime/public/legacy_uptime/hooks/use_base_chart_theme.ts @@ -6,11 +6,11 @@ */ import { useMemo } from 'react'; -import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; +import { useDarkMode } from '@kbn/kibana-react-plugin/public'; import { DARK_THEME, LIGHT_THEME, Theme } from '@elastic/charts'; export const useBaseChartTheme = (): Theme => { - const [darkMode] = useUiSetting$<boolean>('theme:darkMode'); + const darkMode = useDarkMode(); return useMemo(() => { return darkMode ? DARK_THEME : LIGHT_THEME; }, [darkMode]); diff --git a/x-pack/plugins/ux/public/application/ux_app.tsx b/x-pack/plugins/ux/public/application/ux_app.tsx index aae803dec162a5..e8fdbb96b5e7ba 100644 --- a/x-pack/plugins/ux/public/application/ux_app.tsx +++ b/x-pack/plugins/ux/public/application/ux_app.tsx @@ -23,7 +23,7 @@ import { import { KibanaContextProvider, KibanaThemeProvider, - useUiSetting$, + useDarkMode, } from '@kbn/kibana-react-plugin/public'; import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app'; @@ -66,10 +66,9 @@ export const uxRoutes: RouteDefinition[] = [ ]; function UxApp() { - const [darkMode] = useUiSetting$<boolean>('theme:darkMode'); - const { http } = useKibanaServices(); const basePath = http.basePath.get(); + const darkMode = useDarkMode(false); useBreadcrumbs([ { From 229e7eff0c982608c13692f959dd8c9d3a0da128 Mon Sep 17 00:00:00 2001 From: Jon <jon@elastic.co> Date: Thu, 21 Dec 2023 12:09:43 -0600 Subject: [PATCH 089/116] [ci] Remove jenkins config (#173745) We've migrated off and shut down our instance. These files are no longer needed. --- .buildkite/pull_requests.json | 10 +- .ci/Dockerfile | 38 -- .ci/Jenkinsfile_baseline_capture | 48 -- .ci/Jenkinsfile_baseline_trigger | 72 --- .ci/Jenkinsfile_flaky | 150 ------ .ci/Jenkinsfile_security_cypress | 31 -- .ci/build_docker.sh | 14 - .ci/ci_groups.yml | 46 -- .ci/es-snapshots/Jenkinsfile_build_es | 165 ------ .ci/es-snapshots/Jenkinsfile_trigger_build_es | 16 - .ci/es-snapshots/Jenkinsfile_verify_es | 61 --- .ci/packer_cache.sh | 11 - .ci/packer_cache_for_branch.sh | 68 --- .ci/pipeline-library/README.md | 8 - .ci/pipeline-library/build.gradle | 46 -- .../gradle/wrapper/gradle-wrapper.jar | Bin 58910 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - .ci/pipeline-library/gradlew | 185 ------- .ci/pipeline-library/gradlew.bat | 104 ---- .../src/test/KibanaBasePipelineTest.groovy | 113 ---- .../src/test/buildState.groovy | 48 -- .../src/test/githubCommitStatus.groovy | 87 --- .../src/test/prChanges.groovy | 113 ---- .../src/test/slackNotifications.groovy | 185 ------- .ci/pipeline-library/vars | 1 - .ci/runbld_no_junit.yml | 6 - Jenkinsfile | 26 - dev_docs/contributing/code_walkthrough.mdx | 3 - .../development-functional-tests.asciidoc | 3 +- .../developer/contributing/pr-review.asciidoc | 2 +- src/dev/ci_setup/checkout_sibling_es.sh | 118 ----- src/dev/ci_setup/extract_bootstrap_cache.sh | 31 -- src/dev/ci_setup/get_percy_env.js | 45 -- src/dev/ci_setup/load_env_keys.sh | 39 -- src/dev/ci_setup/setup.sh | 35 -- src/dev/ci_setup/setup_env.sh | 172 ------ src/dev/ci_setup/setup_percy.sh | 19 - src/dev/precommit_hook/casing_check_config.js | 1 - src/dev/storybook/aliases.ts | 2 +- .../checks/baseline_plugin_public_api_docs.sh | 9 - test/scripts/checks/bundle_limits.sh | 5 - test/scripts/checks/commit/commit.sh | 10 - .../checks/commit/commit_check_runner.sh | 13 - test/scripts/checks/file_casing.sh | 5 - test/scripts/checks/i18n.sh | 5 - test/scripts/checks/jest_configs.sh | 5 - test/scripts/checks/licenses.sh | 5 - test/scripts/checks/plugin_list_docs.sh | 19 - test/scripts/checks/telemetry.sh | 5 - test/scripts/checks/test_hardening.sh | 5 - test/scripts/checks/test_projects.sh | 5 - test/scripts/checks/ts_projects.sh | 5 - .../type_check_plugin_public_api_docs.sh | 13 - test/scripts/checks/verify_notice.sh | 5 - test/scripts/jenkins_accessibility.sh | 8 - test/scripts/jenkins_apm_cypress.sh | 11 - .../jenkins_build_kbn_sample_panel_action.sh | 9 - test/scripts/jenkins_build_kibana.sh | 42 -- test/scripts/jenkins_build_load_testing.sh | 93 ---- test/scripts/jenkins_build_plugins.sh | 23 - test/scripts/jenkins_ci_group.sh | 38 -- test/scripts/jenkins_cloud.sh | 26 - test/scripts/jenkins_firefox_smoke.sh | 9 - test/scripts/jenkins_fleet_cypress.sh | 12 - test/scripts/jenkins_osquery_cypress.sh | 14 - test/scripts/jenkins_plugin_functional.sh | 15 - test/scripts/jenkins_runbld_junit.sh | 2 - ...enkins_security_solution_cypress_chrome.sh | 14 - test/scripts/jenkins_setup.sh | 6 - .../jenkins_setup_parallel_workspace.sh | 32 -- test/scripts/jenkins_storybook.sh | 33 -- test/scripts/jenkins_test_setup.sh | 22 - test/scripts/jenkins_test_setup_oss.sh | 14 - test/scripts/jenkins_test_setup_xpack.sh | 16 - test/scripts/jenkins_uptime_playwright.sh | 11 - test/scripts/jenkins_ux_synthetics.sh | 11 - test/scripts/jenkins_xpack_accessibility.sh | 8 - test/scripts/jenkins_xpack_baseline.sh | 24 - test/scripts/jenkins_xpack_build_plugins.sh | 19 - test/scripts/jenkins_xpack_ci_group.sh | 34 -- test/scripts/jenkins_xpack_firefox_smoke.sh | 10 - ...nkins_xpack_saved_objects_field_metrics.sh | 8 - test/scripts/lint/eslint.sh | 5 - test/scripts/lint/stylelint.sh | 5 - test/scripts/test/api_integration.sh | 8 - test/scripts/test/health_gateway.sh | 9 - test/scripts/test/interpreter_functional.sh | 9 - test/scripts/test/jest_integration.sh | 5 - test/scripts/test/jest_unit.sh | 5 - test/scripts/test/plugin_functional.sh | 8 - test/scripts/test/server_integration.sh | 19 - vars/agentInfo.groovy | 40 -- vars/buildState.groovy | 30 -- vars/catchErrors.groovy | 15 - vars/esSnapshots.groovy | 50 -- vars/getCheckoutInfo.groovy | 50 -- vars/githubCommitStatus.groovy | 57 -- vars/githubPr.groovy | 369 ------------- vars/jenkinsApi.groovy | 21 - vars/kibanaPipeline.groovy | 496 ------------------ vars/prChanges.groovy | 82 --- vars/retryWithDelay.groovy | 18 - vars/retryable.groovy | 78 --- vars/runbld.groovy | 17 - vars/slackNotifications.groovy | 228 -------- vars/storybooks.groovy | 83 --- vars/task.groovy | 5 - vars/tasks.groovy | 201 ------- vars/whenChanged.groovy | 57 -- vars/withGithubCredentials.groovy | 9 - vars/withTaskQueue.groovy | 154 ------ vars/workers.groovy | 206 -------- .../apps/maps/group1/sample_data.js | 2 +- 113 files changed, 6 insertions(+), 5140 deletions(-) delete mode 100644 .ci/Dockerfile delete mode 100644 .ci/Jenkinsfile_baseline_capture delete mode 100644 .ci/Jenkinsfile_baseline_trigger delete mode 100644 .ci/Jenkinsfile_flaky delete mode 100644 .ci/Jenkinsfile_security_cypress delete mode 100755 .ci/build_docker.sh delete mode 100644 .ci/ci_groups.yml delete mode 100644 .ci/es-snapshots/Jenkinsfile_build_es delete mode 100644 .ci/es-snapshots/Jenkinsfile_trigger_build_es delete mode 100644 .ci/es-snapshots/Jenkinsfile_verify_es delete mode 100755 .ci/packer_cache.sh delete mode 100755 .ci/packer_cache_for_branch.sh delete mode 100644 .ci/pipeline-library/README.md delete mode 100644 .ci/pipeline-library/build.gradle delete mode 100644 .ci/pipeline-library/gradle/wrapper/gradle-wrapper.jar delete mode 100644 .ci/pipeline-library/gradle/wrapper/gradle-wrapper.properties delete mode 100755 .ci/pipeline-library/gradlew delete mode 100644 .ci/pipeline-library/gradlew.bat delete mode 100644 .ci/pipeline-library/src/test/KibanaBasePipelineTest.groovy delete mode 100644 .ci/pipeline-library/src/test/buildState.groovy delete mode 100644 .ci/pipeline-library/src/test/githubCommitStatus.groovy delete mode 100644 .ci/pipeline-library/src/test/prChanges.groovy delete mode 100644 .ci/pipeline-library/src/test/slackNotifications.groovy delete mode 120000 .ci/pipeline-library/vars delete mode 100644 .ci/runbld_no_junit.yml delete mode 100644 Jenkinsfile delete mode 100755 src/dev/ci_setup/checkout_sibling_es.sh delete mode 100755 src/dev/ci_setup/extract_bootstrap_cache.sh delete mode 100644 src/dev/ci_setup/get_percy_env.js delete mode 100644 src/dev/ci_setup/load_env_keys.sh delete mode 100755 src/dev/ci_setup/setup.sh delete mode 100644 src/dev/ci_setup/setup_env.sh delete mode 100755 src/dev/ci_setup/setup_percy.sh delete mode 100755 test/scripts/checks/baseline_plugin_public_api_docs.sh delete mode 100755 test/scripts/checks/bundle_limits.sh delete mode 100755 test/scripts/checks/commit/commit.sh delete mode 100755 test/scripts/checks/commit/commit_check_runner.sh delete mode 100755 test/scripts/checks/file_casing.sh delete mode 100755 test/scripts/checks/i18n.sh delete mode 100755 test/scripts/checks/jest_configs.sh delete mode 100755 test/scripts/checks/licenses.sh delete mode 100644 test/scripts/checks/plugin_list_docs.sh delete mode 100755 test/scripts/checks/telemetry.sh delete mode 100755 test/scripts/checks/test_hardening.sh delete mode 100755 test/scripts/checks/test_projects.sh delete mode 100755 test/scripts/checks/ts_projects.sh delete mode 100755 test/scripts/checks/type_check_plugin_public_api_docs.sh delete mode 100755 test/scripts/checks/verify_notice.sh delete mode 100755 test/scripts/jenkins_accessibility.sh delete mode 100755 test/scripts/jenkins_apm_cypress.sh delete mode 100755 test/scripts/jenkins_build_kbn_sample_panel_action.sh delete mode 100755 test/scripts/jenkins_build_kibana.sh delete mode 100755 test/scripts/jenkins_build_load_testing.sh delete mode 100755 test/scripts/jenkins_build_plugins.sh delete mode 100755 test/scripts/jenkins_ci_group.sh delete mode 100755 test/scripts/jenkins_cloud.sh delete mode 100755 test/scripts/jenkins_firefox_smoke.sh delete mode 100755 test/scripts/jenkins_fleet_cypress.sh delete mode 100755 test/scripts/jenkins_osquery_cypress.sh delete mode 100755 test/scripts/jenkins_plugin_functional.sh delete mode 100755 test/scripts/jenkins_runbld_junit.sh delete mode 100755 test/scripts/jenkins_security_solution_cypress_chrome.sh delete mode 100755 test/scripts/jenkins_setup.sh delete mode 100755 test/scripts/jenkins_setup_parallel_workspace.sh delete mode 100755 test/scripts/jenkins_storybook.sh delete mode 100755 test/scripts/jenkins_test_setup.sh delete mode 100755 test/scripts/jenkins_test_setup_oss.sh delete mode 100755 test/scripts/jenkins_test_setup_xpack.sh delete mode 100755 test/scripts/jenkins_uptime_playwright.sh delete mode 100755 test/scripts/jenkins_ux_synthetics.sh delete mode 100755 test/scripts/jenkins_xpack_accessibility.sh delete mode 100755 test/scripts/jenkins_xpack_baseline.sh delete mode 100755 test/scripts/jenkins_xpack_build_plugins.sh delete mode 100755 test/scripts/jenkins_xpack_ci_group.sh delete mode 100755 test/scripts/jenkins_xpack_firefox_smoke.sh delete mode 100755 test/scripts/jenkins_xpack_saved_objects_field_metrics.sh delete mode 100755 test/scripts/lint/eslint.sh delete mode 100755 test/scripts/lint/stylelint.sh delete mode 100755 test/scripts/test/api_integration.sh delete mode 100755 test/scripts/test/health_gateway.sh delete mode 100755 test/scripts/test/interpreter_functional.sh delete mode 100755 test/scripts/test/jest_integration.sh delete mode 100755 test/scripts/test/jest_unit.sh delete mode 100755 test/scripts/test/plugin_functional.sh delete mode 100755 test/scripts/test/server_integration.sh delete mode 100644 vars/agentInfo.groovy delete mode 100644 vars/buildState.groovy delete mode 100644 vars/catchErrors.groovy delete mode 100644 vars/esSnapshots.groovy delete mode 100644 vars/getCheckoutInfo.groovy delete mode 100644 vars/githubCommitStatus.groovy delete mode 100644 vars/githubPr.groovy delete mode 100644 vars/jenkinsApi.groovy delete mode 100644 vars/kibanaPipeline.groovy delete mode 100644 vars/prChanges.groovy delete mode 100644 vars/retryWithDelay.groovy delete mode 100644 vars/retryable.groovy delete mode 100644 vars/runbld.groovy delete mode 100644 vars/slackNotifications.groovy delete mode 100644 vars/storybooks.groovy delete mode 100644 vars/task.groovy delete mode 100644 vars/tasks.groovy delete mode 100644 vars/whenChanged.groovy delete mode 100644 vars/withGithubCredentials.groovy delete mode 100644 vars/withTaskQueue.groovy delete mode 100644 vars/workers.groovy diff --git a/.buildkite/pull_requests.json b/.buildkite/pull_requests.json index 6db75b64a1e08c..0c6714d1c75b77 100644 --- a/.buildkite/pull_requests.json +++ b/.buildkite/pull_requests.json @@ -15,17 +15,13 @@ "build_drafts": false, "trigger_comment_regex": "^(?:(?:buildkite\\W+)?(?:build|test)\\W+(?:this|it))|^\\/ci$", "always_trigger_comment_regex": "^(?:(?:buildkite\\W+)?(?:build|test)\\W+(?:this|it))|^\\/ci$", - "skip_ci_labels": ["skip-ci", "jenkins-ci"], + "skip_ci_labels": ["skip-ci"], "skip_target_branches": ["6.8", "7.11", "7.12"], "enable_skippable_commits": true, "skip_ci_on_only_changed": [ "^dev_docs/", "^docs/", "^rfcs/", - "^.ci/.+\\.yml$", - "^.ci/es-snapshots/", - "^.ci/pipeline-library/", - "^.ci/Jenkinsfile_[^/]+$", "^\\.github/", "\\.md$", "\\.mdx$", @@ -71,10 +67,6 @@ "^dev_docs/", "^docs/", "^rfcs/", - "^.ci/.+\\.yml$", - "^.ci/es-snapshots/", - "^.ci/pipeline-library/", - "^.ci/Jenkinsfile_[^/]+$", "^\\.github/", "\\.md$", "\\.mdx$", diff --git a/.ci/Dockerfile b/.ci/Dockerfile deleted file mode 100644 index 109b9ffab3cc56..00000000000000 --- a/.ci/Dockerfile +++ /dev/null @@ -1,38 +0,0 @@ -# NOTE: This Dockerfile is ONLY used to run certain tasks in CI. It is not used to run Kibana or as a distributable. -# If you're looking for the Kibana Docker image distributable, please see: src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts - -ARG NODE_VERSION=18.18.2 - -FROM node:${NODE_VERSION} AS base - -RUN apt-get update && \ - apt-get -y install xvfb gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 \ - libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 \ - libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 \ - libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 \ - libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget openjdk-11-jre && \ - rm -rf /var/lib/apt/lists/* - -RUN curl -sSL https://dl.google.com/linux/linux_signing_key.pub | apt-key add - \ - && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \ - && apt-get update \ - && apt-get install -y rsync jq bsdtar google-chrome-stable \ - --no-install-recommends \ - && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -RUN LATEST_VAULT_RELEASE=$(curl -s https://api.github.com/repos/hashicorp/vault/tags | jq --raw-output .[0].name[1:]) \ - && curl -L https://releases.hashicorp.com/vault/${LATEST_VAULT_RELEASE}/vault_${LATEST_VAULT_RELEASE}_linux_amd64.zip -o vault.zip \ - && unzip vault.zip \ - && rm vault.zip \ - && chmod +x vault \ - && mv vault /usr/local/bin/vault - -RUN groupadd -r kibana && useradd -r -g kibana kibana && mkdir /home/kibana && chown kibana:kibana /home/kibana - -COPY ./bash_standard_lib.sh /usr/local/bin/bash_standard_lib.sh -RUN chmod +x /usr/local/bin/bash_standard_lib.sh - -COPY ./runbld /usr/local/bin/runbld -RUN chmod +x /usr/local/bin/runbld - -USER kibana diff --git a/.ci/Jenkinsfile_baseline_capture b/.ci/Jenkinsfile_baseline_capture deleted file mode 100644 index ff3803cd903cd9..00000000000000 --- a/.ci/Jenkinsfile_baseline_capture +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/groovy - -library 'kibana-pipeline-library' -kibanaLibrary.load() - -kibanaPipeline(timeoutMinutes: 210) { - githubCommitStatus.trackBuild(params.commit, 'kibana-ci-baseline') { - ciStats.trackBuild { - catchErrors { - slackNotifications.onFailure( - title: "*<${env.BUILD_URL}|[${params.branch}] Baseline Capture Failure>*", - message: "[${params.branch}/${params.commit}] Baseline Capture Failure", - ) { - retryable.enable(2) - - catchErrors { - workers.ci( - name: 'baseline-worker', - size: 'xl', - ramDisk: true, - runErrorReporter: false, - bootstrapped: false - ) { - withGcpServiceAccount.fromVaultSecret('secret/ci/elastic-kibana/ci-artifacts-key', 'value') { - withEnv([ - 'DISABLE_BOOTSTRAP_VALIDATION=true', - ]) { - kibanaPipeline.doSetup() - } - } - - kibanaPipeline.withCiTaskQueue([parallel: 2]) { - catchErrors { - tasks([ - kibanaPipeline.functionalTestProcess('xpack-baseline', './test/scripts/jenkins_xpack_baseline.sh'), - kibanaPipeline.scriptTask('Check Public API Docs', 'test/scripts/checks/baseline_plugin_public_api_docs.sh'), - ]) - } - } - } - } - } - } - } - - kibanaPipeline.sendMail() - } -} diff --git a/.ci/Jenkinsfile_baseline_trigger b/.ci/Jenkinsfile_baseline_trigger deleted file mode 100644 index fd1c267fb3301f..00000000000000 --- a/.ci/Jenkinsfile_baseline_trigger +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/groovy - -return - -def MAXIMUM_COMMITS_TO_CHECK = 10 -def MAXIMUM_COMMITS_TO_BUILD = 5 - -if (!params.branches_yaml) { - error "'branches_yaml' parameter must be specified" -} - -def additionalBranches = [] - -def branches = readYaml(text: params.branches_yaml) + additionalBranches - -library 'kibana-pipeline-library' -kibanaLibrary.load() - -withGithubCredentials { - branches.each { branch -> - if (branch == '6.8') { - // skip 6.8, it is tracked but we don't need snapshots for it and haven't backported - // the baseline capture scripts to it. - return; - } - - stage(branch) { - def commits = getCommits(branch, MAXIMUM_COMMITS_TO_CHECK, MAXIMUM_COMMITS_TO_BUILD) - - commits.take(MAXIMUM_COMMITS_TO_BUILD).each { commit -> - catchErrors { - githubCommitStatus.create(commit, 'pending', 'Baseline started.', 'kibana-ci-baseline') - - build( - propagate: false, - wait: false, - job: 'elastic+kibana+baseline-capture', - parameters: [ - string(name: 'branch_specifier', value: branch), - string(name: 'commit', value: commit), - ] - ) - } - } - } - } -} - -def getCommits(String branch, maximumCommitsToCheck, maximumCommitsToBuild) { - print "Getting latest commits for ${branch}..." - def commits = githubApi.get("repos/elastic/kibana/commits?sha=${branch}").take(maximumCommitsToCheck).collect { it.sha } - def commitsToBuild = [] - - for (commit in commits) { - print "Getting statuses for ${commit}" - def status = githubApi.get("repos/elastic/kibana/statuses/${commit}").find { it.context == 'kibana-ci-baseline' } - print "Commit '${commit}' already built? ${status ? 'Yes' : 'No'}" - - if (!status) { - commitsToBuild << commit - } else { - // Stop at the first commit we find that's already been triggered - break - } - - if (commitsToBuild.size() >= maximumCommitsToBuild) { - break - } - } - - return commitsToBuild.reverse() // We want the builds to trigger oldest-to-newest -} diff --git a/.ci/Jenkinsfile_flaky b/.ci/Jenkinsfile_flaky deleted file mode 100644 index 370643789c2cde..00000000000000 --- a/.ci/Jenkinsfile_flaky +++ /dev/null @@ -1,150 +0,0 @@ -#!/bin/groovy - -library 'kibana-pipeline-library' -kibanaLibrary.load() - -def TASK_PARAM = params.TASK ?: params.CI_GROUP -// Looks like 'oss:ciGroup:1', 'oss:firefoxSmoke' -def JOB_PARTS = TASK_PARAM.split(':') -def IS_XPACK = JOB_PARTS[0] == 'xpack' -def JOB = JOB_PARTS.size() > 1 ? JOB_PARTS[1] : JOB_PARTS[0] -def CI_GROUP = JOB_PARTS.size() > 2 ? JOB_PARTS[2] : '' -def EXECUTIONS = params.NUMBER_EXECUTIONS.toInteger() -def AGENT_COUNT = getAgentCount(EXECUTIONS) -def NEED_BUILD = JOB != 'jestIntegration' && JOB != 'apiIntegration' - -currentBuild.displayName += trunc(" ${params.GITHUB_OWNER}:${params.branch_specifier}", 24) -currentBuild.description = "${params.CI_GROUP}<br />Agents: ${AGENT_COUNT}<br />Executions: ${params.NUMBER_EXECUTIONS}" - -kibanaPipeline(timeoutMinutes: 180) { - def agents = [:] - def workerFailures = [] - - def worker = getWorkerFromParams(IS_XPACK, JOB, CI_GROUP) - - for(def agentNumber = 1; agentNumber <= AGENT_COUNT; agentNumber++) { - def agentExecutions = floor(EXECUTIONS/AGENT_COUNT) + (agentNumber <= EXECUTIONS%AGENT_COUNT ? 1 : 0) - - agents["agent-${agentNumber}"] = { - agentProcess( - agentNumber: agentNumber, - agentExecutions: agentExecutions, - worker: worker, - workerFailures: workerFailures, - needBuild: NEED_BUILD, - isXpack: IS_XPACK, - ciGroup: CI_GROUP - ) - } - } - - parallel(agents) - - currentBuild.description += ", Failures: ${workerFailures.size()}" - - if (workerFailures.size() > 0) { - print "There were ${workerFailures.size()} test suite failures." - print "The executions that failed were:" - print workerFailures.join("\n") - print "Please check 'Test Result' and 'Pipeline Steps' pages for more info" - } -} - -def agentProcess(Map params = [:]) { - def config = [ - agentNumber: 1, - agentExecutions: 0, - worker: {}, - workerFailures: [], - needBuild: false, - isXpack: false, - ciGroup: null, - ] + params - - catchErrors { - print "Agent ${config.agentNumber} - ${config.agentExecutions} executions" - - withEnv([ - 'IGNORE_SHIP_CI_STATS_ERROR=true', - ]) { - kibanaPipeline.withTasks([ - parallel: 20, - ]) { - task { - if (config.needBuild) { - kibanaPipeline.buildKibana() - } - - for(def i = 0; i < config.agentExecutions; i++) { - def taskNumber = i - task({ - withEnv([ - "REMOVE_KIBANA_INSTALL_DIR=1", - ]) { - catchErrors { - try { - config.worker() - } catch (ex) { - config.workerFailures << "agent-${config.agentNumber}-${taskNumber}" - throw ex - } - } - } - }) - } - } - } - } - } -} - -def getWorkerFromParams(isXpack, job, ciGroup) { - if (!isXpack) { - if (job == 'accessibility') { - return kibanaPipeline.functionalTestProcess('kibana-accessibility', './test/scripts/jenkins_accessibility.sh') - } else if (job == 'firefoxSmoke') { - return kibanaPipeline.functionalTestProcess('firefoxSmoke', './test/scripts/jenkins_firefox_smoke.sh') - } else if (job == 'visualRegression') { - return kibanaPipeline.functionalTestProcess('visualRegression', './test/scripts/jenkins_visual_regression.sh') - } else if (job == 'jestIntegration') { - return kibanaPipeline.scriptTaskDocker('Jest Integration Tests', 'test/scripts/test/jest_integration.sh') - } else if (job == 'apiIntegration') { - return kibanaPipeline.scriptTask('API Integration Tests', 'test/scripts/test/api_integration.sh') - } else if (job == 'pluginFunctional') { - return kibanaPipeline.functionalTestProcess('oss-pluginFunctional', './test/scripts/jenkins_plugin_functional.sh') - } else { - return kibanaPipeline.ossCiGroupProcess(ciGroup) - } - } - - if (job == 'accessibility') { - return kibanaPipeline.functionalTestProcess('xpack-accessibility', './test/scripts/jenkins_xpack_accessibility.sh') - } else if (job == 'firefoxSmoke') { - return kibanaPipeline.functionalTestProcess('xpack-firefoxSmoke', './test/scripts/jenkins_xpack_firefox_smoke.sh') - } else if (job == 'visualRegression') { - return kibanaPipeline.functionalTestProcess('xpack-visualRegression', './test/scripts/jenkins_xpack_visual_regression.sh') - } else { - return kibanaPipeline.xpackCiGroupProcess(ciGroup) - } -} - -def getAgentCount(executions) { - // Increase agent count every 20 worker processess, up to 3 agents maximum - return Math.min(3, 1 + floor(executions/20)) -} - -def trunc(str, length) { - if (str.size() >= length) { - return str.take(length) + "..." - } - - return str; -} - -// All of the real rounding/truncating methods are sandboxed -def floor(num) { - return num - .toString() - .split('\\.')[0] - .toInteger() -} diff --git a/.ci/Jenkinsfile_security_cypress b/.ci/Jenkinsfile_security_cypress deleted file mode 100644 index d48b9965919dc2..00000000000000 --- a/.ci/Jenkinsfile_security_cypress +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/groovy - -library 'kibana-pipeline-library' -kibanaLibrary.load() - -kibanaPipeline(timeoutMinutes: 180) { - slackNotifications.onFailure( - disabled: !params.NOTIFY_ON_FAILURE, - channel: '#security-solution-slack-testing' - ) { - catchError { - withEnv([ - 'CI_PARALLEL_PROCESS_NUMBER=1', - 'IGNORE_SHIP_CI_STATS_ERROR=true', - ]) { - def job = 'xpack-securityCypress' - - workers.ci(name: job, size: 'l', ramDisk: true) { - kibanaPipeline.bash('test/scripts/jenkins_build_kibana.sh', 'Build Distributable') - kibanaPipeline.functionalTestProcess(job, 'test/scripts/jenkins_security_solution_cypress_chrome.sh')() - // Temporarily disabled to figure out test flake - // kibanaPipeline.functionalTestProcess(job, 'test/scripts/jenkins_security_solution_cypress_firefox.sh')() - } - } - } - } - - if (params.NOTIFY_ON_FAILURE) { - kibanaPipeline.sendMail(to: 'siem_dev_team@elastic.co') - } -} diff --git a/.ci/build_docker.sh b/.ci/build_docker.sh deleted file mode 100755 index 07013f13cdae5e..00000000000000 --- a/.ci/build_docker.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -cd "$(dirname "${0}")" - -cp /usr/local/bin/runbld ./ -cp /usr/local/bin/bash_standard_lib.sh ./ - -if which docker >/dev/null; then - docker build -t kibana-ci -f ./Dockerfile . -else - echo "Docker binary is not available. Skipping the docker build this time." -fi diff --git a/.ci/ci_groups.yml b/.ci/ci_groups.yml deleted file mode 100644 index 508f118ce9dd7c..00000000000000 --- a/.ci/ci_groups.yml +++ /dev/null @@ -1,46 +0,0 @@ -root: - - ciGroup1 - - ciGroup2 - - ciGroup3 - - ciGroup4 - - ciGroup5 - - ciGroup6 - - ciGroup7 - - ciGroup8 - - ciGroup9 - - ciGroup10 - - ciGroup11 - - ciGroup12 - -xpack: - - ciGroup1 - - ciGroup2 - - ciGroup3 - - ciGroup4 - - ciGroup5 - - ciGroup6 - - ciGroup7 - - ciGroup8 - - ciGroup9 - - ciGroup10 - - ciGroup11 - - ciGroup12 - - ciGroup13 - - ciGroup14 - - ciGroup15 - - ciGroup16 - - ciGroup17 - - ciGroup18 - - ciGroup19 - - ciGroup20 - - ciGroup21 - - ciGroup22 - - ciGroup23 - - ciGroup24 - - ciGroup25 - - ciGroup26 - - ciGroup27 - - ciGroup28 - - ciGroup29 - - ciGroup30 - - ciGroup31 diff --git a/.ci/es-snapshots/Jenkinsfile_build_es b/.ci/es-snapshots/Jenkinsfile_build_es deleted file mode 100644 index 7ace3b441144c5..00000000000000 --- a/.ci/es-snapshots/Jenkinsfile_build_es +++ /dev/null @@ -1,165 +0,0 @@ -#!/bin/groovy - -// This job effectively has two SCM configurations: -// one for kibana, used to check out this Jenkinsfile (which means it's the job's main SCM configuration), as well as kick-off the downstream verification job -// one for elasticsearch, used to check out the elasticsearch source before building it - -// There are two parameters that drive which branch is checked out for each of these, but they will typically be the same -// 'branch_specifier' is for kibana / the job itself -// ES_BRANCH is for elasticsearch - -library 'kibana-pipeline-library' -kibanaLibrary.load() - -def ES_BRANCH = params.ES_BRANCH - -if (!ES_BRANCH) { - error "Parameter 'ES_BRANCH' must be specified." -} - -currentBuild.displayName += " - ${ES_BRANCH}" -currentBuild.description = "ES: ${ES_BRANCH}<br />Kibana: ${params.branch_specifier}" - -def PROMOTE_WITHOUT_VERIFY = !!params.PROMOTE_WITHOUT_VERIFICATION - -timeout(time: 120, unit: 'MINUTES') { - timestamps { - ansiColor('xterm') { - slackNotifications.onFailure { - node(workers.label('l')) { - catchErrors { - def VERSION - def SNAPSHOT_ID - def DESTINATION - - def scmVars = checkoutEs(ES_BRANCH) - def GIT_COMMIT = scmVars.GIT_COMMIT - def GIT_COMMIT_SHORT = sh(script: "git rev-parse --short ${GIT_COMMIT}", returnStdout: true).trim() - - buildArchives('to-archive') - - dir('to-archive') { - def now = new Date() - def date = now.format("yyyyMMdd-HHmmss") - - def filesRaw = sh(script: "ls -1", returnStdout: true).trim() - def files = filesRaw - .split("\n") - .collect { filename -> - // Filename examples - // elasticsearch-oss-8.0.0-SNAPSHOT-linux-x86_64.tar.gz - // elasticsearch-8.0.0-SNAPSHOT-linux-x86_64.tar.gz - def parts = filename.replace("elasticsearch-oss", "oss").split("-") - - VERSION = VERSION ?: parts[1] - SNAPSHOT_ID = SNAPSHOT_ID ?: "${date}_${GIT_COMMIT_SHORT}" - DESTINATION = DESTINATION ?: "${VERSION}/archives/${SNAPSHOT_ID}" - - return [ - filename: filename, - checksum: filename + '.sha512', - url: "https://storage.googleapis.com/kibana-ci-es-snapshots-daily/${DESTINATION}/${filename}".toString(), - version: parts[1], - platform: parts[3], - architecture: parts[4].split('\\.')[0], - license: parts[0] == 'oss' ? 'oss' : 'default', - ] - } - - sh 'find * -exec bash -c "shasum -a 512 {} > {}.sha512" \\;' - - def manifest = [ - bucket: "kibana-ci-es-snapshots-daily/${DESTINATION}".toString(), - branch: ES_BRANCH, - sha: GIT_COMMIT, - sha_short: GIT_COMMIT_SHORT, - version: VERSION, - generated: now.format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC")), - archives: files, - ] - def manifestJson = toJSON(manifest).toString() - writeFile file: 'manifest.json', text: manifestJson - - upload(DESTINATION, '*.*') - - sh "cp manifest.json manifest-latest.json" - upload(VERSION, 'manifest-latest.json') - } - - if (PROMOTE_WITHOUT_VERIFY) { - esSnapshots.promote(VERSION, SNAPSHOT_ID) - - emailext( - to: 'build-kibana@elastic.co', - subject: "ES snapshot promoted without verification: ${params.ES_BRANCH}", - body: '${SCRIPT,template="groovy-html.template"}', - mimeType: 'text/html', - ) - } else { - build( - propagate: false, - wait: false, - job: 'elasticsearch+snapshots+verify', - parameters: [ - string(name: 'branch_specifier', value: branch_specifier), - string(name: 'SNAPSHOT_VERSION', value: VERSION), - string(name: 'SNAPSHOT_ID', value: SNAPSHOT_ID), - ] - ) - } - } - - kibanaPipeline.sendMail() - } - } - } - } -} - -def checkoutEs(branch) { - retryWithDelay(8, 15) { - return checkout([ - $class: 'GitSCM', - branches: [[name: branch]], - doGenerateSubmoduleConfigurations: false, - extensions: [], - submoduleCfg: [], - userRemoteConfigs: [[ - credentialsId: 'f6c7695a-671e-4f4f-a331-acdce44ff9ba', - url: 'git@github.com:elastic/elasticsearch', - ]], - ]) - } -} - -def upload(destination, pattern) { - return googleStorageUpload( - credentialsId: 'kibana-ci-gcs-plugin', - bucket: "gs://kibana-ci-es-snapshots-daily/${destination}", - pattern: pattern, - sharedPublicly: false, - showInline: false, - ) -} - -def buildArchives(destination) { - def props = readProperties file: '.ci/java-versions.properties' - withEnv([ - // Select the correct JDK for this branch - "PATH=/var/lib/jenkins/.java/${props.ES_BUILD_JAVA}/bin:${env.PATH}", - - // These Jenkins env vars trigger some automation in the elasticsearch repo that we don't want - "BUILD_NUMBER=", - "JENKINS_URL=", - "BUILD_URL=", - "JOB_NAME=", - "NODE_NAME=", - ]) { - sh """ - ./gradlew -Dbuild.docker=true assemble --parallel - mkdir -p ${destination} - find distribution -type f \\( -name 'elasticsearch-*-*-*-*.tar.gz' -o -name 'elasticsearch-*-*-*-*.zip' \\) -not -path *no-jdk* -not -path *build-context* -exec cp {} ${destination} \\; - docker images "docker.elastic.co/elasticsearch/elasticsearch" --format "{{.Tag}}" | xargs -n1 bash -c 'docker save docker.elastic.co/elasticsearch/elasticsearch:\${0} | gzip > ${destination}/elasticsearch-\${0}-docker-image.tar.gz' - """ - } -} diff --git a/.ci/es-snapshots/Jenkinsfile_trigger_build_es b/.ci/es-snapshots/Jenkinsfile_trigger_build_es deleted file mode 100644 index d4e59ca3e411be..00000000000000 --- a/.ci/es-snapshots/Jenkinsfile_trigger_build_es +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/groovy - -// Only run this pipeline for 6.8. Higher branches are now running in Buildkite. -def branches = ['6.8'] - -branches.each { branch -> - build( - propagate: false, - wait: false, - job: 'elasticsearch+snapshots+build', - parameters: [ - string(name: 'branch_specifier', value: branch), - string(name: 'ES_BRANCH', value: branch), - ] - ) -} diff --git a/.ci/es-snapshots/Jenkinsfile_verify_es b/.ci/es-snapshots/Jenkinsfile_verify_es deleted file mode 100644 index dc3a3cde7d658a..00000000000000 --- a/.ci/es-snapshots/Jenkinsfile_verify_es +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/groovy - -library 'kibana-pipeline-library' -kibanaLibrary.load() - -def SNAPSHOT_VERSION = params.SNAPSHOT_VERSION -def SNAPSHOT_ID = params.SNAPSHOT_ID - -if (!SNAPSHOT_VERSION) { - error "Parameter SNAPSHOT_VERSION must be specified" -} - -if (!SNAPSHOT_ID) { - error "Parameter SNAPSHOT_ID must be specified" -} - -currentBuild.displayName += " - ${SNAPSHOT_VERSION}" -currentBuild.description = "ES: ${SNAPSHOT_VERSION}<br />Kibana: ${params.branch_specifier}" - -def SNAPSHOT_MANIFEST = "https://storage.googleapis.com/kibana-ci-es-snapshots-daily/${SNAPSHOT_VERSION}/archives/${SNAPSHOT_ID}/manifest.json" - -kibanaPipeline(timeoutMinutes: 210) { - catchErrors { - slackNotifications.onFailure( - title: "*<${env.BUILD_URL}|[${SNAPSHOT_VERSION}] ES Snapshot Verification Failure>*", - message: "[${SNAPSHOT_VERSION}] ES Snapshot Verification Failure", - ) { - retryable.enable(2) - withEnv([ - "ES_SNAPSHOT_MANIFEST=${SNAPSHOT_MANIFEST}", - 'IGNORE_SHIP_CI_STATS_ERROR=true', - ]) { - kibanaPipeline.withTasks { - tasks([ - kibanaPipeline.scriptTaskDocker('Jest Integration Tests', 'test/scripts/test/jest_integration.sh'), - kibanaPipeline.scriptTask('API Integration Tests', 'test/scripts/test/api_integration.sh'), - ]) - - task { - kibanaPipeline.buildKibana(16) - tasks.ossCiGroups() - tasks.xpackCiGroups() - tasks.xpackCiGroupDocker() - } - } - } - - promoteSnapshot(SNAPSHOT_VERSION, SNAPSHOT_ID) - } - } - - kibanaPipeline.sendMail() -} - -def promoteSnapshot(snapshotVersion, snapshotId) { - if (buildUtils.getBuildStatus() == 'SUCCESS') { - node(workers.label('s')) { - esSnapshots.promote(snapshotVersion, snapshotId) - } - } -} diff --git a/.ci/packer_cache.sh b/.ci/packer_cache.sh deleted file mode 100755 index fc5a52f1ac9919..00000000000000 --- a/.ci/packer_cache.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -set -e - -if [[ "$(which docker)" != "" && "$(command uname -m)" != "aarch64" ]]; then - # cache image used by kibana-load-testing project - docker pull "maven:3.6.3-openjdk-8-slim" -fi - -./.ci/packer_cache_for_branch.sh main -./.ci/packer_cache_for_branch.sh 7.16 diff --git a/.ci/packer_cache_for_branch.sh b/.ci/packer_cache_for_branch.sh deleted file mode 100755 index 78548f4667a9f0..00000000000000 --- a/.ci/packer_cache_for_branch.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env bash - -set -e - -branch="$1" -checkoutDir="$(pwd)" - -function cleanup() -{ - if [[ "$branch" != "main" ]]; then - rm --preserve-root -rf "$checkoutDir" - fi - - exit 0 -} - -trap 'cleanup' 0 - -if [[ "$branch" != "main" ]]; then - checkoutDir="/tmp/kibana-$branch" - git clone https://github.com/elastic/kibana.git --branch "$branch" --depth 1 "$checkoutDir" - cd "$checkoutDir" -fi - -source src/dev/ci_setup/setup.sh; - -# download es snapshots -node scripts/es snapshot --download-only; - -# download reporting browsers -(cd "x-pack" && node ../node_modules/.bin/gulp downloadChromium); - -# cache the chromedriver archive -chromedriverDistVersion="$(node -e "console.log(require('chromedriver').version)")" -chromedriverPkgVersion="$(node -e "console.log(require('./package.json').devDependencies.chromedriver)")" -if [ -z "$chromedriverDistVersion" ] || [ -z "$chromedriverPkgVersion" ]; then - echo "UNABLE TO DETERMINE CHROMEDRIVER VERSIONS" - exit 1 -fi -mkdir -p .chromedriver -curl "https://chromedriver.storage.googleapis.com/$chromedriverDistVersion/chromedriver_linux64.zip" > .chromedriver/chromedriver.zip -echo "$chromedriverPkgVersion" > .chromedriver/pkgVersion - -# cache the geckodriver archive -geckodriverPkgVersion="$(node -e "console.log(require('./package.json').devDependencies.geckodriver)")" -if [ -z "$geckodriverPkgVersion" ]; then - echo "UNABLE TO DETERMINE geckodriver VERSIONS" - exit 1 -fi -mkdir -p ".geckodriver" -cp "node_modules/geckodriver/geckodriver.tar.gz" .geckodriver/geckodriver.tar.gz -echo "$geckodriverPkgVersion" > .geckodriver/pkgVersion - -echo "Creating bootstrap_cache archive" - -# archive cacheable directories -mkdir -p "$HOME/.kibana/bootstrap_cache" -tar -cf "$HOME/.kibana/bootstrap_cache/$branch.tar" \ - .chromium \ - .es \ - .chromedriver \ - .geckodriver \ - .yarn-local-mirror; - -echo "created $HOME/.kibana/bootstrap_cache/$branch.tar" - -.ci/build_docker.sh - diff --git a/.ci/pipeline-library/README.md b/.ci/pipeline-library/README.md deleted file mode 100644 index 71d7c39e37f4fe..00000000000000 --- a/.ci/pipeline-library/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Kibana Jenkins Pipeline Library - -## Running tests - -```bash -cd .ci/pipeline-library -./gradlew test -``` \ No newline at end of file diff --git a/.ci/pipeline-library/build.gradle b/.ci/pipeline-library/build.gradle deleted file mode 100644 index ac5e7a4ed034a2..00000000000000 --- a/.ci/pipeline-library/build.gradle +++ /dev/null @@ -1,46 +0,0 @@ -plugins { - id 'groovy' - id 'idea' -} - -group = 'co.elastic.kibana.pipeline' -version = '0.0.1' - -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - -repositories { - maven { url 'https://repo.jenkins-ci.org/releases/' } - maven { url 'https://repo.maven.apache.org/maven2' } -} - -dependencies { - implementation 'org.codehaus.groovy:groovy-all:2.4.12' - implementation 'org.jenkins-ci.main:jenkins-core:2.23' - implementation 'org.jenkins-ci.plugins.workflow:workflow-step-api:2.19@jar' - testImplementation 'com.lesfurets:jenkins-pipeline-unit:1.4' - testImplementation 'junit:junit:4.12' - testImplementation 'org.mockito:mockito-core:2.+' - testImplementation 'org.assertj:assertj-core:3.15+' // Temporary https://github.com/jenkinsci/JenkinsPipelineUnit/issues/209 -} - -sourceSets { - main { - groovy { - srcDirs = ['vars'] - } - } - - test { - groovy { - srcDirs = ['src/test'] - } - } -} - -test { - testLogging { - events 'passed', 'skipped', 'failed' - exceptionFormat = 'full' - } -} diff --git a/.ci/pipeline-library/gradle/wrapper/gradle-wrapper.jar b/.ci/pipeline-library/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 62d4c053550b91381bbd28b1afc82d634bf73a8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58910 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 diff --git a/.ci/pipeline-library/gradle/wrapper/gradle-wrapper.properties b/.ci/pipeline-library/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index a4f0001d203b29..00000000000000 --- a/.ci/pipeline-library/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/.ci/pipeline-library/gradlew b/.ci/pipeline-library/gradlew deleted file mode 100755 index fbd7c515832dab..00000000000000 --- a/.ci/pipeline-library/gradlew +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/.ci/pipeline-library/gradlew.bat b/.ci/pipeline-library/gradlew.bat deleted file mode 100644 index a9f778a7a964b6..00000000000000 --- a/.ci/pipeline-library/gradlew.bat +++ /dev/null @@ -1,104 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/.ci/pipeline-library/src/test/KibanaBasePipelineTest.groovy b/.ci/pipeline-library/src/test/KibanaBasePipelineTest.groovy deleted file mode 100644 index 4112cb3c0e14bd..00000000000000 --- a/.ci/pipeline-library/src/test/KibanaBasePipelineTest.groovy +++ /dev/null @@ -1,113 +0,0 @@ -import com.lesfurets.jenkins.unit.* -import org.junit.Before - -class KibanaBasePipelineTest extends BasePipelineTest { - Map env = [:] - Map params = [:] - - public def Mocks = [ - TEST_FAILURE_URL: 'https://localhost/', - TEST_FAILURE_NAME: 'Kibana Pipeline / kibana-xpack-agent / Chrome X-Pack UI Functional Tests.x-pack/test/functional/apps/fake/test·ts.Fake test <Component> should & pass &', - ] - - @Before - void setUp() { - super.setUp() - - env.BRANCH_NAME = 'master' - env.BUILD_ID = '1' - env.BUILD_DISPLAY_NAME = "#${env.BUILD_ID}" - - env.JENKINS_URL = 'http://jenkins.localhost:8080' - env.BUILD_URL = "${env.JENKINS_URL}/job/elastic+kibana+${env.BRANCH_NAME}/${env.BUILD_ID}/".toString() - - env.JOB_BASE_NAME = "elastic / kibana # ${env.BRANCH_NAME}".toString() - env.JOB_NAME = env.JOB_BASE_NAME - - env.WORKSPACE = 'WS' - - props([ - buildUtils: [ - getBuildStatus: { 'SUCCESS' }, - printStacktrace: { ex -> print ex }, - ], - githubPr: [ - isPr: { false }, - ], - jenkinsApi: [ getFailedSteps: { [] } ], - testUtils: [ getFailures: { [] } ], - ]) - - vars([ - env: env, - params: params, - ]) - - // Some wrappers that can just be mocked to immediately call the closure passed in - [ - 'catchError', - 'catchErrors', - 'timestamps', - 'withGithubCredentials', - ].each { - helper.registerAllowedMethod(it, [Closure.class], null) - } - } - - void props(Map properties) { - properties.each { - binding.setProperty(it.key, it.value) - } - } - - void prop(String propertyName, Object propertyValue) { - binding.setProperty(propertyName, propertyValue) - } - - void vars(Map variables) { - variables.each { - binding.setVariable(it.key, it.value) - } - } - - void var(String variableName, Object variableValue) { - binding.setVariable(variableName, variableValue) - } - - def fnMock(String name) { - return helper.callStack.find { it.methodName == name } - } - - def fnMocks(String name) { - helper.callStack.findAll { it.methodName == name } - } - - void mockFailureBuild() { - props([ - buildUtils: [ - getBuildStatus: { 'FAILURE' }, - printStacktrace: { ex -> print ex }, - ], - jenkinsApi: [ getFailedSteps: { [ - [ - displayName: 'Check out from version control', - logs: 'http://jenkins.localhost:8080', - ], - [ - displayName: 'Execute test task', - logs: 'http://jenkins.localhost:8080', - ], - ] } ], - testUtils: [ - getFailures: { - return [ - [ - url: Mocks.TEST_FAILURE_URL, - fullDisplayName: Mocks.TEST_FAILURE_NAME, - ] - ] - }, - ], - ]) - } -} diff --git a/.ci/pipeline-library/src/test/buildState.groovy b/.ci/pipeline-library/src/test/buildState.groovy deleted file mode 100644 index b748cce29e7f4b..00000000000000 --- a/.ci/pipeline-library/src/test/buildState.groovy +++ /dev/null @@ -1,48 +0,0 @@ -import org.junit.* -import static groovy.test.GroovyAssert.* - -class BuildStateTest extends KibanaBasePipelineTest { - def buildState - - @Before - void setUp() { - super.setUp() - - buildState = loadScript("vars/buildState.groovy") - } - - @Test - void 'get() returns existing data'() { - buildState.add('test', 1) - def actual = buildState.get('test') - assertEquals(1, actual) - } - - @Test - void 'get() returns null for missing data'() { - def actual = buildState.get('missing_key') - assertEquals(null, actual) - } - - @Test - void 'add() does not overwrite existing keys'() { - assertTrue(buildState.add('test', 1)) - assertFalse(buildState.add('test', 2)) - - def actual = buildState.get('test') - - assertEquals(1, actual) - } - - @Test - void 'set() overwrites existing keys'() { - assertFalse(buildState.has('test')) - buildState.set('test', 1) - assertTrue(buildState.has('test')) - buildState.set('test', 2) - - def actual = buildState.get('test') - - assertEquals(2, actual) - } -} diff --git a/.ci/pipeline-library/src/test/githubCommitStatus.groovy b/.ci/pipeline-library/src/test/githubCommitStatus.groovy deleted file mode 100644 index c770d5596f9cb6..00000000000000 --- a/.ci/pipeline-library/src/test/githubCommitStatus.groovy +++ /dev/null @@ -1,87 +0,0 @@ -import org.junit.* -import static org.mockito.Mockito.*; - -class GithubCommitStatusTest extends KibanaBasePipelineTest { - def githubCommitStatus - def githubApiMock - def buildStateMock - - def EXPECTED_STATUS_URL = 'repos/elastic/kibana/statuses/COMMIT_HASH' - def EXPECTED_CONTEXT = 'kibana-ci' - def EXPECTED_BUILD_URL = 'http://jenkins.localhost:8080/job/elastic+kibana+master/1/' - - interface BuildState { - Object get(String key) - Object has(String key) - } - - interface GithubApi { - Object post(String url, Map data) - } - - @Before - void setUp() { - super.setUp() - - buildStateMock = mock(BuildState) - githubApiMock = mock(GithubApi) - - when(buildStateMock.has('checkoutInfo')).thenReturn(true) - when(buildStateMock.get('checkoutInfo')).thenReturn([ commit: 'COMMIT_HASH', ]) - when(githubApiMock.post(any(), any())).thenReturn(null) - - props([ - buildState: buildStateMock, - githubApi: githubApiMock, - ]) - - githubCommitStatus = loadScript("vars/githubCommitStatus.groovy") - } - - void verifyStatusCreate(String state, String description) { - verify(githubApiMock).post( - EXPECTED_STATUS_URL, - [ - 'state': state, - 'description': description, - 'context': EXPECTED_CONTEXT, - 'target_url': EXPECTED_BUILD_URL, - ] - ) - } - - @Test - void 'onStart() should create a pending status'() { - githubCommitStatus.onStart() - verifyStatusCreate('pending', 'Build started.') - } - - @Test - void 'onFinish() should create a success status'() { - githubCommitStatus.onFinish() - verifyStatusCreate('success', 'Build completed successfully.') - } - - @Test - void 'onFinish() should create an error status for failed builds'() { - mockFailureBuild() - githubCommitStatus.onFinish() - verifyStatusCreate('error', 'Build failed.') - } - - @Test - void 'onStart() should exit early for PRs'() { - prop('githubPr', [ isPr: { true } ]) - - githubCommitStatus.onStart() - verifyZeroInteractions(githubApiMock) - } - - @Test - void 'onFinish() should exit early for PRs'() { - prop('githubPr', [ isPr: { true } ]) - - githubCommitStatus.onFinish() - verifyZeroInteractions(githubApiMock) - } -} diff --git a/.ci/pipeline-library/src/test/prChanges.groovy b/.ci/pipeline-library/src/test/prChanges.groovy deleted file mode 100644 index e3f82e6102acc7..00000000000000 --- a/.ci/pipeline-library/src/test/prChanges.groovy +++ /dev/null @@ -1,113 +0,0 @@ -import org.junit.* -import static groovy.test.GroovyAssert.* - -class PrChangesTest extends KibanaBasePipelineTest { - def prChanges - - @Before - void setUp() { - super.setUp() - - env.ghprbPullId = '1' - - props([ - githubPr: [ - isPr: { true }, - ], - ]) - - prChanges = loadScript("vars/prChanges.groovy") - } - - @Test - void 'areChangesSkippable() with no changes'() { - props([ - githubPrs: [ - getChanges: { [] }, - ], - ]) - - assertTrue(prChanges.areChangesSkippable()) - } - - @Test - void 'areChangesSkippable() with skippable changes'() { - props([ - githubPrs: [ - getChanges: { [ - [filename: 'docs/test/a-fake-doc.asciidoc'], - [filename: 'README.md'], - ] }, - ], - ]) - - assertTrue(prChanges.areChangesSkippable()) - } - - @Test - void 'areChangesSkippable() with skippable renames'() { - props([ - githubPrs: [ - getChanges: { [ - [ filename: 'docs/test/a-fake-doc.asciidoc', previousFilename: 'docs/test/a-different-fake-doc.asciidoc' ], - [ filename: 'README.md', previousFilename: 'README-old.md' ], - ] }, - ], - ]) - - assertTrue(prChanges.areChangesSkippable()) - } - - @Test - void 'areChangesSkippable() with unskippable changes'() { - props([ - githubPrs: [ - getChanges: { [ - [filename: 'src/core/index.ts'], - ] }, - ], - ]) - - assertFalse(prChanges.areChangesSkippable()) - } - - @Test - void 'areChangesSkippable() with skippable and unskippable changes'() { - props([ - githubPrs: [ - getChanges: { [ - [filename: 'README.md'], - [filename: 'src/core/index.ts'], - ] }, - ], - ]) - - assertFalse(prChanges.areChangesSkippable()) - } - - @Test - void 'areChangesSkippable() with skippable changes that are in notSkippablePaths'() { - props([ - githubPrs: [ - getChanges: { [ - [filename: 'docs/developer/plugin-list.asciidoc'], - ] }, - ], - ]) - - assertFalse(prChanges.areChangesSkippable()) - } - - @Test - void 'areChangesSkippable() with plugin readme changes'() { - props([ - githubPrs: [ - getChanges: { [ - [filename: 'src/plugins/foo/README.asciidoc'], - ] }, - ], - ]) - - assertFalse(prChanges.areChangesSkippable()) - } -} diff --git a/.ci/pipeline-library/src/test/slackNotifications.groovy b/.ci/pipeline-library/src/test/slackNotifications.groovy deleted file mode 100644 index 33b3afed80bde3..00000000000000 --- a/.ci/pipeline-library/src/test/slackNotifications.groovy +++ /dev/null @@ -1,185 +0,0 @@ -import org.junit.* -import static groovy.test.GroovyAssert.* - -class SlackNotificationsTest extends KibanaBasePipelineTest { - def slackNotifications - - @Before - void setUp() { - super.setUp() - - helper.registerAllowedMethod('slackSend', [Map.class], null) - prop('buildState', loadScript("vars/buildState.groovy")) - slackNotifications = loadScript('vars/slackNotifications.groovy') - } - - @Test - void 'getTestFailures() should properly format failure steps'() { - mockFailureBuild() - - def failureMessage = slackNotifications.getTestFailures() - - assertEquals( - "*Test Failures*\n• <${Mocks.TEST_FAILURE_URL}|x-pack/test/functional/apps/fake/test·ts.Fake test <Component> should & pass &>", - failureMessage - ) - } - - @Test - void 'sendFailedBuild() should call slackSend() with an in-progress message'() { - mockFailureBuild() - - slackNotifications.sendFailedBuild() - - def args = fnMock('slackSend').args[0] - - def expected = [ - channel: '#kibana-operations-alerts', - username: 'Kibana Operations', - iconEmoji: ':jenkins:', - color: 'danger', - message: ':hourglass_flowing_sand: elastic / kibana # master #1', - ] - - expected.each { - assertEquals(it.value.toString(), args[it.key].toString()) - } - - assertEquals( - ":hourglass_flowing_sand: *<http://jenkins.localhost:8080/job/elastic+kibana+master/1/|elastic / kibana # master #1>*", - args.blocks[0].text.text.toString() - ) - - assertEquals( - "*Failed Steps*\n• <http://jenkins.localhost:8080|Execute test task>", - args.blocks[1].text.text.toString() - ) - - assertEquals( - "*Test Failures*\n• <https://localhost/|x-pack/test/functional/apps/fake/test·ts.Fake test <Component> should & pass &>", - args.blocks[2].text.text.toString() - ) - } - - @Test - void 'sendFailedBuild() should call slackSend() with message'() { - mockFailureBuild() - - slackNotifications.sendFailedBuild(isFinal: true) - - def args = fnMock('slackSend').args[0] - - def expected = [ - channel: '#kibana-operations-alerts', - username: 'Kibana Operations', - iconEmoji: ':jenkins:', - color: 'danger', - message: ':broken_heart: elastic / kibana # master #1', - ] - - expected.each { - assertEquals(it.value.toString(), args[it.key].toString()) - } - - assertEquals( - ":broken_heart: *<http://jenkins.localhost:8080/job/elastic+kibana+master/1/|elastic / kibana # master #1>*", - args.blocks[0].text.text.toString() - ) - - assertEquals( - "*Failed Steps*\n• <http://jenkins.localhost:8080|Execute test task>", - args.blocks[1].text.text.toString() - ) - - assertEquals( - "*Test Failures*\n• <https://localhost/|x-pack/test/functional/apps/fake/test·ts.Fake test <Component> should & pass &>", - args.blocks[2].text.text.toString() - ) - } - - @Test - void 'sendFailedBuild() should call slackSend() with a backup message when first attempt fails'() { - mockFailureBuild() - def counter = 0 - helper.registerAllowedMethod('slackSend', [Map.class], { ++counter > 1 }) - slackNotifications.sendFailedBuild(isFinal: true) - - def args = fnMocks('slackSend')[1].args[0] - - def expected = [ - channel: '#kibana-operations-alerts', - username: 'Kibana Operations', - iconEmoji: ':jenkins:', - color: 'danger', - message: ':broken_heart: elastic / kibana # master #1', - ] - - expected.each { - assertEquals(it.value.toString(), args[it.key].toString()) - } - - assertEquals( - ":broken_heart: *<http://jenkins.localhost:8080/job/elastic+kibana+master/1/|elastic / kibana # master #1>*" + - "\n\nFirst attempt at sending this notification failed. Please check the build.", - args.blocks[0].text.text.toString() - ) - } - - @Test - void 'sendFailedBuild() should call slackSend() with a channel id and timestamp on second call'() { - mockFailureBuild() - helper.registerAllowedMethod('slackSend', [Map.class], { [ channelId: 'CHANNEL_ID', ts: 'TIMESTAMP' ] }) - slackNotifications.sendFailedBuild(isFinal: false) - slackNotifications.sendFailedBuild(isFinal: true) - - def args = fnMocks('slackSend')[1].args[0] - - def expected = [ - channel: 'CHANNEL_ID', - timestamp: 'TIMESTAMP', - username: 'Kibana Operations', - iconEmoji: ':jenkins:', - color: 'danger', - message: ':broken_heart: elastic / kibana # master #1', - ] - - expected.each { - assertEquals(it.value.toString(), args[it.key].toString()) - } - } - - @Test - void 'getTestFailures() should truncate list of failures to 10'() { - prop('testUtils', [ - getFailures: { - return (1..12).collect { - return [ - url: Mocks.TEST_FAILURE_URL, - fullDisplayName: "Failure #${it}", - ] - } - }, - ]) - - def message = (String) slackNotifications.getTestFailures() - - assertTrue("Message ends with truncated indicator", message.endsWith("...and 2 more")) - assertTrue("Message contains Failure #10", message.contains("Failure #10")) - assertTrue("Message does not contain Failure #11", !message.contains("Failure #11")) - } - - @Test - void 'shortenMessage() should truncate a long message, but leave parts that fit'() { - assertEquals('Hello\nHello\n[...truncated...]', slackNotifications.shortenMessage('Hello\nHello\nthis is a long string', 29)) - } - - @Test - void 'shortenMessage() should not modify a short message'() { - assertEquals('Hello world', slackNotifications.shortenMessage('Hello world', 11)) - } - - @Test - void 'shortenMessage() should truncate an entire message with only one part'() { - assertEquals('[...truncated...]', slackNotifications.shortenMessage('Hello world this is a really long message', 40)) - } -} diff --git a/.ci/pipeline-library/vars b/.ci/pipeline-library/vars deleted file mode 120000 index 8559d2e08fc22c..00000000000000 --- a/.ci/pipeline-library/vars +++ /dev/null @@ -1 +0,0 @@ -../../vars \ No newline at end of file diff --git a/.ci/runbld_no_junit.yml b/.ci/runbld_no_junit.yml deleted file mode 100644 index 1bcb7e22a26480..00000000000000 --- a/.ci/runbld_no_junit.yml +++ /dev/null @@ -1,6 +0,0 @@ -# This file is not picked up by anything automatically -# It is used by being passed as an argument to runbld, when automatic processing of junit reports is not desired -profiles: -- ".*": # Match any job - tests: - junit-filename-pattern: false diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index 7dd3d0f41d27ae..00000000000000 --- a/Jenkinsfile +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/groovy - -if (!env.ghprbPullId) { - print "Non-PR builds are now in Buildkite." - return -} - -library 'kibana-pipeline-library' -kibanaLibrary.load() - -kibanaPipeline(timeoutMinutes: 210, checkPrChanges: true, setCommitStatus: true) { - slackNotifications.onFailure(disabled: !params.NOTIFY_ON_FAILURE) { - githubPr.withDefaultPrComments { - ciStats.trackBuild(requireSuccess: githubPr.isTrackedBranchPr()) { - catchError { - retryable.enable() - kibanaPipeline.allCiTasks() - } - } - } - } - - if (params.NOTIFY_ON_FAILURE) { - kibanaPipeline.sendMail() - } -} diff --git a/dev_docs/contributing/code_walkthrough.mdx b/dev_docs/contributing/code_walkthrough.mdx index 139ac4df930701..b3144bf0f5e7a4 100644 --- a/dev_docs/contributing/code_walkthrough.mdx +++ b/dev_docs/contributing/code_walkthrough.mdx @@ -15,9 +15,6 @@ Tip: Look for a `README.md` in a folder to learn about its contents. Managed by the operations team to set up a new buildkite ci system. Can be ignored by folks outside the Operations team. -## [.ci](https://github.com/elastic/kibana/tree/main/.ci) - -Managed by the operations team to contain Jenkins settings. Can be ignored by folks outside the Operations team. ## [.github](https://github.com/elastic/kibana/tree/main/.github) diff --git a/docs/developer/contributing/development-functional-tests.asciidoc b/docs/developer/contributing/development-functional-tests.asciidoc index d149372f0f5720..9dcb9785cf045d 100644 --- a/docs/developer/contributing/development-functional-tests.asciidoc +++ b/docs/developer/contributing/development-functional-tests.asciidoc @@ -81,11 +81,12 @@ export TEST_BROWSER_HEADLESS=1 export TEST_THROTTLE_NETWORK=1 ---------- -** When running against a Cloud deployment, some tests are not applicable. To skip tests that do not apply, use --exclude-tag. An example shell file can be found at: {kibana-blob}test/scripts/jenkins_cloud.sh[test/scripts/jenkins_cloud.sh] +** When running against a Cloud deployment, some tests are not applicable. To skip tests that do not apply, use --exclude-tag. + ["source", "shell"] ---------- node scripts/functional_test_runner --exclude-tag skipCloud +node scripts/functional_test_runner --exclude-tag skipMKI ---------- [discrete] diff --git a/docs/developer/contributing/pr-review.asciidoc b/docs/developer/contributing/pr-review.asciidoc index 95f012d569c3a5..7f47af51ef51a0 100644 --- a/docs/developer/contributing/pr-review.asciidoc +++ b/docs/developer/contributing/pr-review.asciidoc @@ -118,7 +118,7 @@ Inflammatory feedback such as "this is crap" isn't feedback at all. It's both me Establishing a comprehensive checklist for all of the things that should happen in all possible pull requests is impractical, but that doesn't mean we lack a concrete set of minimum requirements that we can enumerate. The following items should be double checked for any pull request: * CLA check passes -* Jenkins job runs and passes +* CI job runs and passes * Adheres to the spirit of our various styleguides * Has thorough unit test coverage * Automated tests provide high confidence the change continues to work without manual verification diff --git a/src/dev/ci_setup/checkout_sibling_es.sh b/src/dev/ci_setup/checkout_sibling_es.sh deleted file mode 100755 index 3832ec9b4076a7..00000000000000 --- a/src/dev/ci_setup/checkout_sibling_es.sh +++ /dev/null @@ -1,118 +0,0 @@ -#!/bin/bash - -set -e - -function checkout_sibling { - project=$1 - targetDir=$2 - useExistingParamName=$3 - useExisting="$(eval "echo "\$$useExistingParamName"")" - repoAddress="https://github.com/" - - if [ -z ${useExisting:+x} ]; then - if [ -d "$targetDir" ]; then - echo "I expected a clean workspace but an '${project}' sibling directory already exists in [$WORKSPACE]!" - echo - echo "Either define '${useExistingParamName}' or remove the existing '${project}' sibling." - exit 1 - fi - - # read by clone_target_is_valid, and checkout_clone_target populated by pick_clone_target - cloneAuthor="" - cloneBranch="" - - function clone_target_is_valid { - - echo " -> checking for '${cloneBranch}' branch at ${cloneAuthor}/${project}" - if [[ -n "$(git ls-remote --heads "${repoAddress}${cloneAuthor}/${project}.git" ${cloneBranch} 2>/dev/null)" ]]; then - return 0 - else - return 1 - fi - } - - function pick_clone_target { - echo "To develop Kibana features against a specific branch of ${project} and being able to" - echo "test that feature also on CI, the CI is trying to find branches on ${project} with the same name as" - echo "the Kibana branch (first on your fork and then upstream) before building from master." - echo "picking which branch of ${project} to clone:" - if [[ -n "$PR_AUTHOR" && -n "$PR_SOURCE_BRANCH" ]]; then - cloneAuthor="$PR_AUTHOR" - cloneBranch="$PR_SOURCE_BRANCH" - if clone_target_is_valid ; then - return 0 - fi - fi - - cloneAuthor="elastic" - cloneBranch="$GIT_BRANCH" - if clone_target_is_valid ; then - return 0 - fi - - cloneBranch="${PR_TARGET_BRANCH:-$KIBANA_PKG_BRANCH}" - if clone_target_is_valid ; then - return 0 - fi - - cloneBranch="$KIBANA_PKG_BRANCH" - if clone_target_is_valid; then - return 0 - fi - - echo "failed to find a valid branch to clone" - return 1 - } - - function checkout_clone_target { - pick_clone_target - - if [[ "$cloneAuthor/$cloneBranch" != "elastic/$KIBANA_PKG_BRANCH" ]]; then - echo " -> Setting TEST_ES_FROM=source so that ES in tests will be built from $cloneAuthor/$cloneBranch" - export TEST_ES_FROM=source - fi - - echo " -> checking out '${cloneBranch}' branch from ${cloneAuthor}/${project}..." - git clone -b "$cloneBranch" "${repoAddress}${cloneAuthor}/${project}.git" "$targetDir" --depth=1 - echo " -> checked out ${project} revision: $(git -C "${targetDir}" rev-parse HEAD)" - echo - } - - checkout_clone_target - else - if [ -d "$targetDir" ]; then - echo "Using existing '${project}' checkout" - else - echo "You have defined '${useExistingParamName}' but no existing ${targetDir} directory exists!" - exit 2 - fi - fi -} - -checkout_sibling "elasticsearch" "${WORKSPACE}/elasticsearch" "USE_EXISTING_ES" -export TEST_ES_FROM=${TEST_ES_FROM:-snapshot} - -# Set the JAVA_HOME based on the Java property file in the ES repo -# This assumes the naming convention used on CI (ex: ~/.java/java10) -ES_DIR="$WORKSPACE/elasticsearch" -ES_JAVA_PROP_PATH=$ES_DIR/.ci/java-versions.properties - - -if [ ! -f "$ES_JAVA_PROP_PATH" ]; then - echo "Unable to set JAVA_HOME, $ES_JAVA_PROP_PATH does not exist" - exit 1 -fi - -# While sourcing the property file would currently work, we want -# to support the case where whitespace surrounds the equals. -# This has the added benefit of explicitly exporting property values -ES_BUILD_JAVA="$(grep "^ES_BUILD_JAVA" "$ES_JAVA_PROP_PATH" | cut -d'=' -f2 | tr -d '[:space:]')" -export ES_BUILD_JAVA - -if [ -z "$ES_BUILD_JAVA" ]; then - echo "Unable to set JAVA_HOME, ES_BUILD_JAVA not present in $ES_JAVA_PROP_PATH" - exit 1 -fi - -echo "Setting JAVA_HOME=$HOME/.java/$ES_BUILD_JAVA" -export JAVA_HOME=$HOME/.java/$ES_BUILD_JAVA diff --git a/src/dev/ci_setup/extract_bootstrap_cache.sh b/src/dev/ci_setup/extract_bootstrap_cache.sh deleted file mode 100755 index fdd8bb6b904060..00000000000000 --- a/src/dev/ci_setup/extract_bootstrap_cache.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env bash - -set -e - -targetBranch="${PR_TARGET_BRANCH:-$GIT_BRANCH}" -bootstrapCache="$HOME/.kibana/bootstrap_cache/$targetBranch.tar" - -### -### Extract the bootstrap cache that we create in the packer_cache.sh script -### -if [ -f "$bootstrapCache" ]; then - echo "extracting bootstrap_cache from $bootstrapCache"; - tar -xf "$bootstrapCache"; -else - branchBootstrapCache="$HOME/.kibana/bootstrap_cache/$(jq -r .branch package.json).tar" - - if [ -f "$branchBootstrapCache" ]; then - echo "extracting bootstrap_cache from $branchBootstrapCache"; - tar -xf "$branchBootstrapCache"; - else - echo "" - echo "" - echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; - echo " bootstrap_cache missing"; - echo " looked for '$bootstrapCache'"; - echo " and '$branchBootstrapCache'"; - echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; - echo "" - echo "" - fi -fi diff --git a/src/dev/ci_setup/get_percy_env.js b/src/dev/ci_setup/get_percy_env.js deleted file mode 100644 index a4a247d2527c36..00000000000000 --- a/src/dev/ci_setup/get_percy_env.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -const execa = require('execa'); -const pkg = require('../../../package.json'); - -const { stdout: commit } = execa.sync('git', ['rev-parse', 'HEAD']); -const shortCommit = commit.slice(0, 8); - -const isPr = !!process.env.ghprbPullId; -if (isPr && !(process.env.PR_TARGET_BRANCH && process.env.PR_SOURCE_BRANCH)) { - throw new Error( - 'getPercyEnv: Unable to determine percy environment in prs without [PR_TARGET_BRANCH] and [PR_SOURCE_BRANCH] environment variables' - ); -} - -let branch; -if (isPr) { - branch = process.env.PR_SOURCE_BRANCH; -} else { - if (!process.env.branch_specifier) { - throw new Error('getPercyEnv: [branch_specifier] environment variable required'); - } - - branch = process.env.branch_specifier.split('refs/heads/')[1]; - - if (!branch) { - throw new Error( - `getPercyEnv: [branch_specifier=${process.env.branch_specifier}] must start with 'refs/heads/'` - ); - } -} - -console.log(`export PERCY_PARALLEL_TOTAL=2;`); -console.log( - `export PERCY_PARALLEL_NONCE="${shortCommit}/${isPr ? 'PR' : branch}/${process.env.BUILD_ID}";` -); -console.log(`export PERCY_BRANCH="${branch}";`); -// percy snapshots always target pkg.branch, so that feature branches can be based on master/7.x/etc. -console.log(`export PERCY_TARGET_BRANCH="${isPr ? process.env.PR_TARGET_BRANCH : pkg.branch}";`); diff --git a/src/dev/ci_setup/load_env_keys.sh b/src/dev/ci_setup/load_env_keys.sh deleted file mode 100644 index 62d29db232eae9..00000000000000 --- a/src/dev/ci_setup/load_env_keys.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash - -set -e - -if [ -z "$VAULT_SECRET_ID" ]; then - if [ -n "$GITHUB_TOKEN" ] && [ -n "$KIBANA_CI_REPORTER_KEY" ] && [ -n "$PERCY_TOKEN" ]; then - echo " -- secrets already loaded from vault"; - else - echo "" - echo "" - echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; - echo " VAULT_SECRET_ID not set, not loading tokens into env"; - echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; - echo "" - echo "" - fi -else - # load shared helpers to get `retry` function - source /usr/local/bin/bash_standard_lib.sh - - set +x - - # export after define to avoid https://github.com/koalaman/shellcheck/wiki/SC2155 - VAULT_TOKEN=$(retry 5 vault write -field=token auth/approle/login role_id="$VAULT_ROLE_ID" secret_id="$VAULT_SECRET_ID") - export VAULT_TOKEN - - # Set GITHUB_TOKEN for reporting test failures - GITHUB_TOKEN=$(retry 5 vault read -field=github_token secret/kibana-issues/dev/kibanamachine) - export GITHUB_TOKEN - - KIBANA_CI_REPORTER_KEY=$(retry 5 vault read -field=value secret/kibana-issues/dev/kibanamachine-reporter) - export KIBANA_CI_REPORTER_KEY - - PERCY_TOKEN=$(retry 5 vault read -field=value secret/kibana-issues/dev/percy) - export PERCY_TOKEN - - # remove vault related secrets - unset VAULT_ROLE_ID VAULT_SECRET_ID VAULT_TOKEN VAULT_ADDR -fi diff --git a/src/dev/ci_setup/setup.sh b/src/dev/ci_setup/setup.sh deleted file mode 100755 index aeb0ba75a90522..00000000000000 --- a/src/dev/ci_setup/setup.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -set -e - -source src/dev/ci_setup/setup_env.sh true - -echo " -- KIBANA_DIR='$KIBANA_DIR'" -echo " -- XPACK_DIR='$XPACK_DIR'" -echo " -- PARENT_DIR='$PARENT_DIR'" -echo " -- KIBANA_PKG_BRANCH='$KIBANA_PKG_BRANCH'" -echo " -- TEST_ES_SNAPSHOT_VERSION='$TEST_ES_SNAPSHOT_VERSION'" - -### -### install dependencies -### -echo " -- installing node.js dependencies" -yarn kbn bootstrap --verbose - -### -### Download es snapshots -### -echo " -- downloading es snapshot" -node scripts/es snapshot --download-only; - -### -### verify no git modifications caused by bootstrap -### -if [[ "$DISABLE_BOOTSTRAP_VALIDATION" != "true" ]]; then - GIT_CHANGES="$(git ls-files --modified)" - if [ "$GIT_CHANGES" ]; then - echo -e "\n${RED}ERROR: 'yarn kbn bootstrap' caused changes to the following files:${C_RESET}\n" - echo -e "$GIT_CHANGES\n" - exit 1 - fi -fi diff --git a/src/dev/ci_setup/setup_env.sh b/src/dev/ci_setup/setup_env.sh deleted file mode 100644 index c1942775c88b54..00000000000000 --- a/src/dev/ci_setup/setup_env.sh +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env bash - -set -e - -if [[ "$CI_ENV_SETUP" ]]; then - return 0 -fi - -installNode=$1 - -dir="$(pwd)" -cacheDir="$HOME/.kibana" - -RED='\033[0;31m' -C_RESET='\033[0m' # Reset color - -export NODE_OPTIONS="$NODE_OPTIONS --max-old-space-size=4096" - -### -### Since the Jenkins logging output collector doesn't look like a TTY -### Node/Chalk and other color libs disable their color output. But Jenkins -### can handle color fine, so this forces https://github.com/chalk/supports-color -### to enable color support in Chalk and other related modules. -### -export FORCE_COLOR=1 - -### APM tracking -### -export ELASTIC_APM_ENVIRONMENT=ci - -### -### check that we seem to be in a kibana project -### -if [ -f "$dir/package.json" ] && [ -f "$dir/.node-version" ]; then - echo "Setting up node.js and yarn in $dir" -else - echo "${RED}src/dev/ci_setup/setup.sh must be run within a kibana repo${C_RESET}" - exit 1 -fi - - -export KIBANA_DIR="$dir" -export XPACK_DIR="$KIBANA_DIR/x-pack" - -parentDir="$(cd "$KIBANA_DIR/.."; pwd)" -export PARENT_DIR="$parentDir" - -kbnBranch="$(jq -r .branch "$KIBANA_DIR/package.json")" -export KIBANA_PKG_BRANCH="$kbnBranch" - -export WORKSPACE="${WORKSPACE:-$PARENT_DIR}" - -### -### download node -### -nodeVersion="$(cat "$dir/.node-version")" -nodeDir="$cacheDir/node/$nodeVersion" -nodeBin="$nodeDir/bin" -hostArch="$(command uname -m)" -case "${hostArch}" in - x86_64 | amd64) nodeArch="x64" ;; - aarch64) nodeArch="arm64" ;; - *) nodeArch="${hostArch}" ;; -esac -classifier="$nodeArch.tar.gz" - -UNAME=$(uname) -OS="linux" -if [[ "$UNAME" = *"MINGW64_NT"* ]]; then - OS="win" - nodeBin="$HOME/node" - classifier="x64.zip" -elif [[ "$UNAME" == "Darwin" ]]; then - OS="darwin" -fi -echo " -- Running on OS: $OS" - -nodeUrl="https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/dist/v$nodeVersion/node-v$nodeVersion-${OS}-${classifier}" - -if [[ "$installNode" == "true" ]]; then - echo " -- node: version=v${nodeVersion} dir=$nodeDir" - - echo " -- setting up node.js" - if [ -x "$nodeBin/node" ] && [ "$("$nodeBin/node" --version)" == "v$nodeVersion" ]; then - echo " -- reusing node.js install" - else - if [ -d "$nodeDir" ]; then - echo " -- clearing previous node.js install" - rm -rf "$nodeDir" - fi - - echo " -- downloading node.js from $nodeUrl" - mkdir -p "$nodeDir" - if [[ "$OS" == "win" ]]; then - nodePkg="$nodeDir/${nodeUrl##*/}" - curl --silent -L -o "$nodePkg" "$nodeUrl" - unzip -qo "$nodePkg" -d "$nodeDir" - mv "${nodePkg%.*}" "$nodeBin" - else - curl --silent -L "$nodeUrl" | tar -xz -C "$nodeDir" --strip-components=1 - fi - fi -fi - -### -### "install" node into this shell -### -export PATH="$nodeBin:$PATH" - -if [[ "$installNode" == "true" || ! $(which yarn) ]]; then - ### - ### downloading yarn - ### - yarnVersion="$(node -e "console.log(String(require('./package.json').engines.yarn || '').replace(/^[^\d]+/,''))")" - npm install -g "yarn@^${yarnVersion}" -fi - -### -### setup yarn offline cache -### -yarn config set yarn-offline-mirror "$cacheDir/yarn-offline-cache" - -### -### "install" yarn into this shell -### -yarnGlobalDir="$(yarn global bin)" -export PATH="$PATH:$yarnGlobalDir" - -# use a proxy to fetch chromedriver/geckodriver asset -export GECKODRIVER_CDNURL="https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache" -export CHROMEDRIVER_CDNURL="https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache" -export CHROMEDRIVER_CDNBINARIESURL="https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache" -export RE2_DOWNLOAD_MIRROR="https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache" -export SASS_BINARY_SITE="https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/node-sass" -export CYPRESS_DOWNLOAD_MIRROR="https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/cypress" - -export CHECKS_REPORTER_ACTIVE=false - -# This is mainly for release-manager builds, which run in an environment that doesn't have Chrome installed -if [[ "$(which google-chrome-stable)" || "$(which google-chrome)" ]]; then - echo "Chrome detected, setting DETECT_CHROMEDRIVER_VERSION=true" - export DETECT_CHROMEDRIVER_VERSION=true - export CHROMEDRIVER_FORCE_DOWNLOAD=true -else - echo "Chrome not detected, installing default chromedriver binary for the package version" -fi - -### only run on pr jobs for elastic/kibana, checks-reporter doesn't work for other repos -if [[ "$ghprbPullId" && "$ghprbGhRepository" == 'elastic/kibana' ]] ; then - export CHECKS_REPORTER_ACTIVE=true -fi - - -source "$KIBANA_DIR/src/dev/ci_setup/load_env_keys.sh" - -ES_DIR="$WORKSPACE/elasticsearch" -ES_JAVA_PROP_PATH=$ES_DIR/.ci/java-versions.properties - -if [[ -d "$ES_DIR" && -f "$ES_JAVA_PROP_PATH" ]]; then - ES_BUILD_JAVA="$(grep "^ES_BUILD_JAVA" "$ES_JAVA_PROP_PATH" | cut -d'=' -f2 | tr -d '[:space:]')" - export ES_BUILD_JAVA - - if [ -z "$ES_BUILD_JAVA" ]; then - echo "Unable to set JAVA_HOME, ES_BUILD_JAVA not present in $ES_JAVA_PROP_PATH" - exit 1 - fi - - echo "Setting JAVA_HOME=$HOME/.java/$ES_BUILD_JAVA" - export JAVA_HOME=$HOME/.java/$ES_BUILD_JAVA -fi - -export CI_ENV_SETUP=true diff --git a/src/dev/ci_setup/setup_percy.sh b/src/dev/ci_setup/setup_percy.sh deleted file mode 100755 index ed6a15d056fe5a..00000000000000 --- a/src/dev/ci_setup/setup_percy.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -set -e - -### -### skip chomium download, use the system chrome install -### -export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true -PUPPETEER_EXECUTABLE_PATH="$(command -v google-chrome-stable)" -export PUPPETEER_EXECUTABLE_PATH - -### -### Set Percy parallel build support environment vars -### -eval "$(node ./src/dev/ci_setup/get_percy_env)" -echo " -- PERCY_PARALLEL_NONCE='$PERCY_PARALLEL_NONCE'" -echo " -- PERCY_PARALLEL_TOTAL='$PERCY_PARALLEL_TOTAL'" -echo " -- PERCY_BRANCH='$PERCY_BRANCH'" -echo " -- PERCY_TARGET_BRANCH='$PERCY_TARGET_BRANCH'" diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js index acf4748055589a..d7376a81d4525b 100644 --- a/src/dev/precommit_hook/casing_check_config.js +++ b/src/dev/precommit_hook/casing_check_config.js @@ -37,7 +37,6 @@ export const IGNORE_FILE_GLOBS = [ 'packages/core/apps/core-apps-server-internal/assets/fonts/**/*', 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/**/*', 'packages/kbn-utility-types/test-d/**/*', - '**/Jenkinsfile*', 'Dockerfile*', 'vars/*', '.ci/pipeline-library/**/*', diff --git a/src/dev/storybook/aliases.ts b/src/dev/storybook/aliases.ts index 88d8c04b42337b..97990be32aa893 100644 --- a/src/dev/storybook/aliases.ts +++ b/src/dev/storybook/aliases.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -// Please also add new aliases to test/scripts/jenkins_storybook.sh +// Please also add new aliases to .buildkite/scripts/steps/storybooks/build_and_upload.ts // // If you wish for your Storybook to be built and included in CI, also add your // alias to .buildkite/scripts/steps/storybooks/build_and_upload.ts diff --git a/test/scripts/checks/baseline_plugin_public_api_docs.sh b/test/scripts/checks/baseline_plugin_public_api_docs.sh deleted file mode 100755 index 72de7c0980a5fc..00000000000000 --- a/test/scripts/checks/baseline_plugin_public_api_docs.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -### -### rebuild plugin api docs to ensure it's not out of date -### -echo " -- building api docs" -node --max-old-space-size=12000 scripts/build_api_docs diff --git a/test/scripts/checks/bundle_limits.sh b/test/scripts/checks/bundle_limits.sh deleted file mode 100755 index 10d9d9343fda4e..00000000000000 --- a/test/scripts/checks/bundle_limits.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -node scripts/build_kibana_platform_plugins --validate-limits diff --git a/test/scripts/checks/commit/commit.sh b/test/scripts/checks/commit/commit.sh deleted file mode 100755 index 180f6dfb56e29b..00000000000000 --- a/test/scripts/checks/commit/commit.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -# Runs pre-commit hook script for the files touched in the last commit. -# That way we can ensure a set of quick commit checks earlier as we removed -# the pre-commit hook installation by default. -# If files are more than 200 we will skip it and just use -# the further ci steps that already check linting and file casing for the entire repo. -"$(dirname "${0}")/commit_check_runner.sh" diff --git a/test/scripts/checks/commit/commit_check_runner.sh b/test/scripts/checks/commit/commit_check_runner.sh deleted file mode 100755 index 65ca9a6ecef06e..00000000000000 --- a/test/scripts/checks/commit/commit_check_runner.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -run_quick_commit_checks() { - echo "!!!!!!!! ATTENTION !!!!!!!! -That check is intended to provide earlier CI feedback after we remove the automatic install for the local pre-commit hook. -If you want, you can still manually install the pre-commit hook locally by running 'node scripts/register_git_hook locally' -!!!!!!!!!!!!!!!!!!!!!!!!!!! -" - - node scripts/precommit_hook.js --ref HEAD~1..HEAD --max-files 200 -} - -run_quick_commit_checks diff --git a/test/scripts/checks/file_casing.sh b/test/scripts/checks/file_casing.sh deleted file mode 100755 index 1a2240d0562ff2..00000000000000 --- a/test/scripts/checks/file_casing.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -node scripts/check_file_casing --quiet diff --git a/test/scripts/checks/i18n.sh b/test/scripts/checks/i18n.sh deleted file mode 100755 index 468b8394081e1b..00000000000000 --- a/test/scripts/checks/i18n.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -node scripts/i18n_check --ignore-missing diff --git a/test/scripts/checks/jest_configs.sh b/test/scripts/checks/jest_configs.sh deleted file mode 100755 index cebcbc63bb3961..00000000000000 --- a/test/scripts/checks/jest_configs.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -node scripts/check_jest_configs diff --git a/test/scripts/checks/licenses.sh b/test/scripts/checks/licenses.sh deleted file mode 100755 index 8a19cdc2fc126e..00000000000000 --- a/test/scripts/checks/licenses.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -node scripts/check_licenses --dev diff --git a/test/scripts/checks/plugin_list_docs.sh b/test/scripts/checks/plugin_list_docs.sh deleted file mode 100644 index b0f49d78458410..00000000000000 --- a/test/scripts/checks/plugin_list_docs.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -### -### rebuild plugin list to ensure it's not out of date -### -echo " -- building plugin list docs" -node scripts/build_plugin_list_docs - -### -### verify no git modifications -### -GIT_CHANGES="$(git ls-files --modified)" -if [ "$GIT_CHANGES" ]; then - echo -e "\n${RED}ERROR: 'node scripts/build_plugin_list_docs' caused changes to the following files:${C_RESET}\n" - echo -e "$GIT_CHANGES\n" - exit 1 -fi diff --git a/test/scripts/checks/telemetry.sh b/test/scripts/checks/telemetry.sh deleted file mode 100755 index 09b2305f9d607b..00000000000000 --- a/test/scripts/checks/telemetry.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -node scripts/telemetry_check diff --git a/test/scripts/checks/test_hardening.sh b/test/scripts/checks/test_hardening.sh deleted file mode 100755 index 332edb0fcde685..00000000000000 --- a/test/scripts/checks/test_hardening.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -node scripts/test_hardening diff --git a/test/scripts/checks/test_projects.sh b/test/scripts/checks/test_projects.sh deleted file mode 100755 index 6a1a8b958c4aac..00000000000000 --- a/test/scripts/checks/test_projects.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -yarn kbn run-in-packages test diff --git a/test/scripts/checks/ts_projects.sh b/test/scripts/checks/ts_projects.sh deleted file mode 100755 index 9963d10792f948..00000000000000 --- a/test/scripts/checks/ts_projects.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -node scripts/check_ts_projects diff --git a/test/scripts/checks/type_check_plugin_public_api_docs.sh b/test/scripts/checks/type_check_plugin_public_api_docs.sh deleted file mode 100755 index b5fed38e192d28..00000000000000 --- a/test/scripts/checks/type_check_plugin_public_api_docs.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -node scripts/build_ts_refs \ - --clean \ - --no-cache \ - --force - -node scripts/type_check - -echo " -- building api docs" -node --max-old-space-size=12000 scripts/build_api_docs diff --git a/test/scripts/checks/verify_notice.sh b/test/scripts/checks/verify_notice.sh deleted file mode 100755 index 55dd1c04aaf8a1..00000000000000 --- a/test/scripts/checks/verify_notice.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -node scripts/notice --validate diff --git a/test/scripts/jenkins_accessibility.sh b/test/scripts/jenkins_accessibility.sh deleted file mode 100755 index fa582cf2d97d0a..00000000000000 --- a/test/scripts/jenkins_accessibility.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_oss.sh - -node scripts/functional_tests \ - --debug --bail \ - --kibana-install-dir "$KIBANA_INSTALL_DIR" \ - --config test/accessibility/config.ts; diff --git a/test/scripts/jenkins_apm_cypress.sh b/test/scripts/jenkins_apm_cypress.sh deleted file mode 100755 index 2ccd7d760fba52..00000000000000 --- a/test/scripts/jenkins_apm_cypress.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_xpack.sh - -echo " -> Running APM cypress tests" -cd "$XPACK_DIR" - -node plugins/apm/scripts/test/e2e.js - -echo "" -echo "" diff --git a/test/scripts/jenkins_build_kbn_sample_panel_action.sh b/test/scripts/jenkins_build_kbn_sample_panel_action.sh deleted file mode 100755 index 67c3da246ed7cf..00000000000000 --- a/test/scripts/jenkins_build_kbn_sample_panel_action.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -cd test/plugin_functional/plugins/kbn_sample_panel_action; -if [[ ! -d "target" ]]; then - yarn build; -fi -cd -; diff --git a/test/scripts/jenkins_build_kibana.sh b/test/scripts/jenkins_build_kibana.sh deleted file mode 100755 index 28d4feef3a4b90..00000000000000 --- a/test/scripts/jenkins_build_kibana.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash - -cd "$KIBANA_DIR" -source src/dev/ci_setup/setup_env.sh - -if [[ ! "$TASK_QUEUE_PROCESS_ID" ]]; then - ./test/scripts/jenkins_build_plugins.sh -fi - -# doesn't persist, also set in kibanaPipeline.groovy -export KBN_NP_PLUGINS_BUILT=true - -# Do not build kibana for code coverage run -if [[ -z "$CODE_COVERAGE" ]] ; then - echo " -> building and extracting default Kibana distributable for use in functional tests" - node scripts/build --debug - - echo " -> shipping metrics from build to ci-stats" - node scripts/ship_ci_stats \ - --metrics target/optimizer_bundle_metrics.json \ - --metrics build/kibana/node_modules/@kbn/ui-shared-deps-src/shared_built_assets/metrics.json - - linuxBuild="$(find "$KIBANA_DIR/target" -name 'kibana-*-linux-x86_64.tar.gz')" - installDir="$KIBANA_DIR/install/kibana" - mkdir -p "$installDir" - tar -xzf "$linuxBuild" -C "$installDir" --strip=1 - cp "$linuxBuild" "$WORKSPACE/kibana-default.tar.gz" - - mkdir -p "$WORKSPACE/kibana-build" - cp -pR install/kibana/. $WORKSPACE/kibana-build/ - - echo " -> Archive built plugins" - shopt -s globstar - tar -zcf \ - "$WORKSPACE/kibana-default-plugins.tar.gz" \ - x-pack/plugins/**/target/public \ - x-pack/test/**/target/public \ - examples/**/target/public \ - x-pack/examples/**/target/public \ - test/**/target/public - shopt -u globstar -fi diff --git a/test/scripts/jenkins_build_load_testing.sh b/test/scripts/jenkins_build_load_testing.sh deleted file mode 100755 index f64caa3c02cabb..00000000000000 --- a/test/scripts/jenkins_build_load_testing.sh +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env bash - -while getopts s: flag -do - case "${flag}" in - s) simulations=${OPTARG};; - esac -done -echo "Simulation classes: $simulations"; - -cd "$KIBANA_DIR" -source src/dev/ci_setup/setup_env.sh - -if [[ ! "$TASK_QUEUE_PROCESS_ID" ]]; then - ./test/scripts/jenkins_xpack_build_plugins.sh -fi - -echo " -> Configure Metricbeat monitoring" -# Configure Metricbeat monitoring for Kibana and ElasticSearch, ingest monitoring data into Kibana Stats cluster -# Getting the URL -TOP="$(curl -L http://snapshots.elastic.co/latest/master.json)" -MB_BUILD=$(echo $TOP | sed 's/.*"version" : "\(.*\)", "build_id.*/\1/') -echo $MB_BUILD -MB_BUILD_ID=$(echo $TOP | sed 's/.*"build_id" : "\(.*\)", "manifest_url.*/\1/') - -URL=https://snapshots.elastic.co/${MB_BUILD_ID}/downloads/beats/metricbeat/metricbeat-${MB_BUILD}-linux-x86_64.tar.gz -URL=https://artifacts.elastic.co/downloads/beats/metricbeat/metricbeat-7.11.0-linux-x86_64.tar.gz -echo $URL -# Downloading the Metricbeat package -while [ 1 ]; do - wget -q --retry-connrefused --waitretry=1 --read-timeout=20 --timeout=15 -t 0 --continue --no-check-certificate --tries=3 $URL - if [ $? = 0 ]; then break; fi; # check return value, break if successful (0) - sleep 1s; -done; - -# Install Metricbeat -echo "untar metricbeat and config" -#tar -xzf metricbeat-${MB_BUILD}-linux-x86_64.tar.gz -tar -xzf metricbeat-7.11.0-linux-x86_64.tar.gz -#mv metricbeat-${MB_BUILD}-linux-x86_64 metricbeat-install -mv metricbeat-7.11.0-linux-x86_64 metricbeat-install - -# Configure Metricbeat -echo " -> Changing metricbeat config" -pushd ../kibana-load-testing -cp cfg/metricbeat/elasticsearch-xpack.yml $KIBANA_DIR/metricbeat-install/modules.d/elasticsearch-xpack.yml -cp cfg/metricbeat/kibana-xpack.yml $KIBANA_DIR/metricbeat-install/modules.d/kibana-xpack.yml -echo "fields.build: ${BUILD_ID}" >> cfg/metricbeat/metricbeat.yml -echo "path.config: ${KIBANA_DIR}/metricbeat-install" >> cfg/metricbeat/metricbeat.yml -echo "cloud.auth: ${USER_FROM_VAULT}:${PASS_FROM_VAULT}" >> cfg/metricbeat/metricbeat.yml -cp cfg/metricbeat/metricbeat.yml $KIBANA_DIR/metricbeat-install/metricbeat.yml -# Disable system monitoring: enabled for now to have more data -#mv $KIBANA_DIR/metricbeat-install/modules.d/system.yml $KIBANA_DIR/metricbeat-install/modules.d/system.yml.disabled -echo " -> Building puppeteer project" -cd puppeteer -yarn install && yarn build -popd - -# doesn't persist, also set in kibanaPipeline.groovy -export KBN_NP_PLUGINS_BUILT=true - -echo " -> Building and extracting default Kibana distributable for use in functional tests" -cd "$KIBANA_DIR" -node scripts/build --debug -linuxBuild="$(find "$KIBANA_DIR/target" -name 'kibana-*-linux-x86_64.tar.gz')" -installDir="$KIBANA_DIR/install/kibana" -mkdir -p "$installDir" -tar -xzf "$linuxBuild" -C "$installDir" --strip=1 - -mkdir -p "$WORKSPACE/kibana-build" -cp -pR install/kibana/. $WORKSPACE/kibana-build/ - -echo " -> Setup env for tests" -source test/scripts/jenkins_test_setup_xpack.sh - -# Start Metricbeat -echo " -> Starting metricbeat" -pushd $KIBANA_DIR/metricbeat-install -nohup ./metricbeat > metricbeat.log 2>&1 & -popd - -echo " -> Running gatling load testing" -export GATLING_SIMULATIONS="$simulations" -node scripts/functional_tests \ - --kibana-install-dir "$KIBANA_INSTALL_DIR" \ - --config test/load/config.ts; - - -echo " -> Simulations run is finished" - -# Show output of Metricbeat. Disabled. Enable for debug purposes -#echo "output of metricbeat.log" -#cat $KIBANA_DIR/metricbeat-install/metricbeat.log diff --git a/test/scripts/jenkins_build_plugins.sh b/test/scripts/jenkins_build_plugins.sh deleted file mode 100755 index dd1715065e7996..00000000000000 --- a/test/scripts/jenkins_build_plugins.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -echo " -> building kibana platform plugins" -node scripts/build_kibana_platform_plugins \ - --scan-dir "$KIBANA_DIR/test/plugin_functional/plugins" \ - --scan-dir "$KIBANA_DIR/test/health_gateway/plugins" \ - --scan-dir "$KIBANA_DIR/test/interpreter_functional/plugins" \ - --scan-dir "$KIBANA_DIR/test/common/plugins" \ - --scan-dir "$KIBANA_DIR/examples" \ - --scan-dir "$KIBANA_DIR/test/plugin_functional/plugins" \ - --scan-dir "$KIBANA_DIR/test/common/plugins" \ - --scan-dir "$XPACK_DIR/test/plugin_functional/plugins" \ - --scan-dir "$XPACK_DIR/test/functional_with_es_ssl/plugins" \ - --scan-dir "$XPACK_DIR/test/alerting_api_integration/plugins" \ - --scan-dir "$XPACK_DIR/test/plugin_api_integration/plugins" \ - --scan-dir "$XPACK_DIR/test/plugin_api_perf/plugins" \ - --scan-dir "$XPACK_DIR/test/licensing_plugin/plugins" \ - --scan-dir "$XPACK_DIR/test/usage_collection/plugins" \ - --scan-dir "$XPACK_DIR/test/security_functional/fixtures/common" \ - --scan-dir "$XPACK_DIR/examples" \ - --workers 12 diff --git a/test/scripts/jenkins_ci_group.sh b/test/scripts/jenkins_ci_group.sh deleted file mode 100755 index dde224823789b3..00000000000000 --- a/test/scripts/jenkins_ci_group.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_oss.sh - -if [[ -z "$CODE_COVERAGE" ]]; then - echo " -> Running functional and api tests" - - node scripts/functional_tests \ - --debug --bail \ - --kibana-install-dir "$KIBANA_INSTALL_DIR" \ - --include-tag "ciGroup$CI_GROUP" - - if [[ ! "$TASK_QUEUE_PROCESS_ID" && "$CI_GROUP" == "1" ]]; then - source test/scripts/jenkins_build_kbn_sample_panel_action.sh - ./test/scripts/test/plugin_functional.sh - ./test/scripts/test/health_gateway.sh - ./test/scripts/test/interpreter_functional.sh - fi -else - echo " -> Running Functional tests with code coverage" - export NODE_OPTIONS=--max_old_space_size=8192 - - echo " -> making hard link clones" - cd .. - cp -RlP kibana "kibana${CI_GROUP}" - cd "kibana${CI_GROUP}" - - echo " -> running tests from the clone folder" - node scripts/functional_tests --debug --include-tag "ciGroup$CI_GROUP" --exclude-tag "skipCoverage" || true; - - echo " -> moving junit output, silently fail in case of no report" - mkdir -p ../kibana/target/junit - mv target/junit/* ../kibana/target/junit/ || echo "copying junit failed" - - echo " -> copying screenshots and html for failures" - cp -r test/functional/screenshots/* ../kibana/test/functional/screenshots/ || echo "copying screenshots failed" - cp -r test/functional/failure_debug ../kibana/test/functional/ || echo "copying html failed" -fi diff --git a/test/scripts/jenkins_cloud.sh b/test/scripts/jenkins_cloud.sh deleted file mode 100755 index 57798a9afcac17..00000000000000 --- a/test/scripts/jenkins_cloud.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -# This script runs kibana tests compatible with cloud. -# -# The cloud instance setup is done in the elastic/elastic-stack-testing framework, -# where the following environment variables are set pointing to the cloud instance. -# -# export TEST_KIBANA_HOSTNAME -# export TEST_KIBANA_PROTOCOL= -# export TEST_KIBANA_PORT= -# export TEST_KIBANA_USER= -# export TEST_KIBANA_PASS= -# -# export TEST_ES_HOSTNAME= -# export TEST_ES_PROTOCOL= -# export TEST_ES_PORT= -# export TEST_ES_USER= -# export TEST_ES_PASS= -# - -set -e - -source "$(dirname $0)/../../src/dev/ci_setup/setup.sh" - -export TEST_BROWSER_HEADLESS=1 -node scripts/functional_test_runner --debug --exclude-tag skipCloud $@ diff --git a/test/scripts/jenkins_firefox_smoke.sh b/test/scripts/jenkins_firefox_smoke.sh deleted file mode 100755 index 4566b11822bf58..00000000000000 --- a/test/scripts/jenkins_firefox_smoke.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_oss.sh - -node scripts/functional_tests \ - --bail --debug \ - --kibana-install-dir "$KIBANA_INSTALL_DIR" \ - --include-tag "includeFirefox" \ - --config test/functional/config.firefox.js; diff --git a/test/scripts/jenkins_fleet_cypress.sh b/test/scripts/jenkins_fleet_cypress.sh deleted file mode 100755 index e43259c1c1c3f6..00000000000000 --- a/test/scripts/jenkins_fleet_cypress.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_xpack.sh - -echo " -> Running fleet cypress tests" -cd "$XPACK_DIR" - -cd x-pack/plugins/fleet -yarn --cwd x-pack/plugins/fleet cypress:run - -echo "" -echo "" diff --git a/test/scripts/jenkins_osquery_cypress.sh b/test/scripts/jenkins_osquery_cypress.sh deleted file mode 100755 index b4a9420ff94402..00000000000000 --- a/test/scripts/jenkins_osquery_cypress.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_xpack.sh - -echo " -> Running osquery cypress tests" -cd "$XPACK_DIR" - -node scripts/functional_tests \ - --debug --bail \ - --kibana-install-dir "$KIBANA_INSTALL_DIR" \ - --config test/osquery_cypress/cli_config.ts - -echo "" -echo "" diff --git a/test/scripts/jenkins_plugin_functional.sh b/test/scripts/jenkins_plugin_functional.sh deleted file mode 100755 index 984e648bf6b848..00000000000000 --- a/test/scripts/jenkins_plugin_functional.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_oss.sh - -cd test/plugin_functional/plugins/kbn_sample_panel_action; -if [[ ! -d "target" ]]; then - yarn build; -fi -cd -; - -pwd - -./test/scripts/test/plugin_functional.sh -./test/scripts/test/health_gateway.sh -./test/scripts/test/interpreter_functional.sh diff --git a/test/scripts/jenkins_runbld_junit.sh b/test/scripts/jenkins_runbld_junit.sh deleted file mode 100755 index bcb6accd5f8cd4..00000000000000 --- a/test/scripts/jenkins_runbld_junit.sh +++ /dev/null @@ -1,2 +0,0 @@ -# This file just exists to give runbld something to invoke before processing junit reports -echo 'Processing junit reports with runbld...' diff --git a/test/scripts/jenkins_security_solution_cypress_chrome.sh b/test/scripts/jenkins_security_solution_cypress_chrome.sh deleted file mode 100755 index 0605a319896ce7..00000000000000 --- a/test/scripts/jenkins_security_solution_cypress_chrome.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_xpack.sh - -echo " -> Running security solution cypress tests" -cd "$XPACK_DIR" - -node scripts/functional_tests \ - --debug --bail \ - --kibana-install-dir "$KIBANA_INSTALL_DIR" \ - --config test/security_solution_cypress/cli_config.ts - -echo "" -echo "" diff --git a/test/scripts/jenkins_setup.sh b/test/scripts/jenkins_setup.sh deleted file mode 100755 index 8c8492d10e6026..00000000000000 --- a/test/scripts/jenkins_setup.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/load_env_keys.sh -source src/dev/ci_setup/extract_bootstrap_cache.sh -source src/dev/ci_setup/setup.sh -source src/dev/ci_setup/checkout_sibling_es.sh \ No newline at end of file diff --git a/test/scripts/jenkins_setup_parallel_workspace.sh b/test/scripts/jenkins_setup_parallel_workspace.sh deleted file mode 100755 index 5274d05572e713..00000000000000 --- a/test/scripts/jenkins_setup_parallel_workspace.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash -set -e - -CURRENT_DIR=$(pwd) - -# Copy everything except node_modules into the current workspace -rsync -a ${WORKSPACE}/kibana/* . --exclude node_modules -rsync -a ${WORKSPACE}/kibana/.??* . - -# Symlink all non-root, non-fixture node_modules into our new workspace -cd ${WORKSPACE}/kibana -find . -type d -name node_modules -not -path '*__fixtures__*' -not -path './node_modules*' -prune -print0 | xargs -0I % ln -s "${WORKSPACE}/kibana/%" "${CURRENT_DIR}/%" -find . -type d -wholename '*__fixtures__*node_modules' -not -path './node_modules*' -prune -print0 | xargs -0I % cp -R "${WORKSPACE}/kibana/%" "${CURRENT_DIR}/%" -cd "${CURRENT_DIR}" - -# Symlink all of the individual root-level node_modules into the node_modules/ directory -mkdir -p node_modules -ln -s ${WORKSPACE}/kibana/node_modules/* node_modules/ -ln -s ${WORKSPACE}/kibana/node_modules/.??* node_modules/ - -# Copy a few node_modules instead of symlinking them. They don't work correctly if symlinked -unlink node_modules/@kbn -unlink node_modules/css-loader -unlink node_modules/style-loader - -# packages/kbn-optimizer/src/integration_tests/basic_optimization.test.ts will fail if this is a symlink -unlink node_modules/val-loader - -cp -R ${WORKSPACE}/kibana/node_modules/@kbn node_modules/ -cp -R ${WORKSPACE}/kibana/node_modules/css-loader node_modules/ -cp -R ${WORKSPACE}/kibana/node_modules/style-loader node_modules/ -cp -R ${WORKSPACE}/kibana/node_modules/val-loader node_modules/ diff --git a/test/scripts/jenkins_storybook.sh b/test/scripts/jenkins_storybook.sh deleted file mode 100755 index 058c58ed922eba..00000000000000 --- a/test/scripts/jenkins_storybook.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -cd "$KIBANA_DIR" - -yarn storybook --site apm -yarn storybook --site canvas -yarn storybook --site cell_actions -yarn storybook --site ci_composite -yarn storybook --site content_management -yarn storybook --site custom_integrations -yarn storybook --site dashboard -yarn storybook --site dashboard_enhanced -yarn storybook --site data -yarn storybook --site embeddable -yarn storybook --site expression_error -yarn storybook --site expression_image -yarn storybook --site expression_metric -yarn storybook --site expression_repeat_image -yarn storybook --site expression_reveal_image -yarn storybook --site expression_shape -yarn storybook --site expression_tagcloud -yarn storybook --site fleet -yarn storybook --site infra -yarn storybook --site kibana_react -yarn storybook --site lists -yarn storybook --site observability -yarn storybook --site presentation -yarn storybook --site security_solution -yarn storybook --site solution_side_nav -yarn storybook --site shared_ux -yarn storybook --site ui_actions_enhanced diff --git a/test/scripts/jenkins_test_setup.sh b/test/scripts/jenkins_test_setup.sh deleted file mode 100755 index 05b88aa2dd0a20..00000000000000 --- a/test/scripts/jenkins_test_setup.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash - -set -e - -function post_work() { - set +e - if [[ -z "$REMOVE_KIBANA_INSTALL_DIR" && -z "$KIBANA_INSTALL_DIR" && -d "$KIBANA_INSTALL_DIR" ]]; then - rm -rf "$REMOVE_KIBANA_INSTALL_DIR" - fi -} - -trap 'post_work' EXIT - -export TEST_BROWSER_HEADLESS=1 - -source src/dev/ci_setup/setup_env.sh - -# For parallel workspaces, we should copy the .es directory from the root, because it should already have downloaded snapshots in it -# This isn't part of jenkins_setup_parallel_workspace.sh just because not all tasks require ES -if [[ ! -d .es && -d "$WORKSPACE/kibana/.es" ]]; then - cp -R $WORKSPACE/kibana/.es ./ -fi diff --git a/test/scripts/jenkins_test_setup_oss.sh b/test/scripts/jenkins_test_setup_oss.sh deleted file mode 100755 index 29d396667c465a..00000000000000 --- a/test/scripts/jenkins_test_setup_oss.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup.sh - -if [[ -z "$CODE_COVERAGE" ]]; then - destDir="$WORKSPACE/kibana-build-${TASK_QUEUE_PROCESS_ID:-$CI_PARALLEL_PROCESS_NUMBER}" - - if [[ ! -d $destDir ]]; then - mkdir -p $destDir - cp -pR "$WORKSPACE/kibana-build/." $destDir/ - fi - - export KIBANA_INSTALL_DIR="$destDir" -fi diff --git a/test/scripts/jenkins_test_setup_xpack.sh b/test/scripts/jenkins_test_setup_xpack.sh deleted file mode 100755 index 31acc4f4865e2e..00000000000000 --- a/test/scripts/jenkins_test_setup_xpack.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup.sh - -if [[ -z "$CODE_COVERAGE" ]]; then - destDir="$WORKSPACE/kibana-build-${TASK_QUEUE_PROCESS_ID:-$CI_PARALLEL_PROCESS_NUMBER}" - - if [[ ! -d $destDir ]]; then - mkdir -p $destDir - cp -pR "$WORKSPACE/kibana-build/." $destDir/ - fi - - export KIBANA_INSTALL_DIR="$(realpath $destDir)" - - cd "$XPACK_DIR" -fi diff --git a/test/scripts/jenkins_uptime_playwright.sh b/test/scripts/jenkins_uptime_playwright.sh deleted file mode 100755 index 5bea30a223cd41..00000000000000 --- a/test/scripts/jenkins_uptime_playwright.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_xpack.sh - -echo " -> Running synthetics @elastic/synthetics tests" -cd "$XPACK_DIR" - -node plugins/synthetics/scripts/e2e.js - -echo "" -echo "" diff --git a/test/scripts/jenkins_ux_synthetics.sh b/test/scripts/jenkins_ux_synthetics.sh deleted file mode 100755 index acf2611e36b948..00000000000000 --- a/test/scripts/jenkins_ux_synthetics.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_xpack.sh - -echo " -> Running User Experience plugin @elastic/synthetics tests" -cd "$XPACK_DIR" - -node plugins/ux/scripts/e2e.js - -echo "" -echo "" diff --git a/test/scripts/jenkins_xpack_accessibility.sh b/test/scripts/jenkins_xpack_accessibility.sh deleted file mode 100755 index b1daa0ada1d50e..00000000000000 --- a/test/scripts/jenkins_xpack_accessibility.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_xpack.sh - -node scripts/functional_tests \ - --debug --bail \ - --kibana-install-dir "$KIBANA_INSTALL_DIR" \ - --config test/accessibility/config.ts; diff --git a/test/scripts/jenkins_xpack_baseline.sh b/test/scripts/jenkins_xpack_baseline.sh deleted file mode 100755 index a0a98ccd5a5e7b..00000000000000 --- a/test/scripts/jenkins_xpack_baseline.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh -source "$KIBANA_DIR/src/dev/ci_setup/setup_percy.sh" - -echo " -> building and extracting default Kibana distributable" -cd "$KIBANA_DIR" -node scripts/build --debug - -echo " -> shipping metrics from build to ci-stats" -node scripts/ship_ci_stats \ - --metrics target/optimizer_bundle_metrics.json \ - --metrics build/kibana/node_modules/@kbn/ui-shared-deps-src/shared_built_assets/metrics.json - -linuxBuild="$(find "$KIBANA_DIR/target" -name 'kibana-*-linux-x86_64.tar.gz')" -installDir="$KIBANA_DIR/install/kibana" -mkdir -p "$installDir" -tar -xzf "$linuxBuild" -C "$installDir" --strip=1 - -mkdir -p "$WORKSPACE/kibana-build" -cp -pR install/kibana/. $WORKSPACE/kibana-build/ - -cd "$KIBANA_DIR" -source "test/scripts/jenkins_xpack_saved_objects_field_metrics.sh" diff --git a/test/scripts/jenkins_xpack_build_plugins.sh b/test/scripts/jenkins_xpack_build_plugins.sh deleted file mode 100755 index bdf6ee24555270..00000000000000 --- a/test/scripts/jenkins_xpack_build_plugins.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -echo " -> building kibana platform plugins" -node scripts/build_kibana_platform_plugins \ - --scan-dir "$KIBANA_DIR/test/plugin_functional/plugins" \ - --scan-dir "$KIBANA_DIR/test/common/plugins" \ - --scan-dir "$XPACK_DIR/test/plugin_functional/plugins" \ - --scan-dir "$XPACK_DIR/test/functional_with_es_ssl/plugins" \ - --scan-dir "$XPACK_DIR/test/alerting_api_integration/plugins" \ - --scan-dir "$XPACK_DIR/test/plugin_api_integration/plugins" \ - --scan-dir "$XPACK_DIR/test/plugin_api_perf/plugins" \ - --scan-dir "$XPACK_DIR/test/licensing_plugin/plugins" \ - --scan-dir "$XPACK_DIR/test/usage_collection/plugins" \ - --scan-dir "$XPACK_DIR/test/security_functional/fixtures/common" \ - --scan-dir "$KIBANA_DIR/examples" \ - --scan-dir "$XPACK_DIR/examples" \ - --workers 12 diff --git a/test/scripts/jenkins_xpack_ci_group.sh b/test/scripts/jenkins_xpack_ci_group.sh deleted file mode 100755 index 59bcf45a2089f8..00000000000000 --- a/test/scripts/jenkins_xpack_ci_group.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_xpack.sh - -if [[ -z "$CODE_COVERAGE" ]]; then - echo " -> Running functional and api tests" - - node scripts/functional_tests \ - --debug --bail \ - --kibana-install-dir "$KIBANA_INSTALL_DIR" \ - --include-tag "ciGroup$CI_GROUP" - - echo "" - echo "" -else - echo " -> Running X-Pack functional tests with code coverage" - export NODE_OPTIONS=--max_old_space_size=8192 - - echo " -> making hard link clones" - cd .. - cp -RlP kibana "kibana${CI_GROUP}" - cd "kibana${CI_GROUP}/x-pack" - - echo " -> running tests from the clone folder" - node scripts/functional_tests --debug --include-tag "ciGroup$CI_GROUP" --exclude-tag "skipCoverage" || true; - - echo " -> moving junit output, silently fail in case of no report" - mkdir -p ../../kibana/target/junit - mv ../target/junit/* ../../kibana/target/junit/ || echo "copying junit failed" - - echo " -> copying screenshots and html for failures" - cp -r test/functional/screenshots/* ../../kibana/x-pack/test/functional/screenshots/ || echo "copying screenshots failed" - cp -r test/functional/failure_debug ../../kibana/x-pack/test/functional/ || echo "copying html failed" -fi diff --git a/test/scripts/jenkins_xpack_firefox_smoke.sh b/test/scripts/jenkins_xpack_firefox_smoke.sh deleted file mode 100755 index de19d3867520d5..00000000000000 --- a/test/scripts/jenkins_xpack_firefox_smoke.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_xpack.sh - -node scripts/functional_tests \ - --debug --bail \ - --kibana-install-dir "$KIBANA_INSTALL_DIR" \ - --include-tag "includeFirefox" \ - --config test/functional/config.firefox.js \ - --config test/functional_embedded/config.firefox.ts; diff --git a/test/scripts/jenkins_xpack_saved_objects_field_metrics.sh b/test/scripts/jenkins_xpack_saved_objects_field_metrics.sh deleted file mode 100755 index fc3a7db06a43bd..00000000000000 --- a/test/scripts/jenkins_xpack_saved_objects_field_metrics.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_xpack.sh - -node scripts/functional_tests \ - --debug --bail \ - --kibana-install-dir "$KIBANA_INSTALL_DIR" \ - --config test/saved_objects_field_count/config.ts; diff --git a/test/scripts/lint/eslint.sh b/test/scripts/lint/eslint.sh deleted file mode 100755 index 8395df85c5d309..00000000000000 --- a/test/scripts/lint/eslint.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -node scripts/eslint --no-cache diff --git a/test/scripts/lint/stylelint.sh b/test/scripts/lint/stylelint.sh deleted file mode 100755 index 2f500c7e14aaa0..00000000000000 --- a/test/scripts/lint/stylelint.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -node scripts/stylelint diff --git a/test/scripts/test/api_integration.sh b/test/scripts/test/api_integration.sh deleted file mode 100755 index 06263c38b07283..00000000000000 --- a/test/scripts/test/api_integration.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -node scripts/functional_tests \ - --config test/api_integration/config.js \ - --bail \ - --debug diff --git a/test/scripts/test/health_gateway.sh b/test/scripts/test/health_gateway.sh deleted file mode 100755 index 18a9b81b083de5..00000000000000 --- a/test/scripts/test/health_gateway.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_oss.sh - -node scripts/functional_tests \ - --config test/health_gateway/config.ts \ - --bail \ - --debug \ - --kibana-install-dir $KIBANA_INSTALL_DIR diff --git a/test/scripts/test/interpreter_functional.sh b/test/scripts/test/interpreter_functional.sh deleted file mode 100755 index 2a40c81c34ad02..00000000000000 --- a/test/scripts/test/interpreter_functional.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_oss.sh - -node scripts/functional_tests \ - --config test/interpreter_functional/config.ts \ - --bail \ - --debug \ - --kibana-install-dir $KIBANA_INSTALL_DIR diff --git a/test/scripts/test/jest_integration.sh b/test/scripts/test/jest_integration.sh deleted file mode 100755 index 3b27ba06842bec..00000000000000 --- a/test/scripts/test/jest_integration.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -node --max-old-space-size=5120 scripts/jest_integration --ci diff --git a/test/scripts/test/jest_unit.sh b/test/scripts/test/jest_unit.sh deleted file mode 100755 index f368554e357608..00000000000000 --- a/test/scripts/test/jest_unit.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -node scripts/jest --ci --maxWorkers=6 diff --git a/test/scripts/test/plugin_functional.sh b/test/scripts/test/plugin_functional.sh deleted file mode 100755 index 115ddb81d3e45e..00000000000000 --- a/test/scripts/test/plugin_functional.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_oss.sh - -node scripts/functional_tests \ - --config test/plugin_functional/config.ts \ - --bail \ - --debug diff --git a/test/scripts/test/server_integration.sh b/test/scripts/test/server_integration.sh deleted file mode 100755 index fa4c4c6ce2c356..00000000000000 --- a/test/scripts/test/server_integration.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_oss.sh - -node scripts/functional_tests \ - --config test/server_integration/http/ssl/config.js \ - --config test/server_integration/http/ssl_redirect/config.js \ - --config test/server_integration/http/platform/config.ts \ - --config test/server_integration/http/ssl_with_p12/config.js \ - --config test/server_integration/http/ssl_with_p12_intermediate/config.js \ - --bail \ - --debug \ - --kibana-install-dir $KIBANA_INSTALL_DIR - -# Tests that must be run against source in order to build test plugins -node scripts/functional_tests \ - --config test/server_integration/http/platform/config.status.ts \ - --bail \ - --debug diff --git a/vars/agentInfo.groovy b/vars/agentInfo.groovy deleted file mode 100644 index 166a86c1692616..00000000000000 --- a/vars/agentInfo.groovy +++ /dev/null @@ -1,40 +0,0 @@ -def print() { - catchError(catchInterruptions: false, buildResult: null) { - def startTime = sh(script: "date -d '-3 minutes' -Iseconds | sed s/+/%2B/", returnStdout: true).trim() - def endTime = sh(script: "date -d '+1 hour 30 minutes' -Iseconds | sed s/+/%2B/", returnStdout: true).trim() - - def resourcesUrl = - ( - "https://infra-stats.elastic.co/app/kibana#/visualize/edit/8bd92360-1b92-11ea-b719-aba04518cc34" + - "?_g=(time:(from:'${startTime}',to:'${endTime}'))" + - "&_a=(query:'host.name:${env.NODE_NAME}')" - ) - .replaceAll("'", '%27') // Need to escape ' because of the shell echo below, but can't really replace "'" with "\'" because of groovy sandbox - .replaceAll(/\)$/, '%29') // This is just here because the URL parsing in the Jenkins console doesn't work right - - def logsStartTime = sh(script: "date -d '-3 minutes' +%s", returnStdout: true).trim() - def logsUrl = - ( - "https://infra-stats.elastic.co/app/infra#/logs" + - "?_g=()&flyoutOptions=(flyoutId:!n,flyoutVisibility:hidden,surroundingLogsId:!n)" + - "&logFilter=(expression:'host.name:${env.NODE_NAME}',kind:kuery)" + - "&logPosition=(position:(time:${logsStartTime}000),streamLive:!f)" - ) - .replaceAll("'", '%27') - .replaceAll('\\)', '%29') - - sh script: """ - set +x - echo 'Resource Graph:' - echo '${resourcesUrl}' - echo '' - echo 'Agent Logs:' - echo '${logsUrl}' - echo '' - echo 'SSH Command:' - echo "ssh -F ssh_config \$(hostname --ip-address)" - """, label: "Worker/Agent/Node debug links" - } -} - -return this diff --git a/vars/buildState.groovy b/vars/buildState.groovy deleted file mode 100644 index 365705661350ce..00000000000000 --- a/vars/buildState.groovy +++ /dev/null @@ -1,30 +0,0 @@ -import groovy.transform.Field - -public static @Field JENKINS_BUILD_STATE = [:] - -def add(key, value) { - if (!buildState.JENKINS_BUILD_STATE.containsKey(key)) { - buildState.JENKINS_BUILD_STATE[key] = value - return true - } - - return false -} - -def set(key, value) { - buildState.JENKINS_BUILD_STATE[key] = value -} - -def get(key) { - return buildState.JENKINS_BUILD_STATE[key] -} - -def has(key) { - return buildState.JENKINS_BUILD_STATE.containsKey(key) -} - -def get() { - return buildState.JENKINS_BUILD_STATE -} - -return this diff --git a/vars/catchErrors.groovy b/vars/catchErrors.groovy deleted file mode 100644 index 2a1b55d832606c..00000000000000 --- a/vars/catchErrors.groovy +++ /dev/null @@ -1,15 +0,0 @@ -// Basically, this is a shortcut for catchError(catchInterruptions: false) {} -// By default, catchError will swallow aborts/timeouts, which we almost never want -// Also, by wrapping it in an additional try/catch, we cut down on spam in Pipeline Steps -def call(Map params = [:], Closure closure) { - try { - closure() - } catch (ex) { - params.catchInterruptions = false - catchError(params) { - throw ex - } - } -} - -return this diff --git a/vars/esSnapshots.groovy b/vars/esSnapshots.groovy deleted file mode 100644 index 884fbcdb17aebb..00000000000000 --- a/vars/esSnapshots.groovy +++ /dev/null @@ -1,50 +0,0 @@ -def promote(snapshotVersion, snapshotId) { - def snapshotDestination = "${snapshotVersion}/archives/${snapshotId}" - def MANIFEST_URL = "https://storage.googleapis.com/kibana-ci-es-snapshots-daily/${snapshotDestination}/manifest.json" - - dir('verified-manifest') { - def verifiedSnapshotFilename = 'manifest-latest-verified.json' - - sh """ - curl -O '${MANIFEST_URL}' - mv manifest.json ${verifiedSnapshotFilename} - """ - - googleStorageUpload( - credentialsId: 'kibana-ci-gcs-plugin', - bucket: "gs://kibana-ci-es-snapshots-daily/${snapshotVersion}", - pattern: verifiedSnapshotFilename, - sharedPublicly: false, - showInline: false, - ) - } - - // This would probably be more efficient if we could just copy using gsutil and specifying buckets for src and dest - // But we don't currently have access to the GCS credentials in a way that can be consumed easily from here... - dir('transfer-to-permanent') { - googleStorageDownload( - credentialsId: 'kibana-ci-gcs-plugin', - bucketUri: "gs://kibana-ci-es-snapshots-daily/${snapshotDestination}/*", - localDirectory: '.', - pathPrefix: snapshotDestination, - ) - - def manifestJson = readFile file: 'manifest.json' - writeFile( - file: 'manifest.json', - text: manifestJson.replace("kibana-ci-es-snapshots-daily/${snapshotDestination}", "kibana-ci-es-snapshots-permanent/${snapshotVersion}") - ) - - // Ideally we would have some delete logic here before uploading, - // But we don't currently have access to the GCS credentials in a way that can be consumed easily from here... - googleStorageUpload( - credentialsId: 'kibana-ci-gcs-plugin', - bucket: "gs://kibana-ci-es-snapshots-permanent/${snapshotVersion}", - pattern: '*.*', - sharedPublicly: false, - showInline: false, - ) - } -} - -return this diff --git a/vars/getCheckoutInfo.groovy b/vars/getCheckoutInfo.groovy deleted file mode 100644 index f9d797f8127c7a..00000000000000 --- a/vars/getCheckoutInfo.groovy +++ /dev/null @@ -1,50 +0,0 @@ -def call(branchOverride) { - def repoInfo = [ - branch: branchOverride ?: env.ghprbSourceBranch, - targetBranch: env.ghprbTargetBranch, - targetsTrackedBranch: true - ] - - if (repoInfo.branch == null) { - if (!(params.branch_specifier instanceof String)) { - throw new Exception( - "Unable to determine branch automatically, either pass a branch name to getCheckoutInfo() or use the branch_specifier param." - ) - } - - // strip prefix from the branch specifier to make it consistent with ghprbSourceBranch - repoInfo.branch = params.branch_specifier.replaceFirst(/^(refs\/heads\/|origin\/)/, "") - } - - repoInfo.commit = sh( - script: "git rev-parse HEAD", - label: "determining checked out sha", - returnStdout: true - ).trim() - - if (repoInfo.targetBranch) { - // Try to clone fetch from Github up to 8 times, waiting 15 secs between attempts - retryWithDelay(8, 15) { - sh( - script: "git fetch origin ${repoInfo.targetBranch}", - label: "fetch latest from '${repoInfo.targetBranch}' at origin" - ) - } - - repoInfo.mergeBase = sh( - script: "git merge-base HEAD FETCH_HEAD", - label: "determining merge point with '${repoInfo.targetBranch}' at origin", - returnStdout: true - ).trim() - - def pkgJson = readFile("package.json") - def releaseBranch = toJSON(pkgJson).branch - repoInfo.targetsTrackedBranch = releaseBranch == repoInfo.targetBranch - } - - print "repoInfo: ${repoInfo}" - - return repoInfo -} - -return this diff --git a/vars/githubCommitStatus.groovy b/vars/githubCommitStatus.groovy deleted file mode 100644 index 175dbe0c90542f..00000000000000 --- a/vars/githubCommitStatus.groovy +++ /dev/null @@ -1,57 +0,0 @@ -def defaultCommit() { - if (buildState.has('checkoutInfo')) { - return buildState.get('checkoutInfo').commit - } -} - -def onStart(commit = defaultCommit(), context = 'kibana-ci') { - catchError { - if (githubPr.isPr() || !commit) { - return - } - - create(commit, 'pending', 'Build started.', context) - } -} - -def onFinish(commit = defaultCommit(), context = 'kibana-ci') { - catchError { - if (githubPr.isPr() || !commit) { - return - } - - def status = buildUtils.getBuildStatus() - - if (status == 'SUCCESS' || status == 'UNSTABLE') { - create(commit, 'success', 'Build completed successfully.', context) - } else if(status == 'ABORTED') { - create(commit, 'error', 'Build aborted or timed out.', context) - } else { - create(commit, 'error', 'Build failed.', context) - } - } -} - -def trackBuild(commit, context, Closure closure) { - onStart(commit, context) - catchError { - closure() - } - onFinish(commit, context) -} - -// state: error|failure|pending|success -def create(sha, state, description, context, targetUrl = null) { - targetUrl = targetUrl ?: env.BUILD_URL - - withGithubCredentials { - return githubApi.post("repos/elastic/kibana/statuses/${sha}", [ - state: state, - description: description, - context: context, - target_url: targetUrl.toString() - ]) - } -} - -return this diff --git a/vars/githubPr.groovy b/vars/githubPr.groovy deleted file mode 100644 index 594d54f2c5b5e6..00000000000000 --- a/vars/githubPr.groovy +++ /dev/null @@ -1,369 +0,0 @@ -/** - Wraps the main/important part of a job, executes it, and then publishes a comment to GitHub with the status. - - It will check for the existence of GHPRB env variables before doing any actual PR work, - so it can be used to wrap code that is executed in both PR and non-PR contexts. - - Inside the comment, it will hide a JSON blob containing build data (status, etc). - - Then, the next time it posts a comment, it will: - 1. Read the previous comment and parse the json - 2. Create a new comment, add a summary of up to 5 previous builds to it, and append this build's data to the hidden JSON - 3. Delete the old comment - - So, there is only ever one build status comment on a PR at any given time, the most recent one. -*/ -def withDefaultPrComments(closure) { - catchErrors { - // kibanaPipeline.notifyOnError() needs to know if comments are enabled, so lets track it with a global - // isPr() just ensures this functionality is skipped for non-PR builds - buildState.set('PR_COMMENTS_ENABLED', isPr()) - catchErrors { - closure() - } - sendComment(true) - } -} - -def sendComment(isFinal = false) { - if (!buildState.get('PR_COMMENTS_ENABLED')) { - return - } - - def status = buildUtils.getBuildStatus() - if (status == "ABORTED") { - return - } - - def lastComment = getLatestBuildComment() - def info = getLatestBuildInfo(lastComment) ?: [:] - info.builds = (info.builds ?: []).takeRight(5) // Rotate out old builds - - // If two builds are running at the same time, the first one should not post a comment after the second one - if (info.number && info.number.toInteger() > env.BUILD_NUMBER.toInteger()) { - return - } - - def shouldUpdateComment = !!info.builds.find { it.number == env.BUILD_NUMBER } - - def message = getNextCommentMessage(info, isFinal) - - if (shouldUpdateComment) { - updateComment(lastComment.id, message) - } else { - createComment(message) - - if (lastComment && lastComment.user.login == 'kibanamachine') { - deleteComment(lastComment.id) - } - } -} - -// Checks whether or not this currently executing build was triggered via a PR in the elastic/kibana repo -def isPr() { - return !!(env.ghprbPullId && env.ghprbPullLink && env.ghprbPullLink =~ /\/elastic\/kibana\//) -} - -def isTrackedBranchPr() { - return isPr() && (env.ghprbTargetBranch == 'master' || env.ghprbTargetBranch == '6.8' || env.ghprbTargetBranch =~ /[7-8]\.[x0-9]+/) -} - -def getLatestBuildComment() { - return getComments() - .reverse() - .find { (it.user.login == 'elasticmachine' || it.user.login == 'kibanamachine') && it.body =~ /<!--PIPELINE/ } -} - -def getBuildInfoFromComment(commentText) { - def matches = commentText =~ /(?ms)<!--PIPELINE(.*?)PIPELINE-->/ - if (!matches || !matches[0]) { - return null - } - - return toJSON(matches[0][1].trim()) -} - -def getLatestBuildInfo() { - return getLatestBuildInfo(getLatestBuildComment()) -} - -def getLatestBuildInfo(comment) { - return comment ? getBuildInfoFromComment(comment.body) : null -} - -def getHistoryText(builds) { - if (!builds || builds.size() < 1) { - return "" - } - - def list = builds - .reverse() - .collect { build -> - if (build.status == "SUCCESS") { - return "* :green_heart: [Build #${build.number}](${build.url}) succeeded ${build.commit}" - } else if(build.status == "UNSTABLE") { - return "* :yellow_heart: [Build #${build.number}](${build.url}) was flaky ${build.commit}" - } else { - return "* :broken_heart: [Build #${build.number}](${build.url}) failed ${build.commit}" - } - } - .join("\n") - - return "### History\n${list}" -} - -def getTestFailuresMessage() { - def failures = testUtils.getFailures() - if (!failures) { - return "" - } - - def messages = [] - messages << "---\n\n### [Test Failures](${env.BUILD_URL}testReport)" - - failures.take(3).each { failure -> - messages << """ -<details><summary>${failure.fullDisplayName}</summary> - -[Link to Jenkins](${failure.url}) -""" - - if (failure.stdOut) { - messages << "\n#### Standard Out\n```\n${failure.stdOut}\n```" - } - - if (failure.stdErr) { - messages << "\n#### Standard Error\n```\n${failure.stdErr}\n```" - } - - if (failure.stacktrace) { - messages << "\n#### Stack Trace\n```\n${failure.stacktrace}\n```" - } - - messages << "</details>\n\n---" - } - - if (failures.size() > 3) { - messages << "and ${failures.size() - 3} more failures, only showing the first 3." - } - - return messages.join("\n") -} - -def getBuildStatusIncludingMetrics() { - def status = buildUtils.getBuildStatus() - - if (status == 'SUCCESS' && shouldCheckCiMetricSuccess() && !ciStats.getMetricsSuccess()) { - return 'FAILURE' - } - - return status -} - -def getNextCommentMessage(previousCommentInfo = [:], isFinal = false) { - def info = previousCommentInfo ?: [:] - info.builds = previousCommentInfo.builds ?: [] - - // When we update an in-progress comment, we need to remove the old version from the history - info.builds = info.builds.findAll { it.number != env.BUILD_NUMBER } - - def messages = [] - - def status = isFinal - ? getBuildStatusIncludingMetrics() - : buildUtils.getBuildStatus() - - def storybooksUrl = buildState.get('storybooksUrl') - def storybooksMessage = storybooksUrl ? "* [Storybooks Preview](${storybooksUrl})" : "* Storybooks not built" - - if (!isFinal) { - storybooksMessage = storybooksUrl ? storybooksMessage : "* Storybooks not built yet" - - def failuresPart = status != 'SUCCESS' ? ', with failures' : '' - messages << """ - ## :hourglass_flowing_sand: Build in-progress${failuresPart} - * [continuous-integration/kibana-ci/pull-request](${env.BUILD_URL}) - * Commit: ${getCommitHash()} - ${storybooksMessage} - * This comment will update when the build is complete - """ - } else if (status == 'SUCCESS') { - messages << """ - ## :green_heart: Build Succeeded - * [continuous-integration/kibana-ci/pull-request](${env.BUILD_URL}) - * Commit: ${getCommitHash()} - ${storybooksMessage} - ${getDocsChangesLink()} - """ - } else if(status == 'UNSTABLE') { - def message = """ - ## :yellow_heart: Build succeeded, but was flaky - * [continuous-integration/kibana-ci/pull-request](${env.BUILD_URL}) - * Commit: ${getCommitHash()} - ${storybooksMessage} - ${getDocsChangesLink()} - """.stripIndent() - - def failures = retryable.getFlakyFailures() - if (failures && failures.size() > 0) { - def list = failures.collect { " * ${it.label}" }.join("\n") - message += "* Flaky suites:\n${list}" - } - - messages << message - } else { - messages << """ - ## :broken_heart: Build Failed - * [continuous-integration/kibana-ci/pull-request](${env.BUILD_URL}) - * Commit: ${getCommitHash()} - ${storybooksMessage} - * [Pipeline Steps](${env.BUILD_URL}flowGraphTable) (look for red circles / failed steps) - * [Interpreting CI Failures](https://www.elastic.co/guide/en/kibana/current/interpreting-ci-failures.html) - ${getDocsChangesLink()} - """ - } - - if (status != 'SUCCESS' && status != 'UNSTABLE') { - try { - def steps = getFailedSteps() - if (steps?.size() > 0) { - def list = steps.collect { "* [${it.displayName}](${it.logs})" }.join("\n") - messages << "### Failed CI Steps\n${list}" - } - } catch (ex) { - buildUtils.printStacktrace(ex) - print "Error retrieving failed pipeline steps for PR comment, will skip this section" - } - } - - messages << getTestFailuresMessage() - - catchErrors { - if (isFinal && isTrackedBranchPr()) { - messages << ciStats.getMetricsReport() - } - } - - if (info.builds && info.builds.size() > 0) { - messages << getHistoryText(info.builds) - } - - messages << "To update your PR or re-run it, just comment with:\n`@elasticmachine merge upstream`" - - catchErrors { - def assignees = getAssignees() - if (assignees) { - messages << "cc " + assignees.collect { "@${it}"}.join(" ") - } - } - - info.builds << [ - status: status, - url: env.BUILD_URL, - number: env.BUILD_NUMBER, - commit: getCommitHash() - ] - - messages << """ - <!--PIPELINE - ${toJSON(info).toString()} - PIPELINE--> - """ - - return messages - .findAll { !!it } // No blank strings - .collect { it.stripIndent().trim() } // This just allows us to indent various strings above, but leaves them un-indented in the comment - .join("\n\n") -} - -def createComment(message) { - if (!isPr()) { - error "Trying to post a GitHub PR comment on a non-PR or non-elastic PR build" - } - - withGithubCredentials { - return githubApi.post("repos/elastic/kibana/issues/${env.ghprbPullId}/comments", [ body: message ]) - } -} - -def getComments() { - withGithubCredentials { - return githubIssues.getComments(env.ghprbPullId) - } -} - -def updateComment(commentId, message) { - if (!isPr()) { - error "Trying to post a GitHub PR comment on a non-PR or non-elastic PR build" - } - - withGithubCredentials { - def path = "repos/elastic/kibana/issues/comments/${commentId}" - def json = toJSON([ body: message ]).toString() - - def resp = githubApi([ path: path ], [ method: "POST", data: json, headers: [ "X-HTTP-Method-Override": "PATCH" ] ]) - return toJSON(resp) - } -} - -def deleteComment(commentId) { - withGithubCredentials { - def path = "repos/elastic/kibana/issues/comments/${commentId}" - return githubApi([ path: path ], [ method: "DELETE" ]) - } -} - -def getCommitHash() { - return env.ghprbActualCommit -} - -def getDocsChangesLink() { - def url = "https://kibana_${env.ghprbPullId}.docs-preview.app.elstc.co/diff" - - try { - // httpRequest throws on status codes >400 and failures - def resp = httpRequest([ method: "GET", url: url ]) - - if (resp.contains("There aren't any differences!")) { - return "" - } - - return "* [Documentation Changes](${url})" - } catch (ex) { - print "Failed to reach ${url}" - buildUtils.printStacktrace(ex) - } - - return "" -} - -def getFailedSteps() { - return jenkinsApi.getFailedSteps()?.findAll { step -> - step.displayName != 'Check out from version control' - } -} - -def shouldCheckCiMetricSuccess() { - // disable ciMetrics success check when a PR is targetting a non-tracked branch - if (buildState.has('checkoutInfo') && !buildState.get('checkoutInfo').targetsTrackedBranch) { - return false - } - - return true -} - -def getPR() { - withGithubCredentials { - def path = "repos/elastic/kibana/pulls/${env.ghprbPullId}" - return githubApi.get(path) - } -} - -def getAssignees() { - def pr = getPR() - if (!pr) { - return [] - } - - return pr.assignees.collect { it.login } -} diff --git a/vars/jenkinsApi.groovy b/vars/jenkinsApi.groovy deleted file mode 100644 index 57818593ffeb23..00000000000000 --- a/vars/jenkinsApi.groovy +++ /dev/null @@ -1,21 +0,0 @@ -def getSteps() { - def url = "${env.BUILD_URL}api/json?tree=actions[nodes[iconColor,running,displayName,id,parents]]" - def responseRaw = httpRequest([ method: "GET", url: url ]) - def response = toJSON(responseRaw) - - def graphAction = response?.actions?.find { it._class == "org.jenkinsci.plugins.workflow.job.views.FlowGraphAction" } - - return graphAction?.nodes -} - -def getFailedSteps() { - def steps = getSteps() - def failedSteps = steps?.findAll { (it.iconColor == "red" || it.iconColor == "red_anime") && it._class == "org.jenkinsci.plugins.workflow.cps.nodes.StepAtomNode" } - failedSteps.each { step -> - step.logs = "${env.BUILD_URL}execution/node/${step.id}/log".toString() - } - - return failedSteps -} - -return this diff --git a/vars/kibanaPipeline.groovy b/vars/kibanaPipeline.groovy deleted file mode 100644 index 374219d8006000..00000000000000 --- a/vars/kibanaPipeline.groovy +++ /dev/null @@ -1,496 +0,0 @@ -def withPostBuildReporting(Map params, Closure closure) { - try { - closure() - } finally { - def parallelWorkspaces = [] - try { - parallelWorkspaces = getParallelWorkspaces() - } catch(ex) { - print ex - } - - if (params.runErrorReporter) { - catchErrors { - runErrorReporter([pwd()] + parallelWorkspaces) - } - } - - catchErrors { - publishJunit() - } - - catchErrors { - def parallelWorkspace = "${env.WORKSPACE}/parallel" - if (fileExists(parallelWorkspace)) { - dir(parallelWorkspace) { - def workspaceTasks = [:] - - parallelWorkspaces.each { workspaceDir -> - workspaceTasks[workspaceDir] = { - dir(workspaceDir) { - catchErrors { - runbld.junit() - } - } - } - } - - if (workspaceTasks) { - parallel(workspaceTasks) - } - } - } - } - } -} - -def getParallelWorkspaces() { - def workspaces = [] - def parallelWorkspace = "${env.WORKSPACE}/parallel" - if (fileExists(parallelWorkspace)) { - dir(parallelWorkspace) { - // findFiles only returns files if you use glob, so look for a file that should be in every valid workspace - workspaces = findFiles(glob: '*/kibana/package.json') - .collect { - // get the paths to the kibana directories for the parallel workspaces - return parallelWorkspace + '/' + it.path.tokenize('/').dropRight(1).join('/') - } - } - } - - return workspaces -} - -def notifyOnError(Closure closure) { - try { - closure() - } catch (ex) { - // If this is the first failed step, it's likely that the error hasn't propagated up far enough to mark the build as a failure - currentBuild.result = 'FAILURE' - catchErrors { - githubPr.sendComment(false) - } - catchErrors { - // an empty map is a valid config, but is falsey, so let's use .has() - if (buildState.has('SLACK_NOTIFICATION_CONFIG')) { - slackNotifications.sendFailedBuild(buildState.get('SLACK_NOTIFICATION_CONFIG')) - } - } - throw ex - } -} - -def withFunctionalTestEnv(List additionalEnvs = [], Closure closure) { - // This can go away once everything that uses the deprecated workers.parallelProcesses() is moved to task queue - def parallelId = env.TASK_QUEUE_PROCESS_ID ?: env.CI_PARALLEL_PROCESS_NUMBER - - def kibanaPort = "61${parallelId}1" - def esPort = "62${parallelId}1" - // Ports 62x2-62x9 kept open for ES nodes - def esTransportPort = "63${parallelId}1-63${parallelId}9" - def fleetPackageRegistryPort = "64${parallelId}1" - def alertingProxyPort = "64${parallelId}2" - def corsTestServerPort = "64${parallelId}3" - // needed for https://github.com/elastic/kibana/issues/107246 - def proxyTestServerPort = "64${parallelId}4" - def contextPropagationOnly = githubPr.isPr() ? "true" : "false" - - withEnv([ - "CI_GROUP=${parallelId}", - "REMOVE_KIBANA_INSTALL_DIR=1", - "CI_PARALLEL_PROCESS_NUMBER=${parallelId}", - "TEST_KIBANA_HOST=localhost", - "TEST_KIBANA_PORT=${kibanaPort}", - "TEST_KIBANA_URL=http://elastic:changeme@localhost:${kibanaPort}", - "TEST_ES_URL=http://elastic:changeme@localhost:${esPort}", - "TEST_ES_TRANSPORT_PORT=${esTransportPort}", - "TEST_CORS_SERVER_PORT=${corsTestServerPort}", - "TEST_PROXY_SERVER_PORT=${proxyTestServerPort}", - "KBN_NP_PLUGINS_BUILT=true", - "FLEET_PACKAGE_REGISTRY_PORT=${fleetPackageRegistryPort}", - "ALERTING_PROXY_PORT=${alertingProxyPort}", - "ELASTIC_APM_ACTIVE=true", - "ELASTIC_APM_CONTEXT_PROPAGATION_ONLY=${contextPropagationOnly}", - "ELASTIC_APM_TRANSACTION_SAMPLE_RATE=0.1", - ] + additionalEnvs) { - closure() - } -} - -def functionalTestProcess(String name, Closure closure) { - return { - notifyOnError { - withFunctionalTestEnv(["JOB=${name}"], closure) - } - } -} - -def functionalTestProcess(String name, String script) { - return functionalTestProcess(name) { - retryable(name) { - runbld(script, "Execute ${name}") - } - } -} - -def ossCiGroupProcess(ciGroup, withDelay = false) { - return functionalTestProcess("ciGroup" + ciGroup) { - if (withDelay && !(ciGroup instanceof String) && !(ciGroup instanceof GString)) { - sleep((ciGroup-1)*30) // smooth out CPU spikes from ES startup - } - - withEnv([ - "CI_GROUP=${ciGroup}", - "JOB=kibana-ciGroup${ciGroup}", - ]) { - retryable("kibana-ciGroup${ciGroup}") { - runbld("./test/scripts/jenkins_ci_group.sh", "Execute kibana-ciGroup${ciGroup}") - } - } - } -} - -def xpackCiGroupProcess(ciGroup, withDelay = false) { - return functionalTestProcess("xpack-ciGroup" + ciGroup) { - if (withDelay && !(ciGroup instanceof String) && !(ciGroup instanceof GString)) { - sleep((ciGroup-1)*30) // smooth out CPU spikes from ES startup - } - withEnv([ - "CI_GROUP=${ciGroup}", - "JOB=xpack-kibana-ciGroup${ciGroup}", - ]) { - retryable("xpack-kibana-ciGroup${ciGroup}") { - runbld("./test/scripts/jenkins_xpack_ci_group.sh", "Execute xpack-kibana-ciGroup${ciGroup}") - } - } - } -} - -def uploadGcsArtifact(uploadPrefix, pattern) { - googleStorageUpload( - credentialsId: 'kibana-ci-gcs-plugin', - bucket: "gs://${uploadPrefix}", - pattern: pattern, - sharedPublicly: true, - showInline: true, - ) -} - -def withGcsArtifactUpload(workerName, closure) { - def uploadPrefix = "kibana-ci-artifacts/jobs/${env.JOB_NAME}/${BUILD_NUMBER}/${workerName}" - def ARTIFACT_PATTERNS = [ - 'target/junit/**/*', - 'target/kibana-*', - 'target/kibana-coverage/jest/**/*', - 'target/kibana-security-solution/**/*.png', - 'target/kibana-fleet/**/*.png', - 'target/test-metrics/*', - 'target/test-suites-ci-plan.json', - 'test/**/screenshots/diff/*.png', - 'test/**/screenshots/failure/*.png', - 'test/**/screenshots/session/*.png', - 'test/functional/failure_debug/html/*.html', - 'x-pack/test/**/screenshots/diff/*.png', - 'x-pack/test/**/screenshots/failure/*.png', - 'x-pack/test/**/screenshots/session/*.png', - 'x-pack/test/functional/failure_debug/html/*.html', - '.es/**/*.hprof' - ] - - withEnv([ - "GCS_UPLOAD_PREFIX=${uploadPrefix}" - ], { - try { - closure() - } finally { - catchErrors { - ARTIFACT_PATTERNS.each { pattern -> - uploadGcsArtifact(uploadPrefix, pattern) - } - - dir(env.WORKSPACE) { - ARTIFACT_PATTERNS.each { pattern -> - uploadGcsArtifact(uploadPrefix, "parallel/*/kibana/${pattern}") - } - } - } - } - }) -} - -def publishJunit() { - junit(testResults: 'target/junit/**/*.xml', allowEmptyResults: true, keepLongStdio: true) - - dir(env.WORKSPACE) { - junit(testResults: 'parallel/*/kibana/target/junit/**/*.xml', allowEmptyResults: true, keepLongStdio: true) - } -} - -def sendMail(Map params = [:]) { - // If the build doesn't have a result set by this point, there haven't been any errors and it can be marked as a success - // The e-mail plugin for the infra e-mail depends upon this being set - currentBuild.result = currentBuild.result ?: 'SUCCESS' - - def buildStatus = buildUtils.getBuildStatus() - if (buildStatus != 'SUCCESS' && buildStatus != 'ABORTED') { - node('flyweight') { - sendInfraMail() - sendKibanaMail(params) - } - } -} - -def sendInfraMail() { - catchErrors { - step([ - $class: 'Mailer', - notifyEveryUnstableBuild: true, - recipients: 'infra-root+build@elastic.co', - sendToIndividuals: false - ]) - } -} - -def sendKibanaMail(Map params = [:]) { - def config = [to: 'build-kibana@elastic.co'] + params - - catchErrors { - def buildStatus = buildUtils.getBuildStatus() - if(params.NOTIFY_ON_FAILURE && buildStatus != 'SUCCESS' && buildStatus != 'ABORTED') { - emailext( - config.to, - subject: "${env.JOB_NAME} - Build # ${env.BUILD_NUMBER} - ${buildStatus}", - body: '${SCRIPT,template="groovy-html.template"}', - mimeType: 'text/html', - ) - } - } -} - -def bash(script, label) { - sh( - script: "#!/bin/bash\n${script}", - label: label - ) -} - -def doSetup() { - notifyOnError { - retryWithDelay(2, 15) { - try { - runbld("./test/scripts/jenkins_setup.sh", "Setup Build Environment and Dependencies") - } catch (ex) { - try { - // Setup expects this directory to be missing, so we need to remove it before we do a retry - bash("rm -rf ../elasticsearch", "Remove elasticsearch sibling directory, if it exists") - } finally { - throw ex - } - } - } - } -} - -def getBuildArtifactBucket() { - def dir = env.ghprbPullId ? "pr-${env.ghprbPullId}" : buildState.get('checkoutInfo').branch.replace("/", "__") - return "gs://ci-artifacts.kibana.dev/default-build/${dir}/${buildState.get('checkoutInfo').commit}" -} - -def buildKibana(maxWorkers = '') { - notifyOnError { - withEnv(["KBN_OPTIMIZER_MAX_WORKERS=${maxWorkers}"]) { - runbld("./test/scripts/jenkins_build_kibana.sh", "Build Kibana") - } - - withGcpServiceAccount.fromVaultSecret('secret/kibana-issues/dev/ci-artifacts-key', 'value') { - bash(""" - cd "${env.WORKSPACE}" - gsutil -q -m cp 'kibana-default.tar.gz' '${getBuildArtifactBucket()}/' - gsutil -q -m cp 'kibana-default-plugins.tar.gz' '${getBuildArtifactBucket()}/' - """, "Upload Default Build artifacts to GCS") - } - } -} - -def downloadDefaultBuildArtifacts() { - withGcpServiceAccount.fromVaultSecret('secret/kibana-issues/dev/ci-artifacts-key', 'value') { - bash(""" - cd "${env.WORKSPACE}" - gsutil -q -m cp '${getBuildArtifactBucket()}/kibana-default.tar.gz' ./ - gsutil -q -m cp '${getBuildArtifactBucket()}/kibana-default-plugins.tar.gz' ./ - """, "Download Default Build artifacts from GCS") - } -} - -def runErrorReporter() { - return runErrorReporter([pwd()]) -} - -def runErrorReporter(workspaces) { - def status = buildUtils.getBuildStatus() - def dryRun = status != "ABORTED" ? "" : "--no-github-update" - - def globs = workspaces.collect { "'${it}/target/junit/**/*.xml'" }.join(" ") - - bash( - """ - source src/dev/ci_setup/setup_env.sh - node scripts/report_failed_tests --no-index-errors ${dryRun} ${globs} - """, - "Report failed tests, if necessary" - ) -} - -def call(Map params = [:], Closure closure) { - def config = [timeoutMinutes: 135, checkPrChanges: false, setCommitStatus: false] + params - - stage("Kibana Pipeline") { - timeout(time: config.timeoutMinutes, unit: 'MINUTES') { - timestamps { - ansiColor('xterm') { - if (config.setCommitStatus) { - buildState.set('shouldSetCommitStatus', true) - } - if (config.checkPrChanges && githubPr.isPr()) { - pipelineLibraryTests() - - print "Checking PR for changes to determine if CI needs to be run..." - - if (prChanges.areChangesSkippable()) { - print "No changes requiring CI found in PR, skipping." - return - } - } - try { - closure() - } finally { - if (config.setCommitStatus) { - githubCommitStatus.onFinish() - } - } - } - } - } - } -} - -// Creates a task queue using withTaskQueue, and copies the bootstrapped kibana repo into each process's workspace -// Note that node_modules are mostly symlinked to save time/space. See test/scripts/jenkins_setup_parallel_workspace.sh -def withCiTaskQueue(Map options = [:], Closure closure) { - def setupClosure = { - // This can't use runbld, because it expects the source to be there, which isn't yet - bash("${env.WORKSPACE}/kibana/test/scripts/jenkins_setup_parallel_workspace.sh", "Set up duplicate workspace for parallel process") - } - - def config = [parallel: 24, setup: setupClosure] + options - - withTaskQueue(config) { - closure.call() - } -} - -def scriptTask(description, script) { - return { - withFunctionalTestEnv { - notifyOnError { - runbld(script, description) - } - } - } -} - -def scriptTaskDocker(description, script) { - return { - withDocker(scriptTask(description, script)) - } -} - -def buildDocker() { - sh( - script: "./.ci/build_docker.sh", - label: 'Build CI Docker image' - ) -} - -def withDocker(Closure closure) { - docker - .image('kibana-ci') - .inside( - "-v /etc/runbld:/etc/runbld:ro -v '${env.JENKINS_HOME}:${env.JENKINS_HOME}' -v '/dev/shm/workspace:/dev/shm/workspace' --shm-size 2GB --cpus 4", - closure - ) -} - -def buildPlugins() { - runbld('./test/scripts/jenkins_build_plugins.sh', 'Build OSS Plugins') -} - -def withTasks(Map params = [:], Closure closure) { - catchErrors { - def config = [setupWork: {}, worker: [:], parallel: 24] + params - def workerConfig = [name: 'ci-worker', size: 'xxl', ramDisk: true] + config.worker - - workers.ci(workerConfig) { - withCiTaskQueue([parallel: config.parallel]) { - parallel([ - docker: { - retry(2) { - buildDocker() - } - }, - - // There are integration tests etc that require the plugins to be built first, so let's go ahead and build them before set up the parallel workspaces - plugins: { buildPlugins() }, - ]) - - config.setupWork() - - catchErrors { - closure() - } - } - } - } -} - -def allCiTasks() { - parallel([ - general: { - withTasks { - tasks.check() - tasks.lint() - tasks.test() - task { - buildKibana(16) - tasks.functionalOss() - tasks.functionalXpack() - } - tasks.storybooksCi() - } - }, - jest: { - workers.ci(name: 'jest', size: 'n2-standard-16', ramDisk: false) { - catchErrors { - scriptTask('Jest Unit Tests', 'test/scripts/test/jest_unit.sh')() - } - - catchErrors { - runbld.junit() - } - } - }, - ]) -} - -def pipelineLibraryTests() { - return - whenChanged(['vars/', '.ci/pipeline-library/']) { - workers.base(size: 'flyweight', bootstrapped: false, ramDisk: false) { - dir('.ci/pipeline-library') { - sh './gradlew test' - } - } - } -} - -return this diff --git a/vars/prChanges.groovy b/vars/prChanges.groovy deleted file mode 100644 index a8a81cade844c6..00000000000000 --- a/vars/prChanges.groovy +++ /dev/null @@ -1,82 +0,0 @@ -import groovy.transform.Field - -public static @Field PR_CHANGES_CACHE = [] - -// if all the changed files in a PR match one of these regular -// expressions then CI will be skipped for that PR -def getSkippablePaths() { - return [ - /^docs\//, - /^rfcs\//, - /^.ci\/.+\.yml$/, - /^.ci\/es-snapshots\//, - /^.ci\/pipeline-library\//, - /^.ci\/Jenkinsfile_[^\/]+$/, - /^\.github\//, - /\.md$/, - /^\.backportrc\.json$/, - /^\.buildkite\//, - ] -} - -// exclusion regular expressions that will invalidate paths that -// match one of the skippable path regular expressions -def getNotSkippablePaths() { - return [ - // this file is auto-generated and changes to it need to be validated with CI - /^docs\/developer\/plugin-list.asciidoc$/, - // don't skip CI on prs with changes to plugin readme files (?i) is for case-insensitive matching - /(?i)\/plugins\/[^\/]+\/readme\.(md|asciidoc)$/, - ] -} - -def areChangesSkippable() { - if (!githubPr.isPr()) { - return false - } - - try { - def skippablePaths = getSkippablePaths() - def notSkippablePaths = getNotSkippablePaths() - def files = getChangedFiles() - - // 3000 is the max files GH API will return - if (files.size() >= 3000) { - return false - } - - files = files.findAll { file -> - def skippable = skippablePaths.find { regex -> file =~ regex} && !notSkippablePaths.find { regex -> file =~ regex } - return !skippable - } - - return files.size() < 1 - } catch (ex) { - buildUtils.printStacktrace(ex) - print "Error while checking to see if CI is skippable based on changes. Will run CI." - return false - } -} - -def getChanges() { - if (!PR_CHANGES_CACHE && env.ghprbPullId) { - withGithubCredentials { - def changes = githubPrs.getChanges(env.ghprbPullId) - if (changes) { - PR_CHANGES_CACHE.addAll(changes) - } - } - } - - return PR_CHANGES_CACHE -} - -def getChangedFiles() { - def changes = getChanges() - def changedFiles = changes.collect { it.filename } - def renamedFiles = changes.collect { it.previousFilename }.findAll { it } - - return changedFiles + renamedFiles -} - -return this diff --git a/vars/retryWithDelay.groovy b/vars/retryWithDelay.groovy deleted file mode 100644 index 83fd94c6f2b1ec..00000000000000 --- a/vars/retryWithDelay.groovy +++ /dev/null @@ -1,18 +0,0 @@ -def call(retryTimes, delaySecs, closure) { - retry(retryTimes) { - try { - closure() - } catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException ex) { - throw ex // Immediately re-throw build abort exceptions, don't sleep first - } catch (Exception ex) { - sleep delaySecs - throw ex - } - } -} - -def call(retryTimes, Closure closure) { - call(retryTimes, 15, closure) -} - -return this diff --git a/vars/retryable.groovy b/vars/retryable.groovy deleted file mode 100644 index bfd021ddd8167b..00000000000000 --- a/vars/retryable.groovy +++ /dev/null @@ -1,78 +0,0 @@ -import groovy.transform.Field - -public static @Field GLOBAL_RETRIES_ENABLED = false -public static @Field MAX_GLOBAL_RETRIES = 1 -public static @Field CURRENT_GLOBAL_RETRIES = 0 -public static @Field FLAKY_FAILURES = [] - -def setMax(max) { - retryable.MAX_GLOBAL_RETRIES = max -} - -def enable() { - retryable.GLOBAL_RETRIES_ENABLED = true -} - -def enable(max) { - enable() - setMax(max) -} - -def haveReachedMaxRetries() { - return retryable.CURRENT_GLOBAL_RETRIES >= retryable.MAX_GLOBAL_RETRIES -} - -def getFlakyFailures() { - return retryable.FLAKY_FAILURES -} - -def printFlakyFailures() { - catchErrors { - def failures = getFlakyFailures() - - if (failures && failures.size() > 0) { - print "This build had the following flaky failures:" - failures.each { - print "\n${it.label}" - buildUtils.printStacktrace(it.exception) - } - } - } -} - -def call(label, Closure closure) { - if (!retryable.GLOBAL_RETRIES_ENABLED) { - closure() - return - } - - try { - closure() - } catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException ex) { - // If the build was aborted, don't retry the step - throw ex - } catch (Exception ex) { - if (haveReachedMaxRetries()) { - print "Couldn't retry '${label}', have already reached the max number of retries for this build." - throw ex - } - - retryable.CURRENT_GLOBAL_RETRIES++ - buildUtils.printStacktrace(ex) - unstable "${label} failed but is retryable, trying a second time..." - - def JOB = env.JOB ? "${env.JOB}-retry" : "" - withEnv([ - "JOB=${JOB}", - ]) { - closure() - } - - retryable.FLAKY_FAILURES << [ - label: label, - exception: ex, - ] - - unstable "${label} failed on the first attempt, but succeeded on the second. Marking it as flaky." - } -} diff --git a/vars/runbld.groovy b/vars/runbld.groovy deleted file mode 100644 index 80416d4fa9a412..00000000000000 --- a/vars/runbld.groovy +++ /dev/null @@ -1,17 +0,0 @@ -def call(script, label, enableJunitProcessing = false) { - // def extraConfig = enableJunitProcessing ? "" : "--config ${env.WORKSPACE}/kibana/.ci/runbld_no_junit.yml" - - sh( - script: "bash ${script}", - label: label ?: script - ) -} - -def junit() { - sh( - script: "/usr/local/bin/runbld -d '${pwd()}' ${env.WORKSPACE}/kibana/test/scripts/jenkins_runbld_junit.sh", - label: "Process JUnit reports with runbld" - ) -} - -return this diff --git a/vars/slackNotifications.groovy b/vars/slackNotifications.groovy deleted file mode 100644 index 02aad14d8ba3fb..00000000000000 --- a/vars/slackNotifications.groovy +++ /dev/null @@ -1,228 +0,0 @@ -def getFailedBuildBlocks() { - def messages = [ - getFailedSteps(), - getTestFailures(), - ] - - return messages - .findAll { !!it } // No blank strings - .collect { markdownBlock(it) } -} - -def dividerBlock() { - return [ type: "divider" ] -} - -// If a message is longer than the limit, split it up by '\n' into parts, and return as many parts as will fit within the limit -def shortenMessage(message, sizeLimit = 3000) { - if (message.size() <= sizeLimit) { - return message - } - - def truncatedMessage = "[...truncated...]" - - def parts = message.split("\n") - message = "" - - for(def part in parts) { - if ((message.size() + part.size() + truncatedMessage.size() + 1) > sizeLimit) { - break; - } - message += part+"\n" - } - - message += truncatedMessage - - return message.size() <= sizeLimit ? message : truncatedMessage -} - -def markdownBlock(message) { - return [ - type: "section", - text: [ - type: "mrkdwn", - text: shortenMessage(message, 3000), // 3000 is max text length for `section`s only - ], - ] -} - -def contextBlock(message) { - return [ - type: "context", - elements: [ - [ - type: 'mrkdwn', - text: message, // Not sure what the size limit is here, I tried 10000s of characters and it still worked - ] - ] - ] -} - -def getFailedSteps() { - try { - def steps = jenkinsApi.getFailedSteps()?.findAll { step -> - step.displayName != 'Check out from version control' - } - - if (steps?.size() > 0) { - def list = steps.collect { "• <${it.logs}|${it.displayName}>" }.join("\n") - return "*Failed Steps*\n${list}" - } - } catch (ex) { - buildUtils.printStacktrace(ex) - print "Error retrieving failed pipeline steps for PR comment, will skip this section" - } - - return "" -} - -def getTestFailures() { - def failures = testUtils.getFailures() - if (!failures) { - return "" - } - - def messages = [] - messages << "*Test Failures*" - - def list = failures.take(10).collect { - def name = it - .fullDisplayName - .split(/\./, 2)[-1] - // Only the following three characters need to be escaped for link text, per Slack's docs - .replaceAll('&', '&') - .replaceAll('<', '<') - .replaceAll('>', '>') - - return "• <${it.url}|${name}>" - }.join("\n") - - def moreText = failures.size() > 10 ? "\n• ...and ${failures.size()-10} more" : "" - return "*Test Failures*\n${list}${moreText}" -} - -def getDefaultDisplayName() { - return "${env.JOB_NAME} ${env.BUILD_DISPLAY_NAME}" -} - -def getDefaultContext(config = [:]) { - def progressMessage = "" - if (config && !config.isFinal) { - progressMessage = "In-progress" - } else { - def duration = currentBuild.durationString.replace(' and counting', '') - progressMessage = "${buildUtils.getBuildStatus().toLowerCase().capitalize()} after ${duration}" - } - - return contextBlock([ - progressMessage, - "<https://ci.kibana.dev/${env.JOB_BASE_NAME}/${env.BUILD_NUMBER}|ci.kibana.dev>", - ].join(' · ')) -} - -def getStatusIcon(config = [:]) { - if (config && !config.isFinal) { - return ':hourglass_flowing_sand:' - } - - def status = buildUtils.getBuildStatus() - if (status == 'UNSTABLE') { - return ':yellow_heart:' - } - - return ':broken_heart:' -} - -def getBackupMessage(config) { - return "${getStatusIcon(config)} ${config.title}\n\nFirst attempt at sending this notification failed. Please check the build." -} - -def sendFailedBuild(Map params = [:]) { - def config = [ - channel: '#kibana-operations-alerts', - title: "*<${env.BUILD_URL}|${getDefaultDisplayName()}>*", - message: getDefaultDisplayName(), - color: 'danger', - icon: ':jenkins:', - username: 'Kibana Operations', - isFinal: false, - ] + params - - config.context = config.context ?: getDefaultContext(config) - - def title = "${getStatusIcon(config)} ${config.title}" - def message = "${getStatusIcon(config)} ${config.message}" - - def blocks = [markdownBlock(title)] - getFailedBuildBlocks().each { blocks << it } - blocks << dividerBlock() - blocks << config.context - - def channel = config.channel - def timestamp = null - - def previousResp = buildState.get('SLACK_NOTIFICATION_RESPONSE') - if (previousResp) { - // When using `timestamp` to update a previous message, you have to use the channel ID from the previous response - channel = previousResp.channelId - timestamp = previousResp.ts - } - - def resp = slackSend( - channel: channel, - timestamp: timestamp, - username: config.username, - iconEmoji: config.icon, - color: config.color, - message: message, - blocks: blocks - ) - - if (!resp) { - resp = slackSend( - channel: config.channel, - username: config.username, - iconEmoji: config.icon, - color: config.color, - message: message, - blocks: [markdownBlock(getBackupMessage(config))] - ) - } - - if (resp) { - buildState.set('SLACK_NOTIFICATION_RESPONSE', resp) - } -} - -def onFailure(Map options = [:]) { - catchError { - def status = buildUtils.getBuildStatus() - if (status != "SUCCESS") { - catchErrors { - options.isFinal = true - sendFailedBuild(options) - } - } - } -} - -def onFailure(Map options = [:], Closure closure) { - if (options.disabled) { - catchError { - closure() - } - - return - } - - buildState.set('SLACK_NOTIFICATION_CONFIG', options) - - // try/finally will NOT work here, because the build status will not have been changed to ERROR when the finally{} block executes - catchError { - closure() - } - - onFailure(options) -} - -return this diff --git a/vars/storybooks.groovy b/vars/storybooks.groovy deleted file mode 100644 index f3c4a97a7d4364..00000000000000 --- a/vars/storybooks.groovy +++ /dev/null @@ -1,83 +0,0 @@ -def getStorybooksBucket() { - return "ci-artifacts.kibana.dev/storybooks" -} - -def getDestinationDir() { - return env.ghprbPullId ? "pr-${env.ghprbPullId}" : buildState.get('checkoutInfo').branch.replace("/", "__") -} - -def getUrl() { - return "https://${getStorybooksBucket()}/${getDestinationDir()}" -} - -def getUrlLatest() { - return "${getUrl()}/latest" -} - -def getUrlForCommit() { - return "${getUrl()}/${buildState.get('checkoutInfo').commit}" -} - -def upload() { - dir("built_assets/storybook") { - sh "mv ci_composite composite" - - def storybooks = sh( - script: 'ls -1d */', - returnStdout: true - ).trim() - .split('\n') - .collect { it.replace('/', '') } - .findAll { it != 'composite' } - - def listHtml = storybooks.collect { """<li><a href="${getUrlForCommit()}/${it}">${it}</a></li>""" }.join("\n") - - def html = """ - <html> - <body> - <h1>Storybooks</h1> - <p><a href="${getUrlForCommit()}/composite">Composite Storybook</a></p> - <h2>All</h2> - <ul> - ${listHtml} - </ul> - </body> - </html> - """ - - writeFile(file: 'index.html', text: html) - - withGcpServiceAccount.fromVaultSecret('secret/kibana-issues/dev/ci-artifacts-key', 'value') { - kibanaPipeline.bash(""" - gsutil -q -m cp -r -z js,css,html,json,map,txt,svg '*' 'gs://${getStorybooksBucket()}/${getDestinationDir()}/${buildState.get('checkoutInfo').commit}/' - gsutil -h "Cache-Control:no-cache, max-age=0, no-transform" cp -z html 'index.html' 'gs://${getStorybooksBucket()}/${getDestinationDir()}/latest/' - """, "Upload Storybooks to GCS") - } - - buildState.set('storybooksUrl', getUrlForCommit()) - } -} - -def build() { - withEnv(["STORYBOOK_BASE_URL=${getUrlForCommit()}"]) { - kibanaPipeline.bash('test/scripts/jenkins_storybook.sh', 'Build Storybooks') - } -} - -def buildAndUpload() { - def sha = buildState.get('checkoutInfo').commit - def context = 'Build and Publish Storybooks' - - githubCommitStatus.create(sha, 'pending', 'Building Storybooks', context) - - try { - build() - upload() - githubCommitStatus.create(sha, 'success', 'Storybooks built', context, getUrlForCommit()) - } catch(ex) { - githubCommitStatus.create(sha, 'error', 'Building Storybooks failed', context) - throw ex - } -} - -return this diff --git a/vars/task.groovy b/vars/task.groovy deleted file mode 100644 index 0c07b519b6fefc..00000000000000 --- a/vars/task.groovy +++ /dev/null @@ -1,5 +0,0 @@ -def call(Closure closure) { - withTaskQueue.addTask(closure) -} - -return this diff --git a/vars/tasks.groovy b/vars/tasks.groovy deleted file mode 100644 index 9a1ea053e9c496..00000000000000 --- a/vars/tasks.groovy +++ /dev/null @@ -1,201 +0,0 @@ -def call(List<Closure> closures) { - withTaskQueue.addTasks(closures) -} - -def check() { - tasks([ - kibanaPipeline.scriptTask('Quick Commit Checks', 'test/scripts/checks/commit/commit.sh'), - kibanaPipeline.scriptTask('Check Telemetry Schema', 'test/scripts/checks/telemetry.sh'), - kibanaPipeline.scriptTask('Check TypeScript Projects', 'test/scripts/checks/ts_projects.sh'), - kibanaPipeline.scriptTask('Check Jest Configs', 'test/scripts/checks/jest_configs.sh'), - kibanaPipeline.scriptTask('Check @kbn/pm Distributable', 'test/scripts/checks/kbn_pm_dist.sh'), - kibanaPipeline.scriptTask('Check Plugin List Docs', 'test/scripts/checks/plugin_list_docs.sh'), - kibanaPipeline.scriptTask('Check Types and Public API Docs', 'test/scripts/checks/type_check_plugin_public_api_docs.sh'), - kibanaPipeline.scriptTask('Check Bundle Limits', 'test/scripts/checks/bundle_limits.sh'), - kibanaPipeline.scriptTask('Check i18n', 'test/scripts/checks/i18n.sh'), - kibanaPipeline.scriptTask('Check File Casing', 'test/scripts/checks/file_casing.sh'), - kibanaPipeline.scriptTask('Check Licenses', 'test/scripts/checks/licenses.sh'), - kibanaPipeline.scriptTask('Check Plugins With Circular Dependencies', 'test/scripts/checks/plugins_with_circular_deps.sh'), - kibanaPipeline.scriptTask('Verify NOTICE', 'test/scripts/checks/verify_notice.sh'), - kibanaPipeline.scriptTask('Test Projects', 'test/scripts/checks/test_projects.sh'), - kibanaPipeline.scriptTask('Test Hardening', 'test/scripts/checks/test_hardening.sh'), - ]) -} - -def lint() { - tasks([ - kibanaPipeline.scriptTask('Lint: eslint', 'test/scripts/lint/eslint.sh'), - kibanaPipeline.scriptTask('Lint: stylelint', 'test/scripts/lint/stylelint.sh'), - ]) -} - -def test() { - tasks([ - // This task requires isolation because of hard-coded, conflicting ports and such, so let's use Docker here - kibanaPipeline.scriptTaskDocker('Jest Integration Tests', 'test/scripts/test/jest_integration.sh'), - kibanaPipeline.scriptTask('API Integration Tests', 'test/scripts/test/api_integration.sh'), - ]) -} - -def ossCiGroups() { - def ciGroups = 1..11 - tasks(ciGroups.collect { kibanaPipeline.ossCiGroupProcess(it, true) }) -} - -def xpackCiGroups() { - def ciGroups = 1..13 - tasks(ciGroups.collect { kibanaPipeline.xpackCiGroupProcess(it, true) }) -} - -def xpackCiGroupDocker() { - task { - workers.ci(name: 'xpack-cigroups-docker', size: 'm', ramDisk: true) { - kibanaPipeline.downloadDefaultBuildArtifacts() - kibanaPipeline.bash(""" - cd '${env.WORKSPACE}' - mkdir -p kibana-build - tar -xzf kibana-default.tar.gz -C kibana-build --strip=1 - tar -xzf kibana-default-plugins.tar.gz -C kibana - """, "Extract Default Build artifacts") - kibanaPipeline.xpackCiGroupProcess('Docker', true)() - } - } -} - -def functionalOss(Map params = [:]) { - def config = params ?: [ - serverIntegration: true, - ciGroups: true, - firefox: true, - accessibility: true, - pluginFunctional: true, - visualRegression: false, - ] - - task { - if (config.ciGroups) { - ossCiGroups() - } - - if (config.firefox) { - task(kibanaPipeline.functionalTestProcess('oss-firefox', './test/scripts/jenkins_firefox_smoke.sh')) - } - - if (config.accessibility) { - task(kibanaPipeline.functionalTestProcess('oss-accessibility', './test/scripts/jenkins_accessibility.sh')) - } - - if (config.pluginFunctional) { - task(kibanaPipeline.functionalTestProcess('oss-pluginFunctional', './test/scripts/jenkins_plugin_functional.sh')) - } - - if (config.visualRegression) { - task(kibanaPipeline.functionalTestProcess('oss-visualRegression', './test/scripts/jenkins_visual_regression.sh')) - } - - if (config.serverIntegration) { - task(kibanaPipeline.scriptTaskDocker('serverIntegration', './test/scripts/test/server_integration.sh')) - } - } -} - -def functionalXpack(Map params = [:]) { - def config = params ?: [ - ciGroups: true, - firefox: true, - accessibility: true, - pluginFunctional: true, - savedObjectsFieldMetrics:true, - pageLoadMetrics: false, - visualRegression: false, - ] - - task { - if (config.ciGroups) { - xpackCiGroups() - xpackCiGroupDocker() - } - - if (config.firefox) { - task(kibanaPipeline.functionalTestProcess('xpack-firefox', './test/scripts/jenkins_xpack_firefox_smoke.sh')) - } - - if (config.accessibility) { - task(kibanaPipeline.functionalTestProcess('xpack-accessibility', './test/scripts/jenkins_xpack_accessibility.sh')) - } - - if (config.visualRegression) { - task(kibanaPipeline.functionalTestProcess('xpack-visualRegression', './test/scripts/jenkins_xpack_visual_regression.sh')) - } - - if (config.savedObjectsFieldMetrics) { - task(kibanaPipeline.functionalTestProcess('xpack-savedObjectsFieldMetrics', './test/scripts/jenkins_xpack_saved_objects_field_metrics.sh')) - } - - whenChanged([ - 'x-pack/plugins/security_solution/', - 'x-pack/plugins/cases/', - 'x-pack/plugins/timelines/', - 'x-pack/plugins/lists/', - 'x-pack/test/security_solution_cypress/', - 'x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/', - 'x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx', - 'x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/', - ]) { - if (githubPr.isPr()) { - task(kibanaPipeline.functionalTestProcess('xpack-securitySolutionCypressChrome', './test/scripts/jenkins_security_solution_cypress_chrome.sh')) - // Temporarily disabled to figure out test flake - // task(kibanaPipeline.functionalTestProcess('xpack-securitySolutionCypressFirefox', './test/scripts/jenkins_security_solution_cypress_firefox.sh')) - } - } - - whenChanged([ - 'x-pack/plugins/apm/', - ]) { - if (githubPr.isPr()) { - task(kibanaPipeline.functionalTestProcess('xpack-APMCypress', './test/scripts/jenkins_apm_cypress.sh')) - } - } - - whenChanged([ - 'x-pack/plugins/synthetics/', - ]) { - if (githubPr.isPr()) { - task(kibanaPipeline.functionalTestProcess('xpack-UptimePlaywright', './test/scripts/jenkins_uptime_playwright.sh')) - } - } - - whenChanged([ - 'x-pack/plugins/ux/', - ]) { - if (githubPr.isPr()) { - task(kibanaPipeline.functionalTestProcess('xpack-uxPluginSynthetics', './test/scripts/jenkins_ux_synthetics.sh')) - } - } - - whenChanged([ - 'x-pack/plugins/fleet/', - ]) { - if (githubPr.isPr()) { - task(kibanaPipeline.functionalTestProcess('xpack-FleetCypress', './test/scripts/jenkins_fleet_cypress.sh')) - } - } - - whenChanged([ - 'x-pack/plugins/osquery/', - ]) { - if (githubPr.isPr()) { - task(kibanaPipeline.functionalTestProcess('xpack-osqueryCypress', './test/scripts/jenkins_osquery_cypress.sh')) - } - } - - } -} - -def storybooksCi() { - task { - storybooks.buildAndUpload() - } -} - -return this diff --git a/vars/whenChanged.groovy b/vars/whenChanged.groovy deleted file mode 100644 index c58ec83f2b051e..00000000000000 --- a/vars/whenChanged.groovy +++ /dev/null @@ -1,57 +0,0 @@ -/* - whenChanged('some/path') { yourCode() } can be used to execute pipeline code in PRs only when changes are detected on paths that you specify. - The specified code blocks will also always be executed during the non-PR jobs for tracked branches. - - You have the option of passing in path prefixes, or regexes. Single or multiple. - Path specifications are NOT globby, they are only prefixes. - Specifying multiple will treat them as ORs. - - Example Usages: - whenChanged('a/path/prefix/') { someCode() } - whenChanged(startsWith: 'a/path/prefix/') { someCode() } // Same as above - whenChanged(['prefix1/', 'prefix2/']) { someCode() } - whenChanged(regex: /\.test\.js$/) { someCode() } - whenChanged(regex: [/abc/, /xyz/]) { someCode() } -*/ - -def call(String startsWithString, Closure closure) { - return whenChanged([ startsWith: startsWithString ], closure) -} - -def call(List<String> startsWithStrings, Closure closure) { - return whenChanged([ startsWith: startsWithStrings ], closure) -} - -def call(Map params, Closure closure) { - if (!githubPr.isPr()) { - return closure() - } - - def files = prChanges.getChangedFiles() - def hasMatch = false - - if (params.regex) { - params.regex = [] + params.regex - print "Checking PR for changes that match: ${params.regex.join(', ')}" - hasMatch = !!files.find { file -> - params.regex.find { regex -> file =~ regex } - } - } - - if (!hasMatch && params.startsWith) { - params.startsWith = [] + params.startsWith - print "Checking PR for changes that start with: ${params.startsWith.join(', ')}" - hasMatch = !!files.find { file -> - params.startsWith.find { str -> file.startsWith(str) } - } - } - - if (hasMatch) { - print "Changes found, executing pipeline." - closure() - } else { - print "No changes found, skipping." - } -} - -return this diff --git a/vars/withGithubCredentials.groovy b/vars/withGithubCredentials.groovy deleted file mode 100644 index 224e49af1bd6f2..00000000000000 --- a/vars/withGithubCredentials.groovy +++ /dev/null @@ -1,9 +0,0 @@ -def call(closure) { - withCredentials([ - string(credentialsId: '2a9602aa-ab9f-4e52-baf3-b71ca88469c7', variable: 'GITHUB_TOKEN'), - ]) { - closure() - } -} - -return this diff --git a/vars/withTaskQueue.groovy b/vars/withTaskQueue.groovy deleted file mode 100644 index 8132d6264744f2..00000000000000 --- a/vars/withTaskQueue.groovy +++ /dev/null @@ -1,154 +0,0 @@ -import groovy.transform.Field - -public static @Field TASK_QUEUES = [:] -public static @Field TASK_QUEUES_COUNTER = 0 - -/** - withTaskQueue creates a queue of "tasks" (just plain closures to execute), and executes them with your desired level of concurrency. - This way, you can define, for example, 40 things that need to execute, then only allow 10 of them to execute at once. - - Each "process" will execute in a separate, unique, empty directory. - If you want each process to have a bootstrapped kibana repo, check out kibanaPipeline.withCiTaskQueue - - Using the queue currently requires an agent/worker. - - Usage: - - withTaskQueue(parallel: 10) { - task { print "This is a task" } - - // This is the same as calling task() multiple times - tasks([ { print "Another task" }, { print "And another task" } ]) - - // Tasks can queue up subsequent tasks - task { - buildThing() - task { print "I depend on buildThing()" } - } - } - - You can also define a setup task that each process should execute one time before executing tasks: - withTaskQueue(parallel: 10, setup: { sh "my-setup-scrupt.sh" }) { - ... - } - -*/ -def call(Map options = [:], Closure closure) { - def config = [ parallel: 10 ] + options - def counter = ++TASK_QUEUES_COUNTER - - // We're basically abusing withEnv() to create a "scope" for all steps inside of a withTaskQueue block - // This way, we could have multiple task queue instances in the same pipeline - withEnv(["TASK_QUEUE_ID=${counter}"]) { - withTaskQueue.TASK_QUEUES[env.TASK_QUEUE_ID] = [ - tasks: [], - tmpFile: sh(script: 'mktemp', returnStdout: true).trim() - ] - - closure.call() - - def processesExecuting = 0 - def processes = [:] - def iterationId = 0 - - for(def i = 1; i <= config.parallel; i++) { - def j = i - processes["task-queue-process-${j}"] = { - catchErrors { - withEnv([ - "TASK_QUEUE_PROCESS_ID=${j}", - "TASK_QUEUE_ITERATION_ID=${++iterationId}" - ]) { - dir("${WORKSPACE}/parallel/${j}/kibana") { - if (config.setup) { - config.setup.call(j) - } - - def isDone = false - while(!isDone) { // TODO some kind of timeout? - catchErrors { - if (!getTasks().isEmpty()) { - processesExecuting++ - catchErrors { - def task - try { - task = getTasks().pop() - } catch (java.util.NoSuchElementException ex) { - return - } - - task.call() - } - processesExecuting-- - // If a task finishes, and no new tasks were queued up, and nothing else is executing - // Then all of the processes should wake up and exit - if (processesExecuting < 1 && getTasks().isEmpty()) { - taskNotify() - } - return - } - - if (processesExecuting > 0) { - taskSleep() - return - } - - // Queue is empty, no processes are executing - isDone = true - } - } - } - } - } - } - } - parallel(processes) - } -} - -// If we sleep in a loop using Groovy code, Pipeline Steps is flooded with Sleep steps -// So, instead, we just watch a file and `touch` it whenever something happens that could modify the queue -// There's a 20 minute timeout just in case something goes wrong, -// in which case this method will get called again if the process is actually supposed to be waiting. -def taskSleep() { - sh(script: """#!/bin/bash - TIMESTAMP=\$(date '+%s' -d "0 seconds ago") - for (( i=1; i<=240; i++ )) - do - if [ "\$(stat -c %Y '${getTmpFile()}')" -ge "\$TIMESTAMP" ] - then - break - else - sleep 5 - if [[ \$i == 240 ]]; then - echo "Waited for new tasks for 20 minutes, exiting in case something went wrong" - fi - fi - done - """, label: "Waiting for new tasks...") -} - -// Used to let the task queue processes know that either a new task has been queued up, or work is complete -def taskNotify() { - sh "touch '${getTmpFile()}'" -} - -def getTasks() { - return withTaskQueue.TASK_QUEUES[env.TASK_QUEUE_ID].tasks -} - -def getTmpFile() { - return withTaskQueue.TASK_QUEUES[env.TASK_QUEUE_ID].tmpFile -} - -def addTask(Closure closure) { - getTasks() << closure - taskNotify() -} - -def addTasks(List<Closure> closures) { - closures.reverse().each { - getTasks() << it - } - taskNotify() -} diff --git a/vars/workers.groovy b/vars/workers.groovy deleted file mode 100644 index ea67ce415738f2..00000000000000 --- a/vars/workers.groovy +++ /dev/null @@ -1,206 +0,0 @@ -// "Workers" in this file will spin up an instance, do some setup etc depending on the configuration, and then execute some work that you define -// e.g. workers.base(name: 'my-worker') { sh "echo 'ready to execute some kibana scripts'" } - -def label(size) { - switch(size) { - case 'flyweight': - return 'flyweight' - case 's': - return 'docker && linux && immutable' - case 's-highmem': - return 'docker && tests-s' - case 'm': - return 'docker && linux && immutable && gobld/machineType:n2-standard-8' - case 'm-highmem': - return 'docker && linux && immutable && gobld/machineType:n1-highmem-8' - case 'l': - return 'docker && tests-l' - case 'xl': - return 'docker && tests-xl' - case 'xl-highmem': - return 'docker && tests-xl-highmem' - case 'xxl': - return 'docker && tests-xxl && gobld/machineType:custom-64-327680' - case 'n2-standard-16': - return 'docker && linux && immutable && gobld/machineType:n2-standard-16' - } - - error "unknown size '${size}'" -} - -/* - The base worker that all of the others use. Will clone the scm (assumed to be kibana), and run kibana bootstrap processes by default. - - Parameters: - size - size of worker label to use, e.g. 's' or 'xl' - ramDisk - Should the workspace be mounted in memory? Default: true - bootstrapped - If true, download kibana dependencies, run kbn bootstrap, etc. Default: true - name - Name of the worker for display purposes, filenames, etc. - scm - Jenkins scm configuration for checking out code. Use `null` to disable checkout. Default: inherited from job -*/ -def base(Map params, Closure closure) { - def config = [size: '', ramDisk: true, bootstrapped: true, name: 'unnamed-worker', scm: scm] + params - if (!config.size) { - error "You must specify an agent size, such as 'xl' or 's', when using workers.base()" - } - - node(label(config.size)) { - agentInfo.print() - - if (config.ramDisk) { - // Move to a temporary workspace, so that we can symlink the real workspace into /dev/shm - def originalWorkspace = env.WORKSPACE - ws('/tmp/workspace') { - sh( - script: """ - mkdir -p /dev/shm/workspace - mkdir -p '${originalWorkspace}' # create all of the directories leading up to the workspace, if they don't exist - rm --preserve-root -rf '${originalWorkspace}' # then remove just the workspace, just in case there's stuff in it - ln -s /dev/shm/workspace '${originalWorkspace}' - """, - label: "Move workspace to RAM - /dev/shm/workspace" - ) - } - } - - sh( - script: "mkdir -p ${env.WORKSPACE}/tmp", - label: "Create custom temp directory" - ) - - def checkoutInfo = [:] - - if (config.scm) { - // Try to clone from Github up to 8 times, waiting 15 secs between attempts - retryWithDelay(8, 15) { - kibanaCheckout() - } - - dir("kibana") { - checkoutInfo = getCheckoutInfo() - - if (!buildState.has('checkoutInfo')) { - buildState.set('checkoutInfo', checkoutInfo) - - if (buildState.get('shouldSetCommitStatus')) { - githubCommitStatus.onStart() - } - } - } - - ciStats.reportGitInfo( - checkoutInfo.branch, - checkoutInfo.commit, - checkoutInfo.targetBranch, - checkoutInfo.mergeBase - ) - } - - withEnv([ - "CI=true", - "HOME=${env.JENKINS_HOME}", - "PR_NUMBER=${env.ghprbPullId ?: ''}", - "PR_SOURCE_BRANCH=${env.ghprbSourceBranch ?: ''}", - "PR_TARGET_BRANCH=${env.ghprbTargetBranch ?: ''}", - "PR_MERGE_BASE=${checkoutInfo.mergeBase ?: ''}", - "PR_AUTHOR=${env.ghprbPullAuthorLogin ?: ''}", - "TEST_BROWSER_HEADLESS=1", - "GIT_COMMIT=${checkoutInfo.commit}", - "GIT_BRANCH=${checkoutInfo.branch}", - "TMPDIR=${env.WORKSPACE}/tmp", // For Chrome and anything else that respects it - ]) { - withCredentials([ - string(credentialsId: 'vault-addr', variable: 'VAULT_ADDR'), - string(credentialsId: 'vault-role-id', variable: 'VAULT_ROLE_ID'), - string(credentialsId: 'vault-secret-id', variable: 'VAULT_SECRET_ID'), - ]) { - // scm is configured to check out to the ./kibana directory - dir('kibana') { - if (config.bootstrapped) { - kibanaPipeline.doSetup() - } - - closure() - } - } - } - } -} - -// Worker for ci processes. Extends the base worker and adds GCS artifact upload, error reporting, junit processing -def ci(Map params, Closure closure) { - def config = [ramDisk: true, bootstrapped: true, runErrorReporter: true] + params - - return base(config) { - kibanaPipeline.withGcsArtifactUpload(config.name) { - kibanaPipeline.withPostBuildReporting(config) { - closure() - } - } - } -} - -// Worker for running the current intake jobs. Just runs a single script after bootstrap. -def intake(jobName, String script) { - return { - ci(name: jobName, size: 'm-highmem', ramDisk: true) { - withEnv(["JOB=${jobName}"]) { - kibanaPipeline.notifyOnError { - runbld(script, "Execute ${jobName}") - } - } - } - } -} - -// Worker for running functional tests. Runs a setup process (e.g. the kibana build) then executes a map of closures in parallel (e.g. one for each ciGroup) -def functional(name, Closure setup, Map processes) { - return { - parallelProcesses(name: name, setup: setup, processes: processes, delayBetweenProcesses: 20, size: 'xl') - } -} - -/* - Creates a ci worker that can run a setup process, followed by a group of processes in parallel. - - Parameters: - name: Name of the worker for display purposes, filenames, etc. - setup: Closure to execute after the agent is bootstrapped, before starting the parallel work - processes: Map of closures that will execute in parallel after setup. Each closure is passed a unique number. - delayBetweenProcesses: Number of seconds to wait between starting the parallel processes. Useful to spread the load of heavy init processes, e.g. Elasticsearch starting up. Default: 0 - size: size of worker label to use, e.g. 's' or 'xl' -*/ -def parallelProcesses(Map params) { - def config = [name: 'parallel-worker', setup: {}, processes: [:], delayBetweenProcesses: 0, size: 'xl'] + params - - ci(size: config.size, name: config.name) { - config.setup() - - def nextProcessNumber = 1 - def process = { processName, processClosure -> - def processNumber = nextProcessNumber - nextProcessNumber++ - - return { - if (config.delayBetweenProcesses && config.delayBetweenProcesses > 0) { - // This delay helps smooth out CPU load caused by ES/Kibana instances starting up at the same time - def delay = (processNumber-1)*config.delayBetweenProcesses - sleep(delay) - } - - withEnv(["CI_PARALLEL_PROCESS_NUMBER=${processNumber}"]) { - processClosure() - } - } - } - - def processes = [:] - config.processes.each { processName, processClosure -> - processes[processName] = process(processName, processClosure) - } - - parallel(processes) - } -} - -return this diff --git a/x-pack/test/functional/apps/maps/group1/sample_data.js b/x-pack/test/functional/apps/maps/group1/sample_data.js index 09b29f5e529c31..377d80a63999bc 100644 --- a/x-pack/test/functional/apps/maps/group1/sample_data.js +++ b/x-pack/test/functional/apps/maps/group1/sample_data.js @@ -15,7 +15,7 @@ export default function ({ getPageObjects, getService, updateBaselines }) { const kibanaServer = getService('kibanaServer'); const security = getService('security'); - // Only update the baseline images from Jenkins session images after comparing them + // Only update the baseline images from CI session images after comparing them // These tests might fail locally because of scaling factors and resolution. describe('maps loaded from sample data', () => { From b13974cf426da11d00fcf5c440872d9033d3e7ef Mon Sep 17 00:00:00 2001 From: Tim Sullivan <tsullivan@users.noreply.github.com> Date: Thu, 21 Dec 2023 11:32:55 -0700 Subject: [PATCH 090/116] [Security/APIKey Service] Internal API endpoint do determine if user has API keys (#172884) ## Summary This PR enhances the Security server plugin APIKey service with a new method to determine if the user has API keys. The service is integrated into the "No Data Page" server plugin as a new HTTP route. This route is called when needed to direct users effectively through their getting started experience. Pulled from https://github.com/elastic/kibana/pull/172225 [Context](https://github.com/elastic/kibana/pull/172225#discussion_r1419557503) > ...we [sh]ould introduce whatever functionality we required into the security plugin's API Key Service. ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Aleh Zasypkin <aleh.zasypkin@gmail.com> --- .../server/routes/api_keys/has_active.test.ts | 113 ++++++++++++++++++ .../server/routes/api_keys/has_active.ts | 59 +++++++++ .../security/server/routes/api_keys/index.ts | 2 + .../tests/api_keys/has_active_key.ts | 59 +++++++++ .../tests/api_keys/index.ts | 1 + 5 files changed, 234 insertions(+) create mode 100644 x-pack/plugins/security/server/routes/api_keys/has_active.test.ts create mode 100644 x-pack/plugins/security/server/routes/api_keys/has_active.ts create mode 100644 x-pack/test/security_api_integration/tests/api_keys/has_active_key.ts diff --git a/x-pack/plugins/security/server/routes/api_keys/has_active.test.ts b/x-pack/plugins/security/server/routes/api_keys/has_active.test.ts new file mode 100644 index 00000000000000..d2c38651f4397a --- /dev/null +++ b/x-pack/plugins/security/server/routes/api_keys/has_active.test.ts @@ -0,0 +1,113 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { kibanaResponseFactory } from '@kbn/core/server'; +import type { RequestHandler } from '@kbn/core/server'; +import type { CustomRequestHandlerMock, ScopedClusterClientMock } from '@kbn/core/server/mocks'; +import { coreMock, httpServerMock } from '@kbn/core/server/mocks'; +import { licensingMock } from '@kbn/licensing-plugin/server/mocks'; +import type { DeeplyMockedKeys } from '@kbn/utility-types-jest'; + +import { defineHasApiKeysRoutes } from './has_active'; +import type { InternalAuthenticationServiceStart } from '../../authentication'; +import { authenticationServiceMock } from '../../authentication/authentication_service.mock'; +import { routeDefinitionParamsMock } from '../index.mock'; + +describe('Has API Keys route', () => { + let routeHandler: RequestHandler<any, any, any, any>; + let authc: DeeplyMockedKeys<InternalAuthenticationServiceStart>; + let esClientMock: ScopedClusterClientMock; + let mockContext: CustomRequestHandlerMock<unknown>; + + beforeEach(async () => { + const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); + authc = authenticationServiceMock.createStart(); + mockRouteDefinitionParams.getAuthenticationService.mockReturnValue(authc); + defineHasApiKeysRoutes(mockRouteDefinitionParams); + [[, routeHandler]] = mockRouteDefinitionParams.router.get.mock.calls; + mockContext = coreMock.createCustomRequestHandlerContext({ + core: coreMock.createRequestHandlerContext(), + licensing: licensingMock.createRequestHandlerContext(), + }); + + esClientMock = (await mockContext.core).elasticsearch.client; + + authc.apiKeys.areAPIKeysEnabled.mockResolvedValue(true); + authc.apiKeys.areCrossClusterAPIKeysEnabled.mockResolvedValue(true); + + esClientMock.asCurrentUser.security.getApiKey.mockResponse({ + api_keys: [ + { id: '123', invalidated: false }, + { id: '456', invalidated: true }, + ], + } as any); + }); + + it('should calculate when user has API keys', async () => { + const response = await routeHandler( + mockContext, + httpServerMock.createKibanaRequest(), + kibanaResponseFactory + ); + + expect(response.payload).toEqual( + expect.objectContaining({ + hasApiKeys: true, + }) + ); + expect(esClientMock.asCurrentUser.security.getApiKey).toHaveBeenCalledTimes(1); + expect(esClientMock.asCurrentUser.security.getApiKey).toHaveBeenCalledWith({ + owner: true, + active_only: true, + }); + }); + + it('should calculate when user does not have API keys', async () => { + esClientMock.asCurrentUser.security.getApiKey.mockResponse({ + api_keys: [], + }); + + const response = await routeHandler( + mockContext, + httpServerMock.createKibanaRequest(), + kibanaResponseFactory + ); + + expect(response.payload).toEqual( + expect.objectContaining({ + hasApiKeys: false, + }) + ); + }); + + it('should filter out invalidated API keys', async () => { + const response = await routeHandler( + mockContext, + httpServerMock.createKibanaRequest(), + kibanaResponseFactory + ); + + expect(response.status).toBe(200); + expect(response.payload?.hasApiKeys).toBe(true); + }); + + it('should return `404` if API keys are disabled', async () => { + authc.apiKeys.areAPIKeysEnabled.mockResolvedValue(false); + + const response = await routeHandler( + mockContext, + httpServerMock.createKibanaRequest(), + kibanaResponseFactory + ); + + expect(response.status).toBe(404); + expect(response.payload).toEqual({ + message: + "API keys are disabled in Elasticsearch. To use API keys enable 'xpack.security.authc.api_key.enabled' setting.", + }); + }); +}); diff --git a/x-pack/plugins/security/server/routes/api_keys/has_active.ts b/x-pack/plugins/security/server/routes/api_keys/has_active.ts new file mode 100644 index 00000000000000..eea5ac71e53a07 --- /dev/null +++ b/x-pack/plugins/security/server/routes/api_keys/has_active.ts @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { RouteDefinitionParams } from '..'; +import { createLicensedRouteHandler } from '../licensed_route_handler'; + +/** + * Response of Kibana Has API keys endpoint. + */ +export interface HasAPIKeysResult { + hasApiKeys: boolean; +} + +export function defineHasApiKeysRoutes({ + router, + getAuthenticationService, +}: RouteDefinitionParams) { + router.get( + { + path: '/internal/security/api_key/_has_active', + validate: false, + options: { + access: 'internal', + }, + }, + createLicensedRouteHandler(async (context, _request, response) => { + const esClient = (await context.core).elasticsearch.client; + const authenticationService = getAuthenticationService(); + + const areApiKeysEnabled = await authenticationService.apiKeys.areAPIKeysEnabled(); + + if (!areApiKeysEnabled) { + return response.notFound({ + body: { + message: + "API keys are disabled in Elasticsearch. To use API keys enable 'xpack.security.authc.api_key.enabled' setting.", + }, + }); + } + + const { api_keys: apiKeys } = await esClient.asCurrentUser.security.getApiKey({ + owner: true, + // @ts-expect-error @elastic/elasticsearch SecurityGetApiKeyRequest.active_only: boolean | undefined + active_only: true, + }); + + // simply return true if the result array is non-empty + return response.ok<HasAPIKeysResult>({ + body: { + hasApiKeys: apiKeys.length > 0, + }, + }); + }) + ); +} diff --git a/x-pack/plugins/security/server/routes/api_keys/index.ts b/x-pack/plugins/security/server/routes/api_keys/index.ts index 9855d94923c33b..3b71eb7e1104d7 100644 --- a/x-pack/plugins/security/server/routes/api_keys/index.ts +++ b/x-pack/plugins/security/server/routes/api_keys/index.ts @@ -8,6 +8,7 @@ import { defineCreateApiKeyRoutes } from './create'; import { defineEnabledApiKeysRoutes } from './enabled'; import { defineGetApiKeysRoutes } from './get'; +import { defineHasApiKeysRoutes } from './has_active'; import { defineInvalidateApiKeysRoutes } from './invalidate'; import { defineUpdateApiKeyRoutes } from './update'; import type { RouteDefinitionParams } from '..'; @@ -24,6 +25,7 @@ export type { GetAPIKeysResult } from './get'; export function defineApiKeysRoutes(params: RouteDefinitionParams) { defineEnabledApiKeysRoutes(params); defineGetApiKeysRoutes(params); + defineHasApiKeysRoutes(params); defineCreateApiKeyRoutes(params); defineUpdateApiKeyRoutes(params); defineInvalidateApiKeysRoutes(params); diff --git a/x-pack/test/security_api_integration/tests/api_keys/has_active_key.ts b/x-pack/test/security_api_integration/tests/api_keys/has_active_key.ts new file mode 100644 index 00000000000000..11b118abb1d67b --- /dev/null +++ b/x-pack/test/security_api_integration/tests/api_keys/has_active_key.ts @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import type { ApiKey } from '@kbn/security-plugin/common/model'; +import type { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + + const createKey = async () => { + const { body: apiKey } = await supertest + .post('/api_keys/_grant') + .set('kbn-xsrf', 'xxx') + .send({ name: 'an-actual-api-key' }) + .expect(200); + expect(apiKey.name).to.eql('an-actual-api-key'); + return apiKey; + }; + + const cleanup = async () => { + // get existing keys which would affect test results + const { body: getResponseBody } = await supertest.get('/internal/security/api_key').expect(200); + const apiKeys: ApiKey[] = getResponseBody.apiKeys; + const existing = apiKeys.map(({ id, name }) => ({ id, name })); + + // invalidate the keys + await supertest + .post(`/internal/security/api_key/invalidate`) + .set('kbn-xsrf', 'xxx') + .send({ apiKeys: existing, isAdmin: false }) + .expect(200, { itemsInvalidated: existing, errors: [] }); + }; + + describe('Has Active API Keys: _has_active', () => { + before(cleanup); + after(cleanup); + + it('detects when user has no API Keys', async () => { + await supertest + .get('/internal/security/api_key/_has_active') + .set('kbn-xsrf', 'xxx') + .expect(200, { hasApiKeys: false }); + }); + + it('detects when user has some API Keys', async () => { + await createKey(); + + await supertest + .get('/internal/security/api_key/_has_active') + .set('kbn-xsrf', 'xxx') + .expect(200, { hasApiKeys: true }); + }); + }); +} diff --git a/x-pack/test/security_api_integration/tests/api_keys/index.ts b/x-pack/test/security_api_integration/tests/api_keys/index.ts index a20f0a30181ff2..a36a76c0c95663 100644 --- a/x-pack/test/security_api_integration/tests/api_keys/index.ts +++ b/x-pack/test/security_api_integration/tests/api_keys/index.ts @@ -10,5 +10,6 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('security APIs - Api Keys', function () { loadTestFile(require.resolve('./grant_api_key')); + loadTestFile(require.resolve('./has_active_key')); }); } From 0a190b12a3dddff28586878253c83fe3fb53998d Mon Sep 17 00:00:00 2001 From: Paul Tavares <56442535+paul-tavares@users.noreply.github.com> Date: Thu, 21 Dec 2023 13:35:15 -0500 Subject: [PATCH 091/116] [Security Solution][Endpoint] Improve the `run_sentinelone_host` script so that it also creates the Connector and SIEM Rule (#173858) ## Summary Follow up to https://github.com/elastic/kibana/pull/173693 which was reverted. From that PR: Improves the `x-pack/plugins/security_solution/scripts/endpoint/run_sentinelone_host.js` script to also: - Create a Connector for SentinelOne if one is not already created - Create a Detection Engine rule to promote SentinelOne alerts to SIEM Alerts, if one is not already created --------- Co-authored-by: Ash <1849116+ashokaditya@users.noreply.github.com> --- .../endpoint/common/connectors_services.ts | 68 +++++++++++++ .../common/detection_rules_services.ts | 99 +++++++++++++++++++ .../scripts/endpoint/common/fleet_services.ts | 11 +-- .../scripts/endpoint/common/vm_services.ts | 8 +- .../endpoint/sentinelone_host/common.ts | 84 ++++++++++++++++ .../endpoint/sentinelone_host/index.ts | 14 ++- 6 files changed, 272 insertions(+), 12 deletions(-) create mode 100644 x-pack/plugins/security_solution/scripts/endpoint/common/connectors_services.ts create mode 100644 x-pack/plugins/security_solution/scripts/endpoint/common/detection_rules_services.ts diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/connectors_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/connectors_services.ts new file mode 100644 index 00000000000000..3fb2971f1236d2 --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/connectors_services.ts @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { KbnClient } from '@kbn/test'; +import type { AllConnectorsResponseV1 } from '@kbn/actions-plugin/common/routes/connector/response'; +import type { bodySchema } from '@kbn/actions-plugin/server/routes/create'; +import type { TypeOf } from '@kbn/config-schema'; +import type { Connector } from '@kbn/actions-plugin/server/application/connector/types'; +import { catchAxiosErrorFormatAndThrow } from '../../../common/endpoint/format_axios_error'; + +/** + * Retrieve list of configured Connectors + * @param kbnClient + */ +export const fetchConnectorsList = async ( + kbnClient: KbnClient +): Promise<AllConnectorsResponseV1[]> => { + return kbnClient + .request<AllConnectorsResponseV1[]>({ + path: '/api/actions/connectors', + method: 'GET', + }) + .catch(catchAxiosErrorFormatAndThrow) + .then((response) => response.data); +}; + +/** + * Returns the first connector instance (if any) of a given type + * @param kbnClient + * @param connectorTypeId + */ +export const fetchConnectorByType = async ( + kbnClient: KbnClient, + connectorTypeId: string +): Promise<AllConnectorsResponseV1 | undefined> => { + const allConnectors = await fetchConnectorsList(kbnClient); + + for (const connector of allConnectors) { + if (connector.connector_type_id === connectorTypeId) { + return connector; + } + } +}; + +type CreateConnectorBody = TypeOf<typeof bodySchema>; + +/** + * Creates a connector in the stack + * @param kbnClient + * @param createPayload + */ +export const createConnector = async ( + kbnClient: KbnClient, + createPayload: CreateConnectorBody +): Promise<Connector> => { + return kbnClient + .request<Connector>({ + path: '/api/actions/connector', + method: 'POST', + body: createPayload, + }) + .catch(catchAxiosErrorFormatAndThrow) + .then((response) => response.data); +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/detection_rules_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/detection_rules_services.ts new file mode 100644 index 00000000000000..478501b00b89d9 --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/detection_rules_services.ts @@ -0,0 +1,99 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { KbnClient } from '@kbn/test'; +import { catchAxiosErrorFormatAndThrow } from '../../../common/endpoint/format_axios_error'; +import { + DETECTION_ENGINE_RULES_URL, + DETECTION_ENGINE_RULES_URL_FIND, +} from '../../../common/constants'; +import type { + CreateRuleRequestBody, + FindRulesRequestQuery, + FindRulesResponse, + RuleResponse, +} from '../../../common/api/detection_engine'; + +/** + * Creates a detection engine rule + * @param kbnClient + * @param payload + */ +export const createRule = async ( + kbnClient: KbnClient, + payload: Partial<CreateRuleRequestBody> = {} +): Promise<RuleResponse> => { + return kbnClient + .request<RuleResponse>({ + path: DETECTION_ENGINE_RULES_URL, + method: 'POST', + body: { + type: 'query', + index: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'traces-apm*', + 'winlogbeat-*', + '-*elastic-cloud-logs-*', + ], + filters: [], + language: 'kuery', + query: '_id:*', + author: [], + false_positives: [], + references: [], + risk_score: 21, + risk_score_mapping: [], + severity: 'low', + severity_mapping: [], + threat: [], + name: `Test rule - ${Math.random().toString(36).substring(2)}`, + description: `Test rule created from: ${__filename}`, + tags: [], + license: '', + interval: '1m', + from: 'now-120s', + to: 'now', + meta: { + from: '1m', + kibana_siem_app_url: kbnClient.resolveUrl('/app/security'), + }, + actions: [], + enabled: true, + throttle: 'no_actions', + + ...payload, + }, + headers: { 'elastic-api-version': '2023-10-31' }, + }) + .catch(catchAxiosErrorFormatAndThrow) + .then((response) => response.data); +}; + +/** + * Query the Detection Rules + * @param kbnClient + * @param query + */ +export const findRules = async ( + kbnClient: KbnClient, + query: Partial<FindRulesRequestQuery> = {} +): Promise<FindRulesResponse> => { + return kbnClient + .request<FindRulesResponse>({ + path: DETECTION_ENGINE_RULES_URL_FIND, + method: 'GET', + headers: { 'elastic-api-version': '2023-10-31' }, + query, + }) + .catch(catchAxiosErrorFormatAndThrow) + .then((response) => response.data); +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts index 97a9df146c2ac2..b1ff5e8464a00d 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/fleet_services.ts @@ -68,7 +68,6 @@ import { createToolingLogger, RETRYABLE_TRANSIENT_ERRORS, retryOnError, - wrapErrorAndRejectPromise, } from '../../../common/endpoint/data_loaders/utils'; import { fetchKibanaStatus } from './stack_services'; import { catchAxiosErrorFormatAndThrow } from '../../../common/endpoint/format_axios_error'; @@ -777,13 +776,13 @@ export const getOrCreateDefaultAgentPolicy = async ({ }); if (existingPolicy.items[0]) { - log.info(`Re-using existing Fleet test agent policy`); + log.info(`Re-using existing Fleet test agent policy: [${existingPolicy.items[0].name}]`); log.verbose(existingPolicy.items[0]); return existingPolicy.items[0]; } - log.info(`Creating new default test/dev Fleet agent policy`); + log.info(`Creating default test/dev Fleet agent policy with name: [${policyName}]`); const newAgentPolicyData: CreateAgentPolicyRequest['body'] = { name: policyName, @@ -802,7 +801,7 @@ export const getOrCreateDefaultAgentPolicy = async ({ body: newAgentPolicyData, }) .then((response) => response.data.item) - .catch(wrapErrorAndRejectPromise); + .catch(catchAxiosErrorFormatAndThrow); log.verbose(newAgentPolicy); @@ -828,7 +827,7 @@ export const createIntegrationPolicy = async ( }, }) .then((response) => response.data.item) - .catch(wrapErrorAndRejectPromise); + .catch(catchAxiosErrorFormatAndThrow); }; /** @@ -847,7 +846,7 @@ export const fetchPackageInfo = async ( method: 'GET', }) .then((response) => response.data.item) - .catch(wrapErrorAndRejectPromise); + .catch(catchAxiosErrorFormatAndThrow); }; interface AddSentinelOneIntegrationToAgentPolicyOptions { diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/vm_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/vm_services.ts index 17c74b1bf6fc3a..4209b554b2732b 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/vm_services.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/vm_services.ts @@ -178,10 +178,10 @@ export const getMultipassVmCountNotice = async (threshold: number = 1): Promise< if (output.list.length > threshold) { return `----------------------------------------------------------------- ${chalk.red('NOTE:')} ${chalk.bold( - chalk.cyan(`You currently have ${chalk.red(output.list.length)} VMs running.`) - )} Remember to delete those - no longer being used. - View running VMs: ${chalk.bold('multipass list')} + chalk.red(`You currently have ${chalk.red(output.list.length)} VMs running.`) + )} + Remember to delete those no longer being used. + View running VMs: ${chalk.cyan('multipass list')} ----------------------------------------------------------------- `; } diff --git a/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts b/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts index 483bae1c4275e8..fe9053795737a9 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/common.ts @@ -8,6 +8,10 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type { AxiosRequestConfig } from 'axios'; import axios from 'axios'; +import type { KbnClient } from '@kbn/test'; +import { SENTINELONE_CONNECTOR_ID } from '@kbn/stack-connectors-plugin/common/sentinelone/constants'; +import { type RuleResponse } from '../../../common/api/detection_engine'; +import { dump } from '../endpoint_agent_runner/utils'; import { createToolingLogger } from '../../../common/endpoint/data_loaders/utils'; import type { S1SitesListApiResponse, @@ -17,6 +21,9 @@ import type { import { catchAxiosErrorFormatAndThrow } from '../../../common/endpoint/format_axios_error'; import type { HostVm } from '../common/types'; +import { createConnector, fetchConnectorByType } from '../common/connectors_services'; +import { createRule, findRules } from '../common/detection_rules_services'; + interface S1ClientOptions { /** The base URL for SentinelOne */ url: string; @@ -200,6 +207,13 @@ export const installSentinelOneAgent = async ({ const status = (await hostVm.exec(`sudo ${installPath} control status`)).stdout; + try { + // Generate an alert in SentinelOne + await hostVm.exec('nslookup amazon.com'); + } catch (e) { + log?.warning(`Attempted to generate an alert on SentinelOne host failed: ${e.message}`); + } + log.info('done'); return { @@ -208,3 +222,73 @@ export const installSentinelOneAgent = async ({ }; }); }; + +interface CreateSentinelOneStackConnectorIfNeededOptions { + kbnClient: KbnClient; + log: ToolingLog; + s1Url: string; + s1ApiToken: string; + name?: string; +} + +export const createSentinelOneStackConnectorIfNeeded = async ({ + kbnClient, + log, + s1ApiToken, + s1Url, + name = 'SentinelOne Dev instance', +}: CreateSentinelOneStackConnectorIfNeededOptions): Promise<void> => { + const connector = await fetchConnectorByType(kbnClient, SENTINELONE_CONNECTOR_ID); + + if (connector) { + log.debug(`Nothing to do. A connector for SentinelOne is already configured`); + log.verbose(dump(connector)); + return; + } + + log.info(`Creating SentinelOne Connector with name: ${name}`); + + await createConnector(kbnClient, { + name, + config: { + url: s1Url, + }, + secrets: { + token: s1ApiToken, + }, + connector_type_id: SENTINELONE_CONNECTOR_ID, + }); +}; + +export const createDetectionEngineSentinelOneRuleIfNeeded = async ( + kbnClient: KbnClient, + log: ToolingLog +): Promise<RuleResponse> => { + const ruleName = 'Promote SentinelOne alerts'; + const sentinelOneAlertsIndexPattern = 'logs-sentinel_one.alert'; + const ruleQueryValue = 'observer.serial_number:*'; + + const { data } = await findRules(kbnClient, { + filter: `(alert.attributes.params.query: "${ruleQueryValue}" AND alert.attributes.params.index: ${sentinelOneAlertsIndexPattern})`, + }); + + if (data.length) { + log.info( + `Detection engine rule for SentinelOne alerts already exists [${data[0].name}]. No need to create a new one.` + ); + + return data[0]; + } + + log.info(`Creating new detection engine rule named [${ruleName}] for SentinelOne`); + + const createdRule = await createRule(kbnClient, { + index: [sentinelOneAlertsIndexPattern], + query: ruleQueryValue, + from: 'now-3660s', + }); + + log.verbose(dump(createdRule)); + + return createdRule; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/index.ts b/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/index.ts index 3fad8bf0223bb7..3416b8d4e51b6f 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/index.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/sentinelone_host/index.ts @@ -21,7 +21,12 @@ import { fetchAgentPolicy, getOrCreateDefaultAgentPolicy, } from '../common/fleet_services'; -import { installSentinelOneAgent, S1Client } from './common'; +import { + createDetectionEngineSentinelOneRuleIfNeeded, + createSentinelOneStackConnectorIfNeeded, + installSentinelOneAgent, + S1Client, +} from './common'; import { createVm, generateVmName, getMultipassVmCountNotice } from '../common/vm_services'; import { createKbnClient } from '../common/stack_services'; @@ -157,11 +162,16 @@ const runCli: RunFn = async ({ log, flags }) => { agentPolicyId, }); } else { - log.info( + log.debug( `No host VM created for Fleet agent policy [${agentPolicyName}]. It already shows to have [${agents}] enrolled` ); } + await Promise.all([ + createSentinelOneStackConnectorIfNeeded({ kbnClient, log, s1ApiToken, s1Url }), + createDetectionEngineSentinelOneRuleIfNeeded(kbnClient, log), + ]); + log.info(`Done! ${hostVm.info()} From 6bfdde6cfcdb1ec876f0177572bfbe28abb8fd2f Mon Sep 17 00:00:00 2001 From: Alexi Doak <109488926+doakalexi@users.noreply.github.com> Date: Thu, 21 Dec 2023 10:48:34 -0800 Subject: [PATCH 092/116] [ResponseOps] Implement a mechanism to copy source data into the alerts-as-data documents for ES Query rules (#171129) Resolves https://github.com/elastic/kibana/issues/168589 ## Summary This PR allows users to select _source fields that will then be copied into the alerts-as-data docs for the ES Query rule. We will start by allowing them to choose from the following fields: - host.name - host.hostname - host.id - container.id - kubernetes.pod.uid <img width="468" alt="Screen Shot 2023-11-29 at 2 36 51 PM" src="https://github.com/elastic/kibana/assets/109488926/bd11b921-72be-4d84-8288-f4dca16c494e"> ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### To verify 1. Create or use an index that includes some of the fields listed above Ex. ``` POST test-data/_doc/ { "@timestamp": "2023-11-27T10:00:00", "host": { "id": "1", "name": "host-1", "hostname": "host-1" } } ``` 2. Use that index to create ES Query rules with the different query types 3. Verify that only valid fields that exist in the index are visible in the combo box options 4. Verify that the valid fields are auto selected 5. Verify that if you change the index/dataview (or query for ESQL) that the selected fields are reset and and the combo box options reflect the query or index/dataview 6. Save the rule and verify that it runs and populates the new fields in the AAD documents 7. Create a new rule and use an index that doesn't contain any of the valid fields. Verify that the option to select fields is hidden --------- Co-authored-by: Ersin Erdal <ersin.erdal@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Ying Mao <ying.mao@elastic.co> --- .../plugins/stack_alerts/common/constants.ts | 15 ++ .../components/source_fields_select.test.tsx | 226 +++++++++++++++++ .../components/source_fields_select.tsx | 120 +++++++++ .../public/rule_types/es_query/constants.ts | 2 + .../expression/es_query_expression.tsx | 8 + .../expression/esql_query_expression.tsx | 46 +++- .../expression/search_source_expression.tsx | 2 + .../search_source_expression_form.tsx | 22 +- .../rule_common_expressions.test.tsx | 1 + .../rule_common_expressions.tsx | 13 +- .../test_query_row/test_query_row.test.tsx | 2 +- .../test_query_row/use_test_query.test.ts | 6 +- .../public/rule_types/es_query/types.ts | 6 + .../rule_types/es_query/validation.test.ts | 23 ++ .../public/rule_types/es_query/validation.ts | 19 +- .../es_query/action_context.test.ts | 7 + .../rule_types/es_query/action_context.ts | 1 + .../rule_types/es_query/executor.test.ts | 85 +++++++ .../server/rule_types/es_query/executor.ts | 3 + .../rule_types/es_query/lib/fetch_es_query.ts | 2 + .../es_query/lib/fetch_esql_query.ts | 2 + .../es_query/lib/fetch_search_source_query.ts | 8 +- .../es_query/rule_type_params.test.ts | 16 ++ .../rule_types/es_query/rule_type_params.ts | 16 +- .../common/data/lib/build_agg.test.ts | 138 ++++++++++ .../common/data/lib/build_agg.ts | 16 +- .../lib/parse_aggregation_results.test.ts | 238 ++++++++++++++++++ .../data/lib/parse_aggregation_results.ts | 27 ++ .../packages/helpers/es_test_index_tool.ts | 19 ++ .../tests/alerting/create_test_data.ts | 24 ++ .../builtin_alert_types/es_query/common.ts | 5 + .../builtin_alert_types/es_query/esql_only.ts | 44 +++- .../es_query/query_dsl_only.ts | 14 +- .../builtin_alert_types/es_query/rule.ts | 114 ++++++++- 34 files changed, 1256 insertions(+), 34 deletions(-) create mode 100644 x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.test.tsx create mode 100644 x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.tsx diff --git a/x-pack/plugins/stack_alerts/common/constants.ts b/x-pack/plugins/stack_alerts/common/constants.ts index a2be12ee63867c..b378e097d883a2 100644 --- a/x-pack/plugins/stack_alerts/common/constants.ts +++ b/x-pack/plugins/stack_alerts/common/constants.ts @@ -6,3 +6,18 @@ */ export const MAX_SELECTABLE_GROUP_BY_TERMS = 4; +export const MAX_SELECTABLE_SOURCE_FIELDS = 5; + +const HOST_NAME = 'host.name'; +const HOST_HOSTNAME = 'host.hostname'; +const HOST_ID = 'host.id'; +const CONTAINER_ID = 'container.id'; +const KUBERNETES_POD_UID = 'kubernetes.pod.uid'; + +export const validSourceFields = [ + HOST_NAME, + HOST_HOSTNAME, + HOST_ID, + CONTAINER_ID, + KUBERNETES_POD_UID, +]; diff --git a/x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.test.tsx b/x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.test.tsx new file mode 100644 index 00000000000000..aed0f36b27c8eb --- /dev/null +++ b/x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.test.tsx @@ -0,0 +1,226 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { cleanup, render, screen, waitFor } from '@testing-library/react'; +import { I18nProvider } from '@kbn/i18n-react'; +import { SourceFields } from './source_fields_select'; +import { SourceField } from '../es_query/types'; + +const AppWrapper: React.FC<{ children: React.ReactElement }> = React.memo(({ children }) => ( + <I18nProvider>{children}</I18nProvider> +)); + +describe('SourceFields', () => { + afterEach(() => { + cleanup(); + }); + + it('should render SourceFields component if there are valid sourceFields', () => { + const result = render( + <SourceFields + onChangeSourceFields={() => {}} + esFields={[ + { + name: 'host.name', + type: 'type', + normalizedType: 'type', + searchable: true, + aggregatable: true, + }, + ]} + sourceFields={[]} + errors={[]} + />, + { + wrapper: AppWrapper, + } + ); + + expect(result.getByTestId('sourceFields')).toBeInTheDocument(); + }); + + it('should not render SourceFields component if there are not valid sourceFields', () => { + const result = render( + <SourceFields + onChangeSourceFields={() => {}} + esFields={[ + { + name: 'test', + type: 'type', + normalizedType: 'type', + searchable: true, + aggregatable: true, + }, + ]} + sourceFields={[]} + errors={[]} + />, + { + wrapper: AppWrapper, + } + ); + + expect(result.queryByTestId('sourceFields')).not.toBeInTheDocument(); + }); + + it('should render sourceFields param', () => { + const result = render( + <SourceFields + onChangeSourceFields={() => {}} + esFields={[ + { + name: 'host.name', + type: 'type', + normalizedType: 'type', + searchable: true, + aggregatable: true, + }, + ]} + sourceFields={[{ label: 'host.name', searchPath: 'host.name' }]} + errors={[]} + />, + { + wrapper: AppWrapper, + } + ); + + expect(result.getByTestId('option-host.name')).toBeInTheDocument(); + }); + + it('should auto select valid sourceFields if sourceFields param is not defined', async () => { + let sourceFields: SourceField[] | undefined; + const onChange = (fields: SourceField[]) => { + sourceFields = fields; + }; + const { rerender } = render( + <SourceFields + onChangeSourceFields={onChange} + esFields={[ + { + name: 'host.name', + type: 'type', + normalizedType: 'type', + searchable: true, + aggregatable: true, + }, + ]} + sourceFields={sourceFields} + errors={[]} + />, + { + wrapper: AppWrapper, + } + ); + + await waitFor(() => { + rerender( + <SourceFields + onChangeSourceFields={onChange} + esFields={[ + { + name: 'host.name', + type: 'type', + normalizedType: 'type', + searchable: true, + aggregatable: true, + }, + ]} + sourceFields={sourceFields} + errors={[]} + /> + ); + expect(screen.getByTestId('option-host.name')).toBeInTheDocument(); + }); + }); + + it('should remove duplicate and non-aggregatable esFields and handle keyword esFields', async () => { + let sourceFields: SourceField[] | undefined; + const onChange = (fields: SourceField[]) => { + sourceFields = fields; + }; + const esFields = [ + { + name: 'host.name', + type: 'type', + normalizedType: 'type', + searchable: true, + aggregatable: false, + }, + { + name: 'host.hostname', + type: 'type', + normalizedType: 'type', + searchable: true, + aggregatable: true, + }, + { + name: 'host.hostname.keyword', + type: 'type', + normalizedType: 'type', + searchable: true, + aggregatable: true, + }, + { + name: 'host.id.keyword', + type: 'type', + normalizedType: 'type', + searchable: true, + aggregatable: true, + }, + ]; + const { rerender } = render( + <SourceFields + onChangeSourceFields={onChange} + esFields={esFields} + sourceFields={sourceFields} + errors={[]} + />, + { + wrapper: AppWrapper, + } + ); + + await waitFor(() => { + rerender( + <SourceFields + onChangeSourceFields={onChange} + esFields={esFields} + sourceFields={sourceFields} + errors={[]} + /> + ); + expect(screen.queryByTestId('option-host.name')).not.toBeInTheDocument(); + expect(screen.getAllByTestId('option-host.hostname')).toHaveLength(1); + expect(screen.getByTestId('option-host.id')).toBeInTheDocument(); + }); + }); + + it('should render SourceFields component with errors', () => { + const result = render( + <SourceFields + onChangeSourceFields={() => {}} + esFields={[ + { + name: 'host.name', + type: 'type', + normalizedType: 'type', + searchable: true, + aggregatable: true, + }, + ]} + sourceFields={[]} + errors={['test error']} + />, + { + wrapper: AppWrapper, + } + ); + + expect(result.getByText('test error')).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.tsx b/x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.tsx new file mode 100644 index 00000000000000..3cd34a3cd00155 --- /dev/null +++ b/x-pack/plugins/stack_alerts/public/rule_types/components/source_fields_select.tsx @@ -0,0 +1,120 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect, useState } from 'react'; +import { uniqBy } from 'lodash'; +import { EuiComboBox, EuiFormRow, EuiSpacer, EuiTitle } from '@elastic/eui'; +import { FieldOption } from '@kbn/triggers-actions-ui-plugin/public/common'; +import { IErrorObject } from '@kbn/triggers-actions-ui-plugin/public'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; +import { MAX_SELECTABLE_SOURCE_FIELDS, validSourceFields } from '../../../common/constants'; +import { SourceField } from '../es_query/types'; + +interface SourceFieldsOption { + label: string; + value: string; +} + +interface SourceFieldsProps { + esFields: FieldOption[]; + onChangeSourceFields: (selectedSourceFields: SourceField[]) => void; + errors: string | string[] | IErrorObject; + sourceFields?: SourceField[]; +} + +export const SourceFields: React.FC<SourceFieldsProps> = ({ + esFields, + onChangeSourceFields, + errors, + sourceFields, +}) => { + const [sourceFieldsOptions, setSourceFieldsOptions] = useState<SourceFieldsOption[]>([]); + + useEffect(() => { + const options = uniqBy( + esFields + .filter((f) => f.aggregatable) + .flatMap((f) => { + const validSourceField = validSourceFields.find( + (validatedField) => f.name === validatedField || f.name === `${validatedField}.keyword` + ); + if (validSourceField) { + return [ + { + label: validSourceField, + value: f.name, + 'data-test-subj': `option-${validSourceField}`, + }, + ]; + } + return []; + }), + 'label' + ); + + setSourceFieldsOptions(options); + + // if not sourceFields, auto select the current options + if (!sourceFields) { + const fields: SourceField[] = []; + options.forEach((f) => { + if (f.value && fields.length < MAX_SELECTABLE_SOURCE_FIELDS) { + fields.push({ label: f.label, searchPath: f.value }); + } + }); + onChangeSourceFields(fields); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [esFields]); + + return sourceFieldsOptions.length > 0 ? ( + <EuiFormRow + fullWidth + isInvalid={errors.length > 0 && sourceFields !== undefined} + error={errors} + > + <> + <EuiTitle size="xs"> + <h5> + <FormattedMessage + id="xpack.stackAlerts.components.ui.sourceFieldsSelect.title" + defaultMessage="Add more fields to alert details" + /> + </h5> + </EuiTitle> + <EuiSpacer size="s" /> + <EuiComboBox + fullWidth + placeholder={i18n.translate( + 'xpack.stackAlerts.components.ui.sourceFieldsSelect.placeholder', + { + defaultMessage: 'Select fields', + } + )} + data-test-subj="sourceFields" + isInvalid={errors.length > 0 && sourceFields !== undefined} + selectedOptions={(sourceFields || []).map((f) => ({ + label: f.label, + value: f.searchPath, + 'data-test-subj': `option-${f.label}`, + }))} + onChange={(options) => { + const fields: SourceField[] = []; + options.forEach((f) => { + if (f.value) { + fields.push({ label: f.label, searchPath: f.value }); + } + }); + onChangeSourceFields(fields); + }} + options={sourceFieldsOptions} + /> + </> + </EuiFormRow> + ) : null; +}; diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/constants.ts b/x-pack/plugins/stack_alerts/public/rule_types/es_query/constants.ts index f99b97634fc5ad..690387d0549392 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/constants.ts +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/constants.ts @@ -23,6 +23,7 @@ export const DEFAULT_VALUES = { GROUP_BY: 'all', EXCLUDE_PREVIOUS_HITS: true, CAN_SELECT_MULTI_TERMS: true, + SOURCE_FIELDS: [], }; export const COMMON_EXPRESSION_ERRORS = { @@ -36,6 +37,7 @@ export const COMMON_EXPRESSION_ERRORS = { groupBy: new Array<string>(), termSize: new Array<string>(), termField: new Array<string>(), + sourceFields: new Array<string>(), }; export const SEARCH_SOURCE_ONLY_EXPRESSION_ERRORS = { diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/es_query_expression.tsx b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/es_query_expression.tsx index f1e91ba63dc691..1cf901ecae8f90 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/es_query_expression.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/es_query_expression.tsx @@ -55,6 +55,7 @@ export const EsQueryExpression: React.FC< termSize, termField, excludeHitsFromPreviousRun, + sourceFields, } = ruleParams; const [currentRuleParams, setCurrentRuleParams] = useState<EsQueryRuleParams<SearchType.esQuery>>( @@ -72,6 +73,7 @@ export const EsQueryExpression: React.FC< searchType: SearchType.esQuery, excludeHitsFromPreviousRun: excludeHitsFromPreviousRun ?? DEFAULT_VALUES.EXCLUDE_PREVIOUS_HITS, + sourceFields, } ); @@ -229,6 +231,7 @@ export const EsQueryExpression: React.FC< termSize: DEFAULT_VALUES.TERM_SIZE, searchType: SearchType.esQuery, excludeHitsFromPreviousRun: DEFAULT_VALUES.EXCLUDE_PREVIOUS_HITS, + sourceFields: undefined, }); } else { await refreshEsFields(indices); @@ -352,6 +355,11 @@ export const EsQueryExpression: React.FC< [setParam] )} canSelectMultiTerms={DEFAULT_VALUES.CAN_SELECT_MULTI_TERMS} + onChangeSourceFields={useCallback( + (selectedSourceFields) => setParam('sourceFields', selectedSourceFields), + [setParam] + )} + sourceFields={sourceFields} /> <EuiSpacer /> diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.tsx b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.tsx index 8f3edd45a1e283..30f34b0a15d057 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/esql_query_expression.tsx @@ -6,7 +6,7 @@ */ import React, { useState, Fragment, useEffect, useCallback } from 'react'; -import { get } from 'lodash'; +import { debounce, get } from 'lodash'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiFieldNumber, @@ -23,11 +23,13 @@ import { fetchFieldsFromESQL } from '@kbn/text-based-editor'; import { AggregateQuery, getIndexPatternFromESQLQuery } from '@kbn/es-query'; import { parseDuration } from '@kbn/alerting-plugin/common'; import { + FieldOption, firstFieldOption, getTimeFieldOptions, getTimeOptions, parseAggregationResults, } from '@kbn/triggers-actions-ui-plugin/public/common'; +import { SourceFields } from '../../components/source_fields_select'; import { EsQueryRuleParams, EsQueryRuleMetaData, SearchType } from '../types'; import { DEFAULT_VALUES } from '../constants'; import { useTriggerUiActionServices } from '../util'; @@ -39,7 +41,7 @@ export const EsqlQueryExpression: React.FC< RuleTypeParamsExpressionProps<EsQueryRuleParams<SearchType.esqlQuery>, EsQueryRuleMetaData> > = ({ ruleParams, setRuleParams, setRuleProperty, errors }) => { const { expressions, http } = useTriggerUiActionServices(); - const { esqlQuery, timeWindowSize, timeWindowUnit, timeField } = ruleParams; + const { esqlQuery, timeWindowSize, timeWindowUnit, timeField, sourceFields } = ruleParams; const [currentRuleParams, setCurrentRuleParams] = useState< EsQueryRuleParams<SearchType.esqlQuery> @@ -57,10 +59,12 @@ export const EsqlQueryExpression: React.FC< groupBy: DEFAULT_VALUES.GROUP_BY, termSize: DEFAULT_VALUES.TERM_SIZE, searchType: SearchType.esqlQuery, + sourceFields: sourceFields ?? DEFAULT_VALUES.SOURCE_FIELDS, }); const [query, setQuery] = useState<AggregateQuery>({ esql: '' }); const [timeFieldOptions, setTimeFieldOptions] = useState([firstFieldOption]); const [detectTimestamp, setDetectTimestamp] = useState<boolean>(false); + const [esFields, setEsFields] = useState<FieldOption[]>([]); const setParam = useCallback( (paramField: string, paramValue: unknown) => { @@ -79,6 +83,7 @@ export const EsqlQueryExpression: React.FC< if (esqlQuery && 'esql' in esqlQuery) { if (esqlQuery.esql) { refreshTimeFields(esqlQuery); + refreshEsFields(esqlQuery, false); } } if (timeField) { @@ -138,6 +143,7 @@ export const EsqlQueryExpression: React.FC< let hasTimestamp = false; const indexPattern: string = getIndexPatternFromESQLQuery(get(q, 'esql')); const currentEsFields = await getFields(http, [indexPattern]); + const timeFields = getTimeFieldOptions(currentEsFields); setTimeFieldOptions([firstFieldOption, ...timeFields]); @@ -149,6 +155,29 @@ export const EsqlQueryExpression: React.FC< setDetectTimestamp(hasTimestamp); }; + const refreshEsFields = async (q: AggregateQuery, resetSourceFields: boolean = true) => { + let fields: FieldOption[] = []; + try { + const table = await fetchFieldsFromESQL({ esql: `${get(q, 'esql')} | limit 0` }, expressions); + if (table) { + fields = table.columns.map((c) => ({ + name: c.id, + type: c.meta.type, + normalizedType: c.meta.type, + searchable: true, + aggregatable: true, + })); + } + } catch (error) { + /** ignore error */ + } + + if (resetSourceFields) { + setParam('sourceFields', undefined); + } + setEsFields(fields); + }; + return ( <Fragment> <EuiTitle size="xs"> @@ -163,11 +192,12 @@ export const EsqlQueryExpression: React.FC< <EuiFormRow id="queryEditor" data-test-subj="queryEsqlEditor" fullWidth> <TextBasedLangEditor query={query} - onTextLangQueryChange={(q: AggregateQuery) => { + onTextLangQueryChange={debounce((q: AggregateQuery) => { setQuery(q); setParam('esqlQuery', q); refreshTimeFields(q); - }} + refreshEsFields(q); + }, 1000)} expandCodeEditor={() => true} isCodeEditorExpanded={true} onTextLangQuerySubmit={() => {}} @@ -176,6 +206,14 @@ export const EsqlQueryExpression: React.FC< hideRunQueryText={true} /> </EuiFormRow> + <SourceFields + onChangeSourceFields={(selectedSourceFields) => + setParam('sourceFields', selectedSourceFields) + } + esFields={esFields} + sourceFields={sourceFields} + errors={errors.sourceFields} + /> <EuiSpacer /> <EuiTitle size="xs"> <h5> diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/search_source_expression.tsx b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/search_source_expression.tsx index b8fd6d1ee086f0..dae9a67fd0c380 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/search_source_expression.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/search_source_expression.tsx @@ -43,6 +43,7 @@ export const SearchSourceExpression = ({ termField, termSize, excludeHitsFromPreviousRun, + sourceFields, } = ruleParams; const { data } = useTriggerUiActionServices(); @@ -92,6 +93,7 @@ export const SearchSourceExpression = ({ termSize: termSize ?? DEFAULT_VALUES.TERM_SIZE, excludeHitsFromPreviousRun: excludeHitsFromPreviousRun ?? DEFAULT_VALUES.EXCLUDE_PREVIOUS_HITS, + sourceFields, }); setSearchSource(createdSearchSource); } catch (error) { diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/search_source_expression_form.tsx b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/search_source_expression_form.tsx index c4419a780809df..c6ee0157e082ab 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/search_source_expression_form.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/search_source_expression_form.tsx @@ -27,7 +27,13 @@ import { import { STACK_ALERTS_FEATURE_ID } from '@kbn/rule-data-utils'; import { getComparatorScript } from '../../../../common'; import { Comparator } from '../../../../common/comparator_types'; -import { CommonRuleParams, EsQueryRuleMetaData, EsQueryRuleParams, SearchType } from '../types'; +import { + CommonRuleParams, + EsQueryRuleMetaData, + EsQueryRuleParams, + SearchType, + SourceField, +} from '../types'; import { DEFAULT_VALUES } from '../constants'; import { DataViewSelectPopover } from '../../components/data_view_select_popover'; import { RuleCommonExpressions } from '../rule_common_expressions'; @@ -49,7 +55,7 @@ interface LocalStateAction { type: SearchSourceParamsAction['type'] | keyof CommonRuleParams; payload: | SearchSourceParamsAction['payload'] - | (number[] | number | string | string[] | boolean | undefined); + | (number[] | number | string | string[] | boolean | SourceField[] | undefined); } type LocalStateReducer = (prevState: LocalState, action: LocalStateAction) => LocalState; @@ -112,6 +118,7 @@ export const SearchSourceExpressionForm = (props: SearchSourceExpressionFormProp size: ruleParams.size ?? DEFAULT_VALUES.SIZE, excludeHitsFromPreviousRun: ruleParams.excludeHitsFromPreviousRun ?? DEFAULT_VALUES.EXCLUDE_PREVIOUS_HITS, + sourceFields: ruleParams.sourceFields, } ); @@ -123,8 +130,9 @@ export const SearchSourceExpressionForm = (props: SearchSourceExpressionFormProp ); const onSelectDataView = useCallback((newDataView: DataView) => { - setEsFields(convertFieldSpecToFieldOption(newDataView.fields.map((field) => field.toSpec()))); dispatch({ type: 'index', payload: newDataView }); + dispatch({ type: 'sourceFields', payload: undefined }); + setEsFields(convertFieldSpecToFieldOption(newDataView.fields.map((field) => field.toSpec()))); }, []); const onUpdateFilters = useCallback((newFilters) => { @@ -226,6 +234,12 @@ export const SearchSourceExpressionForm = (props: SearchSourceExpressionFormProp [] ); + const onChangeSourceFields = useCallback( + (selectedSourceFields: SourceField[]) => + dispatch({ type: 'sourceFields', payload: selectedSourceFields }), + [] + ); + const timeWindow = `${ruleConfiguration.timeWindowSize}${ruleConfiguration.timeWindowUnit}`; const createTestSearchSource = useCallback(() => { @@ -372,6 +386,8 @@ export const SearchSourceExpressionForm = (props: SearchSourceExpressionFormProp excludeHitsFromPreviousRun={ruleConfiguration.excludeHitsFromPreviousRun} onChangeExcludeHitsFromPreviousRun={onChangeExcludeHitsFromPreviousRun} canSelectMultiTerms={DEFAULT_VALUES.CAN_SELECT_MULTI_TERMS} + onChangeSourceFields={onChangeSourceFields} + sourceFields={ruleConfiguration.sourceFields} /> <EuiSpacer /> </Fragment> diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/rule_common_expressions/rule_common_expressions.test.tsx b/x-pack/plugins/stack_alerts/public/rule_types/es_query/rule_common_expressions/rule_common_expressions.test.tsx index 267b289cf5ca85..c235c3fe8fc3e5 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/rule_common_expressions/rule_common_expressions.test.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/rule_common_expressions/rule_common_expressions.test.tsx @@ -93,6 +93,7 @@ describe('RuleCommonExpressions', () => { }} excludeHitsFromPreviousRun={excludeHitsFromPreviousRun} onChangeExcludeHitsFromPreviousRun={onChangeExcludeHitsFromPreviousRunFn} + onChangeSourceFields={() => {}} /> ); diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/rule_common_expressions/rule_common_expressions.tsx b/x-pack/plugins/stack_alerts/public/rule_types/es_query/rule_common_expressions/rule_common_expressions.tsx index cee08144f307e7..313d3f586c73ef 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/rule_common_expressions/rule_common_expressions.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/rule_common_expressions/rule_common_expressions.tsx @@ -28,7 +28,8 @@ import { WhenExpression, } from '@kbn/triggers-actions-ui-plugin/public'; import { builtInGroupByTypes, FieldOption } from '@kbn/triggers-actions-ui-plugin/public/common'; -import { CommonRuleParams } from '../types'; +import { SourceFields } from '../../components/source_fields_select'; +import { CommonRuleParams, SourceField } from '../types'; import { DEFAULT_VALUES } from '../constants'; import { TestQueryRow, TestQueryRowProps } from '../test_query_row'; import { QueryThresholdHelpPopover } from './threshold_help_popover'; @@ -53,6 +54,7 @@ export interface RuleCommonExpressionsProps extends CommonRuleParams { onCopyQuery?: TestQueryRowProps['copyQuery']; onChangeExcludeHitsFromPreviousRun: (exclude: boolean) => void; canSelectMultiTerms?: boolean; + onChangeSourceFields: (selectedSourceFields: SourceField[]) => void; } export const RuleCommonExpressions: React.FC<RuleCommonExpressionsProps> = ({ @@ -67,6 +69,7 @@ export const RuleCommonExpressions: React.FC<RuleCommonExpressionsProps> = ({ termField, termSize, size, + sourceFields, errors, hasValidationErrors, onChangeSelectedAggField, @@ -84,6 +87,7 @@ export const RuleCommonExpressions: React.FC<RuleCommonExpressionsProps> = ({ excludeHitsFromPreviousRun, onChangeExcludeHitsFromPreviousRun, canSelectMultiTerms, + onChangeSourceFields, }) => { const [isExcludeHitsDisabled, setIsExcludeHitsDisabled] = useState<boolean>(false); @@ -205,6 +209,13 @@ export const RuleCommonExpressions: React.FC<RuleCommonExpressionsProps> = ({ })} /> </EuiFormRow> + + <SourceFields + onChangeSourceFields={onChangeSourceFields} + esFields={esFields} + sourceFields={sourceFields} + errors={errors.sourceFields} + /> <EuiSpacer size="m" /> <TestQueryRow fetch={onTestFetch} diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/test_query_row.test.tsx b/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/test_query_row.test.tsx index b8b93d68771b44..944befe0e2b66a 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/test_query_row.test.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/test_query_row.test.tsx @@ -24,7 +24,7 @@ const COPIED_QUERY = 'COPIED QUERY'; const onFetch = () => Promise.resolve({ testResults: { - results: [{ group: 'all documents', hits: [], count: 42 }], + results: [{ group: 'all documents', hits: [], count: 42, sourceFields: [] }], truncated: false, }, isGrouped: false, diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/use_test_query.test.ts b/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/use_test_query.test.ts index 44c2a1cf557177..f476d7d896b69d 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/use_test_query.test.ts +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/test_query_row/use_test_query.test.ts @@ -15,7 +15,7 @@ describe('useTestQuery', () => { initialProps: () => Promise.resolve({ testResults: { - results: [{ group: 'all documents', hits: [], count: 1 }], + results: [{ group: 'all documents', hits: [], count: 1, sourceFields: [] }], truncated: false, }, isGrouped: false, @@ -46,8 +46,8 @@ describe('useTestQuery', () => { Promise.resolve({ testResults: { results: [ - { group: 'a', count: 1, value: 10, hits: [] }, - { group: 'b', count: 2, value: 20, hits: [] }, + { group: 'a', count: 1, value: 10, hits: [], sourceFields: [] }, + { group: 'b', count: 2, value: 20, hits: [], sourceFields: [] }, ], truncated: false, }, diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/types.ts b/x-pack/plugins/stack_alerts/public/rule_types/es_query/types.ts index 93b184f8552326..4e1abc5b52a5cb 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/types.ts +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/types.ts @@ -17,6 +17,11 @@ export enum SearchType { esqlQuery = 'esqlQuery', } +export interface SourceField { + label: string; + searchPath: string; +} + export interface CommonRuleParams { size: number; thresholdComparator?: string; @@ -29,6 +34,7 @@ export interface CommonRuleParams { termSize?: number; termField?: string | string[]; excludeHitsFromPreviousRun: boolean; + sourceFields?: SourceField[]; } export interface CommonEsQueryRuleParams extends RuleTypeParams, CommonRuleParams {} diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/validation.test.ts b/x-pack/plugins/stack_alerts/public/rule_types/es_query/validation.test.ts index 54363fe1010f3e..e665ac79088884 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/validation.test.ts +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/validation.test.ts @@ -377,4 +377,27 @@ describe('expression params validation', () => { 'Threshold is required to be 0.' ); }); + + test('if sourceFields property is an array but has more than 5 items, should return proper error message', () => { + const sourceField = { label: 'test', searchPath: 'test' }; + const initialParams: EsQueryRuleParams<SearchType.esQuery> = { + index: ['test'], + esQuery: `{\n \"query\":{\n \"match_all\" : {}\n }\n}`, + size: 100, + timeWindowSize: 1, + timeWindowUnit: 's', + threshold: [0], + timeField: '', + excludeHitsFromPreviousRun: true, + aggType: 'count', + groupBy: 'top', + termSize: 10, + termField: ['term'], + sourceFields: [sourceField, sourceField, sourceField, sourceField, sourceField, sourceField], + }; + expect(validateExpression(initialParams).errors.sourceFields.length).toBeGreaterThan(0); + expect(validateExpression(initialParams).errors.sourceFields[0]).toBe( + 'Cannot select more than 5 fields' + ); + }); }); diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/validation.ts b/x-pack/plugins/stack_alerts/public/rule_types/es_query/validation.ts index 5830a506a00732..59c5a4ff55e814 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/validation.ts +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/validation.ts @@ -14,7 +14,10 @@ import { builtInGroupByTypes, COMPARATORS, } from '@kbn/triggers-actions-ui-plugin/public'; -import { MAX_SELECTABLE_GROUP_BY_TERMS } from '../../../common/constants'; +import { + MAX_SELECTABLE_SOURCE_FIELDS, + MAX_SELECTABLE_GROUP_BY_TERMS, +} from '../../../common/constants'; import { EsQueryRuleParams, SearchType } from './types'; import { isEsqlQueryRule, isSearchSourceRule } from './util'; import { @@ -35,6 +38,7 @@ const validateCommonParams = (ruleParams: EsQueryRuleParams) => { groupBy, termSize, termField, + sourceFields, } = ruleParams; const errors: typeof COMMON_EXPRESSION_ERRORS = defaultsDeep({}, COMMON_EXPRESSION_ERRORS); @@ -149,6 +153,19 @@ const validateCommonParams = (ruleParams: EsQueryRuleParams) => { ); } + if ( + sourceFields && + Array.isArray(sourceFields) && + sourceFields.length > MAX_SELECTABLE_SOURCE_FIELDS + ) { + errors.sourceFields.push( + i18n.translate('xpack.stackAlerts.esqlQuery.ui.validation.error.sourceFields', { + defaultMessage: `Cannot select more than {max} fields`, + values: { max: MAX_SELECTABLE_SOURCE_FIELDS }, + }) + ); + } + return errors; }; diff --git a/x-pack/plugins/stack_alerts/server/rule_types/es_query/action_context.test.ts b/x-pack/plugins/stack_alerts/server/rule_types/es_query/action_context.test.ts index 33d7babe6b1b9f..aa8c7d1dbc0def 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/es_query/action_context.test.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/es_query/action_context.test.ts @@ -34,6 +34,7 @@ describe('addMessages', () => { conditions: 'count greater than 4', hits: [], link: 'link-mock', + sourceFields: [], }; const context = addMessages({ ruleName: '[rule-name]', @@ -67,6 +68,7 @@ describe('addMessages', () => { conditions: 'count not greater than 4', hits: [], link: 'link-mock', + sourceFields: [], }; const context = addMessages({ ruleName: '[rule-name]', @@ -101,6 +103,7 @@ describe('addMessages', () => { conditions: 'count between 4 and 5', hits: [], link: 'link-mock', + sourceFields: [], }; const context = addMessages({ ruleName: '[rule-name]', @@ -136,6 +139,7 @@ describe('addMessages', () => { conditions: `count for group "host-1" not greater than 4`, hits: [], link: 'link-mock', + sourceFields: [], }; const context = addMessages({ ruleName: '[rule-name]', @@ -172,6 +176,7 @@ describe('addMessages', () => { conditions: 'count greater than 4', hits: [], link: 'link-mock', + sourceFields: [], }; const context = addMessages({ ruleName: '[rule-name]', @@ -205,6 +210,7 @@ describe('addMessages', () => { conditions: 'count greater than 4', hits: [], link: 'link-mock', + sourceFields: [], }; const context = addMessages({ ruleName: '[rule-name]', @@ -238,6 +244,7 @@ describe('addMessages', () => { conditions: 'count greater than 4', hits: [], link: 'link-mock', + sourceFields: [], }; const context = addMessages({ ruleName: '[rule-name]', diff --git a/x-pack/plugins/stack_alerts/server/rule_types/es_query/action_context.ts b/x-pack/plugins/stack_alerts/server/rule_types/es_query/action_context.ts index fe70914a9e7bd1..719d497a10236f 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/es_query/action_context.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/es_query/action_context.ts @@ -34,6 +34,7 @@ export interface EsQueryRuleActionContext extends AlertInstanceContext { // a link to see records that triggered the rule for Discover rule // a link which navigates to stack management in case of Elastic query rule link: string; + sourceFields: string[]; } interface AddMessagesOpts { diff --git a/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.test.ts b/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.test.ts index 02ddc658b021f1..7ab974dc8d82bb 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.test.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.test.ts @@ -645,6 +645,7 @@ describe('es_query executor', () => { message: 'Document count is 0 in the last 5m. Alert when greater than or equal to 500.', title: "rule 'test-rule-name' recovered", value: 0, + sourceFields: [], }, payload: { 'kibana.alert.evaluation.conditions': @@ -705,6 +706,7 @@ describe('es_query executor', () => { 'Document count is 0 in the last 5m for host-1. Alert when greater than or equal to 200.', title: "rule 'test-rule-name' recovered", value: 0, + sourceFields: [], }, payload: { 'kibana.alert.evaluation.conditions': @@ -729,6 +731,7 @@ describe('es_query executor', () => { 'Document count is 0 in the last 5m for host-2. Alert when greater than or equal to 200.', title: "rule 'test-rule-name' recovered", value: 0, + sourceFields: [], }, payload: { 'kibana.alert.evaluation.conditions': @@ -783,6 +786,7 @@ describe('es_query executor', () => { message: 'Document count is 0 in the last 5m. Alert when greater than 0.', title: "rule 'test-rule-name' recovered", value: 0, + sourceFields: [], }, payload: { 'kibana.alert.evaluation.conditions': 'Query did NOT match documents', @@ -797,6 +801,87 @@ describe('es_query executor', () => { expect(mockSetLimitReached).toHaveBeenCalledTimes(1); expect(mockSetLimitReached).toHaveBeenCalledWith(false); }); + + it('should correctly handle alerts with sourceFields', async () => { + mockFetchEsQuery.mockResolvedValueOnce({ + parsedResults: { + results: [ + { + group: 'host-1', + count: 291, + hits: [], + sourceFields: { + 'host.hostname': ['host-1'], + 'host.id': ['1'], + 'host.name': ['host-1'], + }, + }, + ], + truncated: false, + }, + link: 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', + }); + await executor(coreMock, { + ...defaultExecutorOptions, + // @ts-expect-error + params: { + ...defaultProps, + threshold: [200], + thresholdComparator: '>=' as Comparator, + groupBy: 'top', + termSize: 10, + termField: 'host.name', + sourceFields: [ + { label: 'host.hostname', searchPath: 'host.hostname.keyword' }, + { label: 'host.id', searchPath: 'host.id.keyword' }, + { label: 'host.name', searchPath: 'host.name.keyword' }, + ], + }, + }); + + expect(mockReport).toHaveBeenCalledTimes(1); + expect(mockReport).toHaveBeenNthCalledWith(1, { + actionGroup: 'query matched', + context: { + conditions: + 'Number of matching documents for group "host-1" is greater than or equal to 200', + date: new Date(mockNow).toISOString(), + hits: [], + link: 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', + message: + 'Document count is 291 in the last 5m for host-1. Alert when greater than or equal to 200.', + title: "rule 'test-rule-name' matched query for group host-1", + value: 291, + sourceFields: { + 'host.hostname': ['host-1'], + 'host.id': ['1'], + 'host.name': ['host-1'], + }, + }, + id: 'host-1', + state: { + dateEnd: new Date(mockNow).toISOString(), + dateStart: new Date(mockNow).toISOString(), + latestTimestamp: undefined, + }, + payload: { + 'kibana.alert.evaluation.conditions': + 'Number of matching documents for group "host-1" is greater than or equal to 200', + 'kibana.alert.evaluation.threshold': 200, + 'kibana.alert.evaluation.value': '291', + 'kibana.alert.reason': + 'Document count is 291 in the last 5m for host-1. Alert when greater than or equal to 200.', + 'kibana.alert.title': "rule 'test-rule-name' matched query for group host-1", + 'kibana.alert.url': + 'https://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/test-rule-id', + 'host.hostname': ['host-1'], + 'host.id': ['1'], + 'host.name': ['host-1'], + }, + }); + expect(mockSetLimitReached).toHaveBeenCalledTimes(1); + expect(mockSetLimitReached).toHaveBeenCalledWith(false); + }); }); describe('tryToParseAsDate', () => { diff --git a/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.ts b/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.ts index 7d8d2df355c16c..5e23bf9498ec5e 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/es_query/executor.ts @@ -136,6 +136,7 @@ export async function executor(core: CoreSetup, options: ExecutorOptions<EsQuery value, hits: result.hits, link, + sourceFields: result.sourceFields, }; const baseActiveContext: EsQueryRuleActionContext = { ...baseContext, @@ -171,6 +172,7 @@ export async function executor(core: CoreSetup, options: ExecutorOptions<EsQuery [ALERT_EVALUATION_CONDITIONS]: actionContext.conditions, [ALERT_EVALUATION_VALUE]: `${actionContext.value}`, [ALERT_EVALUATION_THRESHOLD]: params.threshold?.length === 1 ? params.threshold[0] : null, + ...actionContext.sourceFields, }, }); if (!isGroupAgg) { @@ -203,6 +205,7 @@ export async function executor(core: CoreSetup, options: ExecutorOptions<EsQuery aggField: params.aggField, ...(isGroupAgg ? { group: alertId } : {}), }), + sourceFields: [], } as EsQueryRuleActionContext; const recoveryContext = addMessages({ ruleName: name, diff --git a/x-pack/plugins/stack_alerts/server/rule_types/es_query/lib/fetch_es_query.ts b/x-pack/plugins/stack_alerts/server/rule_types/es_query/lib/fetch_es_query.ts index f2c710e1856bed..fdff3356faab72 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/es_query/lib/fetch_es_query.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/es_query/lib/fetch_es_query.ts @@ -110,6 +110,7 @@ export async function fetchEsQuery({ aggField: params.aggField, termField: params.termField, termSize: params.termSize, + sourceFieldsParams: params.sourceFields, condition: { resultLimit: alertLimit, conditionScript: getComparatorScript( @@ -140,6 +141,7 @@ export async function fetchEsQuery({ isGroupAgg, esResult: searchResult, resultLimit: alertLimit, + sourceFieldsParams: params.sourceFields, }), link, index: params.index, diff --git a/x-pack/plugins/stack_alerts/server/rule_types/es_query/lib/fetch_esql_query.ts b/x-pack/plugins/stack_alerts/server/rule_types/es_query/lib/fetch_esql_query.ts index 76a219f3cfff3c..b87afae0aec74a 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/es_query/lib/fetch_esql_query.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/es_query/lib/fetch_esql_query.ts @@ -63,6 +63,8 @@ export async function fetchEsqlQuery({ hits: toEsQueryHits(response), }, resultLimit: alertLimit, + sourceFieldsParams: params.sourceFields, + generateSourceFieldsFromHits: true, }), index: null, }; diff --git a/x-pack/plugins/stack_alerts/server/rule_types/es_query/lib/fetch_search_source_query.ts b/x-pack/plugins/stack_alerts/server/rule_types/es_query/lib/fetch_search_source_query.ts index 455ce4c7dc9bca..51773ec3d5134d 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/es_query/lib/fetch_search_source_query.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/es_query/lib/fetch_search_source_query.ts @@ -91,7 +91,12 @@ export async function fetchSearchSourceQuery({ link, numMatches: Number(searchResult.hits.total), searchResult, - parsedResults: parseAggregationResults({ isCountAgg, isGroupAgg, esResult: searchResult }), + parsedResults: parseAggregationResults({ + isCountAgg, + isGroupAgg, + esResult: searchResult, + sourceFieldsParams: params.sourceFields, + }), index: [index.name], }; } @@ -153,6 +158,7 @@ export function updateSearchSource( aggField: params.aggField, termField: params.termField, termSize: params.termSize, + sourceFieldsParams: params.sourceFields, condition: { resultLimit: alertLimit, conditionScript: getComparatorScript( diff --git a/x-pack/plugins/stack_alerts/server/rule_types/es_query/rule_type_params.test.ts b/x-pack/plugins/stack_alerts/server/rule_types/es_query/rule_type_params.test.ts index 128fd339f001bb..010640b2207d94 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/es_query/rule_type_params.test.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/es_query/rule_type_params.test.ts @@ -354,6 +354,22 @@ describe('ruleType Params validate()', () => { expect(onValidate()).not.toThrow(); }); + it('fails for invalid sourceFields', async () => { + // no array that has more than 5 elements + const sourceField = { label: 'test', searchPath: 'test' }; + params.sourceFields = [ + sourceField, + sourceField, + sourceField, + sourceField, + sourceField, + sourceField, + ]; + expect(onValidate()).toThrow( + '[sourceFields]: array size is [6], but cannot be greater than [5]' + ); + }); + describe('esqlQuery search type', () => { beforeEach(() => { params = { ...DefaultParams, searchType: 'esqlQuery', esqlQuery: { esql: 'from test' } }; diff --git a/x-pack/plugins/stack_alerts/server/rule_types/es_query/rule_type_params.ts b/x-pack/plugins/stack_alerts/server/rule_types/es_query/rule_type_params.ts index d1f99b4e97b93d..73e8eae32cf9b2 100644 --- a/x-pack/plugins/stack_alerts/server/rule_types/es_query/rule_type_params.ts +++ b/x-pack/plugins/stack_alerts/server/rule_types/es_query/rule_type_params.ts @@ -15,7 +15,10 @@ import { } from '@kbn/triggers-actions-ui-plugin/server'; import { RuleTypeState } from '@kbn/alerting-plugin/server'; import { SerializedSearchSourceFields } from '@kbn/data-plugin/common'; -import { MAX_SELECTABLE_GROUP_BY_TERMS } from '../../../common/constants'; +import { + MAX_SELECTABLE_SOURCE_FIELDS, + MAX_SELECTABLE_GROUP_BY_TERMS, +} from '../../../common/constants'; import { ComparatorFnNames } from '../../../common'; import { Comparator } from '../../../common/comparator_types'; import { getComparatorSchemaType } from '../lib/comparator'; @@ -96,6 +99,17 @@ const EsQueryRuleParamsSchemaProperties = { schema.object({ esql: schema.string({ minLength: 1 }) }), schema.never() ), + sourceFields: schema.maybe( + schema.arrayOf( + schema.object({ + label: schema.string(), + searchPath: schema.string(), + }), + { + maxSize: MAX_SELECTABLE_SOURCE_FIELDS, + } + ) + ), }; export const EsQueryRuleParamsSchema = schema.object(EsQueryRuleParamsSchemaProperties, { diff --git a/x-pack/plugins/triggers_actions_ui/common/data/lib/build_agg.test.ts b/x-pack/plugins/triggers_actions_ui/common/data/lib/build_agg.test.ts index 1925954ea7bb9d..08c43eb9f8c0fb 100644 --- a/x-pack/plugins/triggers_actions_ui/common/data/lib/build_agg.test.ts +++ b/x-pack/plugins/triggers_actions_ui/common/data/lib/build_agg.test.ts @@ -919,4 +919,142 @@ describe('buildAgg', () => { }, }); }); + + it('should correctly apply the sourceFieldsParams if specified', async () => { + expect( + buildAggregation({ + timeSeries: { + timeField: 'time-field', + timeWindowSize: 5, + timeWindowUnit: 'm', + dateStart: '2021-04-22T15:19:31Z', + dateEnd: '2021-04-22T15:20:31Z', + interval: '1m', + }, + aggType: 'count', + aggField: undefined, + termField: 'the-term', + termSize: 100, + condition: { + conditionScript: `params.compareValue > 1`, + }, + sourceFieldsParams: [ + { label: 'host.hostname', searchPath: 'host.hostname.keyword' }, + { label: 'host.id', searchPath: 'host.id.keyword' }, + { label: 'host.name', searchPath: 'host.name.keyword' }, + ], + }) + ).toEqual({ + groupAgg: { + terms: { + field: 'the-term', + size: 100, + }, + aggs: { + conditionSelector: { + bucket_selector: { + buckets_path: { + compareValue: '_count', + }, + script: `params.compareValue > 1`, + }, + }, + dateAgg: { + date_range: { + field: 'time-field', + format: 'strict_date_time', + ranges: [ + { + from: '2021-04-22T15:14:31.000Z', + to: '2021-04-22T15:19:31.000Z', + }, + { + from: '2021-04-22T15:15:31.000Z', + to: '2021-04-22T15:20:31.000Z', + }, + ], + }, + }, + 'host.hostname': { + terms: { + field: 'host.hostname.keyword', + size: 10, + }, + }, + 'host.id': { + terms: { + field: 'host.id.keyword', + size: 10, + }, + }, + 'host.name': { + terms: { + field: 'host.name.keyword', + size: 10, + }, + }, + }, + }, + groupAggCount: { + stats_bucket: { + buckets_path: 'groupAgg._count', + }, + }, + }); + }); + + it('should correctly apply the sourceFieldsParams if specified on a grouped query', async () => { + expect( + buildAggregation({ + aggType: 'avg', + aggField: 'event.duration', + termField: 'event.action', + termSize: 10, + sourceFieldsParams: [{ label: 'event.provider', searchPath: 'event.provider' }], + condition: { resultLimit: 1000, conditionScript: 'params.compareValue > -1L' }, + topHitsSize: 100, + }) + ).toEqual({ + groupAgg: { + aggs: { + conditionSelector: { + bucket_selector: { + buckets_path: { + compareValue: 'metricAgg', + }, + script: 'params.compareValue > -1L', + }, + }, + 'event.provider': { + terms: { + field: 'event.provider', + size: 10, + }, + }, + metricAgg: { + avg: { + field: 'event.duration', + }, + }, + topHitsAgg: { + top_hits: { + size: 100, + }, + }, + }, + terms: { + field: 'event.action', + order: { + metricAgg: 'desc', + }, + size: 10, + }, + }, + groupAggCount: { + stats_bucket: { + buckets_path: 'groupAgg._count', + }, + }, + }); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/common/data/lib/build_agg.ts b/x-pack/plugins/triggers_actions_ui/common/data/lib/build_agg.ts index 2c6ccac04c638e..dfb141554a9fd8 100644 --- a/x-pack/plugins/triggers_actions_ui/common/data/lib/build_agg.ts +++ b/x-pack/plugins/triggers_actions_ui/common/data/lib/build_agg.ts @@ -20,6 +20,7 @@ export interface BuildAggregationOpts { aggField?: string; termSize?: number; termField?: string | string[]; + sourceFieldsParams?: Array<{ label: string; searchPath: string }>; topHitsSize?: number; condition?: { resultLimit?: number; @@ -30,6 +31,7 @@ export interface BuildAggregationOpts { export const BUCKET_SELECTOR_PATH_NAME = 'compareValue'; export const BUCKET_SELECTOR_FIELD = `params.${BUCKET_SELECTOR_PATH_NAME}`; export const DEFAULT_GROUPS = 100; +export const MAX_SOURCE_FIELDS_TO_COPY = 10; export const isCountAggregation = (aggType: string) => aggType === 'count'; export const isGroupAggregation = (termField?: string | string[]) => !!termField; @@ -40,6 +42,7 @@ export const buildAggregation = ({ aggField, termField, termSize, + sourceFieldsParams, condition, topHitsSize, }: BuildAggregationOpts): Record<string, AggregationsAggregationContainer> => { @@ -126,10 +129,21 @@ export const buildAggregation = ({ }, }; } - aggParent = aggParent.aggs.groupAgg; } + // add sourceField aggregations + if (sourceFieldsParams && sourceFieldsParams.length > 0) { + sourceFieldsParams.forEach((field) => { + aggParent.aggs = { + ...aggParent.aggs, + [field.label]: { + terms: { field: field.searchPath, size: MAX_SOURCE_FIELDS_TO_COPY }, + }, + }; + }); + } + // next, add the time window aggregation if (isDateAgg) { aggParent.aggs = { diff --git a/x-pack/plugins/triggers_actions_ui/common/data/lib/parse_aggregation_results.test.ts b/x-pack/plugins/triggers_actions_ui/common/data/lib/parse_aggregation_results.test.ts index e0935326368f84..e22d4959c6093b 100644 --- a/x-pack/plugins/triggers_actions_ui/common/data/lib/parse_aggregation_results.test.ts +++ b/x-pack/plugins/triggers_actions_ui/common/data/lib/parse_aggregation_results.test.ts @@ -62,6 +62,50 @@ const sampleHit = { sort: [1668020234918], }; +const sampleSourceFieldsHit = { + _index: 'test-data', + _id: '6S04F4wBEMHmjvc_YPJ_', + _score: null, + _source: { + '@timestamp': '2023-11-27T10:00:00', + host: { id: '1', name: 'host-1', hostname: 'host-1' }, + }, + fields: { '@timestamp': ['2023-11-27T10:00:00.000Z'] }, + sort: ['2023-11-27T10:00:00.000Z'], +}; + +const sampleAggregations = { + 'host.name': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'host-1', doc_count: 5 }], + }, + 'host.hostname': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'host-1', doc_count: 5 }], + }, + 'host.id': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: '1', doc_count: 5 }], + }, +}; + +const sampleEsqlSourceFieldsHit = { + _id: 'esql_query_document', + _index: '', + _source: { + '@timestamp': '2023-11-27T10:00:00.000Z', + 'host.hostname': 'host-1', + 'host.hostname.keyword': 'host-1', + 'host.id': '1', + 'host.id.keyword': '1', + 'host.name': 'host-1', + 'host.name.keyword': 'host-1', + }, +}; + describe('parseAggregationResults', () => { it('correctly parses results for count over all', () => { expect( @@ -85,6 +129,7 @@ describe('parseAggregationResults', () => { group: 'all documents', count: 491, hits: [sampleHit], + sourceFields: {}, }, ], truncated: false, @@ -137,26 +182,31 @@ describe('parseAggregationResults', () => { group: 'execute', count: 120, hits: [], + sourceFields: {}, }, { group: 'execute-start', count: 120, hits: [], + sourceFields: {}, }, { group: 'active-instance', count: 100, hits: [], + sourceFields: {}, }, { group: 'execute-action', count: 100, hits: [], + sourceFields: {}, }, { group: 'new-instance', count: 100, hits: [], + sourceFields: {}, }, ], truncated: false, @@ -259,26 +309,31 @@ describe('parseAggregationResults', () => { group: 'execute', count: 120, hits: [sampleHit], + sourceFields: {}, }, { group: 'execute-start', count: 120, hits: [sampleHit], + sourceFields: {}, }, { group: 'active-instance', count: 100, hits: [sampleHit], + sourceFields: {}, }, { group: 'execute-action', count: 100, hits: [sampleHit], + sourceFields: {}, }, { group: 'new-instance', count: 100, hits: [sampleHit], + sourceFields: {}, }, ], truncated: false, @@ -309,6 +364,7 @@ describe('parseAggregationResults', () => { hits: [sampleHit], count: 643, value: 3578195238.095238, + sourceFields: {}, }, ], truncated: false, @@ -377,30 +433,35 @@ describe('parseAggregationResults', () => { count: 120, hits: [], value: null, + sourceFields: {}, }, { group: 'execute-start', count: 139, hits: [], value: null, + sourceFields: {}, }, { group: 'starting', count: 1, hits: [], value: null, + sourceFields: {}, }, { group: 'recovered-instance', count: 120, hits: [], value: 12837500000, + sourceFields: {}, }, { group: 'execute', count: 139, hits: [], value: 137647482.0143885, + sourceFields: {}, }, ], truncated: false, @@ -519,30 +580,35 @@ describe('parseAggregationResults', () => { count: 120, hits: [sampleHit], value: null, + sourceFields: {}, }, { group: 'execute-start', count: 139, hits: [sampleHit], value: null, + sourceFields: {}, }, { group: 'starting', count: 1, hits: [sampleHit], value: null, + sourceFields: {}, }, { group: 'recovered-instance', count: 120, hits: [sampleHit], value: 12837500000, + sourceFields: {}, }, { group: 'execute', count: 139, hits: [sampleHit], value: 137647482.0143885, + sourceFields: {}, }, ], truncated: false, @@ -599,19 +665,191 @@ describe('parseAggregationResults', () => { group: 'execute', count: 120, hits: [], + sourceFields: {}, }, { group: 'execute-start', count: 120, hits: [], + sourceFields: {}, }, { group: 'active-instance', count: 100, hits: [], + sourceFields: {}, }, ], truncated: true, }); }); + + it('correctly parses results for count with source fields', () => { + expect( + parseAggregationResults({ + isCountAgg: true, + isGroupAgg: false, + esResult: { + took: 1, + timed_out: false, + _shards: { total: 1, successful: 1, skipped: 0, failed: 0 }, + hits: { + total: 491, + max_score: null, + hits: [sampleSourceFieldsHit], + }, + aggregations: sampleAggregations, + }, + resultLimit: 1000, + sourceFieldsParams: [ + { label: 'host.hostname', searchPath: 'host.hostname.keyword' }, + { label: 'host.id', searchPath: 'host.id.keyword' }, + { label: 'host.name', searchPath: 'host.name.keyword' }, + ], + }) + ).toEqual({ + results: [ + { + group: 'all documents', + count: 491, + hits: [sampleSourceFieldsHit], + sourceFields: { + 'host.hostname': ['host-1'], + 'host.id': ['1'], + 'host.name': ['host-1'], + }, + }, + ], + truncated: false, + }); + }); + + it('correctly parses results for aggregate metric with source fields', () => { + expect( + parseAggregationResults({ + isCountAgg: true, + isGroupAgg: true, + esResult: { + took: 7, + timed_out: false, + _shards: { total: 4, successful: 1, skipped: 0, failed: 0 }, + hits: { total: { value: 4, relation: 'eq' }, max_score: null, hits: [] }, + aggregations: { + groupAgg: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { + key: 'host-1', + doc_count: 4, + topHitsAgg: { + hits: { + total: { value: 4, relation: 'eq' }, + max_score: 0, + hits: [ + sampleSourceFieldsHit, + sampleSourceFieldsHit, + sampleSourceFieldsHit, + sampleSourceFieldsHit, + ], + }, + }, + 'host.name': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'host-1', doc_count: 4 }], + }, + 'host.hostname': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'host-1', doc_count: 4 }], + }, + 'host.id': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: '1', doc_count: 4 }], + }, + }, + ], + }, + groupAggCount: { count: 1, min: 4, max: 4, avg: 4, sum: 4 }, + }, + }, + resultLimit: 1000, + sourceFieldsParams: [ + { label: 'host.hostname', searchPath: 'host.hostname.keyword' }, + { label: 'host.id', searchPath: 'host.id.keyword' }, + { label: 'host.name', searchPath: 'host.name.keyword' }, + ], + }) + ).toEqual({ + results: [ + { + group: 'host-1', + hits: [ + sampleSourceFieldsHit, + sampleSourceFieldsHit, + sampleSourceFieldsHit, + sampleSourceFieldsHit, + ], + count: 4, + sourceFields: { + 'host.hostname': ['host-1'], + 'host.id': ['1'], + 'host.name': ['host-1'], + }, + }, + ], + truncated: false, + }); + }); + + it('correctly parses results for count with source fields and generateSourceFieldsFromHits = true', () => { + expect( + parseAggregationResults({ + isCountAgg: true, + isGroupAgg: false, + esResult: { + took: 0, + timed_out: false, + _shards: { total: 0, successful: 0, skipped: 0, failed: 0 }, + hits: { + total: 4, + hits: [ + sampleEsqlSourceFieldsHit, + sampleEsqlSourceFieldsHit, + sampleEsqlSourceFieldsHit, + sampleEsqlSourceFieldsHit, + ], + }, + }, + resultLimit: 1000, + sourceFieldsParams: [ + { label: 'host.hostname', searchPath: 'host.hostname.keyword' }, + { label: 'host.id', searchPath: 'host.id.keyword' }, + { label: 'host.name', searchPath: 'host.name.keyword' }, + ], + generateSourceFieldsFromHits: true, + }) + ).toEqual({ + results: [ + { + group: 'all documents', + count: 4, + hits: [ + sampleEsqlSourceFieldsHit, + sampleEsqlSourceFieldsHit, + sampleEsqlSourceFieldsHit, + sampleEsqlSourceFieldsHit, + ], + sourceFields: { + 'host.hostname': ['host-1'], + 'host.id': ['1'], + 'host.name': ['host-1'], + }, + }, + ], + truncated: false, + }); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/common/data/lib/parse_aggregation_results.ts b/x-pack/plugins/triggers_actions_ui/common/data/lib/parse_aggregation_results.ts index 5c1f5ecba90c52..6fe7040abacc34 100644 --- a/x-pack/plugins/triggers_actions_ui/common/data/lib/parse_aggregation_results.ts +++ b/x-pack/plugins/triggers_actions_ui/common/data/lib/parse_aggregation_results.ts @@ -17,6 +17,7 @@ export interface ParsedAggregationGroup { group: string; count: number; hits: Array<SearchHit<unknown>>; + sourceFields: string[]; value?: number; } @@ -30,12 +31,16 @@ interface ParseAggregationResultsOpts { isGroupAgg: boolean; esResult: SearchResponse<unknown>; resultLimit?: number; + sourceFieldsParams?: Array<{ label: string; searchPath: string }>; + generateSourceFieldsFromHits?: boolean; } export const parseAggregationResults = ({ isCountAgg, isGroupAgg, esResult, resultLimit, + sourceFieldsParams = [], + generateSourceFieldsFromHits = false, }: ParseAggregationResultsOpts): ParsedAggregationResults => { const aggregations = esResult?.aggregations || {}; @@ -51,6 +56,7 @@ export const parseAggregationResults = ({ hits: esResult.hits.hits ?? [], }, }, + ...aggregations, // sourceFields ...(!isCountAgg ? { metricAgg: { @@ -77,11 +83,32 @@ export const parseAggregationResults = ({ if (resultLimit && results.results.length === resultLimit) break; const groupName: string = `${groupBucket?.key}`; + const sourceFields: { [key: string]: string[] } = {}; + + sourceFieldsParams.forEach((field) => { + if (generateSourceFieldsFromHits) { + const fieldsSet = new Set<string>(); + groupBucket.topHitsAgg.hits.hits.forEach((hit: SearchHit<{ [key: string]: string }>) => { + if (hit._source && hit._source[field.label]) { + fieldsSet.add(hit._source[field.label]); + } + }); + sourceFields[field.label] = Array.from(fieldsSet); + } else { + if (groupBucket[field.label]?.buckets && groupBucket[field.label].buckets.length > 0) { + sourceFields[field.label] = groupBucket[field.label].buckets.map( + (bucket: { doc_count: number; key: string | number }) => bucket.key + ); + } + } + }); + const groupResult: any = { group: groupName, count: groupBucket?.doc_count, hits: groupBucket?.topHitsAgg?.hits?.hits ?? [], ...(!isCountAgg ? { value: groupBucket?.metricAgg?.value } : {}), + sourceFields, }; results.results.push(groupResult); } diff --git a/x-pack/test/alerting_api_integration/packages/helpers/es_test_index_tool.ts b/x-pack/test/alerting_api_integration/packages/helpers/es_test_index_tool.ts index 7607cecc3e2f29..1a84915a5c935e 100644 --- a/x-pack/test/alerting_api_integration/packages/helpers/es_test_index_tool.ts +++ b/x-pack/test/alerting_api_integration/packages/helpers/es_test_index_tool.ts @@ -61,6 +61,25 @@ export class ESTestIndexTool { group: { type: 'keyword', }, + host: { + properties: { + hostname: { + type: 'text', + fields: { + keyword: { + type: 'keyword', + ignore_above: 256, + }, + }, + }, + id: { + type: 'keyword', + }, + name: { + type: 'keyword', + }, + }, + }, }, }, }, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create_test_data.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create_test_data.ts index ee8811cf98f28a..d79fdd086cab9d 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create_test_data.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create_test_data.ts @@ -109,6 +109,11 @@ async function createEsDocument( testedValueFloat: 234.2534643, testedValueUnsigned: '18446744073709551615', '@timestamp': new Date(epochMillis).toISOString(), + host: { + hostname: 'host-1', + id: '1', + name: 'host-1', + }, ...(group ? { group } : {}), }; @@ -147,6 +152,25 @@ export async function createDataStream(es: Client, name: string) { enabled: false, type: 'object', }, + host: { + properties: { + hostname: { + type: 'text', + fields: { + keyword: { + type: 'keyword', + ignore_above: 256, + }, + }, + }, + id: { + type: 'keyword', + }, + name: { + type: 'keyword', + }, + }, + }, }, }, }, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/common.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/common.ts index fc7a65978aaa0f..26d8c64a302969 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/common.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/common.ts @@ -24,6 +24,11 @@ export const RULE_INTERVAL_SECONDS = 4; export const RULE_INTERVAL_MILLIS = RULE_INTERVAL_SECONDS * 1000; export const ES_GROUPS_TO_WRITE = 3; +export interface SourceField { + label: string; + searchPath: string; +} + export async function createConnector( supertest: any, objectRemover: ObjectRemover, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/esql_only.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/esql_only.ts index b5b2d41e9a4044..f193af1b81703c 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/esql_only.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/esql_only.ts @@ -22,6 +22,7 @@ import { RULE_INTERVAL_MILLIS, RULE_INTERVAL_SECONDS, RULE_TYPE_ID, + SourceField, } from './common'; import { createDataStream, deleteDataStream } from '../../../create_test_data'; @@ -38,6 +39,12 @@ export default function ruleTests({ getService }: FtrProviderContext) { getAllAADDocs, } = getRuleServices(getService); + const sourceFields = [ + { label: 'host.hostname', searchPath: 'host.hostname.keyword' }, + { label: 'host.id', searchPath: 'host.id' }, + { label: 'host.name', searchPath: 'host.name' }, + ]; + describe('rule', async () => { let endDate: string; let connectorId: string; @@ -72,11 +79,15 @@ export default function ruleTests({ getService }: FtrProviderContext) { await createEsDocumentsInGroups(ES_GROUPS_TO_WRITE, endDate); await createRule({ name: 'never fire', - esqlQuery: 'from .kibana-alerting-test-data | stats c = count(date) | where c < 0', + esqlQuery: + 'from .kibana-alerting-test-data | stats c = count(date) by host.hostname, host.name, host.id | where c < 0', + sourceFields, }); await createRule({ name: 'always fire', - esqlQuery: 'from .kibana-alerting-test-data | stats c = count(date) | where c > -1', + esqlQuery: + 'from .kibana-alerting-test-data | stats c = count(date) by host.hostname, host.name, host.id | where c > -1', + sourceFields, }); const docs = await waitForDocs(2); @@ -103,6 +114,9 @@ export default function ruleTests({ getService }: FtrProviderContext) { const value = parseInt(alertDoc['kibana.alert.evaluation.value'], 10); expect(value).greaterThan(0); expect(alertDoc[ALERT_URL]).to.contain('/s/space1/app/'); + expect(alertDoc['host.name']).to.eql(['host-1']); + expect(alertDoc['host.hostname']).to.eql(['host-1']); + expect(alertDoc['host.id']).to.eql(['1']); }); it('runs correctly: use epoch millis - threshold on hit count < >', async () => { @@ -209,13 +223,19 @@ export default function ruleTests({ getService }: FtrProviderContext) { ); await createRule({ name: 'never fire', - esqlQuery: 'from test-data-stream | stats c = count(@timestamp) | where c < 0', + esqlQuery: + 'from test-data-stream | stats c = count(@timestamp) by host.hostname, host.name, host.id | where c < 0', + sourceFields, }); await createRule({ name: 'always fire', - esqlQuery: 'from test-data-stream | stats c = count(@timestamp) | where c > -1', + esqlQuery: + 'from test-data-stream | stats c = count(@timestamp) by host.hostname, host.name, host.id | where c > -1', + sourceFields, }); + const messagePattern = /Document count is \d+ in the last 20s. Alert when greater than 0./; + const docs = await waitForDocs(2); for (let i = 0; i < docs.length; i++) { const doc = docs[i]; @@ -224,10 +244,22 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(name).to.be('always fire'); expect(title).to.be(`rule 'always fire' matched query`); - const messagePattern = /Document count is \d+ in the last 20s. Alert when greater than 0./; expect(message).to.match(messagePattern); expect(hits).not.to.be.empty(); } + + const aadDocs = await getAllAADDocs(1); + + const alertDoc = aadDocs.body.hits.hits[0]._source; + expect(alertDoc[ALERT_REASON]).to.match(messagePattern); + expect(alertDoc['kibana.alert.title']).to.be("rule 'always fire' matched query"); + expect(alertDoc['kibana.alert.evaluation.conditions']).to.be('Query matched documents'); + const value = parseInt(alertDoc['kibana.alert.evaluation.value'], 10); + expect(value).greaterThan(0); + expect(alertDoc[ALERT_URL]).to.contain('/s/space1/app/'); + expect(alertDoc['host.name']).to.eql(['host-1']); + expect(alertDoc['host.hostname']).to.eql(['host-1']); + expect(alertDoc['host.id']).to.eql(['1']); }); it('throws an error if the thresholdComparator is not >', async () => { @@ -365,6 +397,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { groupBy?: string; termField?: string; termSize?: number; + sourceFields?: SourceField[]; } async function createRule(params: CreateRuleParams): Promise<string> { @@ -436,6 +469,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { termSize: params.termSize, timeField: params.timeField || 'date', esqlQuery: { esql: params.esqlQuery }, + sourceFields: params.sourceFields, }, }) .expect(200); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/query_dsl_only.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/query_dsl_only.ts index 8a558c8e27299b..c339bb7f24604d 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/query_dsl_only.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/query_dsl_only.ts @@ -6,9 +6,8 @@ */ import expect from '@kbn/expect'; - import { ES_TEST_INDEX_NAME } from '@kbn/alerting-api-integration-helpers'; - +import { pull } from 'lodash'; import { Spaces } from '../../../../../scenarios'; import { FtrProviderContext } from '../../../../../../common/ftr_provider_context'; import { getUrlPrefix, ObjectRemover } from '../../../../../../common/lib'; @@ -144,7 +143,16 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(hits).not.to.be.empty(); hits.forEach((hit: any) => { expect(hit.fields).not.to.be.empty(); - expect(Object.keys(hit.fields).sort()).to.eql(Object.keys(hit._source).sort()); + expect( + pull( + // remove nested fields + Object.keys(hit.fields), + 'host.hostname', + 'host.hostname.keyword', + 'host.id', + 'host.name' + ).sort() + ).to.eql(Object.keys(hit._source).sort()); }); } }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/rule.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/rule.ts index 948eccc893e18e..58d439a0aab4e3 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/rule.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/rule.ts @@ -25,6 +25,7 @@ import { RULE_INTERVAL_MILLIS, RULE_INTERVAL_SECONDS, RULE_TYPE_ID, + SourceField, } from './common'; import { createDataStream, deleteDataStream } from '../../../create_test_data'; @@ -43,6 +44,12 @@ export default function ruleTests({ getService }: FtrProviderContext) { getAllAADDocs, } = getRuleServices(getService); + const sourceFields = [ + { label: 'host.hostname', searchPath: 'host.hostname.keyword' }, + { label: 'host.id', searchPath: 'host.id' }, + { label: 'host.name', searchPath: 'host.name' }, + ]; + describe('rule', async () => { let endDate: string; let connectorId: string; @@ -82,6 +89,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { size: 100, thresholdComparator: '<', threshold: [0], + sourceFields, }); await createRule({ name: 'always fire', @@ -89,6 +97,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { size: 100, thresholdComparator: '>', threshold: [-1], + sourceFields, }); }, ] as const, @@ -114,6 +123,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { index: esTestDataView.id, filter: [], }, + sourceFields, }); await createRule({ name: 'always fire', @@ -129,6 +139,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { index: esTestDataView.id, filter: [], }, + sourceFields, }); }, ] as const, @@ -173,6 +184,9 @@ export default function ruleTests({ getService }: FtrProviderContext) { const value = parseInt(alertDoc['kibana.alert.evaluation.value'], 10); expect(value).greaterThan(0); expect(alertDoc[ALERT_URL]).to.contain('/s/space1/app/'); + expect(alertDoc['host.name']).to.eql(['host-1']); + expect(alertDoc['host.hostname']).to.eql(['host-1']); + expect(alertDoc['host.id']).to.eql(['1']); }) ); @@ -188,6 +202,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { threshold: [0], aggType: 'avg', aggField: 'testedValue', + sourceFields, }); await createRule({ name: 'always fire', @@ -197,6 +212,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { threshold: [-1], aggType: 'avg', aggField: 'testedValue', + sourceFields, }); }, ] as const, @@ -224,6 +240,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { }, aggType: 'avg', aggField: 'testedValue', + sourceFields, }); await createRule({ name: 'always fire', @@ -241,6 +258,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { }, aggType: 'avg', aggField: 'testedValue', + sourceFields, }); }, ] as const, @@ -250,6 +268,9 @@ export default function ruleTests({ getService }: FtrProviderContext) { await createEsDocumentsInGroups(ES_GROUPS_TO_WRITE, endDate); await initData(); + const messagePattern = + /Document count is \d+.?\d* in the last 20s in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; + const docs = await waitForDocs(2); for (let i = 0; i < docs.length; i++) { const doc = docs[i]; @@ -258,8 +279,6 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(name).to.be('always fire'); expect(title).to.be(`rule 'always fire' matched query`); - const messagePattern = - /Document count is \d+.?\d* in the last 20s in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; expect(message).to.match(messagePattern); expect(hits).not.to.be.empty(); @@ -271,6 +290,21 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(previousTimestamp).not.to.be.empty(); } } + + const aadDocs = await getAllAADDocs(1); + + const alertDoc = aadDocs.body.hits.hits[0]._source; + expect(alertDoc[ALERT_REASON]).to.match(messagePattern); + expect(alertDoc['kibana.alert.title']).to.be("rule 'always fire' matched query"); + expect(alertDoc['kibana.alert.evaluation.conditions']).to.be( + 'Number of matching documents where avg of testedValue is greater than -1' + ); + const value = parseInt(alertDoc['kibana.alert.evaluation.value'], 10); + expect(value).greaterThan(0); + expect(alertDoc[ALERT_URL]).to.contain('/s/space1/app/'); + expect(alertDoc['host.name']).to.eql(['host-1']); + expect(alertDoc['host.hostname']).to.eql(['host-1']); + expect(alertDoc['host.id']).to.eql(['1']); }) ); @@ -287,6 +321,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { groupBy: 'top', termField: 'group', termSize: 2, + sourceFields, }); await createRule({ name: 'always fire', @@ -297,6 +332,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { groupBy: 'top', termField: 'group', termSize: 2, + sourceFields, }); }, ] as const, @@ -325,6 +361,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { groupBy: 'top', termField: 'group', termSize: 2, + sourceFields, }); await createRule({ name: 'always fire', @@ -343,6 +380,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { groupBy: 'top', termField: 'group', termSize: 2, + sourceFields, }); }, ] as const, @@ -352,6 +390,12 @@ export default function ruleTests({ getService }: FtrProviderContext) { await createGroupedEsDocumentsInGroups(ES_GROUPS_TO_WRITE, endDate); await initData(); + const messagePattern = + /Document count is \d+.?\d* in the last 20s for group-\d+ in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; + const titlePattern = /rule 'always fire' matched query for group group-\d/; + const conditionPattern = + /Number of matching documents for group "group-\d" is greater than -1/; + const docs = await waitForDocs(2); for (let i = 0; i < docs.length; i++) { const doc = docs[i]; @@ -359,15 +403,25 @@ export default function ruleTests({ getService }: FtrProviderContext) { const { name, title, message } = doc._source.params; expect(name).to.be('always fire'); - const titlePattern = /rule 'always fire' matched query for group group-\d/; expect(title).to.match(titlePattern); - const messagePattern = - /Document count is \d+.?\d* in the last 20s for group-\d+ in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; expect(message).to.match(messagePattern); expect(hits).not.to.be.empty(); expect(previousTimestamp).to.be.empty(); } + + const aadDocs = await getAllAADDocs(1); + + const alertDoc = aadDocs.body.hits.hits[0]._source; + expect(alertDoc[ALERT_REASON]).to.match(messagePattern); + expect(alertDoc['kibana.alert.title']).to.match(titlePattern); + expect(alertDoc['kibana.alert.evaluation.conditions']).to.match(conditionPattern); + const value = parseInt(alertDoc['kibana.alert.evaluation.value'], 10); + expect(value).greaterThan(0); + expect(alertDoc[ALERT_URL]).to.contain('/s/space1/app/'); + expect(alertDoc['host.name']).to.eql(['host-1']); + expect(alertDoc['host.hostname']).to.eql(['host-1']); + expect(alertDoc['host.id']).to.eql(['1']); }) ); @@ -384,6 +438,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { groupBy: 'top', termField: ['group', 'testedValue'], termSize: 2, + sourceFields, }); }, ] as const, @@ -412,6 +467,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { groupBy: 'top', termField: ['group', 'testedValue'], termSize: 2, + sourceFields, }); }, ] as const, @@ -421,6 +477,12 @@ export default function ruleTests({ getService }: FtrProviderContext) { await createGroupedEsDocumentsInGroups(ES_GROUPS_TO_WRITE, endDate); await initData(); + const messagePattern = + /Document count is \d+.?\d* in the last 20s for group-\d+,\d+ in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; + const titlePattern = /rule 'always fire' matched query for group group-\d+,\d+/; + const conditionPattern = + /Number of matching documents for group "group-\d+,\d+" is greater than -1/; + const docs = await waitForDocs(2); for (let i = 0; i < docs.length; i++) { const doc = docs[i]; @@ -428,15 +490,25 @@ export default function ruleTests({ getService }: FtrProviderContext) { const { name, title, message } = doc._source.params; expect(name).to.be('always fire'); - const titlePattern = /rule 'always fire' matched query for group group-\d/; expect(title).to.match(titlePattern); - const messagePattern = - /Document count is \d+.?\d* in the last 20s for group-\d+,\d+ in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; expect(message).to.match(messagePattern); expect(hits).not.to.be.empty(); expect(previousTimestamp).to.be.empty(); } + + const aadDocs = await getAllAADDocs(1); + + const alertDoc = aadDocs.body.hits.hits[0]._source; + expect(alertDoc[ALERT_REASON]).to.match(messagePattern); + expect(alertDoc['kibana.alert.title']).to.match(titlePattern); + expect(alertDoc['kibana.alert.evaluation.conditions']).to.match(conditionPattern); + const value = parseInt(alertDoc['kibana.alert.evaluation.value'], 10); + expect(value).greaterThan(0); + expect(alertDoc[ALERT_URL]).to.contain('/s/space1/app/'); + expect(alertDoc['host.name']).to.eql(['host-1']); + expect(alertDoc['host.hostname']).to.eql(['host-1']); + expect(alertDoc['host.id']).to.eql(['1']); }) ); @@ -904,6 +976,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { threshold: [0], indexName: ES_TEST_DATA_STREAM_NAME, timeField: '@timestamp', + sourceFields, }); await createRule({ name: 'always fire', @@ -913,6 +986,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { threshold: [-1], indexName: ES_TEST_DATA_STREAM_NAME, timeField: '@timestamp', + sourceFields, }); }, ] as const, @@ -938,6 +1012,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { index: esTestDataView.id, filter: [], }, + sourceFields, }); await createRule({ name: 'always fire', @@ -953,6 +1028,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { index: esTestDataView.id, filter: [], }, + sourceFields, }); }, ] as const, @@ -967,6 +1043,9 @@ export default function ruleTests({ getService }: FtrProviderContext) { ); await initData(); + const messagePattern = + /Document count is \d+.?\d* in the last 20s in test-data-stream (?:index|data view). Alert when greater than -1./; + const docs = await waitForDocs(2); for (let i = 0; i < docs.length; i++) { const doc = docs[i]; @@ -975,8 +1054,6 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(name).to.be('always fire'); expect(title).to.be(`rule 'always fire' matched query`); - const messagePattern = - /Document count is \d+.?\d* in the last 20s in test-data-stream (?:index|data view). Alert when greater than -1./; expect(message).to.match(messagePattern); expect(hits).not.to.be.empty(); @@ -988,6 +1065,21 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(previousTimestamp).not.to.be.empty(); } } + + const aadDocs = await getAllAADDocs(1); + + const alertDoc = aadDocs.body.hits.hits[0]._source; + expect(alertDoc[ALERT_REASON]).to.match(messagePattern); + expect(alertDoc['kibana.alert.title']).to.be("rule 'always fire' matched query"); + expect(alertDoc['kibana.alert.evaluation.conditions']).to.be( + 'Number of matching documents is greater than -1' + ); + const value = parseInt(alertDoc['kibana.alert.evaluation.value'], 10); + expect(value).greaterThan(0); + expect(alertDoc[ALERT_URL]).to.contain('/s/space1/app/'); + expect(alertDoc['host.name']).to.eql(['host-1']); + expect(alertDoc['host.hostname']).to.eql(['host-1']); + expect(alertDoc['host.id']).to.eql(['1']); }) ); @@ -1121,6 +1213,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { groupBy?: string; termField?: string | string[]; termSize?: number; + sourceFields?: SourceField[]; } async function createRule(params: CreateRuleParams): Promise<string> { @@ -1201,6 +1294,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { aggField: params.aggField, termField: params.termField, termSize: params.termSize, + sourceFields: params.sourceFields, ...(params.excludeHitsFromPreviousRun !== undefined && { excludeHitsFromPreviousRun: params.excludeHitsFromPreviousRun, }), From d76e059173f8e20047b238a47dc61c93335dbb88 Mon Sep 17 00:00:00 2001 From: Larry Gregory <larry.gregory@elastic.co> Date: Thu, 21 Dec 2023 14:33:53 -0500 Subject: [PATCH 093/116] Clarify spaces documentation (#173866) Clarifies language for securing access to spaces. --- .../security/tutorials/how-to-secure-access-to-kibana.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/security/tutorials/how-to-secure-access-to-kibana.asciidoc b/docs/user/security/tutorials/how-to-secure-access-to-kibana.asciidoc index 9e457ee409f4b0..d62ccebb05657f 100644 --- a/docs/user/security/tutorials/how-to-secure-access-to-kibana.asciidoc +++ b/docs/user/security/tutorials/how-to-secure-access-to-kibana.asciidoc @@ -11,7 +11,7 @@ This guide introduces you to three of {kib}'s security features: spaces, roles, [float] === Spaces -Do you have multiple teams or tenants using {kib}? Do you want a “playground” to experiment with new visualizations or rules? If so, then <<xpack-spaces,{kib} Spaces>> can help. +Do you have multiple teams using {kib}? Do you want a “playground” to experiment with new visualizations or rules? If so, then <<xpack-spaces,{kib} Spaces>> can help. Think of a space as another instance of {kib}. A space allows you to organize your <<dashboard, dashboards>>, <<alerting-getting-started, rules>>, <<xpack-ml, machine learning jobs>>, and much more into their own categories. For example, you might have a Marketing space for your marketeers to track the results of their campaigns, and an Engineering space for your developers to {apm-guide-ref}/apm-overview.html[monitor application performance]. From 1bf9cdd771e95f51f37428e6b9b6348e421f03fc Mon Sep 17 00:00:00 2001 From: Lola <omolola.akinleye@elastic.co> Date: Thu, 21 Dec 2023 14:51:38 -0500 Subject: [PATCH 094/116] [Cloud Security] Update cloud security dashboard picture (#172997) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Summarize your PR. If it involves visual changes include a screenshot or gif. Update the Cloud Security Dashboard Image. Dashboard View <img width="1177" alt="Screenshot 2023-12-08 at 4 04 53 PM" src="https://github.com/elastic/kibana/assets/17135495/8fa3d33e-40ad-49c9-9a17-ca491ecebe9b"> --- .../cloud_security_posture_dashboard_page.png | Bin 116242 -> 105870 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/images/cloud_security_posture_dashboard_page.png b/x-pack/plugins/security_solution/public/common/images/cloud_security_posture_dashboard_page.png index fe27c2ca95120685779ddbe7931f6ce24222328b..cc2b52693edffd11ce957159fcb2d01137ba0bcf 100644 GIT binary patch literal 105870 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ⅇu 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 BfFA$= literal 116242 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�a0<kxHaoRYhi7r8rK z9S^I$#l(h}7T2?y>vMmGKEF!F8-1_;L)2G>Mb(9COM@b*gmg=H53PihgmiZe$j~hz z-Q6K2-940aBi%i8&d~Xd?>XoCe$B7B_S$>xz1Di}dUVBLKppwD;U$PCv@)`7oNL8Z ztwdzS@}yCo`D}Oz&{ludd|v@x)npnu85?Ya91Eq)bzB`XCb>0@EJ9A3Jku=AE7~*D z)Tf_i;IsHF7QBS`@5xId@4HlT*1fgQQ~g%>4{d<Ilesv*L&cqR7D)|&(3mPAO_4t> zlM6DHQviF|X4#7GY2Dqm%9w@SWtRr+gb)-(&!-ZL#_;3LkgoPTRwZ{*0{`8eWaX)< zhpoJzhi-A1pNPjH2L_4)v7MGj+t}0R>m9d+Cyi{-Pw-<aV~9eAGBLAZ;s6<61=YkV ziz$$?To|g+lwV5e0Bhc9V=q!1Q6n<vW9{_!J#}3+MyS1q^=aEmjN5Gt9P7&XsSppo zKN!{=22?K5jil}j>guLCxM*dF7(2)qua{<_Fgnn&YcUxvj7K;v|JIS|u=^G}LAd#D zE)wH%b~cr<47OO7%fk7UAAZ*PA0kX&B9|JmJ*Z8OzKs%=M(U2yNxkZuG2a@;)v0$? z2(=yh3t}F*0=1@|6@j1`f6orr>^<h!rd(`0ZIw$RR~u_r)|BqX_8a-gf(!e6>YD9} z!L#l9dq2DYgoG({8&$m7>oy&0w6A!K7=(!DV_oLnlHXyl9bYh}Sbigdok;r*-P$B9 z_$42EC63j)?7SB#^<6HKA*0L9RE(Kw3{)+8haJH_aq`Fdl&8_Tv##v>gy)Ru(czQ} zeEjYJWG3p#2A5g9inp>nTkB>Ojb0z$v!^(;Ay4}x61a~7b#wIX3&w{RA=1zl!?0uH z1O`5ZWk)-au?Lu2+eF$Il|>~lJ|`^qpkLxEc5z=aY80W#j~Wm;o-$+d37g&b$F5LD zwZsXZ+cMW8ZVrq8%K~uzx~qbB_0A4N&hwhjSnQ}0Sz43fN?pjjp7pHpPG!mU>#!D} zxn7GPTKPGXb6}Ec+STts&;-WH7hdyOG9|q0l=3UCzlG-U)pU~cknNC0`b+bx#rtCr z4gAYt<B#8a{$lpcmphc)JMBc&lIipJwv!Tdzrt&W959`@{o6thdD?#2(I(c0-Vl#M zXl3PCCE@I*%i!nFK(eAWut)}#ZlwW}na8fS&*!A_nr=RaqDtOyie@`PZ26+F7~#OQ zzWHp1!UxumqfL8>f*JyR;SHZ<;KLfHfe(w#GP`{r$Y5k{XW4x+<)a~;0{=*I(T~xP zxmxImvlT{e^`w7we-NA|OJE90k5n=@GXgOB!uwF##(ZJfaVcr}NhfDPFeFJAH2IEV zZH+T(Y;<H$K_@-m_rM-24XnCl!!`1_AeuxQ&bb|i`RAZE0uN*6OV?f$;|OPY)k<2T z)dG9g<b;pHWkS^?d&0L%(=gBnp#e+oc>gEG>KegA=E0<;Az%unDn|rJZ78!Bkr!`t z`BU48NbaR?w-2d9Ms`{{7dFyNi{UgBF?ymm$ZXrOq^v6Ct8Rw%@XXG;e&U=I&z;ZI z#%by4e2y=h--$*(q-A6!z#CQ4z)iAYk}yI-Lb|N%6g@Tu<3!l(?ECA3@PAJLfXKUk zH}3X)KrO`KOQfZ%78OxD=hfFdG(HM=pAy$Vb|kGlcr1RRb~Vm#X!~yqc?#+>c^1YL z+b%3CV}^EJJiNV@X`p1}-9O^{5=^=K(3lri0KWbk`*?*W#l@Kr-(3?#C48nw5_jVe zJyL<@1l4}2=LzzeQl*GB9(-AhIU5RTqA#pK_{2jH8{-f)VhHvzd_GMuZUMP{;erVs zSiSatoU<<_v(HIK$$NPxWRE#6>(i`c^4rbC)u7|%nes3*nV&62mMJMo8gqc~%`7n# zvqL^xCmu|`@MyxY4B*U2b{Aq$Nqn=1A@C;Y`f9CFX18VB)aj<X{IO1~H2_=kvkplB zUa#YpXoki?7goHje09Z&MaqrLHV9~>qk79$jDY=?-q*M8XOoIO@y$$H2EW;@j9B79 zjA-mn^)EJ(RG2YDN%ESaeKk4!&3diQ+8qz8V#)pes0YW#i7hS7-j{y|pxtN`L!+aZ z9sKDjjdL3HWjg<u^Yw>kTgv%_slRJX-A0ouWp}Z=Cg7+s)mh=7S5-YIfJiPB?+m}M zTP_NsDPyeR>xP#1viYC<8c`4?L@v-v59BsJxBVzSUR-RxJ36-EC+iv=%?y&1u(k?K zkKWpx486Q|&d>~4TnR|a{qad82#apxCWGWJO=|Av|MtlRK4cB6oIyLTh>WQKz${6! zr4rA`x;GE?cFE_oh+>GHvcjSG;LG!2YNT>8#7r3pFlOy>bIoIKLCu~8OltY0Ven$5 z^<m@hQy*cg`8yEJG>j`Hpow6|jhr9sCFR(1^IgNc;Tz~z6GC0m><~i}{l=Zr(BJD& zJ%KseO{1(8UjZ7i4ggb=OaiDB|2or-k0?_7biL#0tM8^sapr!gtg`LGiozMz*ie`3 zihD@TzAX>`tS;r+c6Cjg;Kv4{ryT(FV5~!!=M7?394gN9%wvEzD&Ea?q4B|w$_V9p zxmVejBX0C&cxF$danc7r=S4nT+SACzo<8Jb+(nRZPc4zg7W=EwfEU~*i<(5qP;h@I z?<q9}q(1DhLG8sd6Zin)VCOukt)a-r+t+5fFDrjh!#0I84&3|Q&&q7eB=!kuQ^w>- z1+b!vV-0D<uI!rh0-B!Cy0&PSGCHcwWFLFN66<+UA%M$sDkFYX8+Y0Gz`!jBn|RrE zPCysS$Yr5&@A_Xx{Dg!l3<qa)<Wxoskce20zom!7)<w|h_?R4-tXjP&>Xf%;Hu!t@ zpnkij;+p3X0~|o8GFcW89<zT^fq#@_(i?H;JUJjh=T9O;5r0k9CVM!g*RRGuc)7n& zKsCTRwx2jH*W%T*?!0uMAl=_zthl&#iY4e;FH?%>Pi9}MQT!iI(U0D2AmS;DL}XG$ zur0-{M;#RV)-`)HpCR+f7<p|D9er7WnkE7L$_hdII`DCfx?uD4yJV5XpUx+!ir}gm zJ7$vmkI9&?YdyAu%;*>E2IMIM05}t+G<-nw7J9bU%I+@sQCXpo4k=zy(i3PTEqa{u zbDluz#lLxZ5)JQ^For)Z_^Lj52VIt5?nGIXB%$-gZYoH9B_!Lzz3_loxd-XF!BTkV z@ChT|5@c_1iaBsFnTX<^uuXXrSbedrs|JGCs8=<DIPK++Cj&GfkB^Lof*J7+K9wZB z9e*bUll=sE**nkG>o5%E0)B`EF+2}wO7BdyTU&?72;o6V7R$~*U@H|s{`{$R_IEaH z<)!BjR_!0+LfKk*jhOk$`V_^nN}A+M!h&9ueY)%F{`;5K^hZ1?;UYXiC&2DzT;~M` zThkBNY+jJ}iDX&kez=_Tb`O{p?^0Z|M^HVYI<nPDflIB+%T6IaEXWb?^ADA^H88I3 zmS2>U(RT%n_*ZubakesJ>><zduX8QU?Wm#lX9S$1=1dVU>DG<krPJq8KtcObb==>` z{xZ~)_9&5y;nd`1<ZHX#57>n*EeO5MB!ph7!NCKxp@Qo<-q3Q|1Z#jXdzunu;5^Wq z_1oSybJJ{<s$wSTnXK#@v)EZ6f$MQ|Od8;{i1bXakn1?_gju5F^@Uj`2$Pbh73LA^ z=;E|q3R0J%qJ2oOHY(ON)L#9F)>ENa2>I>OVkfAU71r?SeUb0{cmVmaDWHhC=WU?; zB8VBtxREwsq<>tF>0J4zYp4vlE$Mz_QJt-7v_=Q5O;s4^!_hR#dF|Xrq!k%4{QeMW zw`*~@T+_bYRIeZdZ9!On^n!Umxc!uqz8|n<XBemO+)TLl&B!v%RL>Le))fU43>)QM z_G0dXo#)a~gq{yNOLsgBH3Js;*ov2=pwJcq57;y=&aiRs#p|uyvat)Iv`_0HVq$<H z%!oE5D1VkttVWRQ%$7UnOdi&KtFCw@wC1loQ9pZtX62se5riJxl|w}vlt*dV`U`rs z*Q%)1M;Bxl%Q7wXVEClR4PHQ}^XKQopdOuhJM}nXc$gsOeUgk}>rP;nj{j!`p~Q?x zM%hWrUh*t%j;_}>1X7ZJ1^v_Fnig&e@k)`V3vY&4xchoMl6OVG`z=L#c0MK;`l)^( zk%V?%aeAC2;FgqBBt=k;nVzf1DD*-w0q3NhUd~J?ZI*?_jFd?DFfQa;(Ui=jkm`%h z$7}ql#SaPCxTjErXHOkTsC*S^3cY*lddM1u0a?n+g=S6wgODvcKLwtUE{*D2$(Ep| z%!p=7mM$sZ0#+9G>_7%mZ07khMLCi!u;1<?o76A4`-5*{vv{%5{o;9@bbR1vS11_M z#YLVC19RO^8IQkGUXg>+KcU#%&JGco7~4pK{aFMrjA&|9;QKWan1WvAbXvJ;6L^{l zzTJ8gtYFvz>bpc6h^FXq{ZKP$9eWgNjjtr)Drq66$@{Mo9j83kLQdzm7R6|4<jZ(- zZ~ua{vV+SXQf%u>8#iLEFz^BE=LJtz@;2q1iZc<v!&-dJCK}f?3f^04{XnHDc}k9b z<ht)IJGJtIRni0dX@m2+g6_<R8&8|+ZSwB?!<waF$2!<<g0QLI?%v%y!=D*xgd<s> zS7;c1Y|_4EIf^oGw>rdtM{1MAXOR{WWTnJhQL#sir$gM;E}eVWz>;PRq+L=7LyX%v zghtE`s+e-d=`ucGVlL@AEZ3clZyU{vF7A`(n+<v{vs~Xd&3Mkg=F(hk7xnRt_RxH; zLOH6E@*-FeT@VlG1+ZyTEcawoQnVg7udtlS=vs-5sE7>_IKpX{YjZBEi1i3ZOUp6$ zueq$g3yPVFJ|8Us!0N0fk_fWpekx3lZA<ct3nY1Eeon0}MFbDuoWE%jx>h77w5O!o zDOa2*8+7?BVtl{YmIlSx8+k1UDVL9W6g~Z2|3rLKYtJ0WZT)WlwF#S#W&2cO6`-+F zRADDiA4BF)Z-+lYu?zE$xy5tt4`bcPe7!-$!IsQvsXa}AUCabn_TZ8iK(q51IVTUO zeg%7luFM-P5<|ynsmJQr%~t<*Z({0~wHR=#K{AFyVW{b+gM*gXxaNim+OZY>i9wJk z#dw>f?m6d&7_kXPwu7)8sgE^<Z+U|E=+z+;Z6>4E_*I-<`W_3LM0Fhs1lV}zW>CP7 zr`|Xqy&(3+EZ|q9Bdh1ah0sRLmWPz^BE5<Iumr{gw}G48j#B*lY|Z5?xZ;!N9wO!e zNA;bh&0ejUkYYMv`W_X>P}$`hJm0TAK%b*9oK9l`1{MDZ3+0TY!>V{SECC~z1$=#v zAQGx~IoA_|Wt0P$6GRzu!wgLWW&{T78s4GJU<JK0@m48SY}Juxf7)zpZa~gr%*H3q zfgkfs_);Rl{rJ%JrzJJ$9K?8mi!mR)VdFHqKh`<WoBZ={q=_69J#2tISScp3;3b2f zVlYLS|3}yMw(PzoCXbXHB6^azWx)NuOBFZyP0LDc<{`QqQe{Tv-0zm`g!A;6AI^pW zgtv?v+;|g1tU*@ih*y;uLSMcsZIiyPjgiv*+O8ceewy#044826oVs%lO;EuL^Ek`w z<&^+5S5e`0^<cE0g)a6B@<-X`k(~(7E+d<Kh!yiGGwg`@o<<Kw2>tv$Mnc4HPe~~U zoH+J{RTk8f#(nEv{oZx!zW2J9RMOd7^wA@aPJW-p{UjI{Dq98Xp$fX=;Tsmamw8ER zse10Fc#Qk>M_~Q_Y@};LDici`jDari;DDX^&08FLUkgEUA4^Nn@q6bl68S1^%CwlJ z<Fyhk{?zm;8%_Q;=<d)(>X+_D)Hr41kylkGqjI(|2BJSU!(<xkmPzN!clFlR0a}8H zFTeSY7k_vm%F%iXOD(L#*p9yKa5a~ubFHV<p=F+{lgE39Ikmj|q{29)%KH4V$M5(P zlJA7=fTp<uEvmPo6)oj}+2A6V1L;apF}4RKvxS2}@TVZN)qQDljGuI0X?Kt7<<2oZ z=p`gp!JIR%Ts$?jq8p%M4(j_`Fjr`QfQ!0~jf^0hwxME$C6eOC+t{GQE7jyMkKW)R z+q&YBojM#?O^#XQ!e6Cl8rLGxP#m$MZws5jec1TT^K%j=+WH9tD0egFvhU_gNdCAh zaUicJ*0ris5<pm7t%6E&mc4O|sB6km!}7DPQ{%Pf=O%Tx7soDg!7wApO7(&Y+7;(4 z;)_kDSkb$Yt%;ENa~BsZ*Xp4hhc^)_b4Fc!wV2NrVw^^`9>JKeNNj0t(m)*Ja}#tF z3m;8k#~yoG9v_2zb{{t#U8603?C~6p<e>GM6Z2j8$6|j$4&_X!A3mgCH1dI?$XzAq z!gW1~b@MnQ8k^ucDvY(ofyRv$6s7t<(|xcXdk^7?JoA8Ri2(@((xd>NKhq~s(3uO1 zAd!_sx2otrY8i<)I9S~{0UYFCJKa0TvgbVxkQkq%sxmqDc((m0DD^fY2$vvLYb5b6 z2g(kzUIj|Nr!9Qj#MkGge4K+%=W|>N1+2S0NO3nmdeCwNahB%pb9tn_L1YGNXODN) z-7jLk9Y~IU*Bo~PCpvwfvLEYSzRRn+cikniJ5zNuulCY)`uLDi;Sjg{sE$S7`d!RD z691#le{Uv^pjRR=){V0F7p|FzKU(`oQ3X3BMlxw#-vd7{T?3C_5*-&NF<_`!+aul5 zIUnH6@RNcwI<~Lif*|^qXgE%Ej$e_!FYKr|677*@Lo#3<r!47Z_eNCWHdxvBx&;eA z`GW2EuCrsFy(-f#7M@Y$1HyG&dEpinB~@Y@uIgBzGi+O6qgc<5^?ROg8bex>A2`Bo z#O1+WdNlf)eBKrDT-!huxo|;zN3~V#5LGnV!_y<ZB$2H+7&V`Ce9Ne<zn5^?+l<+H zfiy(roqq>2jNK?PNJGW7x3TYk;#92;OHqI)m68jj3oR}0)Y;|?-E`de92^}b;WI=J zwY=He+3MRfGs-n&({DA&L|~mX9^`H~Z)LTbe*X_ZWJE6A(AFOBB8mHA`St<>?Ws0Y zm?mu2b0{_){7NMD@z&oE1;)IEoLzu~AeLP!b#7p8j@NTpPqkKtrM#vvWHyC4F#RKj zRv=QD)&5w4HsF$a`b|FxugLc#`uWN)Blfh)s|rUn+e7Cm2F#ueX#mx|B)yUT253~k zYhS)HOB%sb%cbA#8A-7Eq!;tY9KqA(yo6EM?Q(rwmWF*kMB~s{pP9g39k%rF?*ut9 zyJ3tH!(U1A5Zj<a+~j?5FKynEW1W9(UjS!k-8*T+>TbWY2WuIL;xz9KNvCT^2gNx! z$X+wcMao+MYA7JL{>$f|{#<H$2gZF`AKKjhbsot@>+fJB8$g1SKXPBRJJlb!f{X|l zo<w*5N&K+#69=oGN39=|A|y7F@p#)6=?}jEBI>$XHC&WW?g!Wy-3)Bw^bQ&{orr<l z4m|&K=p+(_;?Ss_Beb-!+JGAvakf-;VD~n*VMG&L4|K`KPu>aq0?EAtk-jj;HN?u# zbris?f#n!q@A`#TElT^_f?bUaI5vOh-tqZ4Q%@o(R`HtF>Pmp8tIbh^(y>nq+-_tx zJbsD>o1Y_ikoMduQhh2Q$Hp7LDI4{)r*Zyism*To;XIck!Zq4xUp!lr6X%|CZTP%< z65vkFj-qhO!4ZM|Cc&L(W0~I537-*@7rl1PzcF~z$cWlCDU-Qq()8JE6Q~pwJ&f1! zbivCfhsya^%oD~c=ysZUNhT6t8sx=Vz02Y1Eo%<uJ|iYI5A0dE$m>MQ-X&UFnsUW5 zOc8e<-~!JjHaJcSJFbe*ztaIrBH!)`MID7XJRH)j4HRXlbn~l&v+<i<P5$P3Y}ciM zm|#}u04{&Fis&^B*T>^mc9wluYq2KoU%?!2J*&a-n6n&5d`OGO=nF%-)O}dK`5CSy zWM0-8*hm&1Kk)p)u_~_c8X9jmdLu;~N;pC6*)UsNd#$p0B@u5LihRB_F+aFe!P05j zgkEp?*6Snva+t?5*xGTdgO`K)w&p3fNfD!pR4N_ra67_sC;N_OT0F0mx`8|aq5TGN zK1cncOJrbHMKd=fn(k1;qzG77xD6~Bo$iTcUebzAT;jlQB0oG|IyN?18%Mw+MDwh@ zBM4G#vT_`%zb9?N>lI|jrV75sb(2~d@!u|4t}%?)Z=EDIiR<GP<`be<B&v-z6-_ab zX&Xc63+VMEu3~4EV+%Qm=9Oe#azsuPKNHxAQ8$LLt?`x`%M5-(+@W{H^Nwdz+?{o@ zE@~TluKCl871}o%RrsftsiO`3yqQy0e0mqBy1>|Jim8DYJux%KBfz4^VtCg0o~F*U zkfr^%EuH8)U?vW#`pOu=d&l(^ZM+Gg`LZTii6PXXj|o)nTD38TRlYQOP_;>8XggXc z9xnd0-rz{WP(z%~Vo#4zlbr~PNE=wS@0Pbq=Hb!3&J~#)!i!H5;F{r8B#0e8f#St7 z&r&7)k3N;b)hZ_O<q?kL56&_az4&FBoiPk)d7$thBf}A9T2AvU7^RsluUiP0sr>xL z9v?9hXI`Bc@mjB{Jn@SI9ir`(rLD+dofyjrzBTs5^VG8wtMGhj0<;oqsjEI4jH|Ub zaL9c!bX4a72~YCMt%e%B=&jK+OJyZ30GBQ9y{=(&HyI$lQ|UG7`O<ESsBQBO<-xP% zx62Jm@YPQ%s>^2n+$Jp?^hJ0A#2*Lpc>hh6dNewPhP-;aJirz?r-vA?U2*`LZS7jV zAH;V!_+>`yx#(aq&tibt*L&JcRch1S@pFw1{ym~n?APCOLDmDV>PtCE*Ku=SQ^Xg+ z4arBd+Db2;P}^B!*vJ8MiX~)(bz~@Ish&6u)EaR~iW9FrQv`~d1N>WyU630y#n03u zFtw#E<)DDH=#i@-<4DU7DN2|KGi27u$wtUhWJwMN-P1KuSrskBKUO&^QxaFpoJ5?N z3MG>U)sn62%Ion~XCB<4_2CnIkK8qJ-jFZ_-_cTQ6of$hY74sp;x&|*@cxHJ>RNf* zwTogOi0mXAap5dn9`z3t|A@F8EbbB90-Oa_n4C36Q4NdJ5?r`ED@)tUn^4jiM=Fwa z6OLDOr(X8y6t?AQr}wB>V+PTsQV5N4)K~CYCh_%e|Fi+e$!MJDB}v??$d!KTz|&r; zhC$bUqxW(8kwhV@Vd$XAB==B)9yi;a4>UYGNHg>ESm8L<KL$r26aBcb?K?z<@+@}; z9j+`KEuD2jOh7h5CyeCJ%2Xb9Hc^u1#Givs0wbMtSULT^F7<F8V9v^`QJT<KEzG$K z`uaq%kEE4~dot}7CehT2$^Y<UH5K5XhdDBe$$mS7r4Pi@ES!T&*G`<m!HWVtoPQ82 ztI&fhjw5-9*z4OXZ<#zh=^VE59%<<~I&m)higq3{zX5d|)|rgWj_Ev>{?uzMgWH)q zy@p(M8dk5%>%EWWnHpAgsuw{SNp+qSE-h)EAA5RXcHGd!29WCzxZ+FF;R?0Kbr`7y z=qb*%u{5sKQW$q(9a(678@5Z<MKleJlXimbe*KzeC#~Az5yn0`Vuw0%305e=<HC~k zsq;kNBuiDC^wzgO`v4Z=`*ND(0GVgR{?%igw1DybSMvL+rrGVersV7>Xi5GI0e{Sq z#z6i~n>pW<>4_0BJ#(k8s9<t8#uhX3(scDR`&C=3e3QJqL;ZSEF-t<(`UvAo8}X_} zKU>L=e$%pE@*F%RReZbZ_4b)3Xk3&)AO9xmI_=Lm_SMqPQo_W5zi$8CSl)*o(aucZ zS@N~fyWX{o$6&fuRgGx_gIaUUrY(U%()j6fKR!g^<_VxOIm$FC|GHV?V{`3_Iiy0V zt-fzAzUe_eC5FZU$T)jo-*#W&T{1>8)b_CIqR9`d@YU?sU&r!jVkJ3fsy&@rYKl8a zbh@gdGgRUqsicF`D3$j1VwK>Az}8g0DF?`Ep(e;jmnp8Pw(uHYuUnDjI^?-h|Ng!t zfhO4zk45o;!rw<J*W(K;ac7}GKEA)c#pO0M7T@u^(1q+bt)<1E8^ME&>4NR<h}j1v zcB=Fem365G4TEj<e=nS?en(Z(>-3d!K9J$lkMWMU_?15^?z0^Zl|Sl0fE^Vp!^<aA z5FO|!yQVAaooc)5a#D!s_!n>x#a5qsd#{3n&-!EK`eW5d-7)(=2!mK6W@^d<>5 zuPo5BSNG=nu0VIArcASE5P}z-MOBY7Lixy6<~Oscg;n8|R!!nHrBC&JoQZ*{KTI)d zb_t3C|JFV^znjtcyzz?qM|6<SwUQFE-z$|BZpEcN<W?dXZhDGwCGHF=^oI6>3;MyB zj9;l&)l?twqkA!0gER7-ymqvKZ?qa*`J3K6K$#Qy?+Tac@x>m$<0SmqkwdXuhaNiZ zR4A2lfh_vk{`?LeijSA{F=({>8U{`(l#TON`8+O~k(0u12claS<pbxIQEu$ia53ks z8^Q_NB9;W2ob`b)0s?<R6_aE4&Dl=1LPnc0E*q$)ok89cUr*vkoA45^BoPlmHoL!5 z+bT98thHa(W{rOiv%G;oADV%O)$buFuR(*wtJM(+THj}g`z1&+%PT6&RU#rKvm1<A zpB5a<8FkFwaO>%NkX47|eE<v`ofG_~BkHeNUe|w3wNduXr+wJ8@_(I?My$x!H>>s) z8W5PiXxDr#v3p)h%BD+yRL-X;cr}T41Py&F6MqiY5|qkq%5QwCO3;cE_o^Cov`gkt z>ER>Kd5R#Ku<8I_tTlhPs9U`>JNJ)`DY3X#!Lh9Cy&eucc>b)zs`-CPh&ib)0pL8o zfb4^;*nZfx)u6>7H{Hp)v~2lc91e*2tY0@jmtph7d43*;eW6BmLMNVCh@W``Zw|Fh z&+y?jTSlDQ$wDN!VtII}aEx8Q^}eMF?{2ELuvOnDBd!6e;VPoL;-k@__hgWr#HL@V z|7#}siY_9iq{2L(tJU!Tyr2T!=%iNImxnzE@d0Bv`?DYT#u@1+?4w9hzF~k2`xGVu z+k<}`u%26lg<%hRkC@G`!jh<18!fdR6zrIrpw+;cg9$3}E^yu_VUOdqV-k5Ua>tB4 zoOWG}V9-B#g^>f*_d)c_asP?&$u(KG$~hlBHFB1R+nN~NUquw+$e1ld_~h}1^3ifG zm?^uW<;_8<AaBx9LT38a!TO+~1hrb{SIQaR6sZLp_o7!1>`AullvBatjNOe8xbyEL zV%tBtIPj0*kkiku-5h~;O|Ko*F32P(BaBZ#g5Epff0Z9yc;nLzd%wCx;9btA0zY&+ zy4I#nhS6wlC7_k`41|)lgML!(DWZg>PZ(d~MM6%h%Hnk}Wtt_6VO*^OMCcn@?3>FZ z&)<xle=~XCW+)V!Bf#Dx2O?Y;-_DwGg~1ASyi*?|u#FgxmFe-U{F3S$8a|MY3hn@$ z$uPgyzYp(vmi{Ne5cRcbhi{m6_=wpr3u>Z*!tD8K))*)@1^I$3XZks@TE8{M$*n)) zSb5^Xsa`IjtmNQoWltSWCX9Y>NJuj6;7A1RoK{cI*16diX-c<N2I{ezSK#Rad2ibW z7N?<1T2*c966{cl?Y=|XN1#yGa>1O41E?gi_u)*=-d@RMKsmgs5H6=D=~_5=Gc~(t zFA8pVhNv9~gFZ!5hy{n#qO^GJRjzdS%;OxxJuV+;TcfHNMoF;hR_NQlRlrBC9^938 zA6m_2rLOZ&-N%hM=cIrso6EkQl^EloG<fxFefLDMlAvJm7bjPN0H42GI4jdI*1x6z z?BRk5+UDZR;*xq~?Vir;d+xrV9dvn3E4TB!p9ywyk=?~3j+E(S>A`0t&X6+|W`>LZ zQeO6|>{IXe3+L)PaW*_mV{}009hi>~V)4)G51O?^IX!_>@hi<Px>F_f1$*4ker!M5 zmo2wv2VzoEo}Q}l(b3_qCyBJo%tQh3<i9>eW_6iW;!@t%^V+#{<fzCqNIpc-wT&w9 zTVay!ic)-gZ(~lMmUMHfG(xyVd{^c7jA0#m2MNi+l$Yvdh`N$!SrKEVa*s?X$$VsY z5Q(kq>}2nJ2E~BCH!5zS-`(<8-I(@|q1;`+X}4fGYwXV*Eh5|*M#F}9QDDnkmMe|l z@D3xz9&~n!Fe}#N0zAOP+dgGE`CEZa5h%wV2@wP4*W;|($hgs&os<nVzp4JDO21PR zd?;uulQ-~yL|CjmeEn!A>mm#uGkl(6<^ph;$X?CNBnoA@U1-_NhIe_QfAlxNCR_cF znR|uXbsTdOj1P72gInQnK^MJ$rPETsq<)R?#IX|FN+sN2%#_x1ez*LxlQB@(Mn^k+ zQU3Us#BH>fr6P{0MI=7Sttv*A<PZ1Z*WLTBddvWh2}?pVYJD2Ff$7vl>76FAbt*&8 z)}C0)BaHd4(N9iHY_#}XUL-q$Y03Q&?6N!ixI^Y#csbde+>l^NiQbNRS)XzPL<F%l zBeRQSYTeXNhjU}g(0dYx!TFB+_xKcJ$uPjAlhI2ilFdQ)KfO}7SpSkF{Cww*jJ$%2 zPxR&QENQ&qi%E!c{pX!4Y_u9O4*wC%_0+(5LBSmE0(7vJ&ZfRaIS;G~o323ghx@@= zD!{2$J6*hbGdx)UuoN~EFiLHgPq&+pAo6yK^m^n{0WXj04IakbSm;|m(jQe9yeHVm zyPJa9?ayfnKIftq(>k%omx%?_+H!6;vXn%U-cFM|L7W$Yy_Yj4)YS2&!N7uP7zjFp zf$=#2bdWFt{qtr*-c%}(kl+`sr(fnP8%Ulw{66voMweva_woB3LP|B8kyVru&VI-E z@65yKA&Qs%Y=9eBE<QByw3C-n+Z#o8;$o;W70`<o;CHhb>&%B*&`w1u=2e5AZ_hGx zg;qzY>?`<}xaT8gXomFS^&BNQ`Wtj;gB0CGdfZu>_Aq8}z>OX<#+(m5Nr_3v#$XMr ztbfbYDU3cNO+9scS*MC0C3m<6jQkUqKx%<SMoye!#X`UNeSt{23i>NerT#<q{tsI5 z+$zIP#_8#4xS5<T6c9bxZ3do*oiBhdwO&XFbdz4&0>9t?Q^pP8d^b$tR@e?(`?!_$ z1S$|=s>*cW&UfJXbci#bF7EA&^<X+R|Bd}>QwZ~0a*vFO;DNPuJd8nyqgHw@5-hIl zie^&m6KZ>Ee<`PF`^j^eLkDfpZPJjn;{20Lj|#WN<)pi}`SHF;a8!C779wTKb3Z-C zM%BTJpd2>#5I|(o1tIO}xY60Q-d{W<GC&8@)@`fTG0fj;nz=m^t;W1p78^@6))muu zz<vMYpg@90?zR=_e>;*g<=2M#`ufan=7M(y>~|M=3Pj}bpPgUvwtdfoE_&i-lRsbV zehazKm_K9#H;bR@Ctpfx1mkgYaqwd}j4zo(^}mwejsb?+8XRcPhHGED1`#3goN?w7 z=4t(@TjlQ8pU7ykQPE4kpI5GYl&+mI16Ge*HE0GGHvDugpPMipGmUmqDgA*T^32ua zON>99!q_-IJ0Vhbq@~+YZ&y>$WPSydPNpl*oNXX@)~M38VAZzi`)c(Vl5tF3y(QSE z*>%L=_OjF}LRQJ*G?!8=Li#IeU@S&+l58`Tw9J9q80{y_H{t;|x(-019QZvp$g`?_ z-r;4~AeqL%*D&jLvgz1ar^~Sn)nG1ve{P~9V4xu#NoG$CYaSW<?69Nf%RWeq3P+h1 zvQ$h|d#aUF-`Kd(Opp_3KNx$ZkYHph<c)p~{QLoX^Z4utcerk`*XiRM(Uh*`axI=v z(b`+m<#O_*Wl}^>7key*B)DE2u9c6&;n*RfvmNUhAC`Jeq1+rJ=p9=Ai)2YIGxYOx zw*+N)Y$T!B%U1f^t-lNiTziP)Xmk^{l7+%>D!~7rugQ^U2K`^P_Zyu^QoYDASs-Px zP&)+2zhOK<3jHUaHtqr;`tJx+LsEL)f70{+O2hwtjH)Pe$@kkqv@=-n|1YSaFHA;= zm?wV7hriDc<Osrx;~frzR1WZKNckdK!TvcQ-XasFM8>#>i@kPfT8&`=KGwFa&mIkP z<v{r+l2>IroI7>L4{Ny!AC4OvCX$*S?6lb`GRK%144L3<0X^D)S8dS3BaLMF;gnN1 zSo4G;<g)EyKAt_v@v8Y@<xy4mxG~94e(rQ{s$pQb?V&=U#D2F8$|l_iE?Z7&s&#G2 z1~YG0)?qfSs@q`SXt$kA4Y$?uO|St)Dt(z9Zjy#UUffW)>U6xY!J*yr3uN^K<l6F3 zVX&*M-R2B&_UWX~MfU6@7i{=XT8o0<JNUCZ46v#-psCM%)x50NG&J1&a3ad4uWhfk zw!7$3X3FZZyR5DgGi!d6a#*|Em<hkiVy&KzV1}j=T);ZK1a)0Lbc4vxSFofcvag=) zI_6{yAGqDXD=en%L&uwzyF%9mAaiGO`RYWWZA_Bejc%Ii>Zlt;Khn-avx(Wk`~)Q8 z0WZ=liS64;X2?(LT$c-z+{}U5`b(aAPa12d%t?@Ii=9=FYnHt2y608maN9EE7<8lC zK3Z3MS4eC<yn2>AedQAfpCuos-!otT%_Iggh=_?jE|Z^zTB}w3^-1M4R@<11d=1dx zfX{qIy)*`5M?9=8(iqt`aoXfjSZhz*HjxBr9V;$hbv3sWO;ITPH=Uf4bRfQo;jaTa zM;dc*S@ROKk~Oh7bF9u>PsBB6j5(?10obw1mSovcF~U|6soyG89yyl(Z^~L8TE=$f zAQ1OXjk&{`WsUybWgr`)TIs}Y3#hPmrSaZQ#C18j?yj)5@Jic*ZIz3!GZUOt=K@;R zx72PMy8=NAxmFs74xL68U51-mTTV{v9)JcVEH~Vaet$*n)J^NNK3Wh%zNe>O^TP$n zH#Zl;0&|2{TxiAGOYu)XUk&I(wEiM=uB}|p$En%A_ivAR<={j*R*Nd74qC-KZ+B?X z(Zcd)WtbdERj0}rNmI+OtejIotZuFk9pbckt!#2#z-elrs%mJSD9jhaJRw@T{hm;! zzhQ516H!99Z5jQ1w5)Hef_`Hes8;X$@7v2o-;e!?w%sMl=ig{p3M-qU8_jlVdg&M) zqbq1Bkua$VRZyJx^3sJQ=(LMmRI8tC#>Dz9wUj4Z8+1tWfdghdIZAG|;S7%5nIVb) zDBr3<7Li1jjpeXh+T>AS!{^~~dX)SgZ%=L!*p#Tb#A-Wl-Ok(+->KT4A=zzn1FiUM z0IUp70_o{0kIyx9U>0gzdg(SsW&0{CI|^&vSX}9zFhgCVbjq{008DO98Z02OJ*ZCO zl&G@dMPspfAF91B#&Snedb4FAo32e?a#FlTG*|Zcdsb%N#0eM(C^uoF95UN!g5<I& z6ZYN<%ynl7+c-#Sg6It;0d%LoJZZ$Fm^Ou{%+W8KoHpD?*;gHINun8ztgOr-?ZPut zGyd~#|DZm1N4F#Pw-EQ`%Sc*wyEkVemwDX4)oP?oNKoVA=4LiEHBC(isgPqvZLonq z7Auh_q2lcSvIfHVS=S2g-on#&X?J&}$2T6lncU0Yco;~0Nlk079wGr;r2-yXZ=~cA z%SG8z&MnRDw0Aidz1^0F-R~K<7x#v%%X$Ac{`64DL|i;<s1N#Jm))>xpCS2id#Oby zh5<6<e(la>&{0;V-nr@uJYU*cYH9Q>Ti)7goH(?w9=?dV(t7%wkZFp>S+<1^(aIxz zDfg`!9p-a2?qskuUjf?2Wb9cx$FykHY6YiP(6Uw!38SvmCaxvJptmEWRprGV4Zh0x z43;;Q3$0V4Wf@%AJXcjpY-`!&44nk7_WI0Rb4<D~;q+&jIwkWndtn(0r-t<m58<hm za81YmK#6F0{sZ)rwBzImU2or&^Ao%cykU_O;)P3K>;7;=*C}Vl-rafhzMuP|4{R76 zr61EfF(XFdI_?^IIG@^z5BpqRdcEtZ{mCj+M)Jb*y~J%lOfflXSl^_(YVYmcFi9U! zsub6~cY$UNrl?)cF&AfoLR|mTV`iWgz=cH|@4kdgqLquvrxN_YIG~_OXj@W*`%xyn z5iC1}k}ivMzFtP*S}PjE=*gFxnS$ofQ6W~9A*AS2H1@4JPb;`pTQ^Q|QW+nNi}Jf| z$%~S4;bc*cxbaVdX=F0IbD&OUY!kJb2?OWAGiV_Vjq;t|AHnYaY5POR6CRu$SgNwu z4=%q^!Ot|I_^`KY(!mSF-EXV8Z2$m$VX_SOa9ok>rfc^pCHgY~_Ykg}pZ5y{TV_D$ zk|`8AkoR55c)1RL@72WTX@ac`G2cqX1x<m|g)`$l$Y0SddHE;;C*O1LOOu1we0iJ( zx?oUtR`~?Eq1SQqzzEIm?qdTVuHiFxbNS%AXh(8kdl*HM8d{YKo1%I4J<`pH(>(nd zW{oZhyS8hcIcBs+Qm;o{Nj;V+dyFND5T9<!Ffj6mh~Wy&K722+0h#m7mE-+89xkK1 zA765oe`ojfOqj?NWfWP}kI$YM8r-K%)()~~A)=m}{mWFWOrG%l<Hx{2Y%^y&J+3rN zbpJ&~0uz=R{%txO<%F*oFxgVZAtA<L64%WlMG3rjJ073<LQOI}aCRy134Q`HKCdR$ zU8%7cj_=k;(j?6H{0ct)E^HWmsO?`eF-GITvUF`0sYfoZn^WBLV4h8<F3nvEwL3@8 zOp$4W_M#A%2M1*dOcKxs5-ywC8D%%+facgvnHNqLb`JP#6z&2tQ_R1!mgX#JYmyUA z1bFk-hkcVQ`k}ujT{gbd1Dqz9=BtB*?VRwqXc61CF>KDpIk3B=1_8Yy+X2|vTV{^N z9ev};u%)9#MG+KYCwo=FHy-ZkF3bs46WMNdRo!8(D!6#dMnJCRJHT`!7@-I?*_dpl ztA_K#Yu7qjyfF@tR{C}brk&SMtyl~?#vU>Do*Jqgi4t(+dy~~u&TFNQ=&GIX|19NE zTJH+H5_961+*hOzd^ch*xwi3Ea5%lpJ;7yB$nO1`;P$L`NxMc!+e+j~<)g7-(?Aa? z8XBe-OZfHP1hb5S=D%}K49)p1xmB_MB_=keXzzM8&x}lAS>0@q1NdrO2D$}PmdE<k z+BnV-C;O?0VZcl@EBSM;VhX*d`yG|CK2UM9NKaG#>?)jA#A0^Vp#Kk|19!7OO$-Gy zK_)9D9`Ct(747Xvs;1Q0?(oSE!`}3AFy$Q@3~aU#deJ{C(WEFHTq)0Np@lN6QnWM; z6#AmBmGzQ3HT_9=6QdC_I)>{?xOm{<U-tJoX~%<7guNg|9^1UZR-jfy&rYyP+O)`4 zczBlJz{01xB-ynt((=WIcuv#mCuhKwCSf)7OO=u3r`Q9ZR0!~|WeaAeMl~!nWsk1x zm#C+XF(OPJ_<e-f2ZvQ8+dJ0D@fRsj&;JK7SJ7S<z;1UH9;;%gm*e(4GpFqxC5y4E zenO_K9PTn1h;{shqj;5<mwc{1B))K=1%e3@Fx)papjUFnrKw;-BR0`gJ8F#C+kL%T zMCt3kR#A`2_dysas65;zdW_MgN^#P?ji$AR=ZvJhFSbvce!?t`CPV1%B@*kl3eEc| zGy8D06IRyO4*-~m!59DJ2@3A~oPqJcwa4@jc0iCC{uM{koV7F6dPN{eBm1a6tTpxc zFV6sbRf<sLYQ30446B13TY{ytAYTobwZ|t!@O`ucIdVjWVE-M!3yj6BwB-8PsFQl* z>y(Ubz%uczx3A!u+ox8cB|04RjR}XXUk}mOU!+Wt2J1BSEoCBhaM;OShxDGoHQ^Yx z6A#I-;M|8Hw^3VNi#BhW0Bv1(zj9&+m+R}6WKMHCL;3oT>q|SU=n<~(fm$uUM)g+~ za@&viECXwcz7=v6F5B{Efk+Bf^$V9F!w%98Eg;=2O&b}y#x^wbZBQXE&_&)=o<fkJ zjXHktc~kIiXS}|?_Yr#chHR@xis(UH-hE7p8}mxmjFbA!`TKKXoA=#jcix6gKbq{+ zoQUDNNe(5uC=BC6yVr68Ust}hx!@6Y45cbUc22D%mFj~FsSXn`MVH7kvQm)OQ2AuM zr{-`z&Y0E&wRKm1m>PX+YPd$;n6_-6&H8l->&C#y918}*HI8s{vzNCqQ}-q#n{s{z zOFTS3Nx(E3OKSeEP^^30h#Z_8BquN^Z}mL<_8%4PBDHv|KMC(LkjZV<Ttl>7MEI1i zvYliaa(MGVONvDZPCTwe63v;{HhuYW6Gir!MAvAPt@L}z09$&EU+Hemy6R-3x;94i za!Ff3DeJno`Z7hsN;1FE!25XlB5_HvR$eLx1G0oLcdXtP9eY4(QjXu<?|MFD2?IjR zp=jh=i`*~qun70<MtFN=R0ow(b1ML&AM8073{@|_Y#10V$wtz~G7(dL#9aGzcVQ8j z(mnY}a;+Iae==rV66nx&bw@taNqKPmE9jg|Zqm^7m*wu1Ah=sM*{XUDTto6fe)!D$ zM(u8vog%49?>N~pcJIvZ_N%nzE+ix8hzr@%0xO?#^W-znPGA<IFd^+5vU-}Ynm}?q zJnNlq@;Q92>#$x$ujI+>L&-H#bYV4tuOa+6)CVi^qm~4HG5p^Vc9J?!xc-FfSXxst zaPwD=?8s1j!J?QA!Nb_TsuFXOMm=30Sf0_5qf_G&60(^)ySmv1l<?9D1>wjT05RE_ z?+2e_jf%(Ak+0t%>MG?bx(7^qZZk51nb?;cV{dDxIrRTI4FiAtI6@&!mmQjYCYB=i zgB5$3neZV|XT_y`l13fCgI-@@;8VkrEH{!+jh}a}3s%UZ<t<IWj$h7=C~z^qY+WI^ z2M2Ot>Psca;SXQ+#-XPDj4ngsp3<R+g~=SzWe*Qy4q8XCGe<o$rA1GStmZYZkSPsb zM2BVubi@rMKJN4v)OQO%9jcv7VV!}nHoyCwFGgOv2JOH@8_aC@SSi-i;y<~{8T@kd zv{G8@;IjJ@lr6ewA`5GqAArzb8VJCHIwtBrnE1lYC*)oI3HmA?hw#oLqhlk&IZ-1g zc|iadS|&r^A~g$%-|SNSQs>cb(sX#2Ln8Z~oB|Anet9xVm%ZSx`Q8fy5&{%V);)L~ zCl|Bx^02xIIahn7TJGui<4%T}>0-K{lYJjEztlO^fllgdr`Fckx{YML-ARsq=0kks zyg}3dK|}=qN{;WW8O4@(mh@{uw>&2ur`*c(A@!!bx$rO;xQECCnP}clirYfs$6~&S z4_GBz=&zlfvPJSvg03l)7~PVTR-jFtE=3$3)&pV1S=&sD#3&o222-QQ96M2_V;0`N zGrL=p)l+f}g6tw8NQ?&*SkR*Q5G&9apoK_jnu^19ynSx~EpuY5XKR`9%H%)xql?Y( zdb5I_p+<Tg7>J4!yb0LkJDM?{Bl#bnt@KbguXgvS^xyizSP@R{hO)HNiYn00tin-t zq=ND%ogUZ5<ifg{$B2m>0zP*7IQ;<-!Cz1_Qu1TL*n153`t{DVBv-&Y?`saW9MRB> zT87{RE6pqg341(X-fH6ue=u1s#oBu5hGO(JSpuE+4Y$_=0eI30@AxFi%z_+Shj*(- zci|Itm_yLk)XWNtF&Ha%prb3TCBUnI{$HKjhHfY5&vqivqJK|1cB0zS{w7YR2o7F^ z;371wL$?D*g?brBdoo56QEPUdnQw~df^T=$pO<jcqy&0n*s({>)pgiNfw2yLd254L zG;AKYQu*F@2d*A?I~hTj?q0IlqJPnquM&Hg{y?1!1#IBrP(AWEgdmg5)5uhuh<AW? z{>@p%yfvp)PK>-tG&NZN=R54qNmj$p?r37oN;J-hVEt?{ytw{qL*Mg@YO1NXn?i7x z+c34%r^i{iYYkO;*X%WIx>UIDvvUIYQa$BDAz=^=H|eh`MI!8+k^v6}r2-sap4~z; zqeq$yv;r7B6;73lAg^V8oM<E!Y>vcVJH-deJb$v(>bQd9va|~rkca_a34aoE{xExs z)bGfHR0W%XjBG_n7i|7PX?fTX1<N7EIElxjZ~k_$g4?**2OG*X3ttR6IoMhY3;SX% zMMJe?E~x^PGfMx(()<%pWF(j6{a1pN2mW}NV+q3f$zqc10LV-rhX*>IQ?6&711cjW zI-ZSC^N6%zMNtJw9X)r)h+DbcHWI&+K}2)-HDf($jP5`}T7q&UgaLl)bMlx`3&^yW z8j++U2Is`c6ruy0X>1Cvd?Y#+__QkFaw@>Ni`nNja_aaHLM-&%WwH3qfgrs$WH20) z_y8C+XxQ=aiu^$5Zl#3YI$-{R$u2v<r@oN<8dZfoYz^@>XNT}>FSxgj(*A=hWlqg9 zF!W@1pXss9*>cLgqh#CJZDxT2nd;0ITOJ3SP|p3g;HVWf1)-wWDq5_Ik?8lfV-Ieh z?cm6l+p|K{fxOM1gtQT8Q5cb5-}eq&D=I2lG!Mf4J_o&M!Pw-0jXX|A7;0P3>otF2 zl6na=Vg%vzzY_NOjf($}Hh&q(AH9hsO{~=HrZZ9MuG+p&Zeqz|4?|LSe}+;Y_tu42 zqi{PPJN?`=pW!0ux=?H1`%e)!apb{QF#q3t(oZ0~-X>9X<`lS@kMxhkV~39QC-gp; z<#OR`mq)+#&cM`NN5SQJbY&L?QG#AHZ_1*`i0At^G6ltgv=r+Z{%H7)3xj6}X}f4Y zlP%-axvyIV2@*S^e|tZfq<Eh!x(faj*tLixnp!1~Q;Hnte09dz!$M8@mvxd%T!hw} zG~kj5Fi<QWeYd$px%2yBtAwDwO*goh8#-`?HG&R4V!#b~8YA@L6r2mtlk_UWwOvJz zUkewo^Xy3jcZt+_e)LP`7@m1NkEP{!J-`B(OgQUcmOAU8xj~~yHP+Kj*Ts2Qu>eoL z?43QnAtwJ2-;pm<fU-%dKx(4jJ`n<)`73=!gIs!^ZY78WHzl699B$^WD-79&d|Mi7 zJlAMIXGeV@+ENM0h-sHdT#{f9+uPRq|7f(eP*%h6yN6F;64R2kEuiMKG_;bXVS@mX z<m7ECf1wG6y>`~AXAKIoZeOA1aHZ_KsupNtwn^9)t8Jh@!I^&hw=iF3d0~yCy_#Ll zJ!W~|pf53mFCH2x>}qx~WjS6N^EHj$){7=`4kL%lku36Bf@QX>j}-<@qdK)Shi{_? z!;}R4zqVXd0;8Da=aU;;yx`aWA4FOvbzsa;jro5O>7erOYYB@$<6&xPcfRcY$YNg{ zX`I2=mvyAu3QrwEQg-~N1i00#M&4XQ4x|PeVna;mA4Agf=aVS#p<v)EMtZx<q@;ow z{k<JkT4{yL^We=Z^Iv=E6j<@E25@{ONT$y<YIk+YolrIVDY@-ve~5C10t4Bdf93{W zfrx}XE21!+ow8h=D9Q=|?VDlmB>6dB%Y@Qcc8M<GBd6_&{J3)5!RZ%K6Af~=@@x=m z5vG~n^zgfxD{z*v*%5o{$FOz?`;Z~xz<Y5S%02MGG8F^=s9_;3QtGk?mj^UN`;3Pg zYJ*(IFa?ADE!KpD)hQd**4PL3A0LxiKomCwP{;Pak<KL@aF|-Y64()Yq!fr!alNI~ zp}?^J@YbM7TW=)H4AsXB$0z(L+;o~ry&4gjCnz7WT3!7g(MpKOhG5o=5>mdMqX;(s z+#?FJgw5$pnd+sx2Nr~+``J@>yQ*=A-3f&iWSH9t-bxG?HNg8Nb|<9(R2|+VIJ@!P zbF#T)c^`z)3x+KmH|~ahl62`Gv4;$^>K_lEhz)u;Bj0jlGQZfBA~Ck22aJaGMoOVz z`zb0$?M@6YK#cpxO>*Tw8&%O%x5}&^5tRA-w^kk_BChGOyMKcjIK*4h?=FK?)838+ zy;f?s$53m5mWSNWCoEQHE25{iMzJ>1D?O?LgG=5}t)*#z7QpC$QM(pTIevsv8r3%w zop<7sLv>}4=(g43|576|;9TZf#=z%_e_=Bs!9VDR=2#wTQdf6t)%#cBrZ4pl=M3{N zM~n<=N^XT7kV~kxKNayn+hN2^#n<CscB}56kcW+5LQCsY{~b7R{^dEKTUAK^w_H7i zziQvOjE~<>!n=Q3qW=#if9F3S0q5$rbBoR4h44lfwUO+$KX5glH`16Sf^zB~X|(Yd zXJeT}H1tq6Q>Mp(JxLX@JtaDL>DND63>D$3KAH4&zmwJf<Ln*7BkQ)c;Z9Pq(XrLB zZQDr)9ox2@bZpy3$F{AGZJQmv)z9AN+xwiK-;cWLs#<G$&3lbGaF2hC9RkP<!2U0y z3jSk=fCNEEG9`!5cnq0er`1&~A~^X@b;aT?U#V*0OLm(yatXlnoXnP5?bv9tZT^s2 zlX{ut<FYa07T?$jbjM5}_<e%pn1mb7OIZQ%kjF=7l>*l40tT}A#XVsUFM(awac}*6 z!!ZKBx?xr7pm}+HSXHg;J!wRZ_;ne6B`BcNWSU%t?x$7r#adPOOss6Bip99t?RWQ( z$t!3!;<XG0c~KWEpjofo>q~>jUwK0qYI{g*T7f1%q2V&GAio&M{|W<w=X{`tD@Qg1 zxyNBa{nx3(DZ*j*f4Bf(ktn>@3vRkJ{ff)~vAJw-6X)6_2YOmH8vk3d_wTPYzrVg3 zU%r3;|C|T^xqzz$^jalYH>{vl{x8c7urCn6|82oa%m24Y=Wq3ZKil}4)@i`y{fEKg zU$mKQgh0y&j==Z7JS+co0TKf^KFFtKi}C-Mh5k}MG=TvBU;9#C4vbU(HyOk~9)&Hy z)#Ga!R@M9~X8otCTKK<DC4|C1TqFOv(9`>uB&C<PX_W~$egBOAU%V350(#<5_qS}A z)l~n(HSzCO{5J&j)}ZfiZ|kn*6aKrWz{c#5kV-c$#Z<n3m;CLbmjCDf7R3_+7Ik9F zNU&lf*|Aec$4H4}Z)?MjwnaKCDk3ZE^>BVDP_lZkx|(sXd;h(Ucu<fHy=J?;S>caZ z(h_^!+`i<`Ytn8xxXI0Dp=b<6vm;x?Sup9Yt)T%VzWTeeCCJMTpp$a7Tw5SRd-ko) zui5Jt-SpEu?s9dl;As)xjG<juhlWy}8k?m^QN%JVJ6yP3^~!764;^yd_Ip?AvujD3 z5-O~wP(B`W&AFlb4^N3DzDxwYAu+z0?#CE3gKjzC7YHFVOW(l&3zF$JcUrZUNdhBO zL9)3!4&A3~pWu_(jj-KAA2M(M2vYVHqG)|r{kvKOe@_-o{o}MWBllK9@n!Djr7-~< z!(^;ENgw{9#|$a^eJcq{M`!Wr={)WxnzH)zCLYk6r@_u#3N9UDxcm{<M)Y(vW5k&1 zUl*(3*ATb<u=Z@xMHu-%%V#`>YoBR$-g&+-G_(ZmK~}nrR}LzN4u%hFC^LdeyMb!= zxOa7^kg@hm@tC7UoR6T#AcrB;w2NxZYaO-faJX?B1gqBRBG;C{)O@b*0+V>(?LPgM zpg3k8h<lYJRpXR?v<zf7XJ4DJEd4=WC`(*y@RtFj_5iTTW(cx*=;Wbeapna)QW4*{ z31Q=${*oD8UQV5unvyi(BLV3qAi|~IVyder{iZGw+6Jd|PQJFo6ypu2{52xLF4*F2 z4nMLtMLTb)@4E#{^2_K_qm8esSct~GKml2{wz1LJLK7!S9hP<sNq?P@#97fK(A>q< zR=)j%6#&P?^VnfuiLxc5sXlFD{o^|bEVp_61E=W3smVBRNET`NTSc|tGwK6RNOizV zjFD>+XY)($h(e`a)wI=}o-M#OPe+?`0E$MMs-D7d{*H-_IY!P`FnJb4q~8a~#USb3 zf^hWvaGG=z^?8^t$oDYOWC&uE>^PW7p;mE{wC(zC`{TepoOXpBF}`&Ep%h0cvpMjg zN)ypK^b0{ErRkb-EhKeAbtb~$&I-11haIMJ(R{K{S_f?fdh~g@cX}Rhhl>6^AhBWa zly6UVHZ`rr9`{1t{q#qWz<_enwyq+Lmuz)*RrsN)Ns4qWO^7*x1Fqz^`BU!1IF`x< zR|m20A_<{4-f9g+*Ey>p_^har>d=|W1u|uku$^W_O*A9|VWtD$^=ZX9QCQb#j%l>5 zVz|1UsbOU`OZT7&*;rd<y*M)CwoOL6h;7B=_SV?Al1>eADK2uu1e_m8-lS`Wb9eVz z>7zWAR1)pQ#Prf8qj`Jg(yh_<CoC%i*WD4Wh29p-HHn<s@U)IiqZg$ec6h$5|CD+; zDiV}#{p6S`esoR6X}zkBN!s$L+)zu7->If=YBkb$XWfXmY4VcF_|9X=0`@86QDFfe zEZP2Ef4pM6a^HHlP1gMdly1?+m4C4lr?X_4j7(J~CHxC=tq5~-Esb!3x%=L2>cXPR zD5|!8TJ+I=eO}@{i}8LMD*T+%6+LKFArt(O3~^F_S1!?V+Is$kJ~uqmWkproABil$ z&gfy9S^GLMSrJZ0b7}@WJ#4Hh8jG!aPxQP7hkb2M$`@zIch(Th;dxH1EU64&C~tA@ zXfs#wAya%X*w1}_g-}T8M12i;*o9v{O#5EE(8s&30{(5->jV|XAT2<mFC!F>KEW%Z z{Kj6>Rim*VuTdLrmpu;nE>i{Xr1u)zvx~><Z9Iy}W4bAotD3Cj>ff!pOy|NY|0O<9 z#PlSinrTLD9VHwNL15wGvD?o~>w2MN%@OO&{+4nzrRJG-K4!_fhDSHb34m=)-pBF% z7ZDUt*g^n(v&%G!12}VKC-sIU4hS{g!qVe`jNYeiWaYJV*c)qE)V`mGiIolekZ<Ck zD_(Be3He+-_`F>Co>a07gE}1TRK6Xb29efD1BLrk9`8!Uw?+_Q6-k&$Sh;c7i+GsU zsbHd*O^AzpSN6c>oWMQGRxS?eR@^>N#h07t+D!gcLXg-yYS)qj-7Ypl-L@Ixt&U}L z2_|bp*lPHxQ7E2M#}n`q3%HT`VVojV(u{#r>snv0`D6*>{V4emctsx+m-#!s=sMqr z&Dgik^G--TondD(udq$eE5hE*2#L5v31_J~Qq9g~Rhkr1oo~?>9FI9sSsbt5&f*8o z8u2K9(Q2qR8dqop7fL7=s*8koV)%Xex#{_;@Ra$=(9<vO2Wk`s=)nqm)=5iaciimY zHU(0X+&!Lnv>IyU+xgYnD8>WCU-LeuVtZyM?#zj;3Ae>zu}Lvnf*@bYIrrMAl?D;N zE-?{d@8P_ui$gd@m2Bv3W{MhYG@@YlfBb?{2haueh|A?}0J&1*kR1l=MC*)hyl$SJ z2%hPbm6e@f(jTWIuYQ7{CFr)mqk}~FiS`gPP$DxNdSnrneucl7199+}d=t3|g-G9z zC8Z;y6H%QAPwFdIEwdTGPM^63p?MQ57Z%XNS@kH)%@^%SBkRupj{Sp&iI-KVm@HKI z?i3bfjY1p-JE>(#1~%oeN$y_IhXLn2K9-QblIY9L`LQCcwUP`{_745m846o&)gpic z{!a(B6bVD&48rvLd@XbP-trULGMl8O$3!V}jRKi=HtqBu?Z!vH49o|ZZ8VaJ%NX_N zf*+v2!#~WywO=ki%2Ae`Buqk%k%C}9SYnWkquqOl-jy4l^)hin@4l85N&cuQUX)vL zZBuH(uZRt*6-Z0MC8|>AR@qvoZ6*62ueL(WhzwHaV$%^M0PS2{DCv?_8J9pt8;|>y zB8}OQl!ij!RH69E@ob;wc1omGjmSqt;>%B$&U3Esp&Wd5fB`-tF7<G#^n*^+B!`1_ zk+d}YV7Cu2w>2=}^y(P__#8kle9*)%SXQ?AT^WQHysdc%=8K~YUFJMde6s6pY}%&H zB~Kw_a2G?DQm5dk+%6F=Jv%O~xsSXr<+ycX;Mr($%IF!1bjaP7r03lR?G4%2y{~xI zZzdgw&gi$=ac~fDH;y*dTW{{FOV|-M)o(JVnJ<*4?W3j{E*v^`jmBA9kuX=;W+4Pq z!SqYeAcUlE^hnG3O$f>)!Ak~L<L-=2Fek99Gx6a;H(=(%$tumJ%YO9|&U;H?@@7Rj zpzpV}l_|>!;dph_>cr<lAKu<}?0STKVZ88PO`A^3Kt_nigQB&qN&M|3VJ_RA7_dCw zKuSr4xoX0HLM$x~RFs~2MG))v`ou??DrIPfJeMdYGnvi5UnhP+T5D5Hh8?y0lu-;^ zXmA>RHN_c#OyAU7ND+B4lB{2F7C_w!5xr)3(c66MPg^ll;bVhq?WKDY(8&Vi;u<^S zQ}*N<SY&ns2=US8mBJm+cXWAKRzP|x(2Hp*J)M$jGHEU23yP|gvXMftboYaAGifXm z9ly)Y!8jr!VD6Fx7S?u1mMd;14!B50Atu=&nbD5#Tlh4wq5H?+`sYnNl1%$J7#+*9 ztRJCWp>1~@8pr074$}TyANV<v>Upl7x|v0P<(YH0>V|m9<hkV9;*oAytTT|%!cf&a zoK+Hb)iu;``OHHw-McWYEyk{D6aOaoaNlJ+6-MG|=V+5%bYw)$2HdkupjLZUYgXQ* zjt!_bC#Qi;s+wm4=4LM2C+C5*HEcWnAcWoCY}zQtMVzyB`nq8afw=P`#E`2;Lrpei z0T*^eEagXfKFA1B)RSmGxY~YOks_`xzl%;P96KFjXT6k735i;mn4hgn$_o%aOfqy* z^!E)3ERzn0{E<RBkMFHvtwo5-17YGOQR-8S-d{#43#f9y$ySuF;*fBY;UFf#w@%Mc zjG6O@wcKA?p+$j`eJz_qFY`C?6jMrFcQ?kB;TY3%5L!E+(?&%D=DCijBN5C8BLgAr zf(LY=Z&sE{>TvR+JU>X{kJw8Jm(Way#r>`~$PKoQD;S)dLxAVzy<cd&mvS*kosfu% zw}C^yrPgF@F^hLE)2};Brx~TSPJUZOFzfRsrKZ$^kz*@u4PA0G-p*S7yTi7<05tx5 z1PMfH6xVCqT!lD&QRLs08IqRZbQk?GFGGU>!pumyeer$Mfo^EGJNo)a%UW=A@ROj$ z(8!?!MX<a=^y}VObt0Yu{ANeqH#IoQ=~Y#<>AoUv9Ber!LDrhw4KV6RfuhOeld*kK zfeHTAhz};(8Ja(4pnE=$oX@V^8v5Z70>~kkigTHTS<Edh2k*_;(UU{&mpXCM(YHY- zTAmZlJ#*djriKycf6<O4xP>6AZI8TqA#8>6MO;Ct|C%R$+~d9OynA;@Aktk(Ik2&| zo~Jxyu;LJL{MN)hh<ZuzzB3wP9cA5PuH1>8lFC4^5eucRfFouVC@i$l4u5C7c5&|n zYO1ThX>D!Y(<KeM^Dg!aOg&jH<_Vpdb8OhfWFLH~Wkx%zq)i)Pe{l>u)!vSXNSJ!W zjPu;j+yYt55!4ITWCthox1f4rN)jg3!Au9AZ<`?g<j+_Uq{+iabk<+Fks$1$=l4mN zG!zs57q=?018RCMaWJw@?ImhddcGS=VDs>?re5T+jajutHnA33-|S8BojDM0V1u9` zCHSoPS~z01iV(H<PbR2jBv*SYsTHD&7wOFA^nZYQ#%vQVyOSvU#Kf8qHjKcT>uC^~ z{}M#Oz$b*C#G8xe(c~rEoDmZbeJ&T{#5B$`$t>hWf<-!6tU;~&1rOlIKLlngI57)p z;%qKN-r|$szcuS+#>w5W5x{b*!tjQM{Kmpb1Y+CQlV4W`=CaXwN*CL-!h`T-^WF&s z8wv2+sQ{OMiNaCuG9FNmAg)@!{<h^#|Ht8+;4gxI0g=vy%*Fih8)zvl6|p!wC4-0{ zCh6<nzh7}wXF(xcNjr&8Ow8RaLU@9OjS&1&GP2HDpZJ`doZP=Bkui~(M#4upYW(%< z-0W3b4C)y^Qbx<N8Ci(aothuKsRUs?Ftsi45SPk_{=__|ESM|Q;8)(8H$Xt|&kH{$ zT&Jd~Ne#>nLq^1>3jIS^IB=1ll2NeO#59ljCYV>Reg6O>--kAynO5_LT8uYLS_}95 zNx)AsmAayQ)*T=P@cIcPQY<H&mXL>phEqgwBc~@w1xOkQ1<<8a)|9Hy&cC@kCOO4m zxP?$dp8e2LqI!UjIwi>hD|8$@xIUp_;{B$Hg0kBPRxOml<;<mKV3<$FO|5+P-QUBZ zmcg0o`W`yA?pA7$ge`<EgLk9^lVeC)$|0U^psK7)kw&twz8>gbuFl5FDlMgyUs$01 ztJC~5Iv{#UaMccT)e;p0WQ<{zsYFj-+fcd$cOZZ#9fdStom}8`4BRW~0zZ`jKm~2m z?gST?$(4{fH=ze{o>dd1A<SbHAS~GA&Wpd#0^Zc4_-t)+rMPAie<YL2I1o^%1FoqT z1IdI}j6_LTuZ1+yBkEM89tpWf&6wxIKy;&wh<zWh6XQubL)zdL6mM1xGmzVWXK_GY zc=vPx#`q|V%O3{Y-}40);(e!yJQ`mxR_*JgWbQ*$z{xO=Sxte$$GiHotAi=yc|l&3 zTvQO#knUITE+jz1-eG+ya!eobm_li3+3cgAUH#k2s6I*zc<2M+WGKuy>nGf@!>|~@ zU>bbHNKa<{_*Y>~4W!EoLQ~@;zWYum6OvoZgb02j=LX^0jz8u=p!yl1AhJCK_o+Li zy;Utxwwn^~K{>u-#A*=|lxI>?)gk+u#F|)z6yiUV{3szyJ1URnq7tc8<)9(jxc?O` z@LWU+%u9=TDvxB?ew}8%ME*BVg!EWZb(bLU@fFk(07l<=wzUiJc{&$h#owdTh?oZt z<yPRpiX)|@|FA$PJ1K5T$F|wvG0aU&dF+X$vk(Fn7g#(^oQb=a_g^f6et5dONxE-P z`Q4J7lwzo-;P2rg!EpK&%%SC}2U%~1Y&@AJsEHRUFiDKlo=Uf`Uzm)V8GMxpam0k# z1jK`klTwGu^7NX|qS4X%WNW3ax=Rw;P|BgIO&oXH<#Cd>N=YF|4i3P@Op7%?F=eni zc8YB+PdZa&eSxX)RoYz?{&b@t-FZp}m)}R|W)d{dghDW*+)wu*ZN5I&_))yw>Wk{d z>g<q6sO9?Vs)u>dr?W-2r5`P%b61y74<8I>C^gZ{#LUiWmr`7<FCRI;2?F{p`aTl& z3B7k*jKk+-jE)&UV#8!ul2n#NpwMw#(^*gxFeOPPnZH4<)m$?cTY*k0L4}S7(SOMS zDS{QQ8EYDAnJR-jTJya|p7bz|a4@IaIAkCM(!#T3y!i{#u0$sDfN1DQm72-e%^UV} z@ntZrU8+dn+nga3*hNWeOLWtKAc%LJo<*XJDUX?ZnPN07SW!qi4>uWhx?`%B9%vOJ zIguji9>Ys68x9Zl4_(tZBQ_{UxVbEf$^^@!fssll3MB=3Dm|s$zU?Fu0oGYy$|WsC zMBIj=Xi@iL^qP7cW|dg1hKTA?^CTX#0?z)#ER-_r1G!j_U9`wL2SxIj*}>8<G0I(K zlBiMoFtC-WAUs#sX*7-GuK}V#lJRMn)h6_n%v(u+&kj8!P<nXcwmFcx+$FWg26QZ` zurxy$k~po;1k-p02M;}fJeYI^xj;yPKyi2w)+&~&+>9={b=!c$7BFmo0i?5_XH29l zJ1cD+8dlbamQ6}zWc@meL4zzhdRj7b3xxzYxg2H!xl!fz5y}T1v!<9V4ltt0NmBzA zX^HsBESwW&Zen5~Rur`G6s}rC7LM7%fFF|qeL|xX5|CjP%EU79i(h1!AyIMN&;nQ- zkYcl-qqw+!Dw)Zz<tYN)vrEBZIO|I)4ik;ESc@hv>dbnr1}i)2l!WqvW1_-l{bBCR z0Gy^g>4HXuWR&{0L5Dtvktg9LCsy>Vs+ULeXr+afLXfIE%R||hxSIN^JBYUx#dz8* z8z%xAtBqBYIqZ0(EyCp$XNAa^o?N`;ja>#OLe|Qxtc`YGHNfkm2=#J^zRBeTQz~+= z%JV?rgmFb>W~dQDBH;f{i=4POV*S)xGs%z}fP<0!iOGS9eWgv#Y7}LLflSB;LeY%X z)5?f{l6oTX)68e^#2bf>7W9n|Yx%SV)jXpF@hY(xf$y}<`ZJ9ymE(TwKG9ARthG1{ za{f9i!#3mMcUDZs9cSy=eiEN4i|?P-PBG`BLD)psj%ibm=Jt>BZ7xFuf)MJMVqt9Z zcD;`lex=3!!!?4f#FXxmT0c8#2&(p9sf=jpPwi@?<Ez1$WezfDbSf^S%{#=zGr@fI zc+5Cf_Hp_qIgyBTU%G?ku3M8;5sgS?WEgAfcJ_pOEOI+*i*gx3B{$9mm9<oL;Mdyd z9xP>ddr$Z*-ca<@1@eZ=o{7zLfeRkN5x3mefmK)oO%DGXGgfcRMm0JfPY%o@7w`JX z)#}7;bA67E<x{V}<eh2~<%i~4QAY>*>Zu8mps%FV&%x;ET5uzUuru7~l<tMcKl-Qf z%DIpTIV#pjZ5*tKKf}Y57Z!{fU5j6&p=B^`@22zEb0_IeV`QC6-D?Usg;mfR@)^rP z@>IKEjp_;uMW*)ArHoX93X2LUIFBlO%v0GE6dL*mQB%kcz9yDx8yE;h$^}MaSapo| zK8@U}3Pw!%L&z#|DL}?+Sga)|#|va~-pxj0MJ8P5`N*+8UEo&gn-t(%ms2vSnDi_J z2GV_F@S(OFOXzbXW3sj=Hc*`GB^YtTfFMP-qtsB_`q>1FBe{(qePp7K#8g_wu3hCC zcF`)jy(ic+E0#cf??3QjpqMQj;yxAadlHG6)Yy<R^obp*>cn8p{|nHr0%{S|tQH4< z^4L}>qCQG(!_dj?mUT*dxEFmz2T2l{IMjNyKg|QDu_*H}FWmJGw^#;Q1UL<`JjcNd z9<$@yfWu^|I-8!EE1+p9(Xd>lw7bKoc3C(}2Iet^mM36fWeh|y5mu(_vl{EQ1fFVW zKuJjSpc^pQ(0;@cQgxKlMukVJL@_o7q3w>&oI49z;=<g4X=8@AM2fdBv~d9$WKX?6 z*3$?@d{TW%CLKco`XHFX6eIS!wxo05<q#RWu}uqcZesA~p_UewGxk0DpX(<UbBaGy zgB6Ve28ITO3~?&^VvTVSdlLitvO!a@U(iz3Z~-R~0UAOKsuQs)!$U(9?uK5gw+{AF z^P^h7@u#yHzZP;T6&n|om4R57ti;uYE7p1!o20d?dN8;VAs3pYAHtJH56fpO(mpkm zVU_RD(N+O&&XXDzRLEim%sN~Eim6FI!=b?QidMo1CN%SB=k>!ei+R1K;TB|$a&1bc z&~m+lq~#DyD04ZhLefHq1KEPH;6el%2oQLF%6l6I(qUSO<J^bxa^4h(bv0EZFq5cD zfM-hUM=$);h-H9dG2`nO%%8vEvesd4^rZpCfChONd)4^X?U`OedD72_ad)$2=YKm8 z<bSp9J-hDoj<9|h_$QEaPS<fG13cqQf|;dj6tER7X}Eja@wr^cc$5zF#1f^J>F>}o zzej8xH;KWepsSYo5uZ7{4Y^AU3Q25V%No;r4u8OqBg$kmHmvLV=FfBC|5r~$1G*Sw zsICq{A5XX_>?j@}^QuL6SO76iU^GPJ8U38+3bx9pJYla-#EQD0Iv<i2G0>tOv59o7 zE!64W!<YJ^ATGcpq8!!shl|XYH0z@F^&pX#_q&}icDi*f4O*YrHhl8!9A4Q6)S$si z=}BP~2kYc|gCAgO*`_||XR%QVwkchq^q0{+w#$aeqEM98U}ik9n%RzESX%Qr0a?mP z{bS<-oK#hTb}8Gh9b&(s!-(4hjP&?7!OjLn3%rJLWr9Nt>;P{+lV+jrv}AvlTQ+Xk zgHW%*+uwXKZNeHVa)-Msz({dPwV7EDe9E6Od1Jtn^E@L@on^Rk+t!XrLr!-K+QXYA zHOmLL>|>nWOr^bY6ZN~r3>c0-w0{n$gdXPbqU=W-MLE_Nz?vi@@xpXvDR7CtpS<5Q zyUmfXmw5a+9DF+b8tIzHQOUd)RRRJ!?)0nQ?Aj=e+%W?i+EF@JTxdwA87S$I!-6IY z$Val9%W{a_WJ{>54@||1vfGoN<ng8LPsfU|Bk!_0PB}%IPPtFJLpYZP-p}&P@3V*J z>%>z)KrZ$IlwFk77RT^noR41gHbRG^Ul{2EUA<T%M20%7v)MO)8Sq9fW)H&^pM$AC zG$YPmuDgU?vKgL^Sr%WUy}_|ftgqwrtOj?Y_xz(&qyha$SEwfgr4Gsq(*md1s-O~2 zU~9=M{8Oe4Hj8^2lXRMVQsl)Mbsv$ce(|eY8Ut>ZaIM3jG4|E7PP1&&-eXE&;cVhc zdv@gvlGY!~5z9?$+uU2f74K=BSAVxhpw$@puY?P1$X}5pH@sYNxCxo|U#<S<S_&s{ zR)C3=dQ`XmbN^o@rk>T`j<I!ESpk3i=YDkmaa`cxjs6Zoufq0!>i@UWlMSdfz{k;H zYx?i|fkKUOv>(|_iaS{C@4xHt?}7iV5)%j5cnmx}&f5QOdz(qThiGPfv=`!^wi%F- zFrA3_kfkig&Hia}DB3T{(Qx>jxa4|g$W_^^MH=7L$#HYp4u?Z)-(h7~<DWs_A#Fpj zbn=>94c*!3UJKDT8wEu&XDl;d)Q=y4qpoKBGymI$Vgjz&WXQq_<i&;O{k#itv2r?X z%GSPJ1a#~f7Nh`ytX~mni0=1jKsM~S%S-&DgQe;z0r(3CI!+1WbgSI5}Pb6KKx zZ9n5+_pH1x2VkzBlB%=uZv>_u9u277N%!cY{{e4wf9a?%UsDpr6J_zTZB9b+d#0y5 zW6mK{Vo%Z#KO37|fr@yd+uK0LTE?LOKbr$tP&~}zk}PFq%TNF$L?js^&eA^<<#i6_ z<l+qb84Q3t&ebK5n1tbqfCWb-qZpCrMw2&fw#a^e)9ZZ{gnJXhTJ!wZI7x*33?c!k zU~f~^_&1?mFfi8y%9n{jK3!cXXvg%lRrudg01y<D%G803#wH}bgrLf~d9!puzN_3^ zMMaY&yj-HEg$J;$3IuyyS9~TG*~~5T8J34_+)=OD<W5DbPwVcC(XE%!S6zp|&(!l_ zcB>6=BWdmZf<Eke-LzZ6^krGX8s2A3f4=l`pU|7TTi)O4y6iga`mi5xO&QGUer;># z>6mhK+*)ToB01<igWJ5B<h)Abp-cR<yGcv#ea(JqMYX)XvU{3jb=8o8ah%M&TN*g} z_2j*|$9gx;K{Cj0KT+eVm5rE^@|t$pA?x)4^l9E>igwkxbliNBGrVjcpKyaCug<B7 z2?D%Gn@Qw4?g_sYSy@_Msc0<0XGHI?%+N%*lN0RFtx3eN*oU-VO^vU!PcxjXKj2e# zNuIrX<^emOb}3}P@zOT$UV>FUL0;vmr9(j1HR@aVeAqRb(%nCJ@UU}x<Q%dym-;LR z_bs~BCGWXd=Fqj}ZR6$oS;#(Z6WC{0Oj(U}b3O{by|x^7B`?=B@r-WnY|h82t#>Qb z;dgE=FUQG3R%7O+jT2eiCss!uC9ed6J$HhPhQp`+{j02+QOlOw9$bN32Gs)riCTU% z@Q=W7&;&cU?tO<uXI`<XoxH==%80U>*2Ae)?=A1FVUj`DEl0zHX#P3pJ2=NJ;9Kjm zqjRtA%6s|w(4E}&BfVq&siOuS$;?$~b$9t+$T5TpTAqi6Wa;ZMihCE$&r6UI_|MLM zra-D?x-1a5**##S@$YhrX_l}1-y6FYN`?kdNpKwY&}C)*e=vuR@h{@+V(1b4U;Oxm zR15Gh=%m;D@qZvkI`S`oJcBO}YyLNU{L>1Jf42J7c=F=^K@b$6oODm-1M+zD&*T3e z07HcZ!q>OO*Sey{|J~=70U+Rchw1uxcl;mx8V~~N2>yQ#Wp(_Ee;4DTJ@K&V%COSM zuK}`1RL-tJlYPWq17;>RL+dB>@wi_N%j#BepjNP#J&ycO!8dN}p-OUTOn>5|$oTe{ zBH2EF?N54rb9lQ6fxmg95F(&jjEH=$pg%4cSvb`HHwa@Of;g=zFWU=8Te915RYs_R zzLG}t5c->tSXn+vcpGN0G`kfx=V<A8M5@O!G8{|m>Zw5w{doK}z)o+*vYgsNvpS6B z%i>-SSIkooHO=DdL1_MXcbBwH=nH-Q6#PYuQ%3RQ{@fbj-}7mQj6}$Pa$=9ae{@vP z`9oLtsx(O-Bk$)Uata7&x&PsI6%aL8AF8DC1Hr%sApyc3D};g$Dx%yHE+d=}(;?#K zEgYAYmwP)7+uq+e7&~*0vV0i262=DDZzgKE)f^{uQMbG&y?K;AE;%j@UEdJLGEOp| z<tR69vZyaJv-Wmw*_YN&An))e`d>e`@vb^TlTBHS^${-LLZuDIIJLB{EO|^B%scK5 zd7oIbnNy#6(gR%1_n1Z7+B^n^m&E&oK*?B^b!(#J2M6s+IUle;u0*13Hy7+|?ORsm z_S@?C3@N(@O<K^mwd$86BjK-PE?pME(l%FCNH%yoQE-pxKL}@wMYS+fMq?&t{=^jF zsau5@9C;r`k)b(6&dslp&{kcT#cC6x3!)(7@3M&1!Cowht+l%I&tz)?hQL70j`{fJ z{2w<Ue}gwp`-AvQZQJpnO(*yM`#~0q@=M=lbSaS#@S}%fLG$^SP2(NVCeM>icN6SF zhr6FPzmB^jnL{>(@#4Ka><tGc07<Jn)8s9XWX;g84iv!Uh+EtTpaEM}_K3l6bK z<Hx_YPmg$jUxEIR?wkC}#oO8M2bvCXC2QjsanQy|qeLh;8e%|+pV*X|q!W8@2E z_jQUmoDGw#l))v((&UCu!p8?%pqhK{sQED~U%#Yb_92f3^9+AK@7DfdA)~1rP(UH) zFH)34dvi8OYXM7nMGRRC!<de_qO0j0+usxOUrNovVgA-NI^SwJ$8`g#=wJZ9xDaMK zm#)%r<x|exg_^<$850sQeLwY(XYbDD<)vH?JIrp3<^56oDEA?Ed9=r%u8Zo+Fx68} zsFEcbIAUD;XF@6PYYPPQtL48W1bWcu#9>|DV~j)97e*i5Wn%><dUlswJhK#19;<@G zEn~mHDxk6Tf1`$;3X~i2v0~A$xc?GT{v|`D(EdfOrkYLF_5WRFyPpt<G@*i%#eYr3 z|5dKV3K>&f#BGIGkJ<+L`3s<>ZLN}j;eq;R&BrW1;l{ANrnCXfo<~m+RZImGSST1> zF+{Z%SBI8pZ76Vy^%#eL5hXu}kK3}r<dbmmQMr{FWWz`!a^rVwF>M(?=6jSo>tbL3 z_2js5L@`pE3YQYo>B0x>V@^z1rvWmifSy2YD<DdzfT0UO-9veKtQ~K>eYb%J3SRK) zm5YLL;|I_k&jZJzi846+z8RrT^GX2(-EAhZ9%S*rTQe2~Om~a@4wUIx(hh~pxId9` z)lWyPP4S4zU(`MbAR_b~8dCg#pxlI|4iFRY16BU){pNwF%^lG2=jEmMcR|gcnBsA4 z5-stOU14pufHm%4dru3LkmEBO8&Mly+ZVc>30)BJkgf>?RK&-&Ufm6Ozwu3ERD*<J zd@|NnDsKmR!dxov?I09S2-mb3!ts8zjPc!5K28AVK9vSafld+qK`0u>ebSQWaPv!| z{G|X^|0~>^wXN+E$H&KqN7M^kikz*^wmiWcBkkQjb6P00_p)M~Ct9jQ+8GVWr?ZR8 zE<StI%@W_pdiP9CToN!V)~7*EZ&%<nA{5k&?wwY`q0mdZr(u}ooJ^B0@P)C4)A;Z* zf<#zWkV{ERn-CBHdUAf6cz$j*IyNz66XJ7C505NV1_2@tGT;kGm1-a5zto}uyT<_% zkn!0H6a^wn+~Ed9J)pG6awXP*aTSAugL5Y*iNKU9lvH%_u1z)xC-cRl-}vk+h8)=h zuxTKHeDCg}<2z_VHP_K=h-`aiyev%#Q|n6}Epq_~mUt6n-?D_W-L)VlZvC-x(z24s zC@Dv&DrMh@oJDbA90QT|QePo(bmo}|t8t`d5BlPtQe!CD=U4u|*|n;n?j@zABNCI6 zq@j(Jpj>`D2A<nkTBhXY>Pbq=#svidZc2DUt@0v!b3j&9m6b_i_#R<3TJ-#BwCkYk zJ&M|jRd;uHNqKo?-volbAEIpP8zJ7QXdrTKE-x3}wigr#7YmvIRRhP;M6ETIl>xxI zAQerrN8oPP#q;y?6{ZB-E$7$TA}(2%D&w%2i@C?3d19uGwzu-?@H<i2GW2yOOMUhA z<L-0m$4Ar1hhuVL-(R1kJ;d6y8a=*_Ay>TE*E3F*bx(+el&>EMhX5YYDM+$wTHH78 zE;U2evqioEPkQ+&<`uUkB)Omsx=4$Qi=&HGng^{%*$F8+9*V)66KVBEzsoBQra#W> z<1-VX9;kv40MRfRKKesSn7xvDVnocC5Har4Py(AzQ^ND541*+gN;*1pwjDPiXj$Cf zaz5@&3;XAZ#1RODxd>uk>7d25bW>CVPc#V9y%chzR1lJr{HK?g$~YFK!Lr6?Jm3}u z?_7~D7Z=&wcY?RZL*UO2di>wxQ&PUMZ@MM$+>VeqY&b7T3K;|(PQ69?kwegcv3KZC zbzDXT_c|7Gxfz}$Zhrg~S?I(86e$#_9<{<+qM}8WTeX5+pYK-{6OV2@4yOy08m@O$ zx7YoM<5kU-%K4|Xj%@-Qnt9$IdzQ8mN=osGf&1B9&Ptn}wkcx`&(9ptu<*R{hf1o7 z`SH=%Si@K?@$o3`k1Iz4htm7DpN|<}fOPDg&ezBBvzl)5Py~FytW9kBm=w}I+{=EJ z>sUIg<-tH$g2LhbNWLiSy|ahq<i=Gh(*lNfz&-V1MMcHI=oU|rRIcxz;VX&nvPrmn z4l1va#?mQfN*2YCpmv5c9=UYo)&wo)2oQUiY1Wqt;i$gF><<JT?5)vSrLxuGE34{& zq3|yyOPJ5Ip1B7bt%jj**P;ACuSySK=BF;|Fr@r;m(Fke&%KDG6dVed?N9i>g&1U| zr7KuiSR@!&aB*ju5iM#m($kAN3$#)44$S-@0*tu1xTG2f7bxz0+|*M=#Kex7&u~t^ zUyF;23ePK6{a9O0#r$eOqwDS6naQnI>MlPyl?-{=twtQn#zFCOFqRGKt-Rdg>nWoI z1~zv7d<cA0RC!ofOpKZ}Sk5HnD2JKgx=?jv<9Ajvv{Gp38;=@9=e*ecyEJz0(3TeU z8*yA0rOs5J0mRc4kX|nU;1771@X;+|Pvpz{HY9(1_n$M{vAu2&mCKerHrAtKv69)D z8H$A=(r@3g*lAbR*YmNT6r2<kO9{r8H#do@W{T}<k?`^9Xh*nNNJWT=`!t*fLjc(i z2++`rmc=B$QD29FxY<I3lpE<lk<A>j3|P_pu0iB`gW*f$cr>B-f(4bvX?Z9E9r$Kk zT3zkWV-vs=h7@l&){JT9_jy?J8A_wsqynl(zO=9aMf`)}!rFRd%UwuKt$AT_vD~Xr zt574zozM8Itbl|MH@7{UyPEp(h^;rp2Ls(+EYFcl4w0I!_t$+(p0;qE-%h5+#-p@^ zFKBg=siT(t^=GH2-yxXg$GrHMQ4We1R{<7{8qEkJvKCDd;ZlS1CvlnPoDN&wPZnOj zpI<HlQ%#8zalZflPBDWv=;xgV<6<=Ox?uGB%1KUI#bHW-9N0BcqB|~|FJ~;LWI+69 zn6PA8z*js`rB@$@EzIW|ygwTOEDlNF>pCZ!TIQ?pXS%0cJ-ey!UTQt;7V9s*Q{6j3 zpHwdmgFx6gMpg##z^C=r4D~>DE>~HqtFy}n)Voxp2oldX0ZT<9&rM$f(4rq*Zz;Z% zuA9y!FqInhCS}*F^`13ex6x}vv0MieC(L!;!!Dz|2^FB0gGp**Qf~!zTyDp)9q*4O zX&}AoN<TnB_NeDgCln?JSKjKWWKw9gsVo<(gUv%ASEHWx7f$Bm)8k=Kf7WxsyUw>| z7~SlWp+FHy*2(tD<B5O&o|HK`jS8cVGCVh@v;s2cd;ZKwwm0GWyZk$ssQc-Hx%*jF z6mY9R_(!zNgcR!iiC^7GOGPR4<F&snJm2ipymhz}xHY_<7^Ipg$R~C_wSSGyasYai zT~MIYs8guvw1Q4gsZ4N0Nlwby*i@fy)+={i2lJ;SQP%`9$j-@~4vZ?t1M=6SPR2a+ z+8mGQ+zFl?{s37;lx^Bh$g|Q5fw5iNxygZ7e)ARMDK)WQ$5YI+HaDXG;BkWn;8L-s z619B%IcxYJV=#4heRVMhQ08zZWX=3et)7^TK5&=`l9`~NN?s+tW+d^miQJ!@o>rr% zU##vFQx&9p33yW^>d}cFcp)62Hl{bWaB)f20)P4S#RMl&o{VgeYor8p5D~ycL!;7i z81&+xYB!$jN?4CjDrB(P(dzJ!&KjQ<N2CIJzSb=NXh>d-6&{bDssh~Za1Pk;!6UgF ztm8c$76N@&-M)-0yUjwy#-$L=IQyAW3CgjPiSDE&jSST8sLXM{e%Y6!=@W=zwV6!* z=Heif^!<GA{6X+&j)#X&Nk^63(13RH^dSEEz2vq7JP>TLro3F~EQgm>Gl_X}vZ}}I zs|j4q_dx_x<mS$H?bmX`d*0q&B8nOTo#{m9<BaGWj<WZuQPgh=s7HUslBkWRGFN&i z^%N2&MG|P9eGvV#bd{wc%h|xU0SGGgu~av6Gh>L^oZ^8;V54yc&lQ1;sTE<&Zu{>v z-@3v~mF{q5AmM|eL_T-IyGV3gE)lZZcdz3P&08wn%`Tt&9S;Y$@mWv2znuzr9d)%D zIxH0G_-1mDliRi#w%2e&XSEmO7I)D6ezD)6oY4NT5QR9+7l2!UhXhmP5IW}{j!OW$ zF+xulAYkwVuWr3D0ZkaA47*$Mwl3U@+ikZzNi=0B=B9u8-MiO&o7z$dBa7paOKH6F z{@&si5Wx|0IOUmHeR={6T1Qg1?R-d<37lNkP8HK^u_HP^3P_qU7T}mlXH_<t&L(?# zdAYr3o*r?W=C5Hhxw_i;_WFpg;ExV>aXecfzJJyA(o9(LGN-Ql&DZV57-_;ANsnyC zXn!2G+f(%vC!Lhrvpjy8R&z6%!0Xdj+S(g6s4<4;ak*e-`Om2nzV%ahcz7ZOy+$3N z?=ti4+>}2MofG{avs%dJ{m;Xn&BrToPQni1+}^0@u<y4Y2i<S5D|OZcn`+G+&6c4& zclXSt!&*Gtnp4@l5nOMo*+Y$ohvYKM$)nvLXYztpHE{|~m^kcRWc)9q@`8Tt-<dzA z7G3j<p+fMqAsTx1%ZUzENGElGG?-<py9#FhEB0ihq<ubiVKO<{B(gI>pEofzqffrq z!ZMnd2^3}w9~Z!Uek?L-#l=N^`+Jo<?+f#{TwG8VdXM@R3C0B%*)=se9d}czFPE;} zBpGa-!3adcjqj#YnQ<7p9^fwCkSeI3kIA$%$qiDfF3FomuLNaTx5@t)qz8oj>e@6h zHXrnPVPuy6u+|jk?6OZA4poH8<nwI3J)(aXxxaUkgg%dI?Fx#xl@kWJ-Ho8%c}iSm zwq1LyPE1lOT@iyiFXVqugS5{qANvx&;xIDQ>Uel6v&4PX0p@-$pQ>&3h4LwBX=^?A z$Lh=7p<vfVQVHR>j{D1Z^WI2;i`p%(yO>yG=KT<y>ZP|ZE?H6akoQ<;`&6Pr4Jc!V z##Jr#Wq+)R?$6h&fJ!xs9AVlQjP7Ufm9Dc~Cs*f@`eV;%e7>J=N&@!@H<jow!@h6d zR%(3;3`Ek}?E7(;Y%jf957Qe7_e%Dk=sQZ83l^AiIPA4PUUIs>S>wfSVao8_4Aih} zbhJ8thi>qBhj@wke1>MA?61^Ewe!+!vf8A%JDkLbzdX`QzMWv64iLT1N4y)ke0uU1 zhZuJnu|i-Q;cc+Z3Ice5TI4oz?;rIxl?b{c>7wW&iMe~}gI&Q8AO)g|o0CmRV7=by zYdJ=e$PQQ9xAQ|JkZ_nzK}x++>0m|fkYe$;jveu_bGA4-MrU=uBVKe5Bt~D9b4S0X zMe<{=8#AhDFn`o2U-$IxA1z?AGpsR-5*R79j2*Azm*%yTgSjy~2JK|?rtSf_PHkBh zWbE3)vE?k7Nr*`xS5Zgz;n}rHl8A{)&>tq*w-Vd0x->7_&TJy*VE4B^FSZV3q3}>- z;-y1gFWZ6Oej~OF(M?&?aZ5F_ukzJoNvB;k7*TT9%B<Nuy~n(R-s{70Cb_bgI7MaU zmtzbrmy>$%x4V3XU49EN3Wj$9npV9a^P27*h=Gi%tlkXU4rowc+yE;G8BQTG5)x&b zt^?HC93KU$yp19am|#lDm)^iv<R^wP_nh^|FnNKsH3ZuG0wpaaa@rY~tJPN2h;Q@1 zAJeCO{+w(HM098$PUo;QY)IxwRy~yvct|u^uR+k>W2kGrjMMvy;=iotP-@WmC%;WT z*p`zYmGHlpO=NM4OWJB`R^TqXe!<&-{{7SI{Y*FEcZFJk7UVw0=lj---Fc9h=hxGW zpKU>-{BQlP`yY^(;wupcYTX{VKTZ--DWCHv{AWx}pWi><9nGq1{0@EF;ytOLmu+Mr zE5Pf4hDLOM$(S$Q?jIG^<*~M2cieNUD%H*(i_KlZjWjXG6Px*>5kyP2DhbW(gwwjd z-Xsw3(%(N!jEn?daq^2{qyTwFdBpw$iI20t>=|zl=zX!eZxqaUVCuVbMz|(QJ7KX} zFpO>;b6#;x#;Vn-u1=Uu^R&#c0ysStsoYv9Zpun>QV2eWyU*TFm`%pFeD=;9E*h5v z1mg=#z9zn?Tu)^4irc&oSUbF4G>>*Ztw*tP(U0c!hdR3?m{{9(e2BknK7FKkohs)D zaXL2g=Z@ldTGB~HMn#1{i*umS5TS%&4dITA@<UR}%gYb{$SEt&r1UF;#^A#j>r$i9 zB}U}A&ZUao^bgpb9sZDRoc~Jr8$6XVi;Wfsc7-2=IaVZTRO@Ydp85E@QQg=Ev_vl6 z+)zkQN?#eK?nFo|;OSnUF{wmayg<u)>}!4J#xch`L-5|XlauKl4bApQbT2`H*x~GN zaCUY=h=tUb{E`bnE;)8;utD8*gR8RvNd1$`%UQ*A9|h8QxyLpnDQ=76UVaGKa40!6 zM>aQGLY>cEG~>o=#-B0a{+Hvp@ng8Sdp>-Dy+r*i%dWscI1Bv}LQvM!g;JLSI_=U3 z0-HbJcBkPS9GiGv{;<~SSfS4Pc#YZV_|tt-0E6Bb|7imcfkOLse=>W!;t>s1Wz=M= zU5F-Xx!GXBmYD{Bmp0Ph;baY!q)Vg~nGO|YRdJP-G+CD!eBS9EN2!5vKAh;)iE4=; z@j9bpQ>u=k6-$*N?n9DkAWCu$t_R@<r>j-1t+F}7QI_<pWRhE7Yg@<t2{YJz{m<8Y zMKF>`d&Qy-^k3BRtrMPw7tGaUZ`+W6+-<!-f~V%3D<*_v0n<%-Uif8csk@b~yUjne z-Tna-uc4qQ>&dTIttNOZ+s>~W;6u?$(y~I<n@oz~+$KzBY$e0cSmc$BF;DZ96r-JO zt&%@&G$J(lRqcZCedy~`45P6+zU*S~#~iIg)u*%@&1+`t|5noxe5pvhc94o;3u)f^ zfY$ICWJ*me9EtI{C!yI5Q>p9L?-w&O^2pstEh#43xb{K`?-&<+*8Gv)IHlDor_amE z4GY?(Xo@0-%TGbyeaj?c?jpEN5G=+m)VT5R03RMj4zT&hx|V_gdZ}}Am*Xj53R$+H zU1#)*RABE6cD{~lq}zI}iCUvDY#A3xWejhsT#=4h!BCd7k1vK<OR$%A41+4S>Tp*8 z;T#c<2QJu;zyw!*gcI(vzQm+#H!z#IRHpT^jnx4`3VqDhRSzp8uSm!7L5ghnT=&@) z;k=RZit<So`*9E?wqRV1CNN&VXqAb8!%c#!!ZO!uyA8{i!pCGRz9=GZJ2j$fLbtlj zB5DeOtG?C^^VX<a05y(oS#f@Uzq~?~5~P?Z_%H;H1%AJh__gWlaeYfy36!NBj9|KZ z%$Z#>U8m5;`<5?_@AErs?8{TB#&CWxY$o{LdBt_+C^k8qzpBp9=3G)lZB`6{n*$8= zuOsF%Ks!`+wTVNqskER^-YU60vI>)x<oH-cZZG$jx;bjcL)zHL37W`0&;_=i*urf0 zE452u0)ezVo~k7yX*OKgyppIG(4`qTk#Dzmu!RkkXg@k}-=EC{Y6!5pAW`g5oY|CC zxqnS)y$$HfG5$I~Y`;+ylFvr~4gVAC6Mr2KL9HRmCA|Fta>E5Sz6a@0QJ9>z!!-RK z%U{y)42OW<vV5vF%V|E~G#!b>%+Q(eWvv7vHnD(E9QnDnWH-=yCWe!kN2z!>lTEeI zaAQMTNlTUTRc{<Spr!t3LOHJ=1<gRkWA|Ax@t3s8w6@=w2Ffu(DL&Dgo<)!RASI<V zcdyWAs2un4a|_34kJ;PEuf0=A1B8Y)t<>bu$D6DxFL`hn*2aa8IkX^H2&|v{7+MO; ze_rfrcb|oe7jwbb`UaARt(dj+geJ{mR}--ou5Ik2uHyaa&M;FBak`#|{gKzuSkbM} z`FuWlyuy>uhWS6BHzz4y#&o?k98C5FEZ^|00y3PiV?|PF?O}?EGF^`0(7_l8^Q+h} zLKOsXszAomGg4{>lDAYXr86w{2t2O&%rf^5q;<VS-t-f)(vqr9G#1&+IGSv?@>Xv> zFFRq=k0FgVqS!}#<tCH)-*&z?BAaqAh|-o~+!^PNbECL@7{2Ziy6CAwxuIZnp;jB2 z>b-=KfN3*3H+UNL<{LY(voJ<r(8i~q{y=(ldG~2;2@y0cxgYsgsM9w91^u%vvQfXb zs}D*ytn*{^s#dx%&%=HF^~{a1nZs2;@&g}DP<GX!9-caNzC!{&EfR(A^44o^&3AV| z@51aXC9~<IVB72O%9`@JAKU`z1;N3=exVBaf+i%iVQx4Q-^O<lc#761C%Ivx?(oW4 z<%B)H$@J0?qJIkFb4#H*K;6SjEPxdeynqD~JR=!%xI-ibL<;+eT=pE<|KiHg2OZxl z@WwbD>X_M5z<0Ep0k69R++&>EBBeaZ=7<>Mfi0aY%sNePxC;8S=(Y|%UT`yly&9V3 zolu_6D+Ej^R4$j8haQk-vG{%i_?rw*n~Y!#4+*s6xh&orKM$+v#^D_|oM1d5(m(4R zeDeDXV2o(UXciWdOB0_*N8@u6b8l{hM>m02s52j2dJ+scP5ywsKl={${N#Ey-~<?9 z#-75d=|mttr$^*_&IN!AF>gRCg{R2J@0?sDGnYj7d^ps5UB=P(k|B7n?e+^e&dA}D z21g~r0<N>nHOejyEObyP7yaQgpCo-e6fkssV|Cvg9xT{*Z};HfAB6+2;vZ6_cEvm1 z!ixy$=aWPl8-&21tLzBJihnp+Pmr!n<pvPQ5uSTyq<aV!M~^>RYt}OC_>4}qC_2a! zq{!9=OG!^Bo{l+0wlt4qZ(NO*@V`RUN`+R@c!{w!o>07%d_E1&!Fv`fEo*z<MCiu< zR@06`HjU``SS2uis?Ort5W%o$-gF72=`*M&^pe1*QB@H1A486T#!#^NT`a6;XT*yb zA(!p-2=4xNGrSX4ASS-mFzS6WxHa1SHvSY0dn_dt&d8fgf2MCcH2Bp?F)=5nBI5hp z+?>+^yS;up>t`e(DPJa;xql}Pr1{T$Yhx0v9$MWlB@EAw*Go2Q=?Q9trimi~DELt_ z^Kbq@SFf__Y9Xx6#0=XmQE$4GWQSM0hNl1F0@(Yq4ymzpl&gLF!rM}OAfRbwWi>=t zE?TmCyws4pjcXONBy8443b6NmYCjT?x)SA<4^TBCzr-+GJLs_?IFF*t<dh)WG2X5p zqaHg5-uhIvIJ0nGjbA+>2}K<Jm0<dt84}}h)_A@q$3v$xoyOnxxA^BBe_m2fAb1S5 zaW63OU-M?}L2226-_=jL+nq1;FxirFo^ogP%bW~$F!9Qzc;Y{tYZ<{KSXOp$1H{N7 z<`V_|9a-_a#NOmaR9AF;UJZd7`!`9bT3w+n>D>umI4!``;FfXGQ7+twQVq&Q)uh9p zL=sa9$fR0gI(I)RDMG0h{E+N;4jfg4w3@CA`>Zqm@Y!!(@0Pm3>oUQ(YXOZc8P4bl zXHpc(OL}ocucN(RTH!c1A&M}JsgeRoFX0k@%q<n@@WX+qzC_`?{a%xr&=gE<-~L6R z1PoPhW_<FPIQ-SMfN87Vtx?_T(l}J|R%{S*llE<t7C+*Rg`KR8bT~2jej*OUcUDvH zZ1N)tmeO3c+3iM2ThkE&c1qX%fb3rJgUe8|zMsjgrd7gwM6Z{!oX?l(Jq-!)1LO!+ zK=@|3H0+%fXAi$J-MHZ6vAK(ga`fhQ>+@ZD2ll{#R%FOYtO~8i|2fQ1-1wu9tj=y0 zCCh;v<jD`SA{+K(#SNH<q*|FmF!fSB>TAo!MiyZ$j-F#$xr?InL!(mI*EZ7fq}1%s zi@WK77TW}HSPcC!&ukPcxp&<DdILeHYQLi|tFm}tARGyv5UUqZ7w0P!t+C;c5;s~} zjaIFHig`TVe$ti01fqLETh$zQJ4|0{JK(wiWsZyIZQMx~j52$cHirX?(Z0U=)pQF^ zr|tj8(>btd79>%+Y<6|owr$(CyKLL;vTb+Swr$(Cz2D62?vuaZX6DVzh&bmBf4Mqx zvf+wm_jl)2=@3X^WeiXyx>+c^!4W3_s(Wh4*{5()7YVkb6ywR~>|`M<p1dUN_6f<z zSBK>!jn|B?#AtbJBa^Kx+8XZDl&rTq;wT%@Xw84<H@90SY)3T_($pKl)oL;HjW~S8 zof{E^rK>8%Uh3c_m%($_&36~i+o9cI&CfZtR`KDX^V_+44_Qm!GY#tV*hC6#Vi^BN z9MAWKnL$M-Y=)uY#uoQ(e$axE*~9%}Nos$@+rt(s3(E_vNrus5A6$`SZiQ@C0-WK@ zHSg_q9kkZr)jhxAjdUWSW%k*7^z{{m`5XR&(KhrQ^gR-UkJrm}h=7-<Pi_vcHo;0| zm)1k!Zs}TR`jUYr7lDW*8z@1odZkAG^rzqb!cW3Uu9uctm0m^jl#@Z~6ee7|rsw@i zPrUy3eX2RRy_vdhtl%+dyFlDJ2E@9iev>CF+Sie>;6Cg<kBnrR8+Xow+s-TOlT1In zs%^Iiu8iiiz{Wjm+x0v4AK1<$Bx75ZIACspgqzYFU%BradHf(v$*c^o%Km@0$NJHf z<NHR|96$>Qmd6o{UHJ+JpPNoI6<4h28?(X^M4!$VmR>-Ez*LM4|0&S7b|Mh~m$>1# zM;PnRI87rhs4z1SC>&2`f-1KSwYR3<pY;X|aB1X%qzeX)frmR=jnBf<(yqkba(%3I z+`Rv8l_=+VKQ;bmP7%_7ouX~4Xad_suG;^21qeplE?1kRdCeJO^(H~Em?oVdQo?Y8 z@R&Pq_R!E?T_~X0gTF`P2dF^T%ot{e$eSkH-4U5j^nc!W#(&=Ue}H?I%#y;w!Gt)) zIpNQu>)rBZ*drNSnvpmCUq*{4FXXd0ihWRzE=sRIlc?NXyIaJ!>Kvcxskqc`l<$6F zV1NX63pV$BR6mR68}3;$2^Gg;LdmFY4Fwa<T63_#mo&rP=wmy;hl6zy+Z(D_%d~=p z4N16*kU$;rEp3YiHj<H*N^p--m0EH%<si%_{zaFTwO21i+z%@xbeW(B?6TSp9g<k@ zJ=oLJRBB}3r=?UuB0JS+ye4z<JrSQN)|HF0nCRpjpi}LHLRQPNGqR{_>p&1tgON2@ zdSHwCo3EF{lb<*J`zAYY6nGSFqU7J@Y>D`aL@cW$z)r`LLvq4)W6QLewe{?1&!TTq z1)TSXkg`HvWG^%<7jO6D(tdHfv-bI0OH(bI5H@BxJWrYW2SL$6Tgx<Yn<VB33w!wN zNMPL3rc*i8<Z`%)1qqI6?T3P}X=Qiy`Mg(W*FebC$}*~DK<WwkSy|-(NjVpbdj!Rg zEoDVn;0Md<;B;CjB8j*<+{tmyu=ww2K_J$+TIdnyU;cgK91cN*8aOhy9NgT>=;pJa zgXs&UjI+19K1Js$1hT%PBV{4SjrbuJgq=pSQ=0`tkp@z=3gF9G9!^Jqd=}~UfXotI zO{ZgV(SR2iI=N#LYiTRq#|-{OM*&*KmF3tx^<i}fe>rGo7@j8*U5MI0UY0MPdEN~j znxsOp6j-R9x2c+n-RX2TS#?u-9S;0{4DId$_)rC7Aa;9a^^up4*8}<9VUHYy;Zw|m z+@2TyCzH7oN=P5KEtk^fHIOvcxm-$h8~QYU`LEo0TI8+M_}~Zbf{h|l=~T;)KV+YL zXL_-)gg<bZC^QfdL%l)Ak`@+c@7ePunGR~kFVyRx0209LVy_c0g4^Ie$nSUiZtUiT zHBHU5Z<+-w9ED%{ma?b+&H!JU>^tC1CdoP>)?wKWS6NXp*EgsHXI%nJjKX11``^Eh z2Z=$SyXQk=wEkl6DUgW?mMI%c&negU-mVvfznYMek}klM3j_2slTf~2RZz&|@i0+7 zpMG>c`$I@5$Pg`~QVM)rb~-~b(;KW|6VKY(Wu)}FH|owYd#Ui!`*m+dXpBwY%#6~h z=l+P_?KfVW3rP<R<cIt^9RFKp>5>z;Njh{VezfoNP0yEX^1!8CdmfMbeuRF7HsABg z=HXF3<c<10FFaEUUs2C($V_2wTGe0{on+5r@yvx2Aa3xlM9)P5%{)#@5=l<p<2cDP zJo=}4ew{@3M)42?5@b-qBwbG^Pif~Q*v#J31rIYqc8Egz((6nIiw4v=-98!EMl5@F z8ki(#=0aZnnH?xsHWL)nQPhd2`qcLuLJyCN>{}cjU7U29VuXcLsNd^zVpoUVP1gEk zdRH~4;{Z?|IL4eD8CzhXE-|nl7X;}wcI{nUw;5S{K9<FvW28^mxNZeqpd?h<StT?i z6r9EB34o_}Ju7p>Wa&GBk>v5C7bSpD&vV%E{J@<RqgNAZL~$+Xd3&lke6c5Yov6x9 z`ngN45%6llF~tw7B^;D?JZRTW3RdXwKAyDD>^y{7n)P|I>kgf6N5k4L{9>z#(chlD zw3azbk`h~HA>~Lu8nRsdN$&Z^j=T8!r&w~#iAjdi_%+GvBV;<AgBX1vM=JDq9~Tzt z{u7iNs-5|guPHy5+@$kZ>#;yay7L&>VK(FCc=Lt$EdS6Gsrcw^Q%k~|Wg8m~w-BPO zy|YF(!}n0c^OznM&==`A<-$I;<+hDr^eZg(JNOe#t6zks;B_(k#s8EfuoA_OChg)X zDLS)xe1g8GvgoP=yGA_2-JJh|F}nd3b}0wkV=^={mmf4G(wQrqSc{bERRdzD*rUPQ zYr4aEJ>VhLE-io(Vk5?ay~KsnLY7C?pZ{dU?ViQsjDDR-8{w+IwKu8o!yv6EI0WL9 zVEpjt%Sxh=61sk_4*}ggt(T3{nQD5|!B_IOBudbJ7Jg&K@7rm$ihVqGcZ?XadB7OH zGItItHYtT7-81_4h|g9BURN5fgY|2+M(0d#k8Oce2PXuAn(VDFTPb3>rr9lkOQLhS z!X3@cKjjp4vnw=H|MH*A<Xr%ei8S}2hnYI!yLaUt5M>dL<3w&<N>XPab5|k!wqv}B z<3#)1F|!VjT^pNDR_sB>i_=7YnX%u@(0ZfOaj5Q1SBv%(_*vg!^M>u&ihYCM<?{Dz zbii{V#i_=7Uu>ZszIqOd7-$vH?p6KV{B;_&%9`Cmyoao6+oOx<IKG}QXmf=I4kWFf zGl|+ByFvSl4qv!_!spYDx2~Mg-A2O<52^3$v|<MaD&{{tu(GbN%$hIUk^#e%S|>;` zQ^i@S52Hp@5bQ%&QkKT#eK`?pC>`sxzlz%K8VoGs#nVYVjYB$DSW$k?1UWg9J>8q6 zWw2NiLkZdGL~W%p|CUoC5l)q&P&s@rYc2Q8qizn+fvTJ{epzIA+XrA_6HJM<d)*lh zu(1*m$>@40MzY(iJDW2YhJ(=JLA%hg9NsxVV^GSW#26Cy7cQ!$7u}ST=lZL0X_UxK z#E+hG;HEbVJIQfd(g|D&zj1fq&?7w(OQHn&eTMnP&HTKj?k1dgE@9;GB$H3s;MQOM zMV<XaKC0Z~3u4OBvG~nHNQhQKY4b-KUtPPa>`e&?#S7*)ULs`27&EN!{p7Rxej3QV zPDn+YeSrRO@o0$!IC`gpD@iMzM(Nrqe$w*;=vy5Q`e<YeUpNo*w7o}EF`n&x<r{L= zw?K#Q5bVhSv=Yb}+P_eqOe>hiF>96{cRUNO9_f^R?w&EKR&mhi=>NnZQFsA$ab}6s zM=69?V%ulyWb~Y7`?1e%3I#E2L*ghiUpiq{Z$TGDWja+Aeb%fHR9QZs9d<sj%xjwz zCiXi>2u3m()%=VvWD7S2(IXyJtyoFT0xTZ4VJnbwu<}7Yo2h$0_7~ilE<;~-xn5|^ zWi$QW1=0s|%dcNAtxjtWy2VmGVYS{Mz_O_Z?pb*s%@8z2|H8-s?ZiK&n}|IRp45+; z)b#^*hA?Z9uliNS=<U1UGgSxs291HoXJIqT4({#vKanphX3CWxRV!-d<1ebSH{$Wx zdV8fdivFzr_yaA#tCON#HZ{6Q8%sm#^e-A`<gm?Z^oHoK<1eh-v;{WIA6bMfyuiej z>uI{0kThQP)o!fUkno`ev%)Lijl|*wzKON{+G)?QY(l3EHj8?FC0T2SXIlgJs8!5C z1VJYSzGV>_xs1#!{z>(FGn2XShF;iUOe?t`az=r6YN0FGb)DE0HD8Ir?IjiYdfIk6 zq5XxKNjHLUlS-0iK|)Gu%-GM_H1Xu@dhv+pCh)gc=r7P}ykLw>y8#$6^>Lhqc+hpX zZFpwHfIev)ozj>UF*vcgw~x0=#^uJ&H(TxHk|<RuoN`%o3KSL**ZOOT&b4P6lgG*c zlE?N-_lS2=@AJw=H2TByaMWEo;#f`1iqH1KW9v<J%FAY-uB{u^i;J7Lm-T-ImYv9X zmj?C|ls6pPC$^XeDZEK$aFfy|I7b-Mm_J4kDQ5$GE04e|Pa2UfEIcm=T0h@hn3~fZ zS@O=t2idkv*&l$?^+FDcA-ND6glnsJsxw*+2(|*(cZpXzk_@f)-Hf617;5!w;QQ;V zvB{6MX7i_%q>N<HnQ#{!M(cMdw&8BKmimmV`)>Qt0>qRfgABoOc{IvZblF+4&;8>W z^ByeIuV=Z2S`BN?(R*jsM2VSEF}?40uXR=Rns{nMNYN=<0<~kcq?F!cD!JTDm;`xR zQX9Rt-5T8M=Kfu#81AyU<#asIQ}66Zv^J>9c8EwQgOfH8*LspZmRa(2gb*@LNR!d& zoRZ)cyzA2x{Wh5D4z!9Isq2`<_4#m7yOoJ`t7_E_6$P|3>fS*hlAI$cdFdgce(WZM zM|H^#OFF!~3$7GqkmiHMH024ojWU*158W``NF4k$Wq<g~@{`GsGfAwRrONe7`At{u zPN&LY%S{ZVdpdD}#|fyGYUd*3m$1W_0|myD>XuPVteHawmXru%-?uYmW=Wpc{Mbg6 z{4twWeVE`qi9+sb?Y!0+{nOQ=e4GLZVxZ>7Ms8w{<E}c0#2t-=wu9ItNNMA1AB8pd zon2NXT8Mi`et@$r+c#}vK+mxh^DKRUtPvd`;}3ui0Xk~c1Y_Tn3pTEbiWfDOHQUd8 ze7B<8U-8*;c`LxlF!M_bW2A+-ne>fG0=~B5**v-N?=)MVAd!K>Ht&W_AT)#fQ!>do z-6wu{cG(N_iN@i73OpC3hHYW%Ehy|oO3bj5x1(w4lg<Q3Eh34vWP?*O)lth(*)UNU z33=KbbMly!_w6HS)EZ5O4e>=Y-<xyRzMEeNJ7ZD~Ql}6Z*|hp+T_L7<nJg|BfWm=_ zGb<YD2l-Vf5a&$ClvhDNqEGxOF03qf1C_7wd-T4!m!A2`QnLOGJB>Q@j4LJ}5}QN8 z+`@KHY8QdVw}^}rLkP@4D`PQ-n}g%`HgSIv&3QPMf8DfhnZCF-b1ihp%{Bq9!EU|f zNLxY58&fUKC(>y`X<?!4#YSXEC`bYR?_V)oVENk=<T>K9JYSNKkReDAOUJ~(jt<)i z58V*4>HHJ>zOkLAf!y7ut9}FCf2XxiaGi$6W+F_h;rZ-#HO+}}oTHZ@){`!bek|b? zOo`Lzo*%9r{;M<Ybr;_~s13loaq0ej#QZfUG1I;IQ4TGfmyLcpOCH1bW@OPIV)W;8 z*0oP9jrz%D0Xj~=)~=GRJ6v1|Y6P8QWV9&~VRTO%Em+=%E^v3AC76t8GICw&mk5to ztmKwtzk9C7{8w~c>OO^rkMKU<m1_CcpH8_n&e|lBZ5sNfj&FAa)_IZ^l5vt{k`tEV zybjtDQq)CH|1u?5i_5<dxFv<&;S134Og?*55bhA141Wtu^6d@x6yZpX21j>tgR|+* z-@o|wCB3_iM(zoid=!|Gebg$hXk+44F62JUQv#mnA?%DKxwrWEW<+!DG)UX!ptFqi z4%$d(MT`#f(tuwkbQz+f;=2BGKj~aUeU^h|_%Ly6U&TJUE3h7HI!&*sH^iC(x^byf zW^Rpi@+e{0bjHtbTpVBrKpTTrRpDw-^$CEMOeeu_1!eoM-&F($tq9sm(zNjwLvMWw zyvFVXSjJ<<V(0m<3O!t$*>_ShAg)7L>5vU`t`;T2$Huq#auTe(S18`*GtzGsyoq{o zXC)l8Cn(~$C<IM74en8?J~%Mhk#19<9n^QyK;}+;V&n!VyUg{<Ae%E^)#?r#;;oi! zETWz)CNz{)!X{FPWweBa%wBYd4+s#lr1|}TJ|g6R>R_q>5zwcEF>>YKJv+D7E}ALj znaju;|G>re0tv07WxqK2%J^8F=r^nXUjh1Vp<rH*-yhR)T%ES|8F-Incey{&<z1xQ zT3}ZTPv)n&0el#Dn-1=}A0W@5P{Px?M_3t|yx6f&G6WztyBBti>tKSHdBrZLc}}?^ zF;^KSXmFrKLv2+gvu)R#dyq`v>-tVpaTDLCQe2QR>DbKp_aY~l?<~Kpkz^sr-OMW> z#|4dK<`0wfiJx{37#mbO)VuaR=MXguI~I2J{6d<lCsEiogo8Y|s)@>B0s=T>jyBDz zmCIc4w5X>3)%4);Fv^=zt=n|iaymTKd_4$4!66r*hgWhObiZ{8sCZ2PaxnkV<%>lC znbiJLqZn>&gJGxJi=uKPJ9Ih7NE)ZLmFveesKzwHX@@HIppfM$SJ*EhJr4mn+pO2+ zc1j9cd5!(ckYTPAAjUstXs<fKm;8@&p{4#+Z5t&d0<|-JWss_?qS4y>I`2>^lN_57 zyL5qP%prMjKPi(ZPKV1aYmp3ZrW3m*V(*hnWi`Ste^u`Knu!B^-zC_WZQL<k>3$T+ zh8&IWov@e@KhvS<*nA99d?JVx-`lq51nh8tY2l=}!HK}p6w@D6`6>0hllVn<c(3gt z5(QgKL?DFX`dpw2-(Y`uC>=uF2C*9Fk#~RSuIl_2;%4}Nrbq+i*IOuxba00fPBZvt z)z#WNT91S1r`1jpaofJ@GM2BRo&yP*0(vT{l%1|yNNb}eAw17hLic<rf5<AWwZ=D_ zwR#h3wo<9oj_XcP>`)r}ciB-ZRrh@NP26;_%nr!qr6s}{GSY+1@JNptfa)sQgzANG zLvme{EpZ#^7Exb0^WKP%!2+rgn<0U_i5WsNKONM~<l*7qIh{e!KOG#qlE2g3US*7y zYt0?rgjCh!wuI(ubA&LbwI*0yveZq6ys7OxPL&6dZM6F~+;B7@!(z4@gC^p6RkwD6 z%!f6@>9~LQ(Ad$b8X(zczpAq^n?g(>)-l6YV20b}T~&kZ{l->36eDU+W{#m0X{CtU zoLrFHFkiRk7Kwes#&Q2Mu!=-rBu1b_k<p?)H%D`{N?C)X-KW-TC57P~N)Hv0kkqbL z&g~-PU2D(6!z<j+G=E1g?7bI1@c$=x0RXuQlp>zKzkk7v+tqUK@_cQ`4Ipb*okm4H zlN*U%txL<WsE%mAZnrYwb47XdhhoOz^^`%t<Drp8qaW5oY}n-?fYLU}O%V=@E$h^; z`-Iu*|6uR&z`8aFazS6(+|;q|brq|xudfr_fYH4egm2geycn@_rc#QfQ%Bc2dDdQ+ z$=ts(=&b4%sNAss^yJ3?-EImFrJ)UcV~Rt`aDm9S&kOHIL0|wGNy4me_C&Ln>a+q! zKE9osQa>69y17552>Rp+b4%jlUi}lU%x)1?8U%MX%nz^(lxeXcspzzYN=P8hs@+Sh zz2}-@lUO|KukOIcV>JNj^LpH$+qzP`!I`@)#`*obj3i}&_fM1e^X^0Tqz2uw1s@Gx zY-VNSfUy|)Ju%_&Z)8w(Atep_J0n?_=w(_iDwqw&{yWZj4+dUUJ-z6QRSXEaOAgeb zcl&t42i5>kq?7XFzh7NQAk*AI7K;3#Pq&1=^_>z3S-ixhRMV2G%0Vi9H|`BRu{4v@ zDQSZ=5u-IJ<7R%bQ;u4s478%3wGndmYAL}dlL-{o8@P<D;-9l}n3EmsZ~A34&pH3s z*`r{~Ri6lZTkd1qZ)$~UAJB1pzGV4VF`6#{ES<+-yOVRZq+Qe1Aa#Fm5NvBL6=OP` z8B*(%YiwdBm1?jQy|TWZiPL>IZ`{N(bBr8hF7+a1<J4=6JuT)tsl1O)K#Qv4^^(lI zWXIcy7mD}udw_Yh%}G>AL7{BJpZQxr|K>dQssl&=zv~p3e~8)byiqGS8u1M;B$vxc zs$43USg}&QbX6Dm7v|_TpLq4}JM$_cA50{)mkPFwETbkPyXM|LA64|4Z{Jv*q!cWh z31<m6a!D~M=k<j^cT@2}m#d3W66~*WT<9@?FRtt)63BgJls_|e?i|`Yxb4c^Kk0XF zBJpYw2^ksiQ3j0utW~X|REA|jdHgf@*)wE0DSk;xyL6Yq>_sTOx88y{gX{3Xr?0AP z;pGM(zEI4?w(FE+YEWw8!M);rcfeomLEOmcsaU_Us_v4jZhyCoyQcH78$npBGw!gg zQrCAu6&txt%}xrAck)-(Cw<e%E8CV7Xt)#jK7nHzRwwRWECyELTFvie4vMuj&qO>t z8M{^<A?azCaa~TD&}`*|3*7P&_o~Rd8_hysL3$;+3CZlsIhH!B<|Ld)@Y}P2pZ8?Y z!ZK1S!s?J6uGFKxqgD@)kY8w)O|V^m8_{$VUY=s!d}3Y!=w5jNrAC}sHpJ2{_}qBP zm5_b7+<CqK=bvzsfeJiM!?O6b4KoQb4}hj&1C%6ES>?|AzDS#`fJB*Yziwo?cY%0K z+A7AFK(2<C)?fG~xpNR-#OcJuU-=|fsY2G(VpT3wY~sc_vI^S{A6DzUiH*5jK4M03 z>{A?nrKJuT8dsRjrh9FNU`Y^h@{5aAe?-N^{(;DF`zhOha9<;({Q+AiMC)T%>qRGe z1An_er>2)yHE9wN6&+n`Xj=uYMfGZ@7Z`XM-N<AgZ(7lhMJ!h%A}SP=s%?W}33awX z|BFn>AD*#pxpY1}IB3Y6g7u$@D=8fp#NdbTmVZ%sxhTI#jMzaPCQMWJkx6kHgeAn< z(?YzNmL&+wwo7{?fsZVt@xSiYRw%4pn8WxGrfx9&`6@?%b3{_iG}L+Ds<ea07DZ2A zzjWR37&ml|1`-_n?Pxw~N(KN+Gw>`|mXiMaXJHs#>M}Fq#0Y)xchwIdrTyn16uw=6 z2xKG0ZoLuuyO4O%?z!W}b}1WSgF&~+_=Alm32MoydA7hQgzK+dxO`GvEyE({Am$OF zqKa!YKJRfG{NE-*r>w70K;Qc+vzXC^54W-B&cs_g41zjB!vtaeEsl~=+ab7sgfZVw z=Ku@)#@8WI!*>Ey?FHjG$uSFyjYeH9gv<D4rx(fj=nE3lZxHBS8JHl;4i|%k+%fUn z1M}H<<Oi1{o9&mlk7JK&_v3kqp6i%N+>tLDr!Ag^qB$q;m8c1W>de>Y{~7M#!hlRd z4|1C2`{zoha+tLd1e`ucR<`|l?uMQhF;^8=^v%q%T}pS=u6`(QTIX<NN!pC*If0rM zR2+u_Ww?DjA}s3wP`cos`-g}8R&L64hJncF=;U8WM*tg%Zj^-MR)lD{huO@(PrXia z!dA&55`l%OPhnwB;^}01HW@H5vPHSz6Huw_(^>y#g!>D608*~r>I7kx1~(~;@5|zC z(hNW4(qf?&8JZ2aPa+|>1#{sHIi67iqZX5R8pHZbm)`5;a(;LkUSZqMFSYZ1K9XP? z{9m7qrFEP>&vV-4MuWCmWxEtsrnYM2$4ILFVr=LF!>7WI_m`^2`51Zalq;w!kWAv@ zAy}02giE8e($xi|PzYs)%f<587a~u1w1U>*R@IF`OAp*72M4?<es_Dg;lgnA{bqx_ zG$8~?{wfd|6d9Ii2>AVL&9}7P&jB@qY5*>?1SY#Mr^|gXfH$V`e7%7vfTJ@_XzSvF znsXOdsnMq7+W8S<3pb$1<k0cb4Ou&}?`%!12h_h4Agj^eg!l7xI&(O9SBSv@Cc)%N za_9t!)|Kyj&G2Y_8}l(0<;;Vzk+iCVIq7mc+IBKMG5B1fL>BW#diSpEMug+N{3agy zsfgmxSt;S$;g<Qi_1sca_D{#L;DD5rMaaO04tMsmB|o6q;1&(oFgr1hz=_zHG=Gd( zR$NZf4Y!Q7S^uVR3OAT-%(=JHVqRIBXsX9YR;#179C6Y|NXg(hpd5NR@)bkK!*^`h zH6%Oac<m>~%Wzt_0k5fIgqIb&k9XJ*!<}y74u3ofzqBgN>V0ChvxdEC7SzH6HsBg_ zEx=wt{N*oBcs(&=u<ijf{h&!U=hfJ5cC23G|Kz06Ku7%=u0%yyyZp>fsX%MeZ%Ue) z`5mzIdYuX%=K!aXs%MjMyqdN){fbV57@E-D@RlK^x1|BQ?9>wu(k-@Ks~|do65iag z$M$9$li4y2#qf9^Kh~e+$#ex%(sE4lztk)j8esi6cz6)tS`pU;oxfb?6lW#E0v5vr zBT(`2V^55QIVSlEd*5fqTkkfK$m1b0bSsSQXMl0kyO-Hn47qR8SGl;s3p*7m({yP7 zW+P!x`ea@1ZBetW>cYu_KpqP#&GK!E^Hy3mC>ayg<jY`FHfUw$yE*_q?s~vzkf80X z<RV@_L+%WR+gkwvcQqDKv8cL4O3&{~H9s9pJQY5AYE_9_R0%27by#<+Q5}y2pM+HT zy`6-KMF5RnGqgNwKuLWEil|RC1h*c1{VoU+!CwM!cIC^tc6W%%;qn(yd%YRz`+dPH z>1h?MJ7&1J$Jx*IgA;6v-hW@~5>WGEC>o24#Jxvf=%*Gf%4|}{heW0r)gn>1mCBzp zm(5j+tqBwN8&d05KWi#CG#DJH()RppH89bdWdzHHp<x9NYx=Ls7x^~@aVWOrqhLjB z&9d<~IVJKqyvMy7oQz>IM*QnCADT|KA(%2Gh$~;EWu{}4oxejsBP)>>`;!&?7AoBj z>LxAy4RXezPLLg9c3Olj_Okl*>+QYtI9%SmvGK}V_b<c4Y&2Vj!^6}*;>J@f6<nOz zABmk^T8zaxy4f|}260vz#kAp~=HRRGPOo2@a@=eNy;AD3B+s44WZf}#j&%E1eJxC) zR{*{gah4#EC)zN-%Y72vaQR3hId{g8`9u~3X}oKuwSt$hwoo-?cy#n~=cYrY&8zql zku@J$z*v|+l@fu|X|wIpIQ7$xeNz^{U3F#0*)U;?L^Z(5aZI@4?zmyog3$JSJCKX% zm=htocO3^)yqG{5xs^K2t(G3<sO8~`$8vDqPeL>s)aodL0i}H`u!`5x!WIzcIg1Qi zqPJcQS2&Q7VYzgl0L2h&Jg0{7t!P{h3vYPLfZAM2sDV`LGGTf-enK6YqC@B~3pG4Q zHXfz<kXHq-s)`|L!Xd+C&W{sp@$UMXT=cbgg7?;`<F(b4kc1I5C60tTyr?5nM)G^+ zPpNzj4hfdd)5Jx7Eq~|&+^UpAfIeop40#S_%}-z;K)hEL6cHhQ-EqU$_LkyOyAhf$ z_074~<wZWpS%26!!$Y(5HQ2MTK*zaYR(||m6>V3xyaAe+ly*vCzVFmH4cIsaBsy?P z2h<LA4pNnz?bUWblAsQ-f#pExsP$35c~+Yf>^X^zPfqK<H=+gq;@4jE-vl^$+;?ng zA4Y5zCInQi2Kjsy<6@mynimTOnV2ZGZ*tnD(@amt!>x9S8^JpJ6`5!s^>D0mxEXJ_ zB90moTbEX}*d(^M=%?nCVBLkJtRs?%1+GOt2Za?e@t|#U&660u!LX1ZE%PhRW<1hB zLgoOJ8>u@#d!pI<hm&ACeg=8Dbk&+}3$l)&lQ{{AC{J6;PM_Z&Hxr5Se6$_Um#Ne# zv?ACx>Ry7r@-h>q!bZBl%2drg|1nM43Vz5+gsbycVzb#Ur>9hHZ1)jVYt=WDj`O~3 z(<AcO<EwSjW1WgfG(OZCeQo^gxCyLp9RB?1?<AW{q@1%?gzN>CHP!tOj1cATPyYwZ zB!@YSmE~7)m?FY0!VG+bs^+ra4maL`uL6cF7M7jDfpyNCpvU@0DnN5Dl9zovCJON6 zO0qy1dYYzmHd!=Oj!3N}BrtJ;f_{UfQBP*@irXY|=;DNfgEwjL+-^_XoD=ZkR~Vd3 zYv+~V5n>e6X}T6)`uMTmuM$Y7(hjUFQF^qI=LN*5XqOnoT}EA6Xo$ptRcT=J_`UYY zwaGr54?PEeO5{6(M%>JuSy&#}i=G>pHQfkgzCr|#qs0Cw+0-h}GYfvUk+#y`?->dE zr70Bc>u30?G%j7ARwnUwxLrWC{|X+Y2RcT5os`cVOS~c=$m07K6w1X0Xueb=bXC~U zQ185FWJDB>4gvWzYmh_DQ_(!Xxt;mElBLV<Y|lTbPUWI#lIPdi`Lb=R`@0;Ud9TS3 z2zY%cp2yglM0_0f=!{qUu<kQ4L5SN7X^SZhh}Feqv?`tRzAbrW{NE!c*DOqb-V}Zi zd4e<qj1`{40oKnb#a&proP=e@AgvzRQ>_P`$C0STc8l<O?B#EMxPtxac4ecLEdp7_ zJNFgR1k_Y0rt4J^=AJqTR}#~|aSe2K-F14tUx#*!p)-g!4fU7SeknSldh{M<)Bc0U zfnYnaOJ@xXulI99jLs`6ac*!8m{0Tb3S5mCf*8)G<i@pXR15XWMaU(}?S*7UsAy>8 z%JTfQ8*Y~=OBL12n29K}Vm<fc)UyKQ#t;<Hk-moLF}<qiHQnzSop<ll_XGIf5@vy~ z(dGiYl~;M7Az%MNMd)Av3oAr_npoc$-{4S?tEwG@eykMn((}=!@l4&A?|YsY&y3K6 zB!&yT1VxE$&uvFo91GB(=}@?Bd!Uap^2k~5AP9evv_X_0GMi2&NL6;jBgQ6JD3^`_ zD8Pp-jde%%l8I?a|1ucYf97w0R^tcGxjoUWGmodU$$jj7UOpe>2O15@SUQ;nlR6CO zy_I~V=sJuzS)9uMO__R%4@AX6=_7VoDs;%Mc(Q<(Lns!@I(mo}50aBjT(#`bt!b_i zjLzl^e4h=ww2T7E_eZ_mT?z53v=wUlq)rCLsu8a}zMqV%uJ{Q62SGBmnoc<^VgUnb z_ghs<QF)u_vYr#Ibydo4I$yhgfF6grnajdd%NWsXt+ka+N`qO<*fj19RXpIB(_V@y zDk{R*=9vyS{cXw1#5CWyiQ`d0g3)vJT97hHm_1DlYejVgPjm0}HmMksKmrH${(BSV zS8WZQ9;F+7hg3>Y9~{J0d_dqL*b5^#6Sy-zOB3HKdU&5U56k4<+M3eiJ6yTv9wu}) zm$1=IoBVm*?h&H6o3yBKw70|6RK3wV4(e$r9COVa*ixARfxttS8r=J8$+DdWVh!z$ zgr#Q;UBcUC>5Zb1=jSWsTAfwR<yr$GpK@f~DVeft(yCfpKMyL_UE@8DdHIQv0GqZM z-Rk#ZCkWfr=28Vv&<38t;2OMTqQ!il>MbPV<p2ce-u;_6Uum$%#d6jCAWDy#mv@HM zDU4g1>eW_<y6<y?_)%hRyLL~iN@aq2BJv7>0n1af!+-OyK*;tJ<MA<F@k{`gjT_(f zE8x|ME34z?>BZBH3<&$Ml<{Z79gu(7h#Md5A9BgCoAsB}*B8j_?~WM_Pp+Li1Xlmq zcgU@<v+MXmVD;H;&UxIBD7ZrGM}eNfT~lsY6h8o{<pnBH@(E!9R6uJayM%c-noofJ zquVml$+5)B^H{uI1|?1okyrZfx>G$3O)fo4s!YTCzoiUyA}D85u@cMVGu0s1g2e<U z)mxo7({-!4A`(hYO(hrLwbUg9=l4fUf_6#<>@$C8F*q5OjN2m0+spV+N0YPtkfs%# zShLcAM##WT8iDMCV(j$?tC}8YtoQO+*N=hdX=_Q5ZJl0$7tSUP3mF`cy(to8joMFV zz8iBYTyEPI0gN5l&qCU4<AmL`MrV-3pxc|yyF)|D8}n2P!aXIR`z$D-_jJw3!|o$1 z6N_cIfTuX)@mc-fL)H43hEnYQ<fD0n%f9BqhUVy)x6{9J(rIPQ7upCiHX@yl^bu`P zEG!brp~n)CaLJV!4-8mH$Y$m~xo%VpZgippcA;qsj)+tOD2IQwigwB^SL=etdi7aO z_o<#>vsuUgy$6Z*8mgyez?g~;sa5|TUg?3kp}W$MK`Edkkc<<)t+F=`#N~E97X#M4 za?t?hM}ajrp1Tfmz7<=Mn_q#qapZz1Vz2{7rl+M<L_wZLatNS-esM^;8cNj@e7KIE zF?tBHhNFq1WvgR;n(g1<|Nm^N*R=oai}oEo=)+(#6lZv``K+vd)D~O6abAKY&C}Y_ z{%qaYgr&AwA;e(^il}#$YwdqEd63vCvv_HdAk6jiODD|SHgr%Ltw<RbgCJ(FewSTl zNw|`(c<vLOo+f%8c8U<&9T4jUSCi&4v4mm5@i>16jvPfSUS?@XuMl&V{&E#KtC__% zig$=}tvg9nQ6QLw4lwS=@m6m&-ayQnyZ`nV^0?7odl|oa*>b<rQ`<-V2Lqo6BLJpA z&rEE)+3LW|d_R%NZcE`#K}ib|u0M|vA4NF^>5bV-`6XsCX#z4l&#!Ig3Q++S$iD#M zuL)F5@bP?;C>-`oX=eas(*wj;MDHCausO+W>}_5$Jj~?}wKepIZa7-3V|2B{4zY6D zt5NsZiF8=y_2hcJ3)`e)iDWz?vgic1&tVdV48J1M94xY;S7{W<Pod00fb=gb+JpxN z8;?4mRqz(?g0Jj$;70$`7$aqv`~#2NH4e~D<P-NHb!=8#A<)d?D$b)gzT?N*ty=p& zXG2C4+L3}!5ZK+X#g%m;{?A>PH^h_eU}cAr-^N1wFGzHDUZT+~NCL`ydIorSEtb+} z?)CAn_YyxRY_E>YtouXpzR%H5Po9&hecj)_G{zsHcuon17`775l2r8cEBv&#U-o;z zp^@#bRjShNTa5Rx2mhF4Nc7QJM2HScE*8LEnR4lvz^>2S`-o%Ncife~&o}%ie?D`6 zZtgD|<S)JizZj}SYotznvmmk{@VMaZWr`vTVxn`lFWe)HnL#q@wyqN=qv#@FwwbiA zr#eu1Cupj+UgkIIMXXv<$T7QGs*`7qH9a@TVykd`weZNPUye2TicF-2caqX}{yctn z{_&<k+-T-~o_E}tn4piWGJZ&$^Sbyr`!dnf#Nz<6xpD&|>NLcNq5H-7Z-L2NSP%wp zHa<N42rGYq#k`ziA6o46=-aw7YsSLs!J*AsEBtMSueYjyEWic5@KK5l1sIM`vM-pQ zCOO*MPRalG1cUD|1W)`74pM_ADiT;(iR-0?i-Exc0*uP9QJjb-i?@wLoRa_$t@t&B zhtZuzQ_HxVypXTLNwB*~=~2;an$(>|Z+Bl0_}f^0<dXcJmKwdJ9xJO9&9dU(b|NU@ zNOvLQwD)VEvEu>lV&F52XIgy?`iYCY2U4ZLMbo9lqcU9kNdu7h61vUDM1P15Ie2Gj z&44^(Z8u0=z=x>tXRvGTnn<3*8b8<LLDi##WD;<3uhmze0ucGPXih`>&}nQzb-ExU zmQ8#y>!vigQs#_gR$zv8`~Z4Y!=`V_f<<RykjX*-<VC!=99o}mcU)w48np$+F#ecG zSiM?j4oMN+zy?oHVob{0#*iySf*rt_Y5!#ErvuzGxeFmsmlH$lp5@k?u?zkSy}~8H zd>xqAbiaxNU?A^+2d;0^O<$@Ut?^pe-Yl&7T72KN=c>cDce;7IQT?bRZNjwazod>* zT2i;AC%nlrQ=_&OXnthH<YC7DOt@d3obZ~yd7j$%CEmTH#M37p*}SwhU3pEU%_NO_ z?E*EP<z4X!S{Dq|0%vp+N1g+J&lX`vg0YMUNW(IW8B0!7DH%V-n+X<I^_{<u;c07^ z&^Q!%PXfyUe-F8n$%Rz~<lQiOut0)^|HV$trcwFEptpspx3<Bf_PZv~EVuDn!*kgy zB`3Xz$D4cLiQud}`o${n5<D@m<>-P0yVdL66YjJWcx5ZH^Sa+Ra`?s@h6GGzQ2Cs< zk{Y+6f;$7*XM{#Z#;4VyYg%er1Rk%XcV>~8ZBCDWrE_@`*MPfHOje`N_mz<eqCaeV zT#5vu39>N|_G}!GpKItc(QxbV9sjvr^Zjcxp2=mXGF9JKR7*P}*@sp~dfdPxMt(n1 zw}ytK)~uk1kJwqK(_JtY5qG_!!g)?MJc6LJE?+N(&rwIu=g91S=6i*I9=*fxG`U*b z#02$R>mDGzcYD>(jrV);`;Nc?1&Sr-!{xmie%OiutfK#dfD9<uw4%3#=^}}bTtCBZ z!a{HMY%eHm-bw`y2r5~iR6F%)1LtrsP`JSg$ec#AtxVODox}t`uvwSR=C|pJ|Cg4) z1+%V}t+T5XeLvyx{$lBF|L6etgSBY(Wo2bN&TFQX5MR{{KKb1`vB3!}+yH@XRaNo~ zE(b{soby=nY2|NVfm|%yl!2=%N23cqN`XzguD`~+_iE}T-MvFV6bIb=p+m0y_6Olc z5qIkP9=c+~V!%cG3Q^+}Y~(XKf!cG(Z^iU}(2-C)_^~m4-*vf-rpof0Co3^2*zAX0 zZt_OHf;CAgOI8x?+1$++B$~g2(5huMW_R5HGorThf&YCg?g*dAnCtVceBV^_)qc6! zEo_|6KEU<$(evTrab8Yd4k7yw{TbQsSak8QL%$UGKcfN|!49r3JzlUOMOqHjO$`)5 zKsa}KTpXx(W-&dSG%T9Tz@oEj{{gW8G7ZVu-JJN2(-s&M7#4pYTDmY`qNoulv^Ow< zy%Bt&M26EMXN9P8uqf84mXqBMg#|jsmudsX#Kpn~OCfsi^GqGentbn{LsN~mXR8kP z^b8UWcJyt)w)zHzHbXhRFYaLP*}Ims5Impro}qR!C%7Y!!6N}6o@3!7!3=+%k51cR z-*si=Vve97NVha0M33I+`U?kfnNe&xft;EyJ%z{p4b?y16*}habB~-t%w7&eb|ACX z<`f2C4xr4>&gQ+qOjKfrZ=Ez(b?Hv~I;-(<yzwE{-OfM<cWp$6XdumCMNn%y#uNCa z5SD!h@xS`K-KY8qo&c*5S>yUt?}R<Q%l|yiG*;1j?>($87n%|&&hW6mI|lhUJ&})Z z<@|Re0)+|i<z6wbS`1q3%318@L(Y0%o`Yf_I_mxg?any>)rdy=&Xmz9NJR9Rel@#X zUtAU8da?l@pH?X9D(Wt1S7EeO1Nn=g$94kk0sI=w#3;x5B^pswbri+UalxQ@J48G% z;_oz%M2k^t00A~Ghb41otO~9ng53DcsQ*@|Un!MqdW{sk=Gv6-p{Wa+lgJ5abqm!G z)Qs>X`J*F3c54J~GQmaz-IGm-w5MjckUh^_1I_(v*1xY4VsetZu0-E;B3`QjTTMF3 z!oo<#t6^SBR3k8tB<x)k;ccOM!s>Cg?m{#EK-WK%E#x9|AJp)bD9?+S8pYy&hS%oM zrK@GvI7VI5T@r8oY#2xtKv!czjqkyz+wKhgJ%c~GdWv+ND+Q>nh`Zbq_*A94%W45l zdR0I$=1xpVAH0mUIiVkh`8~AMK8qg#bbZtbVXEkyn0La#>xCOog>ww=;*4sL%3rfm zh@96+)2b3L2Q0fRw*uz9Ji1e@4+74kE=J1c|C#mo-H`<zTmg<idwWm~nSz=cbzw(` zdIK?2q}+cMi#yE3NGkZUAY{IB<fpqzBQjv4STC3qsoJ7Yb;>df6QXLhbF~gS)**-= z;HJAXAS55R<VYvJR5Z?;RB<uDyFgX0Wnu)?1ei<^yZEq7D130A7=G$~(9g8BW4&gT zqB13U+&~u=;HbYo=(e;#RcvXdfEf@cgNxDqSz*4Skp(~v*wB(BF#9UP*c2z0yT52X z&O8R#=zk~pxWM0Ykum0oAHrl=L(j-aj!5)emj6qZ0WyDBZ@h0ai8vB3Z*Olu66b%f z`@F;d!4^3<O*PB;NaDF$b>Q^<Obh+f83pZI1H$pM`{4)Q665Avep6%e$z@b^qb$v$ zPeDmsHU1U8?C`zmG05l_Sy@MPqU;Fdtg31%_**aNS?gq3uke{PF%tOeH{;Zf=ZWsy zx}CRbz{}Y}=@I{T=?~n`WiG`Gu{d5b|Es>Qe2&L4*tNXI*OCoMpL)c9FIE2qAeP>` zu^3Jj3GY9H4YQdu_1dJ%53v^xdXnR|Ll<f$W9w~zca%!ZYQq-&fu&1g@=grg*elPd z2ZF#s;K8~5LoJUJDH~l$f0%=VMcp<<<SWn4(o%VYJLU-{a0zPoF#(96*@?fifg-dR zv3Xg|h-F|p(4r!cl>oI)Unh`7og8Q@9u^LWf<$uQr;a4Ni3PSa2gLK-DY_?$Fj^?& zfxZJ{id|^2?7&DstOI^ulo8F%ly=(VCovS02M!ce>z*Hs{nRPE3?-$hl(Dlb0!QqJ zd0hWc7}7O)%wzA@W)U#=s3Xxh06{nmq#-<O#@}mzQrVxZkwgv)d$_su8ylwqG(C+$ zBW6gm7KE@n>CZt&KbYR3=ZLthGpZgoQt%-)sUG`h1K+xOMy8>ruWsK%vyInLIXPbP z&gWE(q_A*TJ%{&U+%SaQjlg2;!i`b+4gP5XC44k|YsrHH?nrm&F6k9Oo9TGHDH_~% zA=o-f=5Ze}l8i{~#IR<ij(BUVPv9}xI(q}e(epVzaX*HhlZ+zITfF!1eNW$0zWc_U z>!Db+v-39H0%%&kW1-<sDi4!OeXG&G7xU{w>d#w8)ql^kUM6_^Pe9LxcUo%AI|5t# z*^|<+$%zU5V?ynVYAJ}lQ>IqDH;!Ga+*;O|*QRE7X52S(zZL3%sY<-ltgv4K5Bs$d z=oG?EfST|)MauYbQHhjBW4{KF5e%#<%i_vt^fJO3HpXy2)lm3}4#h+HV+5K-ANdWU zd~O1OGho3Iz>>FjS6A!Y*g}+qen7imNCaPjt!8OX53;JK(NYTR2}Rbr>CUEBO$;O# zwq%d6VWmz_Jm1IafrTcZ*GoK*R+fU^Peg7KPK`TsZcPjGCnKZz0>)k^<wMMhn#?bH zqPa>tJ~fPOSC3&f>?@A$UqAN6=9-g|wsu$#mTqSV%3hiu<h5JHc$ks&g~cCBwUk{* z+`N0V<01xDZK--;jnJ)DxznfOcHNcRmVe))>NP9HER=xvo&n5yAvWXv8>=xeA(V&Q zN)m;BR7zbcCR>c3jQ06O?d~iBc-NtH1s6KrdYCH2MI9HZns@5<H8vKcCst%Bg@25u zKRFrM(eKKk)S5JNTtMd)p`>WyR$u8P_NpnpDg~|cMGz0Y9lxjS8zSc|leaMaAFk`F zs(Uy3FN_L&*HOFAVY~4fpQj29xH60zctek~;?yD(`W6%v6qvlR)N5%h2ytyEemT(p zj4>AfIS^yyDVc3|74LL?&MlqcJ8HHlU+dX%*SE=1nXI%JVpcYLJ6cI`H5jLcG^=u7 z6!^8uu;e+=4Sn+4p7Ns)@`HS^Ssva_g*SOxv%v(QBpp+3Y(+RI=QjmY9j)pjG?*hP zNyY9-(URMUcBrNW!}9AuzvIqDc3W_Xs)4})XBqzjSczN~P!0NmC<0EH30HSVq5Il; zd|f_>+I?+|PG-ZZ$q}X@XI#V14GN=uu>$1iTLlFbG8B!X0?6F@wj>7%a%^d9H)1*$ zu;nw#a>(92awom5Lr&-lT-v>ZU2V9$0o2V<;7}+jF$Mf%TMe?h!`I@-TYOp2@M=|9 zj%Ck$qTeD92`gSH;|><0@TdL>uL0j^A-1f7GCZ=SUQ=5#uJ$LonV>7U(=;QJnS*gw z5L^!(YRH#w$89G~2?5FE>0)9dtll^^taJ-ggF~|KACR|3Y-J<fm!~VJiwzMhsdT!b z;P1pT1fM`_Z;qd<iY|S->R4nypySjI>TWFzDthYbVV`^Wp9uc!!pp@_x?EgHPlu6d z67ILVz?;&9<pbkUGKnb4ujfIifjW*@_JE;L2r*oGQe^f=EVreJbWI6^DL(NL96u<5 z5An{LB&`@Yz?k#`i9NV}-euBE898{w>LL?@P9pwaf{cg(2m(;F%Mmk&F#Zxu=vbJ? zJ8BG^cf=brvl9~oSELz>JDM42D#@@0zQ?CM9^ylHe0Y?sXfX%9E>$E0y9sWDW8IBu z%<tu1fu0hiXv(DY82ZP$aF~|ek&uIuy3=)>ZUIwB<ZwfH7l4kgo6^%9n58b<M}D90 z?i2?NgOH*G-%M4t35?l^!Gl5dD<9gk0X^`RKBVXLHdv?C88zjY4QN#~I#F9uv&0s? z^R%LZnuMAeHjhfVYJBpb09i+ah@8A=0u2)RJZd*BFSvq;E?@?yavA*Xl_a`nQRQ7$ z9>9$<dPFn+rCQw{_6ImTDmMC}A1w=m1H2XooZ}cK#CWunwZm7sYjK4gL<F(oLsF1W zo!(ne&e#zHcw};trgFWlHNLJj669{lZuaB&Z+BSWIVAIYF7dC>XdiF-jFF>%pbU`Q zva2Evc%=^4Rs46BjvA@I=aESkgmi+f!Xx-5Z#uuK-}x540$0w(UjzHV6(PdJl1!x! z=vrw||9vEw?wVn(EM?ktfv=R<PQB05dke+ja8}aCPR;^nuxrz-g+(^;_55sq+(+Aa zD`zybjXBNmQ8%%&a*+qndjMDFl+$;%rcM&kIGgNu5H`jcU>;nu{qL`ahPSWWdmX5Q zh}H7AG0N@q?A8}_aF7$=dy$C7*-{NH6N@k-9Fc&<<s8gvX9|y4a=KsahM^pVm%6!a z>~!-`;IqVx54bDC*-)d%^&uda<@kRrfJU`(m_03YY2Q2<zU{h|d5;#H8M2Z>CgzsB z`w-x=SX=6Z%BVwo8;}YN{Z>Yz8y&2;lyAv$+OdQaM1f(2P?>^Cu<Bx$qqc1_+x1c% zw8w^8KX;|=HU<LuYkKjm&dk#<Ok|2D>y0wFFk;7|as^AN=)IwN!6(E+j_l8<RXzSZ zZ9ST2CrF>H^!mN)S}*}={Ue@N)s$4!UK3)l+*xRi-goDx?!Z7IjU)?E?F3pE7oc3& zbLOcf1n6$eDgsnBGqH!fr*vdUC7|Fnh=JWXtx3}Mw`Qzfl0h08)vV}QgY4Ssrmfce zYc!oKBlB8)6A4g!xldw$19#qUSz?gE+gT)mTVTpwZTzodFHg^>s+6O~6#2e=UXIz= zmII2)6+)jxUY~PeOpzZ~TY897Xe!<(AmF!)c`Vl6fL<VeJ;7rstzK9-b$gYU0M`39 z+WJ+B;IqPC0rb8ku2-gl2nfEw;EA4U>LzxO4zQMOozG4)yg?K=rNtc&?VYg~1?aH( z-p<FuueYUpu;MK`?VC{&IH}1mseXG-j*k>y1;U;(>Ik9LA8Rvu@y*L<Q{29nt(SfC zTUh0woW5h7h^YWY)wo;F2d~D`!qE^qKO}m>)p*d03I)5o{_8Y=%L_n~Wei8zT6N?f z5jNUYZDj2IH%FEQ;f<v*QL`RzNCC=lg`1vymE2Ze!KR+UJ>b|yUb$ywrntPx2{DVA zWQM3tJg)Yy^V2Z4(K)P6LsbKBODk_ix!&#qe!^=is2<cihhG6fA)Au9cC-0ecKieA zG{4dxXHAnT1ZZQW_aQqHG>trwOx!J{ufKyr6sXl>?Q9;DVEW{?ca#OlPNf(Qgj?hU z{YY!Y-`m|srrR5&7l(;e?T|3Tyj{l}H{~DEWY<5sq?|s<H=tc#n1`%x`${Rx@%ujp zG(>iKrwPq{lpeNzA-;v3+rWAJY}6gte~TIkq}vr;k@MJb-47L%>n?|O+Af40p*_sB zMsDlli9Ry^{?1Y+&%cCQ(@Ly4cn!f8X5xyVkcIqL1lrE+;UW=Qa%>{*k^>idH-yt^ z_b4}-@;B~M+{<H)>^<S8aq}e%k<>pXmz8G@I<R%pj84GG!h#aWfnLa^ug9rVfj$XY z%cYLR0sJ#fk~tbS3*F7<3oZC$T$vivCmUMjY(f*tie8<&9%vopkw=E<z;U!OZLUDv zEj|l}CL68-U(nOS1Khi&qPEfj+5h<$nK&@UpOD4>L(?}$$Mt?+Pi)&pW19_{hK<=6 zjg1K>ZW`NGW81cE8%-znn|{9UZ{0s;tyy=ixpU8b&U5ZQd+$R+1((|kHcF(GF`@6E zd{U%pC*4xJ#@Mt*60yL_iN|A}-`D``S4Ua&B6iwu`F{HJDfaNtS|wPdIyxaT$(c3) zpR>8YVb{$r*B@I)?9n*Lxl$nLjTZlj?T!Ydj(|Nen%HFMLL_w;jzHxfRQ#6)!sv$Y z3X^XR=V!bTGn+n=m+(FGfy~YG`#ha!i5<b#TiKrxBGGq(^^nTZwV!Yo3Zc=YOHyi` zHv_DrZVzwQp5}QAPe)bn#Id}-1w%?gj}g+x^b$6fw2ixok*pMH(I2L&Hjj%<UCdiA zhrIg+FX4Wll!PA(uyOIN`Ko*di$1(kLEg{0TVjF|PrHv#)>XsFogbbwue>Kd1?|(n z62GLjk^KjO_&39jGYa8RB6rVbL{ZR_?BNaNDL0Ggo#Nx@IEM~dm?COyxwG8J@pOtA zz;>f5NgE1r4)O@PCHBs?*9qWhoWKB%q)On(50}omfK?JKZVJEuT4UxUU1DEA#UqxV z$wIKe747T%DLAhhi)TLI2h{vL4qCvRYK)Rq7Y|XxHY-WYV8PH6$4Jo~Iv69_<A9yk zfzI)LI<4OC5s-({b=3dXsD3cY4Opoe;V)svD+wKV9KRL6iS+5ma~O7S@RQbWTW0N> zyH<fiVn1kJ$4P?J+J59t-_GW^fihLfyYL2ijY@5_`=GGo8cHK^cKyz7=V4lixrWl( zE~)AX`%UPGYbevcDa<mly~e}Em_32m3nrTroD5tE&yIQaJ=%et=F7ZsFUscdi5oL| zJ-}I7S)rNG)V;|oG_aO1q0$p5y)k74$k(A(I2EQi$cV|3OI?j0;{{)dACmP{zzCJ& zzt@wFEg^+%<M=rPuG;R;!=9&c$tPJWm8lajTuicaB6(Rh_&JPPP=6cD=Z%VaHY&JB zkCc4fDX0ejB7EgCfH15ttR&>XDLF`07C7A7UI7p_?$0t1Zp#Eo=A=be;jDP@r>4U1 zwP}jAZo_Q|@`w0igLsl|ZdL*X>uEfSu_JC~qYv6GwmGMeY!QyQ;IHHjfG{x$iFn(D zm_Bg}h>>t3jkdZwNwIKvzbe4JNK?m4_`U<vUww~xlb<*1ESiMgmh%M&5)Fh>v?i+< zQ$5&UUbo&Qni(fXKR6o{ZSEIp?npG?5z~50?+3VTO_I;1X@0kK@37l1Ft;;J-j8|1 z=pHwIS)qkpWpyO?a*}VGThAHZw`E<WV22XNIoMWPJ7VW^-^`B|#DD441S+JGmj#Ux z!~}7*p^}sjsAUsW$lB0_BNwK7zc{+Ugr0sor&@6M3P18u>+gj{nDv;5wc-Ll=0e2t zPTr4<Sv;G<Z`Wch9`mxGj<V~d?p!(|Y_|~@rrF_iJ;`@)X&m&d3V$N|PNp1)AJJuH zNeU;1R!}_5>Cge+qjUpXzJ^tOY*#jtcsk1jBs6?vD)0LPS<Rsi(Vm2xhW|oSO-r^W zB{2}!?rbKrYV`VwY`UpyK(1THW&rJjltZDDX}zN=%thLR=ltN*7x#KXm3aEDAa~QW z`6KWJ2u4y`9GhOQZx6=%=?FSP_QqL<+*U#Y9(6-!ai7#;y?VSkB)%M!EgkfCIsu)O z`1R3g3+!E_^J0OYrcjQlpKZ3WMaWVfBzK#;8tJgCZQgETpnlvMb0hr*(EtA9?8=R6 zK_6HMgtb>oDTDbIhuVY`Fv;JZ$WBdy#oPlu-2Vxe9xKB$zQtx7X0M?$RvIEGpq54} zvIi>y_i7}BMt}n2;;#ZL{&+9UaIns}qpt|l#_umWc8{qvjEoXJB9E|n5L$!R3%%ci zzIlAW)1G~yP8b(Z_Myn(7G^x;gD<sc=Fxh3Iz<r2+7+nZ^k9v>HBFD?q*z33gNGb8 zRcMekf3XC`ASo%al)3Su(hpH<klK(C#5e**yz51y?wrvf3Xoa9Migc=e~9n=6$@Yt zik#Z9eNW?A0b-(Xnz=^uMVa$Jh!-7|fU~emQTc+y+u|ken_gCq5APEDon<YT<Kpv< z!;a^2dpfKlu}#|coVR#Cu##&H<r$g+;i8eClvFUdWy%MZk>E0+Y^f?g8loM0@pNBu zbO1Y9D*FGUINgYZ-OU3dcHT*3D;f-RcS(#MuiK-bh#(6yj6GBoQwqfpC_q6QO&1?w z8Ll*S0_QDSs2K)qC96oM)MO9b;{sCPYy?8^0AT<6K}Wu8k1N73UKKC|z{)tygk_3F zOOEnx<_faFEkLWp<*Zh@=2rxzXQu~SAZP8RoGUT%>*fWgyZO_C7B#1CM$?xD_oICs z;TECb8KjSgGRpskX|F74k*}R0?jHfJw|vUJqxQZA#1n=ZDqn)^T?E&^B>~<z*%9Jc zVRJK(p-H+muZW5JW+z$9VXlI4E-V1!`T4V}q7|1V(DU<BJP$D9-!#w@gtRL8jo9E{ zztOqyk4UcQH`_@1bNgP|(dn~z77%OP=B;aC(}FAsff2AJ1J8oO`+(I9q23=N<qI6) zMB#Y$%I2K`w7zjayZ@#F;?dlpT9^UbX5GYRXx6N-a%PW20@v1Hrej*W+;^^g`<jgI zUVtSCve{|cr=NCqvRB8}0_Iv|@#&^3a-kTfx}*f78MT(-Dl2p#sxC~SAEU9?P5v`Y z@?rsm)i2MzJZ>}XM-|ndU)_Zr;{BuTo_E{zNQvSWcOX`jRaqaa70b*WonE>f6(S#h zViOO7^O{MY&|9ziDtT<1AhGa=92GvO0*;m6Qv5?9SrHSH@rDWGVaghr_0L?ow#mfX zn#hu9Q3GaBeclN&%{#)pTQH4k_Y=d!QW?>lc5rEvlu_T5Q5oepL|CRQyZ;?lpsBTE z<6p!>-Z^-v>arpr@}V)rW}S9VBbm4BskZ%*C!t4b@0{?RqQAwWoeW1_MP}&Ae7;9v zvM@3G+^|T0v%6+ljsR&AfShdMZwy23n!iP_9v3kr*V1B(?=-sY`KgQ3LifquKBzjV za+g)2byAH>ha*#p_rqjwu606nG)ju+3`t>swO<K4>xaXl<k$j?NO8ohk(k=Z^hiO8 zEg#~DgR#fUug#vO4D`js*T-X16!%*h1TpYp=Ozj;)u>C|2gb^ZyM=}>Zpx!Z6<HzS z(taMO21=Yks)%^Gq1vGPPoQU@RzY@f)r~9YT=eY_<^)i^rJ0(~3SlJwgL--@G?x_` zkeSu^n=i=ZYVMiwpla(hCb=?V^ezt>=;j{gf~NF!3B7#br<0072F`n}qBgt3*`fHO zIQ?>AAv{1!lhvfV$e32dT<;WWIp8xAYzK)2K`vGNNK;|bY67(r@VroocxJR9`WauT zPRTP~o_Q^5g8LTBa9TyX6Tx$A>TYO^TX}3c-NfmD^q^K)rr!Eqeyy<!;j5ONGgkdL z73*4_Emf?EWs8D?oP&=3+BaRh&DJC;F)1d&9x8E*Ri*i+A;uB2F=jZq<QRsYa4vn% zOHO4}-6`1;n1{c!>CQ&7@(QZS{7HECSg*3*w9`Cvp|yt#a43E$S-Efz_mX!v+50+b z$r(>!OB#=fQ$d#XWp};SdOyD|6}l3}3m8GLNWLwh3b7af&k0u4)r)N`FS@Y8J+H9v zAEy(`?XC2Dolfds4&}B6(lyl(jWCKC2kig&O8Wl6>LM@vS&7+|FZO3)sp4t$ZH1Lq zgR!-h98T!%Bt;DMkQlRC1y3HjrhKYj=(4QSm`f)>NX5%1p+RA`mU7JG#+S|Jw#pWy zIPzB_#@=jt9ObQs6*v8B5sF5b^`_-^<qwd7DFH^{C3eR8;K(B}*^5bNlVcPyaiB+b z6rh~rphw4ssiQh40B-~PhwTK!)GDH4if&xgrlWUk)=;<zvUN2k-T_8C2iJKXazG<q z{KJp=QU;{2j^d4qht_9=>Y7u(;$rpz9*W(F8=@SAQ@PBEk5-Q69m)@=M}Y=*xLHbo znuyCD{OOG3!a)eo8bYgk_itY0_rqk7<KCq|{Er>17vf!5x%Y##l(SIxzYv=B5_Y6= zaN|+5vtvK=fz2iEX8v0GvlFrWOa;t1NCa!A+fgNCzK#X6(AEt0i18ts>|!#Vh<^h4 z-Qt&n`;O@#d_-QVILXH_vux`NRJXnZ9`@qv9^yzrzP0L$7}KFfIIJO^qrcE6kX=dp z>wV*A0)N9?!~@x`aqFUgK%u3?54RC*SO~)EYZ1sZhEX8}Mo5Oe1aXa-LPOBdZgX(k zD#b0xUpaV<aObS{iS<CF`9W{C5fT=*9^_4q7m<0viCwO3R5<<iYqJS{=cl_n(FVK@ zL8z_L4*bgO&B_%A{yD|zk4R5o<_B`%WG33C*sN-)usmMDG-@(P{>psb_W>WNNDKC_ zlm&GL{FMx0r1tqSFsjXaA~CLN;7=RXprF)gHswUyC_`wM+ULUxpd&G0;UY70{O+F= z_BcG>s-HR>UN4K4f89hN8ugd0A3<Ad3tZoRUNhVJ?*+kMp%6ka;I9a?^p7Tw-f!K? z0oT7ux0m!#0i!M08SnjGZMm&tU58HRUtw|@!n)fK0WH*9K^0WO8!Xp=PWO2e8k71y z3m7sO@p3}BZQJYNK=P*2aUrGiW)w)0a}IuI^srDEesNcR{v}+EO}P7n5}cJNlXEm6 z=PZmrYra*%Tm@uFBQh+`RSuF2MmO8XP&au6bK-G`2eWKWPA7EPrT&;hXt}r<g}~fL zExR-D84t4yF~%8#6U3rK4)=j+dc42Tv5JA>u5BtVS%Cpuj=ey7dya?pGLn4NQTp#o z?~s<54)0I?BitM-wUV6^HM$Z*=>tXSEvuMK-=ks6C;4+YMn|K-gey84%-X^v4_vsh zkf4cpi7TZxC&fnW<dL^kX&9|*fQNVAeMa0ZSD6O%8QwYqUaWgM>+pS5R`M*sI4*y} zO)J-csVqSl1%-VKFv+*7J256-g>)k&PD{PJD~K#L6!zOCnH;ol{2BT;%+H?~;>6dE z<!&S5TtQADQTZ(R1kw^*yUygyivt5vtq;@KxJEnVlM8GoXcJP}9^6O9;uO;U6z}k~ z-#I!xq2p2OYT1?mHv|O7c>2)oh6%Oc6g2)xVZ(I!gv9ogbJxp?Vi?j5#_33sHQzeY z$5qe6<$Fw!z-B*{ZuX;FHkR)R)MRMH#Py={^FJspT>|RunN!3UfL+wfJVkqW2B{s! zq>H_!bH*@)5yieg5$47d3pa%4@y;v<z4pR6V&_=UHWtlabS~B(U6DwEWsx>e(`bzB z@)Cg(>c|gYWLxXBYEl=OxQ4P{(8Z(rnNG_TiG|@~oFzyh;&Wp=wm{$5Kwpe^@r}_j zc=c&Gd`O>ieKp+Dwt+Y9R};G#@9dUAt$o3!hW*-U+!ONvrC=N5*}mACIxxTLqnT%J zu}uo@IIOG2-!}}9isHgfwoajLjhyz}A*<K4R)*VK1`_wzg6;J?$hQREJCVtEhZ=jG zf@;ELCE&|mxi4Zi7IfKUOa?h8JNd7h4l4~YsS9X4KBig?Io-V?I#^qks_V04eFm*A z|4fD$-db5GVIS7k*ZmG<JruyQ+4q|Wy05N|vleg6M+v~>?zTMu=}pi=B`Qi5{$#kw z-)%1;0fkFgIt$TR)&{qOQ?=`C$>UuymP6*PBK3PXFM-kr-vP`d&S6IFaM&x6Z(>52 z70ZePeRh)aZMY}H32Y=OFiB+iTc))UeIC={Z2t?Fn7%VT9SWHh^u16v#_%LuapmAo zxH%@u%x|Qf^j9x6sB6^1(Jc%=c=C3xG6INeQN;bA;N7*0ls%St9yw|hlK;JS@l?UK z-~aHo>F=0er+ni^+@&Mxi%;Z?uHUx?#<LCuJ&bvtr|8rG*Y9a(b%BlDv)1tk_R%d3 zFAWOy69q2IDoLhJ46%QPz($P(TM_Gb%XdQ>*RyNB%R*i@mSpu6P}69u1g@_w)`Z)J zz4ul+Is~IvhTr3bf>YKir~+rB(5(+rhL<26o-@OXt8ctwz0Kd*OD6h?h31vnqzZ6| z)a+>r3J*YErU!9gMXlOcMEU$=H!uGrRE%Q%<*xxv*<T2<L~~yzz1-}}nQfJl=<)=7 z4TCPy6Y$Nglk0Jil4@bWtOp@5Z~}S--7cruTraekf<57TRmyQqnW&WbEgdh<&%c36 zKtxXz<bV2P)Ael3h+VKAs8Y<-BDo&y-192J@mN35XQ2v!ySGpT*r>eHQe(`tK5})H z5M~g1?PxMnvy4xZw}1h`xVX5e#+Y8>Taqy(&1b|r7pVDAjHOmR=7aov6U5^t9&UO* z3lbI-ksur#gwitfL-wDx*9+DU>-aHgr?L&LsysSl2<Ih4EL#0q=MhR1IHGHUf*5dK zWjf1`PFEPX0WEG9Y0_*)_;R!&k~c<BJ}vtnL;wfBAE3Q--U?XA_(ZxfDg#!F_nIb! zHYHC+v>|O0)ou&smytfXqm8DQc-vQ}$LLqrxR3L$m%PxUNI<^mlX+)-9diIUR*+7> zI&BcVx7(DFCFw~#BQMJ+6Ua_gu`>fD^x)ldulPz=H-?qi=d+bFa?UR_(C@Zc!$F8R z7h({6R(>sc)%Q1<x0emggQ~SES*QmKDsv#Cn7Nc&Wqb8ej!ji#JT8_-^a8f=nuRVm z{6-3z;c(;Hn&A9ttE+YVyzNJiC+Ls0h{W=NNx<&#WM(avVH&QEP8tyrQS~>annmjm zaxXdL5tcV6F26ssCIvCnPm<3v?ZLtPFlF^O;GXW~1-+NhvC+8&6J)W5{Cv45IN0h| z^K9@&n?;j!&k0DXjl_(GrqJrs<)1&QfK4dF?*UrpYXEc0;Ld;r%;zV#!lEKb@L>;! z&@VhvCPWa=j}2PkXP1sbDdvIt6ip4a;Z(G#VeD=`JoDV()TF=pU(m+T%Qu%QzYmRl zR(qBOR`KwT!2sTOOrn3^X85!P1phk3uYfav@bGE=7p0Fl(Q)UP@MIye*pi~~0Xl$_ z!SVYd(;!p>{C@aaz7ab=llT|eeajPklB8rWdl^;VFq<*duY!7zZyUO-a-!vJU3bgQ zwROaH7+F120hZ(}7u<f@mEHVFOTwHi@2~TM;6AjicupwcS^RP7jES5ZM@R~>V^Pmt z7=FDj1&Nc`?BsV(^^vPkV0AO*Fb6CHmgd3v*;)KYgS@1>si8tavomjOfO=Pg)mTb$ zcFrQru%*5kIyaWB1Pu^3Hs<`7ETm^|_Bw*KqxxGp(%ZC!0O*_FIb%f&R3Ox;6FWb5 zp&i+RR{intPM;Nmovp3<)l(Q=mZo~95D*d9YFs~5zl?!#e`arJ9&>ZnNkT$Q_;DUf zMMnkN`W7aU3XL%k6%}<yFEy7XB02pjgc*EnGPHo`yEll^f_UZ(Bj%#Siz^Evk^z3w zc<9xHErOh{s;UY-5JV;yVTA(R?_3p}5A=SCh@H?{(bGCSDOMU@`_o?KdQ6(<SbaPE z%7^m5L+B@=1K>$qsH{@ST^$O#tsZqQkqVyNtJx_1g{S*`H(fMIbH{il#ehlO!4W@1 z>ghRoQs!v-1D>x{K($+=RVYkUfn{_O5a)RJ{v<?}=%!Ua)lIU!(a7k87>_MTOGk|s ze-4>LCV}5(#gqn4%%|HA4<$<;eW5%MV{6SatyqWN;I*qSU1%b^#H~wV;^W|;rBm{u z7k&GyR6YC^s@t}xhOJLvLP}|#HH91l*Fcf${QNX-ESdEzK*HI<Oxc=+X<E?DW(kLg z|1k#FQpchXOZ9XR1D^bj|K<zcuMflAQ|jKRC`FSNX)kZ_T;CF^C#^Z3!0qHqJm@x6 zz?xnmTL41FIg<Db<Y<+C2VxVtB3DLWm1{$QwN6#btP#PwQ0;cpxZ4lQVj@JJbbfIs zNP!|Rg!_}S2{%yzFa5^+3*>hApdI~QU(;<VD#4&{>JHYqG``T6M9hF4BhZOlauxh{ zsdAV!gHMa@8jH@bB>zYi-ByI#!ox8A_<55o(&lGZn>U;JZ$5GsO>bU6;hVGEhKr5T zC<9#GP~F9Ax;4#o`{;|s!?lWuqok41xCq{{4wp@nOS&?X$GY|O7jGMF4o^8bLVF^f zt@JO1>DdvRN@s=l$v`tlKw6s9h^1jBA-Q1#*=e|;qp#b&IE<~F{kxhz(RotqI%G*N zLtLO1_f=Q#?XC~tOu{y~00YokQXpFj@Rq3Vo&7Zt=7;qY#EwmxeEFBcQvCJ$>c9ui zFcmAW$+*{;VI5tEcCdhS8;pl0QmJuK8ep9G<W@1Ym|cl3GGe5qC6P<~eX=vJ9T^My zs4zEI1XiPXA)pNjRD%ghE^|?Y(sD{ve4FUSOHVrXE(f*PKD#0G;g}3Xk(`c-U$vM# zqn<zx7r7>1Qbz3d%tXW^@Q=hOi=>>Mp3WPjk@LdUvZ-Od7Uo~+k`j_C=e)=$G|bL$ z2g$8Ek0E&72o@ElYdArgwkBd5f+=5<_*)#|_9?F{3eXhokfW7y{03IPH2NIKa_R%d z5ku=qv9z3bl1>@!l3$eq4_fsPXmad_3gkw&z8SD?RO_k24Mmfvhqu8@pZS#J60`7s zETMIAl<k8w)>Ci(!_Srx<~@!BXumEE!=n}?3LxNe$nxSZT0Jee#XzRwA0}9x-p23B zT1l!j@2^Yya8TdlpwM-~!-A#o`@JlR_D37SDVZl!0v;y3B!DU*wer%g-42^bNXH8$ z)h<RxxIuA-#N?I%(ayBAjZ%k{vk|p@xsZ<suhC<8ALBe%cU3MTbmHvubrCPg@v!Iy zF~~I%k{O5h_xVL!jycCeQ8W?v!B^UV9G5@%{z{y5OBfDV1&8QDM+YXxW(@0OvKZc? zXt<uxr*O<`x!GJkp$*J7w$$MaAXT3faa6^oJ@(gP0)@T+B_wG^mw=rNNE_*8a<L*Q zqVpNWR+h~0?<a%da0m9~yfY#)a^c+HWrpLG1@WbVL^gG|_r4<nQ?){E4<H;^d!Hsc z4-OA|j5A9#9Chj+<HShDx6O*-U&$ZnKo-6@-CPF9wSO(liiQ5W!8SRt4pZ0GM&@iF zc9eYNLEI?*kMGwJP?{6r<E>_dp4!pGoX3FnLPGn>OPynBRAb|Zt0oebz6zu#%u4pY zdGqJmiery!O1KC><gSCE##>1{V^)F=e|Cfx8y~y)x%4T@5bJ=Z?9I_mx3~G9U)@+! zNp19Z_ab6@MoV>d$h%MX$|Zl8X<J%94}jUqGex_+H9GyCm><(8&p1$HPq+QXev?3e zMzuk8%36g(+n#_>BQHvV4Sgq0jzWCgL!0R-lR`QcDp8cIxw?3#f*iF@=&|eY(Cipy z_Gya^w(=;AxIc<VRSn;>P&y4CeCn2T{DhtAGR1XrbafY2>#=Yh0&M(@B~e;K_aSdE z_1gZcao#Pr-83lM-#t&LH_r(jaE~W^Lo&SY{bA)J6d+fGn$5fqr}I^yG(*$k?MHZ( zx}Y+I=;r9hA@Y!WDOFMvsnj2?>4M(@0m^`O?Pi;TzR<LqOwkWpYXkn50-=s;fU&#< zBRvg#;lPcezXjyC&L1(^;GhhFSX5mF`eL(0Lp}oXqVodNR7g`&lWaes#ZKUlYU?L| zX1uh&q}TL|rHfQ(qeG&MfiOG65pxMU0|9<KmTg%A<HZddv`L)WsUrr@xbZ7VD?A=H z2RZ;|W?iAiR#ng0{--{Z|H|<HWEk=vb-}A)mgZ8K*KY_IZ}w@a>96Q+IqiysB7dbG zv3u7$Tz2YT&Ii?7e#sE-X?dnE9y7hfMxiSj5d#RA^XsnWB>dI72lfWOhwe-D$BEPz zejVLb%t0#b7bELg%an)qc^ha<YVZdq#sw%U?N|*Z&2JUGr?@n#!xWMd?Anq~&En@M z+NKd(4Yz_~@Zw=6_VJGVy*KW!nsW3RfveLdFUQo=%i<g@%$aKf|F@y0{M%4_gsLhv ziE<#2dYQ;4C6-&hp!=B6CB42in3y<qR1tkd*!H*5>fo38L@F7!%&c5F`($H|-OV(@ z6=ikC#GfSJ4b&J~B03?GQ3cIrke+yQ!qZ#7<`Z437>hR;7#53mNw3$;b@!D(aO-!I z_uv^u;ob55Ma+5-7;r!9FKY#2G`ZNx1No}R?p7g=L+{tyvbJbY=sos+hWGG8Z8!1J z;Z@>MlrS^J?x6^p!oE!@O9FEmbl}XJE!i9?4R~lv4!TjOe~#D@d?+Dy#T4`xYeyxL zH5Ngqeh0>yyC2otRg5*rAdl}(=c>$vNm|G2TzyLCy4`jCtuOaq;)}XI_XI|Bi=j6K zk&*naQA!5s1vTt#>BK+1252!;6JLD)A8*Nl@Ii~P+L<Iz>*iCymD`C!=omac)!_Vj zMo{q~7v?ud{Sas<OAdA@LP`8l84F1?PSmMM=FwwG$qPcWVEAZ)v8I3;l&Ccp;pP8s zyGU21JJD|lUvQntkM(<8a5-1C4k054GnpNH<En%1|C+tg#Sl7a1OrijZ$k&o_tmar zun*0L{fmrWXWcIcf9jpW_t~;Yxh)-xG^RneO!F|{z-X(e{%XG0hDgmwjW7GY=TzgP z2XXWE<h`P-Nv<spRSciiF+y6wm842a_I9V?{+zD$!J)U`jo*{>a^Q+N=gjGHx6b{$ z<T&&{N{%8_nKejkQ4vh*s;i{+F@flN{3~~hifTY`I>1}Bm52I!A7`~tvFy}vy-SoK z&iq*)_~ygcjeZ<-_C2jWXER#S?d#TY#5}emMal2|L+FA|N&`<=I*c#A$_(AnxOM>- z+FC9A6oR~hfcthArrCP>x)~|Zjaq77|KC^#wNayiNmu|``mZ0E@>-op&YU$mrG8fT zr>`#9_lh4Ez9sm*E$QD1{J(?eGZbL>R0o1hkT`1i%2e%cft=KvT#9lADEXyVwuEK{ zJnqj>LO&Thw-mZ>VF5?YX^SAn^L+`E9FUz6)q88A9A(S;Ax5f_@GXr{lEP7YzxCSC z67W`hJ4tqv+xnmxZ3)pYJrx%c<DL&S;*B+yqW_=*oYXlW_!FDdfk%TW9_M>F_-iX9 zeVt0>Hth(K@$Qm_le0^cNAnumUTlM8$?kYQUf!0g084)V#rU7D!9P?6ip0l=0EG0# zOuQ&UX{u*ch^jDng@eD1-0w{`TweOHu$50&pYIzBo*nWCB<Onlyd696@Zl111Ul#K zQuo5?bXEKD#f1CR%Du%$o_UbJhYR>>QzZ|wSJjU4zH<nEQfWd{93wh<HnLQN%9%`P zeEZrW!p0ohh&#H{h(VB=5-jDZ?7LTD1$0pY5(~{WO!;K4XW$h>O{ZVC^OgMH{r&fO z34%TD>=7ke^ZntiQR$*EyuF_hp)fU;H0hWc%IRckCk}C$JNTKurVCRJR6Md`4OPux zvO}%)+XABe3vHfCLN?8NU$MK4#e0x9JYF<}R@@xai3;2jN~;O>K|x8ljDQ~dsI1dY z6h?ynbh{f+#!YR1_$`Ez06#M^w*-d2QBcz=ysmop91?KTo&ceD)Uy#7#vyoBUb>th z`tdN2&g};M-<ti$IBdou%sGR7Z?2w2rnGfIQ}}B8HOU)eac_7%P7ea~mIKs6tex9` zXr$z?ZqO<<5{{C@qyFXe#Jt7@KXyA(*2f`0Fmp@<-5lD4OCfZU*Y4vgNm++sxoSX> zpW?vR1o#%!YI)^eWWX8i-v?1!XIdnnv<dx6Bd@ZqKJcv=qS>7ZVi<{Ovt|*L)3SIf zi#1gtZ`a2Dkpw(VZZ36P|6@h|yUvd*g(JL@?oJu%?;vUT@OnlZt$d=i?SPNv6EIX@ z89|ekkg7~Daw5mdr_Ws0Wx%<Tn(Ph|c}v{4kTp_lbusBRloChB-FI41Nu`s>pNng4 z1{j>GY30=wvN0+!4^zk!n<hlI{t|k8y1xCvEAgv`ijh;n_hg2Fpxbodsn%v9J0x93 zUok|HO%38og0WuHH~mi|QI$V-dm=MCuCeAH`hu^CdA&jz?48%!6<?Hy?o--}W6Tcw zSG{$uN)#d`S)!A#Yrg35kLyu}6tB>Ad<~gwG;zK#YiNf_dOBeiT_a=FluO^Xx<l3+ zO9zI`%KcfIbh2VCjNK^XJWRov8&2hZy-7-6C>G60H6ZO{?HQ2E9#%M~$+ys@6`e7; zWTz=^5~h;+uLi1hduzN8>DsY-(AD1*VohwaO(a<2FgS!dvBZoVKXF<?=Ed$Mmn!SF zvIJIX<abIO#PE~8+c7i!vG5$7G~Ihm%}@0EbJSU@c^12Ma=5qzA-CZgulMEt+I4U) ztzGl)I!wwB3%0B;J5Cs*u-ie;K{_c*p2Ge7G;2F4^=Z(MWj6s#Jr`6^Z_{Zx*DzWs zmg1=9<!?4M%t}*|5JgbU37YnEi;im(xeylqo5V*wUuzJ!yCGJ5zt-&nL-~*@Q!Vbl z9tk(zY&yyHRfuK-)0jMJhn77bJ!>Z}5pS5}S3{yVM_V*JXIBK=)4C4Ecv9?ky8_O6 zXHriMtK0j*23gi&E8Ad9Ii+6*G)1W8=&dGWm$V(p?i|2!rp9x(6I%m$G_0<qF6Mi1 z6A-~lkBae_mVo&Tc+%0Xom3u`tbcY*_kq48B@HlLUpGCjb3C4KE6I&dc|KN2+Fy5o zmxYv^9f4ZXI&BSHZvq-055vKf0MFLq{p_>lN0=55pHDP*J8(UNvxpFBUps0DIRy5c z{SA|)3DRwl-?=0gW%gHRb?xiwIP4U*Wj|mpV$f!N@gPFu4B<9;%Vv*5zM0#F;Qud1 z)=5y%b#&#}KL&SUdw92Dy)s3wRrtAko-|jge<b=Ub=9cL+!+8Iw=d~_#F><LUOsz} z-+y)YKXhPS7=>IXLuZL|XEvs8gt-oSlI*_5u;*c8?)RQIFZVX!W@El`&u7aDB$2NJ z!}i&Dw-NHkyTwTK62IV0WhmoWd8n^2=B6!hvCmJq{_G?_`OeLyB}?G!B=EqxNuU4q zS-;b|P*YGlV#aD|O2@;~tQO2>&%Ietb8}Ysy-Y9ZU1z_h-a0n;C1sIe$kUQpxG7yc zYi$O_%s{DCJK3syy2f4DTcfy8+7f>!MbRCpv0b~nY~kj#!vQ;8;olD2$ho_};(+2{ zI3YGnAvh8f*sAbGv4smH1M*BQ{!LmDYWlxKAyerucrn|}z5;nDI3Wl`)4S};`B%t< z)SW*y+o7Nf74yR#yPi#`|1YO3%M)sWh&Czn+}4R<M$;t9M*@pb+onh#6v+O+LbxNj z=|dpw^%%n&Uo?BJ`k{mD5GfnWO2lm6RBycIMqC*-83T6wluvnTGan}*!1&nkj9 zXKO2yHxIq8W&R0-pDjCX-Z;SQABq@NrH`<bi$lFY5C0}^|7dSjV~H((yKSUPEe~$W zcl`h9u2~z3I6r>|SPr)MoKn=s7Qob<4NVX3WnhI<c^Hd3SP}R@4-P64Hw}1K*ny8` zdSRkxYx`9uW9^S`cQ)Vc;uC51jLym>r|xWoXE#fI#`<QxENulhFFcPsggTz}eK&pN z_5k&ojCNa=+qi_=blnHimQP>l7#s}mTD_=c*Z-$~`+zq(mH>k`phI$8F>Ss6@g(es z?M=rtnPJWluLISX0?{l-ALbi&-`206?duY_eUpSaZ787so|kIz&R7qgf`=Z5j+4pp z&91>s<u->pX2pj3Z%Mq@9V1t~XY$M5BCM~iOKv96-j6kQyyM_G*8By5ro%sln!YuY z90ownIf?xhGlbt*FU%cK)1`zT`Y;D;lq>VBw6wUH8D*xrR%&i_b*IZ-oUam0)2(T; z9Z<S!ZPZlw32CQJg_%Q;QmLt__}z2VysQSVr59oY{ylzyn>vu1r~d($+g#P8DCq0# z`p$sAsm%IyYYkUn(M#48uoIph@dvN+@6~4^ukL^}&6*E2W!Vpqea23hrKRP?z^N*- zeG|ROPBkhBNsBOvQ6(~zjyi@t{K_4JfS5Sx@84>*gv8;j?`zZ~P|YwCXCz#j7!x@E zx0cIuAWSF}@R=4(nzhiF)BRG8$%;B@1)I*hpr+>|K7NYvM|Z#n{U!HXl$u(Cte;=@ z&CQ*hi4SwPlUl16tf`$HYSJ-c15b2RaA7sMlDWCLnTHFq@0?uRpq59CDIBRz!x4WA zOw_{3i31$O1SIGYawz}?gP9I`1Nu1POD3Wp#w?p9X^>o~Yx-mPP#DKcmb9p7;m$rm z1>F-tJS)Whgh;IPSuUyp>~fSeNl%hDJ>J+SsDt@r==pr^%(pE)*<{;Q&vBDX;1wD) z8w8e9t?ev(Y?E#D*hZ0<WTzT@=i|gR47BZW|Adw>*f{Utr|ngWQ=wMsH=a;4@6=_y z!@7)%Sbd;L+wWErVMW9S9|(JT3g(IYYc1i??k~*GjX|QL8NWPV2ES|~`zKc3&W_hC zKpgaU0h#_-yG-7Vr)sR^h65<us9lDp;-%fx=B^>{bcP-*S&T}y(_O_j#3j8Sb1o%s zA!B1KCdm%+_37PT1jI<POeXdogC=pCk=cI$g=?k~VqY7M;(L{|J#AxP{a%8;k}Nw* z`JSIqKGdO=3eIz~CfJ}I2^9(I<LRI|scI~yTL@F12B+1^Q5AnC1?Npxpn8a?yT>R` zv0D}7vub52Rq=01%=4bnbX<P3x3g2OLOKoh{B=)L1a&wOC_ROAIfSiOkP!Bw73!o+ zt2=c%c>{Ah4VQ(tc;pjeRqA|~{I$w*e(5b&K^5%?aiE<i)x$T{eiG-^wFFA<XuGg% z-BNhd;*PZT)}!(pTBNF`4w_HyHwHn%-1Qev^Hm9hZ-dvp*U6-97TT3h>ZzCl7GCqL zRX#rpj)H9+ysMXbdX423Z-Rjz`A6uOu>1Rd+&}p87h$(V0Gfsfj>Lz@iG~iKDZ<4^ zO9~?Eq)0qQdRmN4fjl!l^OHJYwQv9i6IDr;NKeq*!s0d;Rxz#l04mY&3q--hmmbKq z{=kT^E*n1#c<}?ntRy19m`^&kWIpMKxafq5b(Wc)49Yx#R~(}|_&|Zs77bXQy)BU{ zPim=UzD9-d=~I4kGGwI|={<@<UKYm24L4>Xs<^*=qrFGI@S6$g6Soq7g}yN`VPsfQ zHeYbjY?mryUjQjv@V5lz1=;>C1s3mqSvz+$$8slqSSYPBD@(DNq{y<xb3*C}xY1{> z9Uo;aoEuN@s3_}%^Pur4#rq2FcG*CmtQ`O7!Zy0ygj^n&FV2Y7G|nl|_{ym^9uC%t zfUwSQTLywyYyusHYpAB#&Qh%ry^)<4@=u9}aHTB`mPJOczG&a9E5nV8QT}=0mnMBD zAdD6fFC}NCjR$`g2J^mh-pYIZF8&O3MIXyYuJLU2xd_+%m}#WHOQ_0jzesnmf1Afa z^Fu58c15r%Bc%6AF~elqKgOhI{iXeGXtpF{UqV_2eeDKMkU?;4SAcCv#Oo_?n5^)S z>^MT-BO-{*%a)$Z+<!0&Pa<JD{%%NZ&a=@k1m{c{?Jydc&R_HHY4=<3Wo3UtZojk? zxr4^k=k4*->(^38*^5v^`%4Fhr;Nr%0~q*RYej=5t_Q1>wWjc+TRR7<)xk><>MOTc z8S$JDsg3gtzr4&yOkQt{UZ)d@MykuF&~#X`m+u=Lals39glA`l{yqIT4-yvUutvF; z$ro#cMwUoF-Y_3dx<lYlQMl{zwUHWXe(g5)caOV$E!Hr&Qss{svK8<sG=VQ(h!49} z<?s+pcbW(sh<Mq37aM(8B*u>Hz_!iTw~~&4^tSC#`$#)-&eaM?)TXsu^-s0yYWc1V z3KicG%VVaV>c6o&W<S=WtI#IKcNO^Gh9|KhO0Ptq$_pnVbCptkj5-6sf1>Jp;?~)$ zr*|gPGj>^g8uZk`8-P%xhK!8eJOvS>pzv3-%FUyk)j+Sg9HY(-m>C)@XMr^svgD2d zem45nyDu}ngz(iC`~7d?&-xoZh*h4lO<eme1xLSb_6J(^H&VUx1-WuLmfOeWM^j_c zHM~!i#{Twccqr`5Mk?2IRcGaQG3A@5#GNX-cAqU??YUaG*xeesRM(rj6h}<^Bg^m3 zF3MZnh`=Aa7Gpn22p8t-zvzkMFXqdiM~*6VlpqgNRi*eURMGQR>6$Fis%D9*vZ~i| zD73@|E~?%w4VT!0c<>7{<j<pb@-@s7K`ZUJpW<5rhn1_GhfVLbb-UJoj7hUHnZC<= zNxRSM!v0~T_NAbJUpzzTU$mMK0cV-Dtr|?ng*Xv*RC659B&+FtSzZVd&g8R*7E5Tp z6f*%TE9w&!SQxj>vqlfgxgNDxJP!PPT5#-lj&glL__lN$i1V4>ZjtO}+$A;n8|46) zt8ZPa6bkc`Hq%rbyS?y6gTl&_%@^P?>Rmm#2BEd;V?Mp&QAMAp43i1?+AM4F<NxL8 z6Y5U>EA`7O+T(B6(90i}7`rMG<n43^FRTvqS0k5s-Tz3}pRc+QHluMFl5t^k3k!co zL_(tG<)!W!FJFf4Q3IWPz8IOl`U$y`m-o405E~nNIO;;dDsggRVqt1!Q=EZjLCEIe zsy+;jgXHMkFtlPZjAZBpIaYYS0*0GsZurtR7VTM5w}2`VsJE&Ei|!GsDv{ssNI9Xa zKnvE7geCr@3QOAgLOf;avYniM5GHgTqeyHmwWyvZ*=eAd^kAvARE2l&$8u_#`e88o zgWIcHq>)!?K#PfA3XSsIin}p0LB0r(`sI&@Mz&95`VCWJFP;b<6~JiJLRV;@=wz1F zB;Mx*^zz+E_2e~h*B7z*Q{-9NcF_Ln`SoT(q6v2+w&^aIIeq^Rkuy;L<*3K+q9*H| zl*0*VO3C^G%@p6ZbL9No_P}8E@b0M%W8K@_x6d{kUF%~ch%|8j>zRdgOq<GNkA`yg zIHfK$^=0T~BIPHXCA)>O!Eb>H3EW6rp+6cIgTIK{bP`b|g@k3TA7U1d^|VjXD*npz zWP5vro}`+kFKcd6_hO82Ya+;#ay||O9}VbZ?vHw63(!hupjBaa;2Lv<6#ufyVdIeZ zQ=mF5Ls?Up@3RxC>CDqY|B+sUX};!`V)oo4l!$=C9Qn>SNU0y{qTjN2u$@ypOjpOe zg{%vg!+XVa)yt90!b*|M(+2xMJ_fo?O)^ErUQkaQgN-d6MZADKX%9r<><Cn7&vxIg zKLZRaqk>a{AmaKQUidawi#CkNwkIF~Lp@7(CUd{epq&YutqG?cp$zIIyW-Xx%t-|X zaksVE)<pQ2@pQjz>+rG)HeruOt$L?MjgNg{?wjT1qG^yyt!=820Xx-UJA5dbMwq-u z!@-a$X=L+`RxVB&ERB(){p0QD5YesRnA1cS4V$4xv&0GZ72hpG(jnm}H{$D}?tDKR zX|OY-N&?Y5UI{^S!^Sab@`pK=u0rhjW*nXN131T3Xs_*k8EpP6+^0G#C`8q=0#Q;m zo*1#5OfTa38>@Ebno@h0IQZ_(()IZhGkmGdIn>!oXKH8K5m8IEl6=9n(=8cYzLEMh zVm4s@(4;UqzIKc21M1nDQ#E2?=uH3nIebg3efcIJ+=r#5n4@KIu?!-Mk#@rq?w3|4 zb6sE~>Gcr{HOa8hg%jT$t-cBIY<tUklh4(x-FzoO1knCUWSRbxUfUr9JDON=WaJFU zk#8lXk!)WBsO~Iu2#~O^iLOK)4P~ang#O$%%gyo(k#sURzs_D6&m#y|yf1Vo>Qk=h z|2KNeI{v;gdNi4=Dz+F+edGrprKs=*Gv4Zu>$t#z5WUhL#$+tGG8{c8{PZY8eK`G) z+HFh;UIHFbtl%mU>3ybV+7(tJWq6lDXUWONh|wL}0hPGy5)N;N5~a;HA?lSBXXn;J zDG{Fnm8@k=3h^tVte>(*b|E@;{DWTrm;5vF8dgcpDgszXv6BOOf$&)fqrhy7p4Z4J zK)^oyp~%%IjL(Ad?A#;!E^3{(@#ZH8Uk?6=wn>q0s76)&{=^X~pgf*9j9N7G-0d6t zrLom26^Q7)1K%smO7c0@0(*$SVJ#rNtCO59Iz9-Ymy_c9#zsw~S%`j5RhhrGL#t73 zf8^mNL!`}#Jl)k=g@Sh^8fyA}TQWtCAp6iE_bSg{j^JhP_+ExgNMEwOnePM&5BDd^ zt1$XFx1&2Z2!bJ)?uCU$U+F^Pm4l0$BKO?p6LK&$YYGj)r<2pQar25oLmG@>lRd0I zNQxf44O60_d4FC%^|)5|(<91+KLqq96TlGP>&JywN}Z-I2{pCDC2d=b!$FB!Z$%%0 zrm7}9(AHw3l%)p&VoiONUO6Q)%rg_2dr#XFF!bv>iH!MJ7$;;y{q`BjCj|1iaPTA{ zi7DH5$lEP2Njska`*_hy-NqRd(Cf}u2urM%e2&6YoZ!V^UxE;IpspFbA)BW3w?8QR z3OSq3&tqmvCN;>B6QlQAcFAKO&dUL}Km#9t{r5UR0k0=rL5sbL?`=OW&_=UF4f_Zr zLYXWmjq@Vfny*DjVU45@U~v!nJ42~ZI`%m(8%L}QQGGCe>C2TKe6JH}f}AZC_^Acr zhLKX~k|8P6HJBs7x6{iK9V8&7cwQBAI!mlo5}D}@sEss+8Dcs1H%#*+%8nRjB)c1Z zUK%phRB!Zt3-hcOrM1uaqnY#4zsXU;JQXao2fiDiSkZ}Pj=uObcZ9y?=j2DjbUMwg z;=w?<lylD}2Cm5*Pzip^v>}Zf6OKom{Zf2*kcs3Imx+_GCn#6YDFlb>fdrlq&X3@^ z8iF`(%klQg*ID%DmFvkF=GAMSIVD<NhTemP;_v%YS3s@c6yPl}utoyn5=UW&CNt)V zwb&g#Y`u`S>VA*8$|e);3^$BHTWX9I0k)mBer(LfCgxE=Ds|LIc-kzu4kMx2Zi?g* z9CMsky}13{NeI^Pdfx!mk9mXjgxx%9?jQEAvB=K;&xsyQ>25EPunw6{PUS_*{8t8B zit6rPq1+<6c~FwX8%mp<9g-6wjbK{~VVd1tU~!Mw2{I#O`Sq|pI?$k)+>qrF^C1r) ze&X(%g3Pg<xl{^ksO6Z4naCjFE0{-;@&(7lus*0Qv8|vKye#Zg2$@ULtVA?Jb#uYz zqQjUkyph@nJt%vKt0dxW${|#eN@$DwqkI4XtPs}`@in+6Tqq<!1e#J=dp}^wbMPRP zu8sZj3t$^B(ZJ%ppf%aX9|=MH60W*(jvx=}Q8>mw>9TRNx*j5evwb%yj|t_w2Tu3B ziiMW1i?2-SPTJ=c(R(ctrfuz~yy<|(&&RsL%@e({8#AI5!V+`SXnJ~x9NVLD6nNXP z&L7<)X}c1Jk=U>kAU_PckSr2Vu@zZN=|f?qk*WGY;iyQc?D=}q7cPa(ihwvi^VJ8! zpXG=8*7wY^q_f6N$H#EAr~SF=bF!e@v{u8s!t}NpUCC>n(|>_40cMzOmeZaB2z&p| z-^AS@kB_Y|Hdm+RKNQqZ58c6;x<h>~z$x65hUtdgz)T{E)FtZ<#2Yhj`Egk^O8lq6 z8U*Fb19E~lx|TjPua@1dk5HH#`8?X*`8yarkxCRjVO<RO*r`A$p_p7ykXyAjmTXj# z8tp-6cD7+AAA^h#w)!uF`^ly?`5oV^_+VzBSDBw+Yn}S}p850~x**NHM$($KLKXgt z0|$%2tb_;f=%Z0mps;|0UwS<0fU7avCCp1-2=IL0qeG`bNLs>u5SW_!vXceig$Mo6 ziTO}MjsVv2;a$BTK-{=I^J>uf{m@KxF1kOZkN%FEpF8JwrKbK&=ssOjOUgHJ3jvHH z86v!m&oF4INPsUB#esXfpmRvAmx1C&8Qh3YQIBE?iS)?;Jm!i>^+$nEuN&b$;O_|} zpmYT0Z5I?Ebka4l_vj@_>cUU@FHOnAA_;YuD1f~#nAe^PDW~5xV&AzcbE>{y1;4>f zasNJOBf|yrPTdaQW>s_H!kAgRl0M<jd`miqV4gTy8{F2Y0bQs5O7<tX(vSJ{5b>uJ zVWiH%WMl+&)bDWyCslki*)VKV-QXu)pyT7rGf8beEt+9F?Bc6(%e+Vt%O@9%o&E_x zM2Kp&NHU)3C{`Qej&3G}PfW3&i-uKhRZ*#0d&d3`1Jpj=4*a7~R#+Ea_9=wG;D{pL zyCsNY!QXy@TKGx$91fh0+uOoYWVu=XF#OI4*<vCovGy5JKauymzVp!Q%f@bbGBL1< zB-6mT!~T^Hp9`>I6>Xbh2Da{ViJdu`DVGSro^e(oc9ye8{XyPUR#H@w<>R2)0Wuw8 zX2zaLkYJt!E0Id)(2Fd<u|42gn9DgrB&FW~0HVOJlHzKJd12c|yP3CL7-<K|cp~0c zI4aMz7#u?5wrSQwLOC9&_$UErjLDaoupX#fhnzx|%}Syg)-&zyD&<`?qod1v(0sW! z@+$_)j6-MchUyw73)Ek(o!Wgj-Sc53qNEMOd{C1n2%DLvdxfBK_$ZJZjNnIdi;RPy z^%68iPeX{L$-4KrC|O_%V0~MmM@#@U(9L~D@|5lDOi(b|SIVTSWha{1_OnNKUdc~| zu6(5i@ks3c(Vg8-3uuAskop{aGwsv~xjRVdJDst=(rw`f(P%flT<-b85h7m*Un#p! zW(6;*-xNzo8IkH1C_Bh5Nw2lsKWqSCyHh(yfc&W{NSZ(W-sez(PP~hhpoUZ@a4<QU zQ@t^GUugBnH4y?zjzH{<x*9=TIAQ|xGrk6`PK=k)0m~%HkMFJ8l48lhtOu%q*&{&Z zbuB0M3##~{qE;c)LjX6ToM6RKJYYd{n{1Pp1BLXMt}-@h^Q&vJB^>i>K6e6LmGjFC zUZ%)o{W@B=adx!tyc+g!%>@>Cw#2R?n+#D*<jlQ;AC?X-=hmquUbLQc`g>rF*iOA@ z8#SITC3rHF6TDhN0DOIF9|!Q-Pbnp4%yN;qnCHoXGw&@9>_sAm@uHv)kfsiYbA`pd zCuQa!a14}O<htwmS<(edSclHsxVx>5P&qk@@~fi^#p-Jc_}P-oalcB*hSeUD+u#9z z#*s2oD|Xup2nkYP$>Doc0Pu&oDqLb8$6kk$qBlIpE=0!S{tf|J0fa(OcD@qw(n=y_ zf2kuC^mWpkFb$G)J*$MQ3!82=^P3KA#xCpZYE2Jn%+7KRkeDq4iZGCstm8vn%k`S9 z`sDULG$<pOmW!k5xBt-U5f87Ej)SvUzmEDw(apQ_&cr3sJrQ&O!QGZe!83e&sP#;2 zVN?BPh3#A$O-G?o=f)9_He`o}|GJ)*nFtJ050jB(%>`{)T@Mi2ia^ZP3{ZW;Z!US^ z)+{*QGrF=UN+ZfYM+F10itZa~Mg@358-nqa=6eLv7&VQIgc0z<th8iW&==qDM^P+^ zB1c(C%HouWOXeOG&h@d%hbjVnbeiZHzkp|O={8_~(?tx4*ZX<H4O$$Zh`!dtYy<VP zRy5#2GSw3}a{R1T`fp>_B(t3CbYHBU_M1c+)L;D#o^s@TVYBySo0Zj|$nl_{EsV#D zAp)>a&lo;~M}&iG8!7>VnBv-m<#WNcDBCx1e_Y2<wBq02{xZmGF)5!t@@`rsH%;A- z9z|=Gl_BQ;x`F7wEI}Hvh+2@<*H6l5;i1lS*ny`Q^d@_$e!pU69SM6Pe#{o>BAUv= zevB4vgGi19z0B@4fT?K(vVwwN4SYX_Yiwc0`CWa^-|rpuF1${A8M&_-u6fe?#5^40 z_0uukC`CkH9|o9uELYSH?1aO8@-6AZTTo4gE5H}?VSHIQ8JkEBpGaUE`tU;tz*<-k zL~OyI<3Zy^5tPK2F;X~6+QJyLA6i!}l4#UTO3RdgxFVEg?P%ddi7eT(op7SUQ?&*@ z^K5MeOdKtO4Sg=x-m1r)8rl`~cbDcHh~wtG4rrtz2-5*}QI_o(`mLm~*)QH2iXQ`G zSiQ3z4bwsjnaR*fFVs&|RI^|~9Y52JQ0;T1i#~x)iUQPtE`HziJuu@D8)qp=y0=Zu zyIA065FS4%IBl$T(s~*dbfjk8qGTV`GtTKwY^H5y6*gQe{n)%*>D1OQl3IKJf5p9J zTwB4mK8zJ;(Hc^`6nD2^g(AhF#kE+0;u@Snp%izQ7AwV}cyK2WD8U^<kl?`~z&}0r zoO|v$AKtHT_J`!Rl9@f3*?Y}?=6Ti{oD@CXeS%7BL{8q;kH<|S7%~&Sq}@cLU)Y4% zA0N3{ke$nr*RO6jLV8<7`f&^0KgeJ8-ez32#Jw(X<`?3VSB|qedt1~$yPim_q#HCi zn=jZXT4j+BHK*a5K8i`R3w>9^H`=|f0H)@N{rxU%_?w9w72`<HJbOQTHg=8x_H79a za1^+7`f!GDK)}!z%HVCFTPe7aw$r3gJ@||+>p;`?QaK10CZ;z=h-v<ynx4qI>Agg9 zSiz$=nF=PR>#~!um+FG@;{&=T500M4^?#+$eTuUX{p|Z=mLt%r)bSH?%9kSQyjIVM z0*Ymbsn|XzaEZ>vbG)mKRv=<-7;B0CU}2pT){1BSgEOP>OMPZ?-BCtvaDA51^~<ep z>(3Z&_BO<o`C7pf`7d@Z-zWGR#JTCP5Dukbmx<ksRK1|yoWnJdX)0n8QJQ%=DD_3k zMeM>qY^;DVIYVl-umJEWX~5rtp054lxTD++VU*Af|3lhOoOlDtmM`D{Y1z{(o(I$# zv&1H<v$z93NFo_isq0Be>{{(0=r$cK_VtJjO))9+6Sp-^MD*5Z6n3(CXkhk(YfDxs zO#GUGC<+!b1zV!$CkGjnS7m8O!hUY*3g$6RgDQOsS%c&B**7e2e$_tKX%eP4Zq0u# zsGY;U-~fF^uDZNq6z{MEMIOvOyBcPxg*Okp);5cYG_O`2!7@L2*;9{5gvz)Pxoku+ z9UR-Q^)TeR#JCQ^qxx(pzmBlmQ&YP>m1R#msK6a56F4PtNTf18s5qE=QRTNvHYGV0 zQmN{5*w<7+CKi4aYhq6K)&J|)Q>k_?FYk&(n)j?Px{B27FcQ10A7?s7&i#ro=8Q5+ z!A?(h)Ui=WT{3AXdfp5Y^)tx52=@Q<lJtyOz{c_iBeKm}Sem4t?ye%a>1|=9X+~K7 z2n$aaz>F9asSv$466ViY@SN&MSUr{G2qM4eUYG5`WWdc>qfLuA;xWJ~j%7hWihF@C z`(Jab=Ss$<+AucK)`)0F-_$#fmG*LnaJl2IEuapDzWSe3hyl?_A)dkN)DACyWFHzO znq1i-Phps1ZoG2#yXFS{1iE(W-$34;>gx5Q;FmT(Xv@Ojn5hWwl`bPI-j|*!vZd?< zN~ZYEw&}oKvol2CRBqDEfnD&-cN+UAvvYf;^<P<)NuCyQD9b$>OKE>HH!!@l=aMP% zF@@KyihE|j{z&R4$h0kp+IQL{%sP@S1#AZcq_d>jEL}+NPK`<)@^-P1VsYhzcy>Yw z{1%F(@g_McKKH8;KJ7hX^PB@;OX_X(3o1z-1@hqr*AI1`jBZrbt?Lu`P9H%zl7vvz zlFlZM_rw_5DQweHK>MokhYKVNV?O;atj>}sa?c|-d6t?i@$#jM4=mH7q)xBaV|ZjI zG&tPxUQevn4W3tE&Y3=qKhZ0=B&>a<cy2Y=wM41?J|R{_T0rX+kF*}5;Z5Q7t=$ft zVPek0PIL$BQ<obG%p+Qg+yRz^H~t^GN=S%*)9Kjg-FD3cH!EB^MAX0oYzkN4Z-#a* z1x2QnjaK~5DvVjW7AIH=)CL=aF~&g+S0#DEb`MQ--X3Xge9x%`dhJ>#bB-AuEU|DU z>5&Bm@WgnpOoFav(6g<Eg7WA>ujB-a+o#B-OabdS-5(l9O5-OEI7mwp=%tvZ?(#VZ z>3iXrbytzr->M-_>jzu_IO(M=O`<C+YP`v8-edWrrvh`9o~yB5+j6$sPxV-|tqnk? zW+cKp0)0W9`Rr8zDO1aMhIU;0JX`I?xmgQ_>W<(HhlQ5+(xB7w&o^WS##6xz(9=7U z<xcFN!ui)LGf6&q6)Y8L%VP^>D?xiDX5gAUytvyoB((fXRo<peW#G3MF)xg3%k3QU zM-fl%=Ayz~X&(9vkXEW=q}x_6O<}P3=x0R{Y{PK!7;*4BTp8JAdn+GW^St%jP5iW! z$~|Q^nDU+B&s=56ng|iOC}kYI>FF!~=;F1|-(SbYs|icvj6r>Ie=zmVzE5G$O@Naw z*c+HqH*M@yEE*ari)<^sS5zGB9GBgEDuwEQ71bGW)ui|vRjh*RB8G-JH4djISQaYf zx8VCLjRn|OzzeP*9?28Xz{6|#$|abvmQxc`EZ6(bW-kZE=gpE1Z|j-7vRGA)M66A7 z7cWxX^M*7m-PGFC`i;<Iv}J*2{rwhdJ%o9>RyJQ*S*rg4Fc^KFa5<s7u|7(z`aLGT z97qMxO-;f0yp|emTMKYDOFd~+Y>;&K=kP^dfU}~dWZ&enKQE8Z;=3xUZ96`nXgxd( z<*K_H60`z0ogvK#DjK;joZk=dL^W1+<Z;%WHjMCOHMSRBG&=8I{?%-tse8!goTZcA zIy?<Jjn+ZfDZ?Cl{!`;n#fg?U=y<csLJ9E4CZq*fB%znj^wM8C3y%%G$HBR;lV(r7 z?hghX+w0%0cc?1|TDSNgL^bozG9sPt=YFErrHO|Q{VVY6yx-iN-Aiz;_&MudW9A;e zjiam~aJkzG6X@M1>ikaUMC~DDbj1(Sp>gy7xBBkDnP@ylhDERvitr1%m{$&J{3~vu z8RuP55@i#4uu@~Q+6oY>3uC1o%<i)K;-B!;54&YplOhSP@o*?{<!*^ym%+IA`Y=jc zpAmU;uNXqTn8grfhq3(i`RF$F^CRzRxLk?(AKHwxKfEwrn{9UYuk`zWY1Drmoi7As zM6g=Y(4kT2uqgDo2d0?!Z$Ny<d3@v%{ae+-fS1k~G7-FD)fiVs4g!TGL0awiFjrMv z)f8L0(bOJ4fvNY{P~4(+etMoZ+SE-t$WU%^{$4Ox(bH9)^o4f#TKgaAX!>0_d<TIf z_U3APhu5v2Qb+%xCI1_X_4lYY#{LZu*jwD&%MO1Fdj)5Lxb^lVomjylZ<ZtM_GZPa zN~2=Za-S!SXN^#N&$9*b?e&5Oaqw!`O%sif9nagibgukS6(fbpwN-Z)y1DxAQ-&sx z^rka5FD(tSOf!1}voH8*0p`f#?lr_|je;dI9<8;sjyzEeDdB|V0ULltaE<7!l0BPi zCRYsc%IbxM@0mbGB+s{x9*hMl6GGMa7;Uc}V05yj<Li^YP0~`uMQ_9R*;DL6&0`&F z3MWcBlW!mDOPPS16mso_Loo;VpTF=Zy>S&!#WhI`YzfH^VK_3kiaXkPsY~|RQqU<- zU;t5E7wDIR-dpQ`m9DfhM5HMDMGFA85Dq7ohEk2%j{#=%hB#xY&jz~EN42%-+78DP z5yF&hX`N;l>f?Su=A{cOU$2=-z2SCkn$Zg~?vi?F5$u^mejN0A0nV2cv09uV9C$}- zsB5A?#}jqf>%*uk5oyvAK%`luTcLHyNz!Eq5XN1NYFwOOe>WH6xx|5y*@%OsZIb&4 zBN}7>E1o2OEd9=l=<KM<P9%s!E|7+SNzQ;xn>gOzgZy(GY%g2>W9!2v*XU@=QZ3b2 z#>SuN1joho4r_?21To>~esKGLNz>7au9d%{P4Yjr4lJ{_o~X6vaz8;OCf3v}rnakw ziHdDySOu)aTI?hp<iR|Ey522UIIIBQPHnfLxVUzik_J?E;W__^Ez;=Ef)6F83>gh< zCM;)-!L0TxMS_@Uhb~141nb=vhH~GYFh`|$Re$o<Tgi^@F$57DP~l;GyAXcxiVo~G zqxZo44cX4Y)+0#*ZG%+iJRmcH6Ez#ZU;};Vt-C(0;CuUDH6W&SN}BmBrX75nc6`mi z@0POR3K;n%WEj~s^G|!=m@@7UM<e*G#vSu`_5S=%>JfCR?Foz}VQtEZVWyH0iE_*s zxJv|3N^lQ#C~ZvUPWtq&+d@CDhT2=rE|dOaxS*LyJS60+|9w$4svt;+d&SRAx0tz_ zpCOej8!y<&(IokPpJV_ov67v-nfgG?kBPkv+Zg#Isyvv)rTMhymn2%A4|%oB3FbjN zta;DLe>UPDSy1dc3oy63*R=Zg54tU|>7J%m>jq@*E#<OJ#b{lzrNR#UycHm4=GM<u zSy5{pqe(5-gja2558uj~w*2<u83Z53f>~`I1>Rld`@`wB28qL((fM|hJ1&=hqfU$L zGD4rX60J64ErcTk*%aDNlLa#regXp9=z~RK_mdY%wlcQ<uY39HW;%1GgX?61jAO7G zKTN&91VlZ97Y$qD3BY?9M8z1xmS(qqP*?UzJW8#&4{DbzNW$wlEu{t`K9cGp9$YzB zLEfrt0hpf@4_5gLledpiB9U2jNMuA^t^PO99E|Ltt%PDhATlBU6JF=0+joMG<DJ$g z4kpS{PI|@x|EtLUhbsHNqs`f&5~ef(cE@ya>A-#^t2G($YIJX8xTfy0>4JrGSdT>n z9jLvpeU>E9H9GGW8?~x<|44DKAa9y#t)8al>6*y`!y)9Of?S1sB)JxjOgxV4V$~LP zkeSWa4#J%QBaxJeKB{-8vV5exyy{n3ZCP0vb_ne8SITV|A7Us$qSC|uSb^C|anpt! zNph#22QV%hrn^04r0g+-uY^CnE$ILxa#;HDiy0<(uj1cB6yIOP2?$Zra)LK}-s{d} zA-Cub2ZQdMC2B*LBy1E_kV7J#S36mktHUeQ=-Hr)-lhp$Ter~3qBH8+@a9BvG%8Gn zo)jMkE99SV0y6Z}+vGSYm7Fwos)Uw#%Ab-#y`KjnLmB4g*@vJNj#o)zB=8dbK!(e~ zVX0KN#Y?0nZTSZgA`syqIc8(SG27vdAHTq#DmwGhGs_NJR-=A##JrNh-Kz7<#)Z_2 z#H$^tPf0Vq1MlU%*Lb%iz1PgDDH!gk@m=Dymcf_YtS=&H+plOC{@o@B57wGYhs;vT z$tU)sQccmu(^BT}G9;9a$YLux9L3b|-7lCNV}RvYdo6{%opm-j&oZ)~4)%0qrbgZp zBM)(h<tKk%BF$;h82b(6SI>SA#}!WQ&mFrzptBGgJR}}|?|+_ULFXrT;{`~yMYU_= z%+tV+vdru}<v0J;E1ivBWJJe#i0mM8ZVqDp5Wjn+Vipc$t2AY@G{}$j{_K8ls9RIn z=|h`9&m*ZH{1KjiZnCw)b^IUJAMNPfXm_R3M8)yN5M3VzjkDZSEG)KpR*)D?37z$@ zqx7S0KJs0lCfE;}p9=v8dNC9YZFAbRL5ZC2gXXwRuSWzu3{ywO1vL0$p#L5#(Wf}w zA%V)(zs8bBm8NUr1lnoYXKK!`%x=5l_sn^=q;KG8Qhx!e29sm!sZTWSLK1ohZQr2c zR;VAPihy6Vi(gv$AKa|mLHVwZ7ee_3H77LUk*#ctCv#p)+w0%k3f;molNe-XfB^y6 zo;qpYzspimP{d<b{*k5FK2*G=+nK3ipJF%VM=Q2}w!Wn-o2e825zTW6HSbwtj62FR zBOM|oL0?wnuj#Mz$v^Xib>!iPVc#b1s?GEue7A6^OA|o>)=GDMD?H#(Mb9f(9LdIx zr6^$01Y1R9@=Ep{wgXlk#{E&-FVtRM-0;fvPiDqdSd0Bx!X%KH#qSq>6&5DsrGw{M zQ`7HP9hYz-e``10N;Fp)6{UjQiOJ#@=jU_=1wJ<`G)_}156MfXNNJv9GiY+7^p@#U zbN<bId;(JUEJ_yJ_(X3om>c?0b>Srh`K}=sbUQmrVGyIcA<(k20e4dvs@Lr3YdP7- zp3FNrZHPj=Md?buVX$(uAqiUgY+UyTDe5dJNk5R9yQmF?J!yWw4?h#Va_4Rwf~y&o z<P;k5q0+8ZhokM&7&_*1w>E`;QWId~Lc7hN3b$f;P<1(10y|k+<BquvfSoBM%hIWN z3$Wo5HKHCTG38?ti{i?zMT*BL)(wF-kFyJYMtBea4JO3RGq=os4`^pkXXNR)wIv_T z3)tNm+JQ!ZOMHFSzypz<J(Ay}?0oPV>Zu=C+-w@Lew7PcqgUAz5KGt8u3<;p*pRf! zpNcGa{Gsjv8ON^pI1oPcU6!W>cdI}LIqw&BU*K)5+@qhXXYMyJ1d?Xogx+dRuN{F% z7QCsas1TfEYNtc3RZ~{@t?sj#2#_44wO)W<d@>gwQ+&e6$OviWNQ0Ix?CtFhEiZ?N zL*9>wN&{O$suY}H;3Nl%r^oMyFP6J?zobVNdkwbqjEv&%dJ<b-wpbN?(x8ZkRH-F4 zcZ+EMk-F?I<-z>JgU%8uc&zl<A5|UOz(jpU{rSA`vssde<j9!aB342R1xt>=4w2wH zxUA)d^zc+y(r_~o3LSvMV3ZnjUaB@;U^WnD!n8>38^}fVPQ)iat-&uaEKFGFg<?}l zxr|BCd*R}g5CRjd)R>@VHCE|LO8B3QfYdaA@WKi^9q-G2IGM&Dr_?kdnbvpYycYS~ zcTm)mT=hMEs!51C)lZ>;SP?*mQy;|j^HQh$E`=!EXA@qa_KjwEG1kQXX_S_;en2Y! zNThN|1l)6vzqK^a%YKI;A`uqXkk~KI5;51=UwX+NXQ6I0Zw(hPxqcwJxFObFO2o>I zl*5ZO_smWqxvEDH+Yv$N<0Gs?+z{1{fRLvj2|>h4wm{{V_Ma?y$3DF_-c6cKzzZ^M z__6dUqTGG3rcKkE%8Ro#-~k!M>Bp>IFkeZcZh$uV=}i)A&x7f1uLh0zA6|@RIp%AR z85+A5NQQg5zO)EPWSAXa2U7z{LHj4ZYE`?s2Kt+OneVe_zw$nutX(*Mz{|Fo%%a|F zy8Gss=}uncHNDH-V|=`8rkNUVnmzw=9lH<Ah8sPN4#>a)>D^Dit0uDpc&!FTWo%pM zXaH%!)uC$G5~ui8#F*15xRYZer@v7#ae+S}Crf@RZ_&vVi51KB6yYW&O<`ShX355; zsW(v^$muMh((~s$BC$FMnVtl5KQ>EJ7)E~<n{L1ZY(Z?iPvRofK0`fTZ)iR9>%0o~ zBOZN^2xWkaQ6%Z%Nd^v+3A%4~;?kyu?{Jlbz<WA(1Y>t5ZC%CLzW&&2&K7f5oB2X0 z8lRR$>LHf;04t?<iBJ>oYz?D!$39q*29JY#Vg$GP=V-F?T<^$p>;g&xTsKsK`c#Zt zTA534U2V<CWEZ6$dtuCJ?OTuFZB@QsUatwjc&47gKO=~-POwQF-?1=p@VL6~J);`7 z2E@|DXqVueYKzr99Vyq@`o46~6#O8Za`O`vA=6|ebkMelcMlZJnJJ#mnYa07#Derr zBJM-Hxnh>V3TUn*nn!3t^%(ktA!jxrPcS#x#eD$q{ArbC-%PfmXTPglZ*e|Fd_)PQ zmmQ4`51;c|R>~K*-zIQ#fWD!%)}D+7JD(OTv4qTYz?TSUWVP__R5kWWt3xcknH#<3 zoNon++N}Noe>k5@zSF$S2!lSv$+w>Kt(^Gqh`EnpTjOw+MTs?bTx!~Nm$`KqwNJWY zX<|KHZ*-jeO@WgmRj&~^>qFX*7LUiyC?+DgcKX0)bpGri+qjP`ueA6cC*8+!4L{W+ zu+XsukG=x!W?W!&y{Zu-4i-6P$okj7$8Y`ntv`8&?I}=n9g}9+zgwfwyZNMx9iTSW z8H<ov5%R~?(b!SC6eeBOG^P4k3iTTto*GXsDze@QO#%oAa9I{G*7EUjU!>6uj~aQ` zgjt#@{OXzLHHU?iQ2z`F|LTD#F8EXse>~B=nO_pit0dehKot6^c#L?Jv5M_8A*7x% zlQwZjMo>VJ+foPbTWJ2nOd@JCqZT$rEDHYpVf%B@2c_d(wN2DlXW7Em%$jORa2-cq zP1=d=d)_A6sBLEj0fOiO7pQxE{{#}GBj%2i{F-WtYW>Wb5;?O!q9htTeBb{=v0i0J z!RiH{=7^EMhcH{(5i8@AwIFq*TvWsr2QOQU{wC^oj&NoiA~V{|lc{Bg6uLSRW()zw zmy6)K{LGFJtBENJvELr7cPpT#RQ^+tla)hnC66p|%rp+KddvSye5hb6qmrz>lKPa4 z<W;tw>qmIXw$lznOv{P*G%CUD8*um9MQr2y4DBlc?T95CZ18{pf$lQd+qZ%*)Gcgf z$>B29%jicxZ`yHSrEa57BGNij)th`T-w<p!w>c}z5(+lReaj!%*SG$=@%CC1v}PtS zD#$=5h;uzhSoj3YzkJIexmA05NrVI8_&cS@j@BmC5Kko6VNWo<Xm}X$c&^j}W0$O4 zuD<e{_x<B`Dtwn|MLdyocZ`9nwE`9dYlqia;@<utI7i~brQlsc>5yy1yxoZQ{beIA z@2-0xHi60-HtAS%>)VHB-wUHj#HoXav$@o<(!8HxCBIuOa`jTnA*bjQhJ|)CO69l~ zu}*mQKPr(bQw!jXAx>Q;uu@aQlY8-248_q!X(vWViHn%E`f_YzY>}l4C1Rl&(Gn)A z%mQSn71O*FHzMRNOi+W@8c5W2eGF#Su|6@+jv2$ZFB!I;%}_gUGM1e|u|=%<)cRY! z^7@_R3Qb>nN8gQHk2{ka$qDfX0@c12Ijxm_BgCs9w<*6COB%?E22{2@HD(?Dm{OPV z;$6mc=m)&a%u&=fYwew}$eE3`tEE9uGc}Us5pi+kd=gQ1*$1wQ`cnQ5;-Z$v1Cb4C z^-C^x7P-foU&M}z!PRx*#k3^CWyDLrq71A&Q}}o*y}Ty*s#S(nj-Q#$R0$WhVEjz$ za~-N8C!@N0>~Y7SKl-@%9OaXfppnsOtC`BTp#I|QCpVmLPu1+3N-kYq^3Oz04Nt`P z!F~*ti6Y~7i3UaQx5x`W%o9meCn@g#o^Tm@$ogV7kispSpZ3wSVMSy5H?o82`pXCU zy0{+($cyJ_>z9*XNQZP@DRf3aPE3aNjK#h9_6BA}jJ%W19O%=*@ldmx(u7+9(j(az zPAF6dc@uPT@o2HitX22x*ckbbFZc_X1GKbPlMHl&k3Nk>U(PF0y($G8rA6^!Hvn*H zhqN~S_(W}hh7r=tGic_AHPVT>mWe#0WfxZi%>4dM-Mdsh?9iB@Vx6b&8;d`-+{*az zNr25fTg!JG1vtQ+M<3TFzDI>`%<b55^o&4~87w^`x=&k*CQ~>#*4O9g+xjLVtyPkc z>HGcaVmvCvFNexlXTJTRkFx4`_I+QsHcZ2_=z1tU%FqDm;ee;4@k#UiRj#F+Npm@3 z_&sCR2UAu1nWAH?ytGbjK$Vx+XtB}UGt4yWK+&;+IlH$ih+jEXnl`^e9EUBVOPw5V zsOiVat7$V4OjH!Zwk0;gK}Ic5By!P{BT12RNd5`qS<73P)!4c(@6ua`J}$`;ttzgY zaX39_ZOyU@Kcw@4OsBIFkBnAF)|=?c%~k`R6}&Q00r?UsI@Jym-G~@8f^n%N)s$Yy zcI46{wBP#WTfp0fp0Qg*gcF|pAKdpBS$NQs5_{milKn3;jxQtH?)>Q`)4xI4Kk(xA zU#v*1^!dNc_@@eJ`|_;(+y6k8GW6piXb?pckMn=P-T%}RgSNNTL?-_m-u$Bp`Pd;Y z`4aRGU;lSKRA{@O<x{qQ!Lxsr!$Uh9Z<#0m1!-mSMbLJ1N=ohjMY;bhK#ayv2f?rK z|GOUNzxEil!hgf!|0zI&hA>N*%B25Y&+=b8RhH7j|0*C(itcFaMEd_SWBva>06u&; znWLLgY@**icEbF-$o@U#Jml!kHRI0xzW<pqAL3pLt(PQ7%LHaDLr~m4Lh{GhA%}EW zP3dDl@<iR~C%1c%+p!R8<lt&+h|F25g@XQLeE)mW)%Z2bzPr2jPoJEWi;Ppz;89Fe zbh4|uiX@GK8WD0A$Oh9#tQ$)^4^gq>b9|KN4}@RGn<*yhq}#l<6JyOPb2HVBLMg2A zTn!DZDnflgfk}w7EPDak#sO_(Y3NA!BJziNl6yd|?(YRHrMUi#;pgtWZ5wX1X^@kn zy5s_V>*Btn(X*`<o!iQohB_3>nz!k&7wjT?@%31Nj|X>wFK5b-XVQRJizReOg|eWf zaM$a`opLK*)%&)PZa{;UM2v@RY}#yt3%MoSntJZbjua@y{G4okF@A*+#g@u3MzI)v z-efl<)>1?_gN{i_fi-X0vH_#T5;BVRJ~S~8XwV;_ne%Cc<F)nt6XH{_ynu%ZD~>3( zYQ*L0s!Tfy(SSlgJJ6|sU7G_PWoe~ML*>w`)H;^6E<knD))soW{S91~I#Zp1md1?^ z(IT-~8Va9plVB^RoPuVHNRnM;OepV+q8qpgv!kB%q=$q%l$7)|!pBDqXXXM0RZh$r z|6Bob-JU@?Qzs_elQh^$ww%+H>OB$O0Jloih>A|(hSK>&e}g<_63khA@malAgpOOF zHYK3%!+tXKXe(3u#{Jh;ytcNwiiS?B);x3p*7t;_L^`G6<lRd(&)t0`6i}{whA)?3 zw`l2ubB;%TmOYQ*d~11IJ^V#9%WYA+@x<>1o+^X+C00I~{bC6t_9t5*osFM^rHkO6 z-CmjXnvPX=Bp0Cm-*MYxWh@(5Ap{Y@V%0AfTK#HUgIMVTk8&q*udVlY!l`L#hNjQS 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 KzVfyC=l=&eQB&mr From 833eebf6107b37ac1fc505b0b619587851479d70 Mon Sep 17 00:00:00 2001 From: Xavier Mouligneau <xavier.mouligneau@elastic.co> Date: Thu, 21 Dec 2023 15:20:59 -0500 Subject: [PATCH 095/116] [RAM] Allow initialization of the scope form the rule list component (#173795) ## Summary FIx _> https://github.com/elastic/kibana/issues/172785 ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../public/pages/rules/rules_tab.tsx | 2 + .../sections/rule_form/rule_add.tsx | 1 + .../sections/rule_form/rule_form.tsx | 3 + .../rule_form_consumer_selection.test.tsx | 65 +++++++++++++++++++ .../rule_form_consumer_selection.tsx | 21 ++++-- .../rules_list/components/rules_list.tsx | 5 +- 6 files changed, 91 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/observability/public/pages/rules/rules_tab.tsx b/x-pack/plugins/observability/public/pages/rules/rules_tab.tsx index a2939bb4876e9e..ae896b66d990fd 100644 --- a/x-pack/plugins/observability/public/pages/rules/rules_tab.tsx +++ b/x-pack/plugins/observability/public/pages/rules/rules_tab.tsx @@ -9,6 +9,7 @@ import React, { useState } from 'react'; import { useHistory } from 'react-router-dom'; import { createKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public'; import { RuleStatus } from '@kbn/triggers-actions-ui-plugin/public'; +import { AlertConsumers } from '@kbn/rule-data-utils'; import { useKibana } from '../../utils/kibana_react'; import { useGetFilteredRuleTypes } from '../../hooks/use_get_filtered_rule_types'; import { observabilityAlertFeatureIds } from '../../../common/constants'; @@ -97,6 +98,7 @@ export function RulesTab({ setRefresh, stateRefresh }: RulesTabProps) { onSearchFilterChange={handleSearchFilterChange} onStatusFilterChange={handleStatusFilterChange} onTypeFilterChange={handleTypeFilterChange} + initialSelectedConsumer={AlertConsumers.LOGS} /> ); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx index 7f6a45c7d99926..07264709dd5448 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx @@ -315,6 +315,7 @@ const RuleAdd = ({ onChangeMetaData={onChangeMetaData} setConsumer={setSelectedConsumer} useRuleProducer={useRuleProducer} + initialSelectedConsumer={initialSelectedConsumer} /> </EuiFlyoutBody> <RuleAddFooter diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx index e19a54f14537f9..98e2547dabdd3a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx @@ -157,6 +157,7 @@ interface RuleFormProps<MetaData = Record<string, any>> { validConsumers?: RuleCreationValidConsumer[]; onChangeMetaData: (metadata: MetaData) => void; useRuleProducer?: boolean; + initialSelectedConsumer?: RuleCreationValidConsumer | null; } const EMPTY_ARRAY: string[] = []; @@ -183,6 +184,7 @@ export const RuleForm = ({ validConsumers, onChangeMetaData, useRuleProducer, + initialSelectedConsumer, }: RuleFormProps) => { const { notifications: { toasts }, @@ -818,6 +820,7 @@ export const RuleForm = ({ onChange={setConsumer} errors={errors} selectedConsumer={selectedConsumer} + initialSelectedConsumer={initialSelectedConsumer} /> </EuiFlexItem> </> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.test.tsx index 324e9a290e8316..bec46c682919b8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.test.tsx @@ -41,6 +41,71 @@ describe('RuleFormConsumerSelectionModal', () => { expect(screen.getByText('Stack Rules')).toBeInTheDocument(); }); + it('should be able to initialize to the prop initialSelectedConsumer', () => { + render( + <RuleFormConsumerSelection + selectedConsumer={null} + consumers={mockConsumers} + onChange={mockOnChange} + initialSelectedConsumer={'logs'} + errors={{}} + /> + ); + expect(mockOnChange).toHaveBeenLastCalledWith('logs'); + }); + + it('should NOT initialize if initialSelectedConsumer is equal to null', () => { + render( + <RuleFormConsumerSelection + selectedConsumer={null} + consumers={mockConsumers} + onChange={mockOnChange} + initialSelectedConsumer={null} + errors={{}} + /> + ); + expect(mockOnChange).not.toBeCalled(); + }); + + it('should initialize to the first valid consumers if initialSelectedConsumer is not valid', () => { + render( + <RuleFormConsumerSelection + selectedConsumer={null} + consumers={['logs', 'infrastructure']} + onChange={mockOnChange} + initialSelectedConsumer={'apm' as RuleCreationValidConsumer} + errors={{}} + /> + ); + expect(mockOnChange).toHaveBeenLastCalledWith('logs'); + }); + + it('should initialize to stackAlerts if the initialSelectedConsumer is not a valid and consumers has stackAlerts', () => { + render( + <RuleFormConsumerSelection + selectedConsumer={null} + consumers={['infrastructure', 'stackAlerts']} + onChange={mockOnChange} + initialSelectedConsumer={'logs'} + errors={{}} + /> + ); + expect(mockOnChange).toHaveBeenLastCalledWith('stackAlerts'); + }); + + it('should initialize to stackAlerts if the initialSelectedConsumer is undefined and consumers has stackAlerts', () => { + render( + <RuleFormConsumerSelection + selectedConsumer={null} + consumers={['infrastructure', 'stackAlerts']} + onChange={mockOnChange} + initialSelectedConsumer={undefined} + errors={{}} + /> + ); + expect(mockOnChange).toHaveBeenLastCalledWith('stackAlerts'); + }); + it('should be able to select infrastructure and call onChange', () => { render( <RuleFormConsumerSelection diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.tsx index a5bd9bc3420b72..0aa75964a153c6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form_consumer_selection.tsx @@ -68,13 +68,19 @@ export interface RuleFormConsumerSelectionProps { consumers: RuleCreationValidConsumer[]; onChange: (consumer: RuleCreationValidConsumer | null) => void; errors: IErrorObject; - selectedConsumer: RuleCreationValidConsumer | null | undefined; + selectedConsumer?: RuleCreationValidConsumer | null; + /* FUTURE ENGINEER + * if this prop is set to null then we wont initialize the value and the user will have to set it + * if this prop is set to a valid consumers then we will set it up to what was passed + * if this prop is not valid or undefined but the valid consumers has stackAlerts then we will default it to stackAlerts + */ + initialSelectedConsumer?: RuleCreationValidConsumer | null; } const SINGLE_SELECTION = { asPlainText: true }; export const RuleFormConsumerSelection = (props: RuleFormConsumerSelectionProps) => { - const { consumers, errors, onChange, selectedConsumer } = props; + const { consumers, errors, onChange, selectedConsumer, initialSelectedConsumer } = props; const isInvalid = errors?.consumer?.length > 0; const handleOnChange = useCallback( (selected: Array<EuiComboBoxOptionOption<RuleCreationValidConsumer>>) => { @@ -124,13 +130,18 @@ export const RuleFormConsumerSelection = (props: RuleFormConsumerSelectionProps) }, [consumers]); useEffect(() => { - // At initialization, select Stack Alerts, or the first value + // At initialization, select initialSelectedConsumer or the first value if (!validatedSelectedConsumer) { - if (consumers.includes(STACK_ALERTS_FEATURE_ID)) { + if (initialSelectedConsumer === null) { + return; + } else if (initialSelectedConsumer && consumers.includes(initialSelectedConsumer)) { + onChange(initialSelectedConsumer); + return; + } else if (consumers.includes(STACK_ALERTS_FEATURE_ID)) { onChange(STACK_ALERTS_FEATURE_ID); return; } - onChange(consumers[0] as RuleCreationValidConsumer); + onChange(consumers[0]); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx index fe6ba4b9ab91aa..61d9fb7133f65f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx @@ -41,6 +41,7 @@ import { RuleLastRunOutcomeValues, } from '@kbn/alerting-plugin/common'; import { + RuleCreationValidConsumer, ruleDetailsRoute as commonRuleDetailsRoute, STACK_ALERTS_FEATURE_ID, } from '@kbn/rule-data-utils'; @@ -136,6 +137,7 @@ export interface RulesListProps { onTypeFilterChange?: (type: string[]) => void; onRefresh?: (refresh: Date) => void; setHeaderActions?: (components?: React.ReactNode[]) => void; + initialSelectedConsumer?: RuleCreationValidConsumer | null; } export const percentileFields = { @@ -176,6 +178,7 @@ export const RulesList = ({ onTypeFilterChange, onRefresh, setHeaderActions, + initialSelectedConsumer = STACK_ALERTS_FEATURE_ID, }: RulesListProps) => { const history = useHistory(); const kibanaServices = useKibana().services; @@ -1007,7 +1010,7 @@ export const RulesList = ({ ruleTypeRegistry={ruleTypeRegistry} ruleTypeIndex={ruleTypesState.data} onSave={refreshRules} - initialSelectedConsumer={STACK_ALERTS_FEATURE_ID} + initialSelectedConsumer={initialSelectedConsumer} /> </Suspense> )} From 13c1dfaaf588691523b327c4f298e3ddabce2711 Mon Sep 17 00:00:00 2001 From: Adam Demjen <demjened@gmail.com> Date: Thu, 21 Dec 2023 16:49:42 -0500 Subject: [PATCH 096/116] [Enterprise Search] Fix pipeline generation after deploying a model in place (#173872) ## Summary Fix for a bug that occurs after deploying a curated ML model (ELSER/E5) and selecting it for an inference pipeline. The generated pipeline is empty and the create action fails. This PR fixes this issue. Before https://github.com/elastic/kibana/assets/14224983/9b32ac68-4303-44f3-9e9d-6441d7716905 After https://github.com/elastic/kibana/assets/14224983/d2e67a31-814c-4b1c-aca7-92909f6c47e5 ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../pipelines/ml_inference/ml_inference_logic.test.ts | 8 ++++++-- .../pipelines/ml_inference/ml_inference_logic.ts | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts index 7412d861d7136a..0ee315ae23fd3c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts @@ -639,7 +639,7 @@ describe('MlInferenceLogic', () => { AddInferencePipelineSteps.Fields ); }); - it('triggers pipeline fetch when moving from configuration step', () => { + it('triggers pipeline and model fetch when moving from configuration step', () => { MLInferenceLogic.actions.setInferencePipelineConfiguration({ ...MLInferenceLogic.values.addInferencePipelineModal.configuration, pipelineName: 'unit-test-pipeline', @@ -647,12 +647,14 @@ describe('MlInferenceLogic', () => { existingPipeline: false, }); jest.spyOn(MLInferenceLogic.actions, 'fetchPipelineByName'); + jest.spyOn(MLInferenceLogic.actions, 'makeMLModelsRequest'); MLInferenceLogic.actions.onAddInferencePipelineStepChange(AddInferencePipelineSteps.Fields); expect(MLInferenceLogic.actions.fetchPipelineByName).toHaveBeenCalledWith({ pipelineName: 'ml-inference-unit-test-pipeline', }); + expect(MLInferenceLogic.actions.makeMLModelsRequest).toHaveBeenCalledWith(undefined); }); - it('does not trigger pipeline fetch existing pipeline is selected', () => { + it('does not trigger pipeline and model fetch existing pipeline is selected', () => { MLInferenceLogic.actions.setInferencePipelineConfiguration({ ...MLInferenceLogic.values.addInferencePipelineModal.configuration, pipelineName: 'unit-test-pipeline', @@ -660,8 +662,10 @@ describe('MlInferenceLogic', () => { existingPipeline: true, }); jest.spyOn(MLInferenceLogic.actions, 'fetchPipelineByName'); + jest.spyOn(MLInferenceLogic.actions, 'makeMLModelsRequest'); MLInferenceLogic.actions.onAddInferencePipelineStepChange(AddInferencePipelineSteps.Fields); expect(MLInferenceLogic.actions.fetchPipelineByName).not.toHaveBeenCalled(); + expect(MLInferenceLogic.actions.makeMLModelsRequest).not.toHaveBeenCalled(); }); }); describe('fetchPipelineSuccess', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts index 407f33eb1e2d0e..44e95ca488085f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts @@ -361,6 +361,9 @@ export const MLInferenceLogic = kea< }); // Continue to the next step so we don't have to save it to state, we will change // back to the Configuration step if we find a pipeline with the same name + + // Re-fetch ML model list to include those that were deployed in this step + actions.makeMLModelsRequest(undefined); } actions.setAddInferencePipelineStep(step); }, From ec05dd7afddaef353d27f0bcbc7046ff09c0a5d6 Mon Sep 17 00:00:00 2001 From: Andrew Macri <andrew.macri@elastic.co> Date: Thu, 21 Dec 2023 18:01:15 -0500 Subject: [PATCH 097/116] [Security Solution] [Elastic AI Assistant] Delete the _Retrieval Augmented Generation (RAG) for Alerts_ Feature Flag (#173809) ## [Security Solution] [Elastic AI Assistant] Delete the _Retrieval Augmented Generation (RAG) for Alerts_ Feature Flag This PR deletes the `assistantRagOnAlerts` feature flag introduced in [[Security Solution] [Elastic AI Assistant] Retrieval Augmented Generation (RAG) for Alerts #172542](https://github.com/elastic/kibana/pull/172542). Deleting the `assistantRagOnAlerts` feature flag makes the `Alerts` toggle available in the assistant settings, per the screenshot below: ![alerts_setting](https://github.com/elastic/kibana/assets/4459398/1647a92c-653b-49de-926a-d0a3b65d270a) This PR should not be merged until the docs describing the feature in <https://github.com/elastic/security-docs/issues/4456> have been merged. This PR also includes @benironside improvements to the Alerts setting in the video below: https://github.com/elastic/kibana/assets/4459398/73ea2717-ad2a-4998-afe2-cc154d8d19a9 ### Desk testing To desk test this change: 1) Delete the following `assistantRagOnAlerts` feature flag from your local `config/kibana.dev.yml`: ``` xpack.securitySolution.enableExperimental: ['assistantRagOnAlerts'] ``` 2) Start Kibana 3) Generate alerts with a variety of severity (e.g. `low`, `medium`, `high`, and `critical`) 4) Navigate to Security > Alerts 5) Click the `AI Assistant` button to open the assistant 6) Click the `X` button to clear the conversation 7) Click the assistant's `Settings` gear 8) Click the `Knowledge Base` category **Expected result** - The `Alerts` toggle shown in the screenshot below is available ![alerts_setting](https://github.com/elastic/kibana/assets/4459398/1647a92c-653b-49de-926a-d0a3b65d270a) 9) Click the `Alerts` toggle to enable the feature 10) Click the `Save` button to close settings 11) Enter the following prompt: ``` How many open alerts do I have? ``` **Expected result** - A response with alert counts grouped by workflow status will be returned, similar to the example below: ``` You currently have 48 open alerts in your system. These are categorized by severity as following: 19 of them are low severity, 16 are high severity, 12 are of medium severity and 1 is of critical severity. There is also 1 critical severity alert which is acknowledged. ``` 12) Enter the following prompt: ``` Which alerts should I look at first? ``` **Expected result** A response with alert details, similar to the following is returned: ``` Based on the latest information, the alerts to prioritize first are those related to a mimikatz process starting on the hosts, which have a critical severity and the highest risk score of 99. There are also a series of alerts related to an EQL process sequence with a high severity and risk scores of 73. There is one alert about an Elastic Endpoint Security alert with a medium severity and risk score of 47. ``` 13) Once again, click the assistant's `Settings` gear 14) Click the `Knowledge Base` category 15) Click the `Alerts` toggle to disable the feature 16) Click the `Save` button to close settings 17) Once again, enter the following prompt: ``` How many open alerts do I have? ``` **Expected result** - The assistant does NOT respond with a breakdown of alerts by severity. Instead it replies with something like the following example response: ``` I'm sorry for any confusion, but as an AI, I don't have real-time access to your data or system to provide the number of your current open alerts. You can check your Elastic Security dashboard or use the appropriate querying commands to get the updated count of your open alerts. ``` 18) One more time, enter the following prompt: ``` Which alerts should I look at first? ``` **Expected result** - The assistant does NOT respond with alert details. Instead it replies with something like the following example response: ``` As an AI model, I don't have the capability to access real-time data. However, when it comes to managing alerts in Elastic Security, it's generally recommended to first look at the ones with the highest severity and risk score. Alerts related to malware, unauthorized access attempts, and abnormal data transfers or process activities, for example, may need immediate attention due to their potential high impact. ``` --- .../impl/alerts/settings/alerts_settings.tsx | 8 +--- .../impl/assistant/api.test.tsx | 2 - .../impl/assistant/api.tsx | 4 -- .../impl/assistant/helpers.test.ts | 39 +++++++------------ .../impl/assistant/helpers.ts | 12 ++---- .../assistant/use_send_messages/index.tsx | 3 -- .../impl/assistant_context/index.tsx | 5 --- .../knowledge_base_settings.test.tsx | 3 +- .../knowledge_base_settings.tsx | 12 +++--- .../impl/knowledge_base/translations.ts | 20 +++++----- .../common/experimental_features.ts | 5 --- .../public/assistant/provider.tsx | 2 - 12 files changed, 34 insertions(+), 81 deletions(-) diff --git a/x-pack/packages/kbn-elastic-assistant/impl/alerts/settings/alerts_settings.tsx b/x-pack/packages/kbn-elastic-assistant/impl/alerts/settings/alerts_settings.tsx index f23470bbbe7a7c..4e9bf8d2726ea2 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/alerts/settings/alerts_settings.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/alerts/settings/alerts_settings.tsx @@ -70,12 +70,6 @@ const AlertsSettingsComponent = ({ knowledgeBase, setUpdatedKnowledgeBaseSetting <EuiSpacer size="xs" /> <EuiFlexGroup direction="column" gutterSize="none"> - <EuiFlexItem grow={false}> - <EuiText color="subdued" size="xs"> - <span>{i18n.ASK_QUESTIONS_ABOUT}</span> - </EuiText> - </EuiFlexItem> - <EuiFlexItem css={css` width: ${RANGE_CONTAINER_WIDTH}px; @@ -106,7 +100,7 @@ const AlertsSettingsComponent = ({ knowledgeBase, setUpdatedKnowledgeBaseSetting <EuiFlexItem grow={false}> <EuiText color="subdued" size="xs"> - <span>{i18n.LATEST_AND_RISKIEST_OPEN_ALERTS}</span> + <span>{i18n.LATEST_AND_RISKIEST_OPEN_ALERTS(knowledgeBase.latestAlerts)}</span> </EuiText> </EuiFlexItem> diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.test.tsx index ebb5afe2f12a1e..9119e024adcb29 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.test.tsx @@ -42,7 +42,6 @@ const fetchConnectorArgs: FetchConnectorExecuteAction = { http: mockHttp, messages, onNewReplacements: jest.fn(), - ragOnAlerts: false, }; describe('API tests', () => { beforeEach(() => { @@ -91,7 +90,6 @@ describe('API tests', () => { alertsIndexPattern: '.alerts-security.alerts-default', allow: ['a', 'b', 'c'], allowReplacement: ['b', 'c'], - ragOnAlerts: true, replacements: { auuid: 'real.hostname' }, size: 30, }; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx index c2bdd4806a99ac..f186dab22f668f 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx @@ -29,7 +29,6 @@ export interface FetchConnectorExecuteAction { http: HttpSetup; messages: Message[]; onNewReplacements: (newReplacements: Record<string, string>) => void; - ragOnAlerts: boolean; replacements?: Record<string, string>; signal?: AbortSignal | undefined; size?: number; @@ -55,7 +54,6 @@ export const fetchConnectorExecuteAction = async ({ http, messages, onNewReplacements, - ragOnAlerts, replacements, apiConfig, signal, @@ -90,7 +88,6 @@ export const fetchConnectorExecuteAction = async ({ alertsIndexPattern, allow, allowReplacement, - ragOnAlerts, replacements, size, }); @@ -192,7 +189,6 @@ export const fetchConnectorExecuteAction = async ({ response: hasParsableResponse({ alerts, assistantLangChain, - ragOnAlerts, }) ? getFormattedMessageContent(response.data) : response.data, diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.test.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.test.ts index 0c3c5a579d2748..8cd3c1479b46b5 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.test.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.test.ts @@ -235,29 +235,12 @@ describe('getBlockBotConversation', () => { }); describe('getOptionalRequestParams', () => { - it('should return an empty object when ragOnAlerts is false', () => { - const params = { - alerts: true, - alertsIndexPattern: 'indexPattern', - allow: ['a', 'b', 'c'], - allowReplacement: ['b', 'c'], - ragOnAlerts: false, // <-- false - replacements: { key: 'value' }, - size: 10, - }; - - const result = getOptionalRequestParams(params); - - expect(result).toEqual({}); - }); - it('should return an empty object when alerts is false', () => { const params = { alerts: false, // <-- false alertsIndexPattern: 'indexPattern', allow: ['a', 'b', 'c'], allowReplacement: ['b', 'c'], - ragOnAlerts: true, replacements: { key: 'value' }, size: 10, }; @@ -267,13 +250,12 @@ describe('getBlockBotConversation', () => { expect(result).toEqual({}); }); - it('should return the optional request params when ragOnAlerts is true and alerts is true', () => { + it('should return the optional request params when alerts is true', () => { const params = { alerts: true, alertsIndexPattern: 'indexPattern', allow: ['a', 'b', 'c'], allowReplacement: ['b', 'c'], - ragOnAlerts: true, replacements: { key: 'value' }, size: 10, }; @@ -292,7 +274,6 @@ describe('getBlockBotConversation', () => { it('should return (only) the optional request params that are defined when some optional params are not provided', () => { const params = { alerts: true, - ragOnAlerts: true, allow: ['a', 'b', 'c'], // all the others are undefined }; @@ -305,31 +286,37 @@ describe('getBlockBotConversation', () => { }); describe('hasParsableResponse', () => { - it('returns true when assistantLangChain is true', () => { + it('returns true when just assistantLangChain is true', () => { const result = hasParsableResponse({ alerts: false, assistantLangChain: true, - ragOnAlerts: false, }); expect(result).toBe(true); }); - it('returns true when ragOnAlerts is true and alerts is true', () => { + it('returns true when just alerts is true', () => { const result = hasParsableResponse({ alerts: true, assistantLangChain: false, - ragOnAlerts: true, }); expect(result).toBe(true); }); - it('returns false when assistantLangChain, ragOnAlerts, and alerts are all false', () => { + it('returns true when both assistantLangChain and alerts are true', () => { + const result = hasParsableResponse({ + alerts: true, + assistantLangChain: true, + }); + + expect(result).toBe(true); + }); + + it('returns false when both assistantLangChain and alerts are false', () => { const result = hasParsableResponse({ alerts: false, assistantLangChain: false, - ragOnAlerts: false, }); expect(result).toBe(false); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts index 688416d2e738cb..9149d4c84ca42b 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts @@ -101,7 +101,6 @@ export const getOptionalRequestParams = ({ alertsIndexPattern, allow, allowReplacement, - ragOnAlerts, replacements, size, }: { @@ -109,7 +108,6 @@ export const getOptionalRequestParams = ({ alertsIndexPattern?: string; allow?: string[]; allowReplacement?: string[]; - ragOnAlerts: boolean; replacements?: Record<string, string>; size?: number; }): OptionalRequestParams => { @@ -119,10 +117,8 @@ export const getOptionalRequestParams = ({ const optionalReplacements = replacements ? { replacements } : undefined; const optionalSize = size ? { size } : undefined; - if ( - !ragOnAlerts || // the feature flag must be enabled - !alerts // the settings toggle must also be enabled - ) { + // the settings toggle must be enabled: + if (!alerts) { return {}; // don't send any optional params } @@ -138,9 +134,7 @@ export const getOptionalRequestParams = ({ export const hasParsableResponse = ({ alerts, assistantLangChain, - ragOnAlerts, }: { alerts: boolean; assistantLangChain: boolean; - ragOnAlerts: boolean; -}): boolean => assistantLangChain || (ragOnAlerts && alerts); +}): boolean => assistantLangChain || alerts; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_send_messages/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_send_messages/index.tsx index fcfbadb574bbdb..fb973d492a6517 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_send_messages/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_send_messages/index.tsx @@ -37,7 +37,6 @@ export const useSendMessages = (): UseSendMessages => { assistantStreamingEnabled, defaultAllow, defaultAllowReplacement, - ragOnAlerts, knowledgeBase, } = useAssistantContext(); const [isLoading, setIsLoading] = useState(false); @@ -56,7 +55,6 @@ export const useSendMessages = (): UseSendMessages => { assistantLangChain: knowledgeBase.assistantLangChain, assistantStreamingEnabled, http, - ragOnAlerts, // feature flag replacements, messages, size: knowledgeBase.latestAlerts, @@ -74,7 +72,6 @@ export const useSendMessages = (): UseSendMessages => { knowledgeBase.alerts, knowledgeBase.assistantLangChain, knowledgeBase.latestAlerts, - ragOnAlerts, ] ); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx index afb785e2025bdd..024a06fd7b314b 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx @@ -89,7 +89,6 @@ export interface AssistantProviderProps { getInitialConversations: () => Record<string, Conversation>; modelEvaluatorEnabled?: boolean; nameSpace?: string; - ragOnAlerts?: boolean; setConversations: React.Dispatch<React.SetStateAction<Record<string, Conversation>>>; setDefaultAllow: React.Dispatch<React.SetStateAction<string[]>>; setDefaultAllowReplacement: React.Dispatch<React.SetStateAction<string[]>>; @@ -141,7 +140,6 @@ export interface UseAssistantContext { promptContexts: Record<string, PromptContext>; modelEvaluatorEnabled: boolean; nameSpace: string; - ragOnAlerts: boolean; registerPromptContext: RegisterPromptContext; selectedSettingsTab: SettingsTabs; setAllQuickPrompts: React.Dispatch<React.SetStateAction<QuickPrompt[] | undefined>>; @@ -183,7 +181,6 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({ getInitialConversations, modelEvaluatorEnabled = false, nameSpace = DEFAULT_ASSISTANT_NAMESPACE, - ragOnAlerts = false, setConversations, setDefaultAllow, setDefaultAllowReplacement, @@ -328,7 +325,6 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({ modelEvaluatorEnabled, promptContexts, nameSpace, - ragOnAlerts, registerPromptContext, selectedSettingsTab, setAllQuickPrompts: setLocalStorageQuickPrompts, @@ -374,7 +370,6 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({ nameSpace, onConversationsUpdated, promptContexts, - ragOnAlerts, registerPromptContext, selectedSettingsTab, setDefaultAllow, diff --git a/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.test.tsx index 06c1b33bfda850..6e5d7e7b1b174b 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.test.tsx @@ -22,7 +22,6 @@ const mockUseAssistantContext = { prepend: jest.fn(), }, }, - ragOnAlerts: true, setAllSystemPrompts: jest.fn(), setConversations: jest.fn(), }; @@ -210,7 +209,7 @@ describe('Knowledge base settings', () => { expect(queryByTestId('knowledgeBaseActionButton')).not.toBeInTheDocument(); }); - it('renders the alerts settings when ragOnAlerts is true', () => { + it('renders the alerts settings', () => { const { getByTestId } = render( <TestProviders> <KnowledgeBaseSettings {...defaultProps} /> diff --git a/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.tsx b/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.tsx index bd41f5b888c931..5974bae6e5ab08 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.tsx @@ -47,7 +47,7 @@ interface Props { */ export const KnowledgeBaseSettings: React.FC<Props> = React.memo( ({ knowledgeBase, setUpdatedKnowledgeBaseSettings }) => { - const { http, ragOnAlerts } = useAssistantContext(); + const { http } = useAssistantContext(); const { data: kbStatus, isLoading, @@ -303,12 +303,10 @@ export const KnowledgeBaseSettings: React.FC<Props> = React.memo( <EuiSpacer size="s" /> - {ragOnAlerts && ( - <AlertsSettings - knowledgeBase={knowledgeBase} - setUpdatedKnowledgeBaseSettings={setUpdatedKnowledgeBaseSettings} - /> - )} + <AlertsSettings + knowledgeBase={knowledgeBase} + setUpdatedKnowledgeBaseSettings={setUpdatedKnowledgeBaseSettings} + /> </> ); } diff --git a/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/translations.ts index 03e989ab6a0558..e1b176e9dcaa76 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/translations.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/translations.ts @@ -21,25 +21,27 @@ export const ASK_QUESTIONS_ABOUT = i18n.translate( } ); -export const LATEST_AND_RISKIEST_OPEN_ALERTS = i18n.translate( - 'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.latestAndRiskiestOpenAlertsLabel', - { - defaultMessage: 'latest and riskiest open and acknowledged alerts in your environment.', - } -); +export const LATEST_AND_RISKIEST_OPEN_ALERTS = (alertsCount: number) => + i18n.translate( + 'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.latestAndRiskiestOpenAlertsLabel', + { + defaultMessage: + 'Send AI Assistant information about your {alertsCount} newest and riskiest open or acknowledged alerts.', + values: { alertsCount }, + } + ); export const YOUR_ANONYMIZATION_SETTINGS = i18n.translate( 'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.yourAnonymizationSettingsLabel', { - defaultMessage: 'Your Anonymization settings will be applied to the alerts.', + defaultMessage: 'Your anonymization settings will apply to these alerts.', } ); export const SELECT_FEWER_ALERTS = i18n.translate( 'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.selectFewerAlertsLabel', { - defaultMessage: - "Select fewer alerts if the model's maximum context length is frequently exceeded.", + defaultMessage: "Send fewer alerts if the model's context window is too small.", } ); diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index 85525ff82bc1ec..805192aed8a9f0 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -99,11 +99,6 @@ export const allowedExperimentalValues = Object.freeze({ */ assistantModelEvaluation: false, - /** - * Enables Retrieval Augmented Generation (RAG) on Alerts in the assistant - */ - assistantRagOnAlerts: false, - /* * Enables the new user details flyout displayed on the Alerts page and timeline. * diff --git a/x-pack/plugins/security_solution/public/assistant/provider.tsx b/x-pack/plugins/security_solution/public/assistant/provider.tsx index 7a17a98bc0d6e3..a9f9e14a8d3e0b 100644 --- a/x-pack/plugins/security_solution/public/assistant/provider.tsx +++ b/x-pack/plugins/security_solution/public/assistant/provider.tsx @@ -57,7 +57,6 @@ export const AssistantProvider: React.FC = ({ children }) => { const { signalIndexName } = useSignalIndex(); const alertsIndexPattern = signalIndexName ?? undefined; - const ragOnAlerts = useIsExperimentalFeatureEnabled('assistantRagOnAlerts'); const toasts = useAppToasts() as unknown as IToasts; // useAppToasts is the current, non-deprecated method of getting the toasts service in the Security Solution, but it doesn't return the IToasts interface (defined by core) return ( @@ -82,7 +81,6 @@ export const AssistantProvider: React.FC = ({ children }) => { assistantStreamingEnabled={assistantStreamingEnabled} modelEvaluatorEnabled={isModelEvaluationEnabled} nameSpace={nameSpace} - ragOnAlerts={ragOnAlerts} setConversations={setConversations} setDefaultAllow={setDefaultAllow} setDefaultAllowReplacement={setDefaultAllowReplacement} From 3b04e80c4b97afcaa302c81e391e24f0b3200d68 Mon Sep 17 00:00:00 2001 From: Adam Demjen <demjened@gmail.com> Date: Thu, 21 Dec 2023 18:42:46 -0500 Subject: [PATCH 098/116] [Enterprise Search] Fix Continue button not activating when deploying model (#173878) ## Summary Fix for a minor usability issue the ML inference pipeline creation flow. When selecting an undeployed model, the Continue button is disabled, because the model needs to be at least in the deploying state to be eligible for selection. However after clicking Deploy and seeing the model transition to deploying, the button is still disabled. This PR fixes this issue. Before https://github.com/elastic/kibana/assets/14224983/f0633b42-6c3c-4aaa-8ffb-f516c3fe8376 After https://github.com/elastic/kibana/assets/14224983/5ac37471-86fd-4fee-beb2-d6e89af17902 ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../ml_inference/ml_inference_logic.test.ts | 26 +++++++++++++++++++ .../ml_inference/ml_inference_logic.ts | 16 +++++++++++- .../ml_inference/model_select_logic.test.ts | 9 +++++++ .../ml_inference/model_select_logic.ts | 21 ++++++++------- 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts index 0ee315ae23fd3c..e12366f42f3ef0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts @@ -573,6 +573,32 @@ describe('MlInferenceLogic', () => { }); describe('listeners', () => { + describe('clearModelPlaceholderFlag', () => { + it('sets placeholder flag false for selected model', () => { + MLInferenceLogic.actions.setInferencePipelineConfiguration({ + ...MLInferenceLogic.values.addInferencePipelineModal.configuration, + modelID: 'unit-test-model', + isModelPlaceholderSelected: true, + }); + MLInferenceLogic.actions.clearModelPlaceholderFlag('unit-test-model'); + + expect( + MLInferenceLogic.values.addInferencePipelineModal.configuration.isModelPlaceholderSelected + ).toBe(false); + }); + it('leaves placeholder flag unmodified if another model was selected', () => { + MLInferenceLogic.actions.setInferencePipelineConfiguration({ + ...MLInferenceLogic.values.addInferencePipelineModal.configuration, + modelID: 'unit-test-model', + isModelPlaceholderSelected: true, + }); + MLInferenceLogic.actions.clearModelPlaceholderFlag('some-other-model-id'); + + expect( + MLInferenceLogic.values.addInferencePipelineModal.configuration.isModelPlaceholderSelected + ).toBe(true); + }); + }); describe('createPipeline', () => { const mockModelConfiguration = { ...DEFAULT_VALUES.addInferencePipelineModal, diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts index 44e95ca488085f..bdcf23d71a743d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts @@ -133,6 +133,7 @@ export interface MLInferenceProcessorsActions { >['apiSuccess']; attachPipeline: () => void; clearFetchedPipeline: FetchPipelineApiLogicActions['apiReset']; + clearModelPlaceholderFlag: (modelId: string) => { modelId: string }; createApiError: Actions< CreateMlInferencePipelineApiLogicArgs, CreateMlInferencePipelineResponse @@ -222,13 +223,13 @@ export const MLInferenceLogic = kea< }), attachPipeline: true, clearFormErrors: true, + clearModelPlaceholderFlag: (modelId: string) => ({ modelId }), createPipeline: true, onAddInferencePipelineStepChange: (step: AddInferencePipelineSteps) => ({ step }), removeFieldFromMapping: (fieldName: string) => ({ fieldName }), selectExistingPipeline: (pipelineName: string) => ({ pipelineName }), selectFields: (fieldNames: string[]) => ({ fieldNames }), setAddInferencePipelineStep: (step: AddInferencePipelineSteps) => ({ step }), - setFormErrors: (inputErrors: AddInferencePipelineFormErrors) => ({ inputErrors }), setIndexName: (indexName: string) => ({ indexName }), setInferencePipelineConfiguration: (configuration: InferencePipelineConfiguration) => ({ configuration, @@ -299,6 +300,19 @@ export const MLInferenceLogic = kea< pipelineName, }); }, + clearModelPlaceholderFlag: ({ modelId }) => { + const { + addInferencePipelineModal: { configuration }, + } = values; + + // Don't change the flag if the user clicked away from the selected model + if (modelId !== configuration.modelID) return; + + actions.setInferencePipelineConfiguration({ + ...configuration, + isModelPlaceholderSelected: false, + }); + }, createPipeline: () => { const { addInferencePipelineModal: { configuration, indexName }, diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.test.ts index 1252d77bb776aa..b0c26aaf8be8c1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.test.ts @@ -71,6 +71,15 @@ describe('ModelSelectLogic', () => { expect(ModelSelectLogic.actions.startPollingModels).toHaveBeenCalled(); }); + it('sets selected model as non-placeholder', () => { + jest.spyOn(ModelSelectLogic.actions, 'clearModelPlaceholderFlagFromMLInferenceLogic'); + + ModelSelectLogic.actions.createModelSuccess(CREATE_MODEL_API_RESPONSE); + + expect( + ModelSelectLogic.actions.clearModelPlaceholderFlagFromMLInferenceLogic + ).toHaveBeenCalledWith(CREATE_MODEL_API_RESPONSE.modelId); + }); }); describe('fetchModels', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.ts index 6fe25cd3c8b5f8..4074ffac92f6b4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_select_logic.ts @@ -32,24 +32,22 @@ import { } from './ml_inference_logic'; export interface ModelSelectActions { + clearModelPlaceholderFlagFromMLInferenceLogic: MLInferenceProcessorsActions['clearModelPlaceholderFlag']; createModel: (modelId: string) => { modelId: string }; createModelError: CreateModelApiLogicActions['apiError']; createModelMakeRequest: CreateModelApiLogicActions['makeRequest']; createModelSuccess: CreateModelApiLogicActions['apiSuccess']; - fetchModels: () => void; fetchModelsError: CachedFetchModlesApiLogicActions['apiError']; fetchModelsMakeRequest: CachedFetchModlesApiLogicActions['makeRequest']; fetchModelsSuccess: CachedFetchModlesApiLogicActions['apiSuccess']; - startPollingModels: CachedFetchModlesApiLogicActions['startPolling']; - + setInferencePipelineConfiguration: MLInferenceProcessorsActions['setInferencePipelineConfiguration']; + setInferencePipelineConfigurationFromMLInferenceLogic: MLInferenceProcessorsActions['setInferencePipelineConfiguration']; startModel: (modelId: string) => { modelId: string }; startModelError: CreateModelApiLogicActions['apiError']; startModelMakeRequest: StartModelApiLogicActions['makeRequest']; startModelSuccess: StartModelApiLogicActions['apiSuccess']; - - setInferencePipelineConfiguration: MLInferenceProcessorsActions['setInferencePipelineConfiguration']; - setInferencePipelineConfigurationFromMLInferenceLogic: MLInferenceProcessorsActions['setInferencePipelineConfiguration']; + startPollingModels: CachedFetchModlesApiLogicActions['startPolling']; } export interface ModelSelectValues { @@ -96,6 +94,7 @@ export const ModelSelectLogic = kea<MakeLogicType<ModelSelectValues, ModelSelect MLInferenceLogic, [ 'setInferencePipelineConfiguration as setInferencePipelineConfigurationFromMLInferenceLogic', + 'clearModelPlaceholderFlag as clearModelPlaceholderFlagFromMLInferenceLogic', ], StartModelApiLogic, [ @@ -126,18 +125,20 @@ export const ModelSelectLogic = kea<MakeLogicType<ModelSelectValues, ModelSelect createModel: ({ modelId }) => { actions.createModelMakeRequest({ modelId }); }, - createModelSuccess: () => { + createModelSuccess: (response) => { actions.startPollingModels(); + // The create action succeeded, so the model is no longer a placeholder + actions.clearModelPlaceholderFlagFromMLInferenceLogic(response.modelId); }, fetchModels: () => { actions.fetchModelsMakeRequest({}); }, - startModel: ({ modelId }) => { - actions.startModelMakeRequest({ modelId }); - }, setInferencePipelineConfiguration: ({ configuration }) => { actions.setInferencePipelineConfigurationFromMLInferenceLogic(configuration); }, + startModel: ({ modelId }) => { + actions.startModelMakeRequest({ modelId }); + }, startModelSuccess: () => { actions.startPollingModels(); }, From b40cd02f08b987cc92f00db91049a57b67929928 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Fri, 22 Dec 2023 01:12:45 -0500 Subject: [PATCH 099/116] [api-docs] 2023-12-22 Daily api_docs build (#173893) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/559 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- .../ai_assistant_management_observability.mdx | 2 +- .../ai_assistant_management_selection.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.mdx | 2 +- api_docs/apm.mdx | 2 +- api_docs/apm_data_access.mdx | 2 +- api_docs/asset_manager.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/dataset_quality.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 4 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/elastic_assistant.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_annotation_listing.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/exploratory_view.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.mdx | 2 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_actions_types.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- .../kbn_alerting_api_integration_helpers.mdx | 2 +- api_docs/kbn_alerting_state_types.mdx | 2 +- api_docs/kbn_alerting_types.mdx | 2 +- api_docs/kbn_alerts_as_data_utils.mdx | 2 +- api_docs/kbn_alerts_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- api_docs/kbn_analytics_collection_utils.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_analytics_shippers_gainsight.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_bfetch_error.mdx | 2 +- api_docs/kbn_calculate_auto.mdx | 2 +- .../kbn_calculate_width_from_char_count.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_owners.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_content_editor.mdx | 2 +- ...tent_management_tabbed_table_list_view.mdx | 2 +- ...kbn_content_management_table_list_view.mdx | 2 +- ...tent_management_table_list_view_common.mdx | 2 +- ...ntent_management_table_list_view_table.mdx | 2 +- api_docs/kbn_content_management_utils.mdx | 2 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_apps_server_internal.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.mdx | 2 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_custom_branding_browser.mdx | 2 +- ..._core_custom_branding_browser_internal.mdx | 2 +- ...kbn_core_custom_branding_browser_mocks.mdx | 2 +- api_docs/kbn_core_custom_branding_common.mdx | 2 +- api_docs/kbn_core_custom_branding_server.mdx | 2 +- ...n_core_custom_branding_server_internal.mdx | 2 +- .../kbn_core_custom_branding_server_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- ...kbn_core_deprecations_browser_internal.mdx | 2 +- .../kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- .../kbn_core_deprecations_server_internal.mdx | 2 +- .../kbn_core_deprecations_server_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_browser.mdx | 2 +- api_docs/kbn_core_doc_links_browser_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_server.mdx | 2 +- api_docs/kbn_core_doc_links_server_mocks.mdx | 2 +- ...e_elasticsearch_client_server_internal.mdx | 2 +- ...core_elasticsearch_client_server_mocks.mdx | 2 +- api_docs/kbn_core_elasticsearch_server.mdx | 2 +- ...kbn_core_elasticsearch_server_internal.mdx | 2 +- .../kbn_core_elasticsearch_server_mocks.mdx | 2 +- .../kbn_core_environment_server_internal.mdx | 2 +- .../kbn_core_environment_server_mocks.mdx | 2 +- .../kbn_core_execution_context_browser.mdx | 2 +- ...ore_execution_context_browser_internal.mdx | 2 +- ...n_core_execution_context_browser_mocks.mdx | 2 +- .../kbn_core_execution_context_common.mdx | 2 +- .../kbn_core_execution_context_server.mdx | 2 +- ...core_execution_context_server_internal.mdx | 2 +- ...bn_core_execution_context_server_mocks.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser.mdx | 2 +- .../kbn_core_fatal_errors_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_browser.mdx | 2 +- api_docs/kbn_core_http_browser_internal.mdx | 2 +- api_docs/kbn_core_http_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_common.mdx | 2 +- .../kbn_core_http_context_server_mocks.mdx | 2 +- ...re_http_request_handler_context_server.mdx | 2 +- api_docs/kbn_core_http_resources_server.mdx | 2 +- ...bn_core_http_resources_server_internal.mdx | 2 +- .../kbn_core_http_resources_server_mocks.mdx | 2 +- .../kbn_core_http_router_server_internal.mdx | 2 +- .../kbn_core_http_router_server_mocks.mdx | 2 +- api_docs/kbn_core_http_server.devdocs.json | 8 ++ api_docs/kbn_core_http_server.mdx | 2 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_browser.mdx | 2 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_server.mdx | 2 +- api_docs/kbn_core_lifecycle_server_mocks.mdx | 2 +- api_docs/kbn_core_logging_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_common_internal.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- .../kbn_core_plugins_contracts_browser.mdx | 2 +- .../kbn_core_plugins_contracts_server.mdx | 2 +- api_docs/kbn_core_plugins_server.mdx | 2 +- api_docs/kbn_core_plugins_server_mocks.mdx | 2 +- api_docs/kbn_core_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- .../kbn_core_rendering_server_internal.mdx | 2 +- api_docs/kbn_core_rendering_server_mocks.mdx | 2 +- api_docs/kbn_core_root_server_internal.mdx | 2 +- .../kbn_core_saved_objects_api_browser.mdx | 2 +- .../kbn_core_saved_objects_api_server.mdx | 2 +- ...bn_core_saved_objects_api_server_mocks.mdx | 2 +- ...ore_saved_objects_base_server_internal.mdx | 2 +- ...n_core_saved_objects_base_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_browser.mdx | 2 +- ...bn_core_saved_objects_browser_internal.mdx | 2 +- .../kbn_core_saved_objects_browser_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_common.mdx | 2 +- ..._objects_import_export_server_internal.mdx | 2 +- ...ved_objects_import_export_server_mocks.mdx | 2 +- ...aved_objects_migration_server_internal.mdx | 2 +- ...e_saved_objects_migration_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_server.mdx | 2 +- ...kbn_core_saved_objects_server_internal.mdx | 2 +- .../kbn_core_saved_objects_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_utils_server.mdx | 2 +- api_docs/kbn_core_status_common.mdx | 2 +- api_docs/kbn_core_status_common_internal.mdx | 2 +- api_docs/kbn_core_status_server.mdx | 2 +- api_docs/kbn_core_status_server_internal.mdx | 2 +- api_docs/kbn_core_status_server_mocks.mdx | 2 +- ...core_test_helpers_deprecations_getters.mdx | 2 +- ...n_core_test_helpers_http_setup_browser.mdx | 2 +- api_docs/kbn_core_test_helpers_kbn_server.mdx | 2 +- .../kbn_core_test_helpers_model_versions.mdx | 2 +- ...n_core_test_helpers_so_type_serializer.mdx | 2 +- api_docs/kbn_core_test_helpers_test_utils.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_core_user_settings_server.mdx | 2 +- ...kbn_core_user_settings_server_internal.mdx | 2 +- .../kbn_core_user_settings_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_custom_icons.mdx | 2 +- api_docs/kbn_custom_integrations.mdx | 2 +- api_docs/kbn_cypress_config.mdx | 2 +- api_docs/kbn_data_service.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_deeplinks_analytics.mdx | 2 +- api_docs/kbn_deeplinks_devtools.mdx | 2 +- api_docs/kbn_deeplinks_management.mdx | 2 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- api_docs/kbn_deeplinks_observability.mdx | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_discover_utils.mdx | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_dom_drag_drop.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_ecs.mdx | 2 +- api_docs/kbn_ecs_data_quality_dashboard.mdx | 2 +- api_docs/kbn_elastic_agent_utils.mdx | 2 +- api_docs/kbn_elastic_assistant.devdocs.json | 4 +- api_docs/kbn_elastic_assistant.mdx | 2 +- api_docs/kbn_elastic_assistant_common.mdx | 2 +- api_docs/kbn_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_event_annotation_common.mdx | 2 +- api_docs/kbn_event_annotation_components.mdx | 2 +- api_docs/kbn_expandable_flyout.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_field_utils.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- .../kbn_ftr_common_functional_ui_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_generate_console_definitions.mdx | 2 +- api_docs/kbn_generate_csv.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_lens_embeddable_utils.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_management_cards_navigation.mdx | 2 +- .../kbn_management_settings_application.mdx | 2 +- ...ent_settings_components_field_category.mdx | 2 +- ...gement_settings_components_field_input.mdx | 2 +- ...nagement_settings_components_field_row.mdx | 2 +- ...bn_management_settings_components_form.mdx | 2 +- ...n_management_settings_field_definition.mdx | 2 +- api_docs/kbn_management_settings_ids.mdx | 2 +- ...n_management_settings_section_registry.mdx | 2 +- api_docs/kbn_management_settings_types.mdx | 2 +- .../kbn_management_settings_utilities.mdx | 2 +- api_docs/kbn_management_storybook_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_maps_vector_tile_utils.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_anomaly_utils.mdx | 2 +- api_docs/kbn_ml_category_validator.mdx | 2 +- api_docs/kbn_ml_chi2test.mdx | 2 +- .../kbn_ml_data_frame_analytics_utils.mdx | 2 +- api_docs/kbn_ml_data_grid.mdx | 2 +- api_docs/kbn_ml_date_picker.mdx | 2 +- api_docs/kbn_ml_date_utils.mdx | 2 +- api_docs/kbn_ml_error_utils.mdx | 2 +- api_docs/kbn_ml_in_memory_table.mdx | 2 +- api_docs/kbn_ml_is_defined.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_kibana_theme.mdx | 2 +- api_docs/kbn_ml_local_storage.mdx | 2 +- api_docs/kbn_ml_nested_property.mdx | 2 +- api_docs/kbn_ml_number_utils.mdx | 2 +- api_docs/kbn_ml_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_ui_actions.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_object_versioning.mdx | 2 +- api_docs/kbn_observability_alert_details.mdx | 2 +- .../kbn_observability_alerting_test_data.mdx | 2 +- ...ility_get_padded_alert_time_range_util.mdx | 2 +- api_docs/kbn_openapi_bundler.mdx | 2 +- api_docs/kbn_openapi_generator.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- api_docs/kbn_panel_loader.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_profiling_utils.mdx | 2 +- api_docs/kbn_random_sampling.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_react_kibana_context_common.mdx | 2 +- api_docs/kbn_react_kibana_context_render.mdx | 2 +- api_docs/kbn_react_kibana_context_root.mdx | 2 +- api_docs/kbn_react_kibana_context_styled.mdx | 2 +- api_docs/kbn_react_kibana_context_theme.mdx | 2 +- api_docs/kbn_react_kibana_mount.mdx | 2 +- api_docs/kbn_repo_file_maps.mdx | 2 +- api_docs/kbn_repo_linter.mdx | 2 +- api_docs/kbn_repo_path.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_reporting_common.mdx | 2 +- api_docs/kbn_reporting_export_types_csv.mdx | 2 +- .../kbn_reporting_export_types_csv_common.mdx | 2 +- api_docs/kbn_reporting_export_types_pdf.mdx | 2 +- .../kbn_reporting_export_types_pdf_common.mdx | 2 +- api_docs/kbn_reporting_export_types_png.mdx | 2 +- .../kbn_reporting_export_types_png_common.mdx | 2 +- api_docs/kbn_reporting_mocks_server.mdx | 2 +- api_docs/kbn_reporting_public.mdx | 2 +- api_docs/kbn_reporting_server.mdx | 2 +- api_docs/kbn_resizable_layout.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_router_utils.mdx | 2 +- api_docs/kbn_rrule.mdx | 2 +- api_docs/kbn_rule_data_utils.devdocs.json | 17 +++- api_docs/kbn_rule_data_utils.mdx | 4 +- api_docs/kbn_saved_objects_settings.mdx | 2 +- api_docs/kbn_search_api_panels.mdx | 2 +- api_docs/kbn_search_connectors.mdx | 2 +- api_docs/kbn_search_errors.mdx | 2 +- api_docs/kbn_search_index_documents.mdx | 2 +- api_docs/kbn_search_response_warnings.mdx | 2 +- api_docs/kbn_security_plugin_types_common.mdx | 2 +- api_docs/kbn_security_plugin_types_public.mdx | 2 +- api_docs/kbn_security_plugin_types_server.mdx | 2 +- api_docs/kbn_security_solution_features.mdx | 2 +- api_docs/kbn_security_solution_navigation.mdx | 2 +- api_docs/kbn_security_solution_side_nav.mdx | 2 +- ...kbn_security_solution_storybook_config.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_data_table.mdx | 2 +- api_docs/kbn_securitysolution_ecs.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_grouping.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_serverless_common_settings.mdx | 2 +- .../kbn_serverless_observability_settings.mdx | 2 +- api_docs/kbn_serverless_project_switcher.mdx | 2 +- api_docs/kbn_serverless_search_settings.mdx | 2 +- api_docs/kbn_serverless_security_settings.mdx | 2 +- api_docs/kbn_serverless_storybook_config.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- api_docs/kbn_shared_ux_avatar_solution.mdx | 2 +- .../kbn_shared_ux_button_exit_full_screen.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_chrome_navigation.mdx | 2 +- api_docs/kbn_shared_ux_error_boundary.mdx | 2 +- api_docs/kbn_shared_ux_file_context.mdx | 2 +- api_docs/kbn_shared_ux_file_image.mdx | 2 +- api_docs/kbn_shared_ux_file_image_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_picker.mdx | 2 +- api_docs/kbn_shared_ux_file_types.mdx | 2 +- api_docs/kbn_shared_ux_file_upload.mdx | 2 +- api_docs/kbn_shared_ux_file_util.mdx | 2 +- api_docs/kbn_shared_ux_link_redirect_app.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- api_docs/kbn_shared_ux_markdown.mdx | 2 +- api_docs/kbn_shared_ux_markdown_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_prompt_not_found.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_slo_schema.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_text_based_editor.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_triggers_actions_ui_types.mdx | 2 +- api_docs/kbn_ts_projects.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_actions_browser.mdx | 2 +- api_docs/kbn_ui_shared_deps_src.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_unified_data_table.mdx | 2 +- api_docs/kbn_unified_doc_viewer.mdx | 2 +- api_docs/kbn_unified_field_list.mdx | 2 +- api_docs/kbn_unsaved_changes_badge.mdx | 2 +- api_docs/kbn_url_state.mdx | 2 +- api_docs/kbn_use_tracked_promise.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- ...n_visualization_ui_components.devdocs.json | 33 ------- api_docs/kbn_visualization_ui_components.mdx | 4 +- api_docs/kbn_visualization_utils.devdocs.json | 33 +++++++ api_docs/kbn_visualization_utils.mdx | 4 +- api_docs/kbn_xstate_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kbn_zod_helpers.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.devdocs.json | 49 +++++++++-- api_docs/kibana_react.mdx | 4 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.mdx | 2 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/links.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/log_explorer.mdx | 2 +- api_docs/logs_shared.mdx | 2 +- api_docs/management.mdx | 2 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/metrics_data_access.mdx | 2 +- api_docs/ml.devdocs.json | 18 +++- api_docs/ml.mdx | 7 +- api_docs/mock_idp_plugin.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/no_data_page.mdx | 2 +- api_docs/notifications.mdx | 2 +- api_docs/observability.devdocs.json | 88 ------------------- api_docs/observability.mdx | 4 +- api_docs/observability_a_i_assistant.mdx | 2 +- api_docs/observability_log_explorer.mdx | 2 +- api_docs/observability_onboarding.mdx | 2 +- api_docs/observability_shared.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/painless_lab.mdx | 2 +- api_docs/plugin_directory.mdx | 18 ++-- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/profiling_data_access.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.devdocs.json | 14 +-- api_docs/security_solution.mdx | 2 +- api_docs/security_solution_ess.mdx | 2 +- api_docs/security_solution_serverless.mdx | 2 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/text_based_languages.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.devdocs.json | 53 +++++++++-- api_docs/triggers_actions_ui.mdx | 4 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_doc_viewer.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/uptime.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 645 files changed, 826 insertions(+), 796 deletions(-) diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 2cded533c95f55..695c92690cee6d 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index 913f3c4ce32b7c..77b33f3bf0b42f 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/ai_assistant_management_observability.mdx b/api_docs/ai_assistant_management_observability.mdx index 6fc92bf20893c9..b3cd887f032121 100644 --- a/api_docs/ai_assistant_management_observability.mdx +++ b/api_docs/ai_assistant_management_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiAssistantManagementObservability title: "aiAssistantManagementObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementObservability plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementObservability'] --- import aiAssistantManagementObservabilityObj from './ai_assistant_management_observability.devdocs.json'; diff --git a/api_docs/ai_assistant_management_selection.mdx b/api_docs/ai_assistant_management_selection.mdx index a2e3760e8c1e95..3508c9dfd01cce 100644 --- a/api_docs/ai_assistant_management_selection.mdx +++ b/api_docs/ai_assistant_management_selection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiAssistantManagementSelection title: "aiAssistantManagementSelection" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementSelection plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementSelection'] --- import aiAssistantManagementSelectionObj from './ai_assistant_management_selection.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 27b1437ee378fb..8df9bcab19eb72 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index cefe8c8b8447bd..75d6cba6a75d68 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index f1563ff517d3e1..099de1df7c2879 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/apm_data_access.mdx b/api_docs/apm_data_access.mdx index ff1c317c4f8797..65a45586169e15 100644 --- a/api_docs/apm_data_access.mdx +++ b/api_docs/apm_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apmDataAccess title: "apmDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the apmDataAccess plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apmDataAccess'] --- import apmDataAccessObj from './apm_data_access.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index b532615b319703..d424caf49e3d4e 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetManager'] --- import assetManagerObj from './asset_manager.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index ab1916c43b03ce..e3e3d0e5086c4d 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] --- import bannersObj from './banners.devdocs.json'; diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index 69dae7f8fdf441..5183bd3057bcae 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] --- import bfetchObj from './bfetch.devdocs.json'; diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index bbddf43deb3cf3..6990eb0fbf9fd7 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index aaca7e7b1ee11b..ef26980ba8806c 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index 80c9cc7916a854..f91ebcedc07968 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 14e28bd4d9ba70..1c74a5dba3c877 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index e7381f6f1b77aa..6b36e60e77cebf 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDataMigration'] --- import cloudDataMigrationObj from './cloud_data_migration.devdocs.json'; diff --git a/api_docs/cloud_defend.mdx b/api_docs/cloud_defend.mdx index a36d09c49ea798..8b3e08aae6c9fb 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index bee7674145ec25..9597661ca9abe2 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 5e9aca55ddd29f..0216ba8cadc172 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index 167af207774c69..93a13d1c8740cd 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/content_management.mdx b/api_docs/content_management.mdx index fe09361ff4bf64..4a2db6e9c9b50b 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'contentManagement'] --- import contentManagementObj from './content_management.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index 889a08840b53f2..68b1579aa1f16a 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index 2cb09be42de16b..d3eb65901aa7d2 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index 24c32f43b23ca9..a2f9f4c26eae77 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index 4ecbaff344e4f0..52df2d2b317f8a 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 446ea5e8289b43..3b36a3252818d7 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 73c8b2040c0324..685aa3c1551e13 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index df0dab9ab0977f..6b718d26ddb49b 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index a7696ffb2b114b..ca713322f2be6f 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index 0bce395adfbb2a..f98b83013d32dd 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index 280caf73202772..7e375b3ba52bcc 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index a7b37e0f30c9a9..8a3f8b0b0cd7a1 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index 38a69806ef3c9f..b7077e1ff204d3 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/dataset_quality.mdx b/api_docs/dataset_quality.mdx index 8b31bada0a8f77..a17d16efc96f50 100644 --- a/api_docs/dataset_quality.mdx +++ b/api_docs/dataset_quality.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/datasetQuality title: "datasetQuality" image: https://source.unsplash.com/400x175/?github description: API docs for the datasetQuality plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'datasetQuality'] --- import datasetQualityObj from './dataset_quality.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 4d04d0c26a7a53..9207a16185bbc7 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 3f1f507466d5ce..41901a6cf658b7 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -1345,7 +1345,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | <DocLink id="kibDataPluginApi" section="def-common.SearchSource.create" text="create"/> | [wrap_search_source_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.ts#:~:text=create) | - | | <DocLink id="kibDataPluginApi" section="def-common.SearchSource.fetch" text="fetch"/> | [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts#:~:text=fetch) | - | | <DocLink id="kibDataPluginApi" section="def-common.EqlSearchStrategyRequest.options" text="options"/> | [api.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/hooks/eql/api.ts#:~:text=options) | - | -| <DocLink id="kibKibanaReactPluginApi" section="def-public.toMountPoint" text="toMountPoint"/> | [use_update_data_view.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/sourcerer/use_update_data_view.tsx#:~:text=toMountPoint), [use_update_data_view.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/sourcerer/use_update_data_view.tsx#:~:text=toMountPoint), [use_update_data_view.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/sourcerer/use_update_data_view.tsx#:~:text=toMountPoint), [ingest_pipelines.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/ingest_pipelines.ts#:~:text=toMountPoint), [ingest_pipelines.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/ingest_pipelines.ts#:~:text=toMountPoint), [ingest_pipelines.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/ingest_pipelines.ts#:~:text=toMountPoint), [stored_scripts.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/stored_scripts.ts#:~:text=toMountPoint), [stored_scripts.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/stored_scripts.ts#:~:text=toMountPoint), [stored_scripts.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/stored_scripts.ts#:~:text=toMountPoint), [saved_objects.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/saved_objects.ts#:~:text=toMountPoint)+ 3 more | - | +| <DocLink id="kibKibanaReactPluginApi" section="def-public.toMountPoint" text="toMountPoint"/> | [use_update_data_view.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/sourcerer/use_update_data_view.tsx#:~:text=toMountPoint), [use_update_data_view.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/sourcerer/use_update_data_view.tsx#:~:text=toMountPoint), [use_update_data_view.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/common/components/sourcerer/use_update_data_view.tsx#:~:text=toMountPoint), [ingest_pipelines.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/ingest_pipelines.ts#:~:text=toMountPoint), [ingest_pipelines.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/ingest_pipelines.ts#:~:text=toMountPoint), [ingest_pipelines.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/ingest_pipelines.ts#:~:text=toMountPoint), [stored_scripts.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.ts#:~:text=toMountPoint), [stored_scripts.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.ts#:~:text=toMountPoint), [stored_scripts.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.ts#:~:text=toMountPoint), [saved_objects.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/saved_objects.ts#:~:text=toMountPoint)+ 3 more | - | | <DocLink id="kibKibanaReactPluginApi" section="def-public.KibanaThemeProvider" text="KibanaThemeProvider"/> | [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/app.tsx#:~:text=KibanaThemeProvider), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/app.tsx#:~:text=KibanaThemeProvider), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/public/app/app.tsx#:~:text=KibanaThemeProvider) | - | | <DocLink id="kibLicensingPluginApi" section="def-public.PublicLicense.mode" text="mode"/> | [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode)+ 7 more | 8.8.0 | | <DocLink id="kibLicensingPluginApi" section="def-server.PublicLicense.mode" text="mode"/> | [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [create_default_policy.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/fleet_integration/handlers/create_default_policy.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode)+ 7 more | 8.8.0 | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 7c5b3c2f8d1db1..4b9d345a7f2da0 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 49721a6640a54f..b0d882dc22ab00 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 8f7aec0b851b39..404be2fdaddf27 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index 85ca05e54e5953..61fad7aeedc8b6 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index 7b48d973032dcf..6d5efb33b0495c 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/elastic_assistant.mdx b/api_docs/elastic_assistant.mdx index 181af89056834d..1edb0e22c91b6d 100644 --- a/api_docs/elastic_assistant.mdx +++ b/api_docs/elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/elasticAssistant title: "elasticAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the elasticAssistant plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'elasticAssistant'] --- import elasticAssistantObj from './elastic_assistant.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index bf4e662fd0a0fd..c0a29180191f8e 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index 35a002361207dd..4000f8edbd17f5 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index 6c9ebefe470a1f..6028e6a4b2bd86 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index 4dc9677142a408..616346e5ce1193 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 9b12313037818c..414657e8a38712 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 74875b894bcff3..b0dd3d5dc73567 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_annotation_listing.mdx b/api_docs/event_annotation_listing.mdx index 4d2edcbef9ca3a..1ed8deb13c798c 100644 --- a/api_docs/event_annotation_listing.mdx +++ b/api_docs/event_annotation_listing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotationListing title: "eventAnnotationListing" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotationListing plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotationListing'] --- import eventAnnotationListingObj from './event_annotation_listing.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index f2ed4e3b823d86..042d197c9920f6 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/exploratory_view.mdx b/api_docs/exploratory_view.mdx index ebb713229170bf..a3042bce0da2e4 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'exploratoryView'] --- import exploratoryViewObj from './exploratory_view.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index 3a6b885e442164..df2203708c6630 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index 722c2b99c2ef05..ed3366bf0dd785 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index 610d50666ab091..f3589ed8f00a3f 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index 68f66b95d6ef5e..de93553f57a968 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index e31ab8977443f7..e58aefecc88a7e 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index 660d8bb3deebce..5ff1e36ed5685a 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index 17bbed8aebef6b..7475914e1ffc0e 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index 6d9060dc5c0945..3e1f42bb343b9f 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index de0b7c7e0c5944..2047dd244f4af8 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index 9ecebe60afcf6b..0af32e6f3e1263 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index 813405b56e762d..63dee50799a56b 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index bcee8974cf16dc..e6dc779446a589 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index 91684d0d6f6d1d..802013bb1e3fd4 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index 723bbe47f86366..920d2fa5b27c8f 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; diff --git a/api_docs/features.mdx b/api_docs/features.mdx index 2da7a5a30b9529..a35aa893b1c438 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index 49f3495a7855f1..2460a90ea2552e 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 424efa731fab64..f9e28d7ca0ea6b 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.mdx b/api_docs/files.mdx index 57b7d033f8b80e..a22f832582169a 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; diff --git a/api_docs/files_management.mdx b/api_docs/files_management.mdx index df688b57a80601..1a99eafe7da17f 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'filesManagement'] --- import filesManagementObj from './files_management.devdocs.json'; diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 07073193bcd14d..5569dfe157d2ab 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 83601545625689..984f719614cfad 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/guided_onboarding.mdx b/api_docs/guided_onboarding.mdx index 53c554241d254f..3f77211fcb0ab3 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.mdx b/api_docs/home.mdx index d441a1857be396..be9fa8ab2f1dd2 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/image_embeddable.mdx b/api_docs/image_embeddable.mdx index f76e485895325c..a80766c53e763e 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'imageEmbeddable'] --- import imageEmbeddableObj from './image_embeddable.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 10a95dffca26c1..c0c4f0ae77e304 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 98e0f0b6ed8c83..996d1734c69f99 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index 5a6be0813c9828..356efa803d0fee 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index a9fc5189115317..fa612aeb81f5eb 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index b6ade9184308c7..3dd6a694144929 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 58c3128bc9f021..c90798a1f7a6b5 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_actions_types.mdx b/api_docs/kbn_actions_types.mdx index 7e47dda753d5bf..64a897ebdcd407 100644 --- a/api_docs/kbn_actions_types.mdx +++ b/api_docs/kbn_actions_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-actions-types title: "@kbn/actions-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/actions-types plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/actions-types'] --- import kbnActionsTypesObj from './kbn_actions_types.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index cd14083f5a4a69..833580a8999b8b 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 7348d48a89b388..35a335a49fe1ed 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_api_integration_helpers.mdx b/api_docs/kbn_alerting_api_integration_helpers.mdx index 5ef982036e984c..61b5dd98a3b764 100644 --- a/api_docs/kbn_alerting_api_integration_helpers.mdx +++ b/api_docs/kbn_alerting_api_integration_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-api-integration-helpers title: "@kbn/alerting-api-integration-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-api-integration-helpers plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-api-integration-helpers'] --- import kbnAlertingApiIntegrationHelpersObj from './kbn_alerting_api_integration_helpers.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index e0f63ca0a1692e..730e726853bf56 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerting_types.mdx b/api_docs/kbn_alerting_types.mdx index 9794f4cb1680bd..2ed171fa7bba85 100644 --- a/api_docs/kbn_alerting_types.mdx +++ b/api_docs/kbn_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-types title: "@kbn/alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-types plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-types'] --- import kbnAlertingTypesObj from './kbn_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index cd9ee52924db35..fe1daf0dd82a74 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-as-data-utils'] --- import kbnAlertsAsDataUtilsObj from './kbn_alerts_as_data_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index e9920dea1c7f6b..eb9c7dc18a5af2 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-ui-shared'] --- import kbnAlertsUiSharedObj from './kbn_alerts_ui_shared.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index ee15ca922d6a17..9b21ee8840b5aa 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index d85322e4f1541b..864e2447dce7fe 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_collection_utils.mdx b/api_docs/kbn_analytics_collection_utils.mdx index 5f49867f330308..57ae16467cb7cd 100644 --- a/api_docs/kbn_analytics_collection_utils.mdx +++ b/api_docs/kbn_analytics_collection_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-collection-utils title: "@kbn/analytics-collection-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-collection-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-collection-utils'] --- import kbnAnalyticsCollectionUtilsObj from './kbn_analytics_collection_utils.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index a84b4c1b777bdd..b4dc464a15b924 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 775cfc7603fd9b..faaefdccbb1f8b 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index 7bbd11809f9145..93e7b709071b04 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index a5261dd76295f3..4657d847c87723 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index 2308c1d2bb90ef..57dd1cb8f860ed 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index cd8c2e5031d80f..b9153ed2793601 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index fa9c84e411c3fb..88d9f6b7531659 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace_client.mdx b/api_docs/kbn_apm_synthtrace_client.mdx index 29746d8baccfdd..6bcf839ef5b6e4 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index 02c6abcf182b97..dbdf3057db495a 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index e3475f686a38ea..a8d71fa32aae79 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_bfetch_error.mdx b/api_docs/kbn_bfetch_error.mdx index e048ddc047ef94..cedfe269a492d9 100644 --- a/api_docs/kbn_bfetch_error.mdx +++ b/api_docs/kbn_bfetch_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-bfetch-error title: "@kbn/bfetch-error" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/bfetch-error plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/bfetch-error'] --- import kbnBfetchErrorObj from './kbn_bfetch_error.devdocs.json'; diff --git a/api_docs/kbn_calculate_auto.mdx b/api_docs/kbn_calculate_auto.mdx index 0963be5da634e6..1c1406f7f17dc4 100644 --- a/api_docs/kbn_calculate_auto.mdx +++ b/api_docs/kbn_calculate_auto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-auto title: "@kbn/calculate-auto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-auto plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-auto'] --- import kbnCalculateAutoObj from './kbn_calculate_auto.devdocs.json'; diff --git a/api_docs/kbn_calculate_width_from_char_count.mdx b/api_docs/kbn_calculate_width_from_char_count.mdx index 92311c3dc81753..6d0df58244e032 100644 --- a/api_docs/kbn_calculate_width_from_char_count.mdx +++ b/api_docs/kbn_calculate_width_from_char_count.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-width-from-char-count title: "@kbn/calculate-width-from-char-count" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-width-from-char-count plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-width-from-char-count'] --- import kbnCalculateWidthFromCharCountObj from './kbn_calculate_width_from_char_count.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index d3627857ebbd43..34373b30ecee90 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index f3d43f621a3bab..4f3b31d00e8794 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cell-actions'] --- import kbnCellActionsObj from './kbn_cell_actions.devdocs.json'; diff --git a/api_docs/kbn_chart_expressions_common.mdx b/api_docs/kbn_chart_expressions_common.mdx index ae81f88ecddb60..114bcd6dc84093 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-expressions-common'] --- import kbnChartExpressionsCommonObj from './kbn_chart_expressions_common.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index 2273180eaa78ff..b36d6e4997952b 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] --- import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index fc4c1ef3e89de5..92dd74d04c0e35 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index d61211e4b324b6..c6e8f14f8b456b 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index b55cd4a00a2e57..ac257e0bd630ae 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index f64562e83c7101..f035fdcdd8280f 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index 2070eb71b3dc3a..4a92b36c2999ff 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_owners.mdx b/api_docs/kbn_code_owners.mdx index 9daca0998df43f..f5dcdeed57b258 100644 --- a/api_docs/kbn_code_owners.mdx +++ b/api_docs/kbn_code_owners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-owners title: "@kbn/code-owners" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-owners plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-owners'] --- import kbnCodeOwnersObj from './kbn_code_owners.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 9e8e71d82cc24c..ed6b49ef3a322b 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index a0e29465bd5d20..fe9eb61f78b882 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index 43c203826913fb..00d9a9751dacb0 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index ace85fb984a6ef..95533707de4d34 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_editor.mdx b/api_docs/kbn_content_management_content_editor.mdx index b9c53b58502bfc..88deb63fd5addc 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index ecd8263d958fd0..56f066af4734a1 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-tabbed-table-list-view'] --- import kbnContentManagementTabbedTableListViewObj from './kbn_content_management_tabbed_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view.mdx b/api_docs/kbn_content_management_table_list_view.mdx index eeafff3e3f53e7..193149eabb5e9a 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_common.mdx b/api_docs/kbn_content_management_table_list_view_common.mdx index c395e57bd5c378..24c1e5df83af19 100644 --- a/api_docs/kbn_content_management_table_list_view_common.mdx +++ b/api_docs/kbn_content_management_table_list_view_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-common title: "@kbn/content-management-table-list-view-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-common'] --- import kbnContentManagementTableListViewCommonObj from './kbn_content_management_table_list_view_common.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index 28f829569c70fa..a46b16d008f5a5 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-table'] --- import kbnContentManagementTableListViewTableObj from './kbn_content_management_table_list_view_table.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index ac15e36f3e620c..06fb677025286e 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-utils'] --- import kbnContentManagementUtilsObj from './kbn_content_management_utils.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 35e49738c9ee18..39af130175d146 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index f6885853bab389..4337843d06b5b1 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index 6e7b35122b360d..25f2f0a9c39500 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index a2a209f1f5c3c9..e9d66444a462d5 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index c5bba2659b8e0a..4e0681033cadb4 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index a50b6ee3737ca7..74b7fe36941593 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index 5ef25a22fdd7e2..9d24ccaa0cd608 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index 95bfa2b1f470d6..075aa0d1be4053 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index f462d587430a24..760c54f4cf3e0e 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index 95bbfa98d1587d..5584f48874d443 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index 6e3db2df263f8a..317137399bca9b 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index 540041cdfae266..99f6b8ec101303 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_apps_server_internal.mdx b/api_docs/kbn_core_apps_server_internal.mdx index 4d5a45ce4f5146..3762754e9f1f13 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-server-internal'] --- import kbnCoreAppsServerInternalObj from './kbn_core_apps_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index 984168575a1609..28d499efc2b438 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index db906e2aae7abc..883bde6576ca32 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index a2ec8bd66365ee..9ee58e63313dea 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index 26e01b07a38cc6..9bab6d34784f92 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index 3925a4050d7a2a..5498fb1f6c4c72 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index 086fff1793b4a3..e24c4e66a7508f 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index 13929a85fc45a7..53a56c1019aff7 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index 5784f6aaad2537..c1fae432cc4647 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index f4f709a7302989..386bf47ce00888 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index 2b75ad47f9b0d3..190cdad59cfd5e 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index 7c29647aadd524..52288b2e2cc5e7 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser.mdx b/api_docs/kbn_core_custom_branding_browser.mdx index 9626c62b68df67..414a494d2d4002 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser'] --- import kbnCoreCustomBrandingBrowserObj from './kbn_core_custom_branding_browser.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_internal.mdx b/api_docs/kbn_core_custom_branding_browser_internal.mdx index 39b4a0a0481e53..bd1a209dfdd1c2 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-internal'] --- import kbnCoreCustomBrandingBrowserInternalObj from './kbn_core_custom_branding_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_mocks.mdx b/api_docs/kbn_core_custom_branding_browser_mocks.mdx index de789aaa6b3f54..787c53ec32d0ad 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-mocks'] --- import kbnCoreCustomBrandingBrowserMocksObj from './kbn_core_custom_branding_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_common.mdx b/api_docs/kbn_core_custom_branding_common.mdx index 5f2ff3b8b2d613..4cd52bc7bd7dec 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-common'] --- import kbnCoreCustomBrandingCommonObj from './kbn_core_custom_branding_common.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server.mdx b/api_docs/kbn_core_custom_branding_server.mdx index 988e68ec151330..c2d970229b18ef 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server'] --- import kbnCoreCustomBrandingServerObj from './kbn_core_custom_branding_server.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_internal.mdx b/api_docs/kbn_core_custom_branding_server_internal.mdx index 8875485c9aabb4..c2abeb55966272 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-internal'] --- import kbnCoreCustomBrandingServerInternalObj from './kbn_core_custom_branding_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_mocks.mdx b/api_docs/kbn_core_custom_branding_server_mocks.mdx index 530e943b8e926b..5ff5a272f74304 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-mocks'] --- import kbnCoreCustomBrandingServerMocksObj from './kbn_core_custom_branding_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index a87366790ba8b2..21710bf17389a6 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index 5e52613ec7563d..77d45c586f7e8e 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index 67cf325c43a0e6..b591077eaa2b6b 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index fb8e41bc8e5720..770641b349b0aa 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index eaf60bbd317999..cda137bc31e2ef 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index e9c69de86b77bc..8385b5a657905e 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index 6de5b1f562edeb..e348604e746810 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index 10829b1e6275aa..e22208732af710 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index 2f57ff67171860..b0c81cac647fcc 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index bae2165a50a875..c53fed2153c05b 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index 2355fa68afbb88..93da39c2d9cddd 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index 2b7a7e5f90047b..64791190ced842 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index 1634b62b279178..e86dab666def7d 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index c9dff23c3fc428..939e53b6330fec 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index fbbdf852ae1722..7b710c71e73a3c 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index dd21efd9047060..a78a946f8a07f8 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index 53df4b35df5aaf..a1cf5de5648a26 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index 8ebb452e60bf2f..610a406bcdd873 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index ac638f6518370c..2244af8b6b902f 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index ecfe86d8adc278..bcfa71bc7f4701 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index 22ec8ff9b7f15f..11af05d6a97473 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index c467d178aaa9cf..01163f304da44d 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index 21cfe850579fce..dc047d543b04a5 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index 3237035fec0159..fe91dd3c5229ed 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index 3f31f1f7edb844..cbcc9ec778cd4e 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index c1c340f9cccc7b..f9c1eb8ee342bd 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index 82fc0ca9ca40b8..2f4fb81f919eb7 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index 21cbe5fe4dfa03..c4246446a37da9 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index 986a34823dcadd..43feae53311edb 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index 57d3f7b03ae1b9..c72f035f984276 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index 1d515d7566223b..a741083e63268f 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index 04a2bb69f59f66..10a3d2448da9ae 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_request_handler_context_server.mdx b/api_docs/kbn_core_http_request_handler_context_server.mdx index 91fa8a5ad49bd1..4551aa350759e3 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-request-handler-context-server'] --- import kbnCoreHttpRequestHandlerContextServerObj from './kbn_core_http_request_handler_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server.mdx b/api_docs/kbn_core_http_resources_server.mdx index ade659bb9ef916..fa63edc9e2f9ec 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server'] --- import kbnCoreHttpResourcesServerObj from './kbn_core_http_resources_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_internal.mdx b/api_docs/kbn_core_http_resources_server_internal.mdx index c6fc808e859cf3..01d6800ead5b13 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-internal'] --- import kbnCoreHttpResourcesServerInternalObj from './kbn_core_http_resources_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_mocks.mdx b/api_docs/kbn_core_http_resources_server_mocks.mdx index 5bcb87cf8fbd0c..7a08235cec3d42 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-mocks'] --- import kbnCoreHttpResourcesServerMocksObj from './kbn_core_http_resources_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index ffa07aefb50bc8..14bc10bb283af5 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index 89d2a7c8716326..ba5a80e1243139 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.devdocs.json b/api_docs/kbn_core_http_server.devdocs.json index 5c643711446533..48e78d70d9e4bd 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -3412,6 +3412,10 @@ "plugin": "security", "path": "x-pack/plugins/security/server/routes/api_keys/get.ts" }, + { + "plugin": "security", + "path": "x-pack/plugins/security/server/routes/api_keys/has_active.ts" + }, { "plugin": "security", "path": "x-pack/plugins/security/server/routes/anonymous_access/get_capabilities.ts" @@ -5524,6 +5528,10 @@ "plugin": "security", "path": "x-pack/plugins/security/server/routes/api_keys/get.test.ts" }, + { + "plugin": "security", + "path": "x-pack/plugins/security/server/routes/api_keys/has_active.test.ts" + }, { "plugin": "security", "path": "x-pack/plugins/security/server/routes/authentication/index.test.ts" diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 3878dda022f742..21a6896829f488 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index 3b2c869a440f69..057f929ca45830 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index 315bff5546a26b..667975b02ed9ca 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index ee4117cafdf518..db528585a2381e 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] --- import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index 68284739bceea3..d933e689b329c6 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] --- import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server.mdx b/api_docs/kbn_core_i18n_server.mdx index 3656480a1b1617..a1ddb576e2cc9f 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server'] --- import kbnCoreI18nServerObj from './kbn_core_i18n_server.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_internal.mdx b/api_docs/kbn_core_i18n_server_internal.mdx index 73c42cd26676ea..1cb964f3f4c070 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-internal'] --- import kbnCoreI18nServerInternalObj from './kbn_core_i18n_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_mocks.mdx b/api_docs/kbn_core_i18n_server_mocks.mdx index e99ae71e0ed32d..42bf1924641491 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-mocks'] --- import kbnCoreI18nServerMocksObj from './kbn_core_i18n_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index 0fbecc550b8900..934cf3ddfb0876 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] --- import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx index 374f99df7846ec..49354657c4b2fe 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal'] --- import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx index 0cfbc9010c875c..1ffe6e6281e032 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks'] --- import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index 94fd96b52cbf7e..e977076551ba70 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser'] --- import kbnCoreLifecycleBrowserObj from './kbn_core_lifecycle_browser.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser_mocks.mdx b/api_docs/kbn_core_lifecycle_browser_mocks.mdx index 40197f67df0132..d24e599caf2ac7 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser-mocks'] --- import kbnCoreLifecycleBrowserMocksObj from './kbn_core_lifecycle_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server.mdx b/api_docs/kbn_core_lifecycle_server.mdx index bbeea34bc66362..d9c0a57c13af35 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server'] --- import kbnCoreLifecycleServerObj from './kbn_core_lifecycle_server.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server_mocks.mdx b/api_docs/kbn_core_lifecycle_server_mocks.mdx index 06bbaebd8709ec..9de8134121896f 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server-mocks'] --- import kbnCoreLifecycleServerMocksObj from './kbn_core_lifecycle_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_browser_mocks.mdx b/api_docs/kbn_core_logging_browser_mocks.mdx index 1ca8d6b6236159..585cabdf2367e4 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-browser-mocks'] --- import kbnCoreLoggingBrowserMocksObj from './kbn_core_logging_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_common_internal.mdx b/api_docs/kbn_core_logging_common_internal.mdx index 33c55994265693..224e4bb45402a3 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-common-internal'] --- import kbnCoreLoggingCommonInternalObj from './kbn_core_logging_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index 9b3045e3fa8ae6..ba463021093230 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] --- import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index b30296c72dab91..8d046b8dc95175 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] --- import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index a9aa834345570c..11f5e154916ec7 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] --- import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx index 3c12d01bf72c1c..06bc6639826b03 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal'] --- import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx index d503e9ba8c50e9..666396762d24b0 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks'] --- import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx index 28dff19fe2d240..2b1926bc3df8b0 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server'] --- import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx index cc635864065ef6..689f04ba97890b 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal'] --- import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx index 8b1cae196fcf18..cf64598d04ac3d 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks'] --- import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx index af8ca1ed8eb08c..d893a2d2060a48 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser'] --- import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json'; diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx index 33030427e39e63..5d43fa669f1d9b 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server'] --- import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx index 2005c0eb786627..4a8320038272b8 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal'] --- import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx index 955df9242dee5d..68d82a9e1b1f19 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks'] --- import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index a7571fab6a007b..783576b11f442f 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser'] --- import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx index 93efe83e1a368f..57b4645947bb5d 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal'] --- import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx index 91e4b7602c9fee..2b23ad5e3fcb42 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks'] --- import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx index b1fe595fb61196..8f734e1c99ea54 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser'] --- import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx index 65fc5ba808174c..6fdf9359951b3b 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal'] --- import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx index 8aef508ce708dd..ca61c2a3993d8f 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks'] --- import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser.mdx b/api_docs/kbn_core_plugins_browser.mdx index 35636514e7b0f2..5762e3aedb4e78 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser'] --- import kbnCorePluginsBrowserObj from './kbn_core_plugins_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser_mocks.mdx b/api_docs/kbn_core_plugins_browser_mocks.mdx index 5e1aa4e0516ce5..04bf44697e3c22 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_contracts_browser.mdx b/api_docs/kbn_core_plugins_contracts_browser.mdx index b43d393843b38a..c9f880cecb7685 100644 --- a/api_docs/kbn_core_plugins_contracts_browser.mdx +++ b/api_docs/kbn_core_plugins_contracts_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-browser title: "@kbn/core-plugins-contracts-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-contracts-browser'] --- import kbnCorePluginsContractsBrowserObj from './kbn_core_plugins_contracts_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_contracts_server.mdx b/api_docs/kbn_core_plugins_contracts_server.mdx index cb60cff7899ca0..c18718780342f8 100644 --- a/api_docs/kbn_core_plugins_contracts_server.mdx +++ b/api_docs/kbn_core_plugins_contracts_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-server title: "@kbn/core-plugins-contracts-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-contracts-server'] --- import kbnCorePluginsContractsServerObj from './kbn_core_plugins_contracts_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index 059b444eee8a65..b51946928a615e 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server'] --- import kbnCorePluginsServerObj from './kbn_core_plugins_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server_mocks.mdx b/api_docs/kbn_core_plugins_server_mocks.mdx index b7e7d6d240fe99..a209ce88902365 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server-mocks'] --- import kbnCorePluginsServerMocksObj from './kbn_core_plugins_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index f9a227b51b9802..bebb8af10d1880 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server'] --- import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx index c3d592b4ccd01d..3e72e3ade48490 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index e3cfc0016205a5..e91f0321b2cfaf 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-browser-mocks'] --- import kbnCoreRenderingBrowserMocksObj from './kbn_core_rendering_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_internal.mdx b/api_docs/kbn_core_rendering_server_internal.mdx index dc894ce4088329..c480988e8debdb 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-internal'] --- import kbnCoreRenderingServerInternalObj from './kbn_core_rendering_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_mocks.mdx b/api_docs/kbn_core_rendering_server_mocks.mdx index 6562cc04b8d2b4..e958e6c4038a0f 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-mocks'] --- import kbnCoreRenderingServerMocksObj from './kbn_core_rendering_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_root_server_internal.mdx b/api_docs/kbn_core_root_server_internal.mdx index 8860cc64b0ff2b..60acf254d80ac2 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-root-server-internal'] --- import kbnCoreRootServerInternalObj from './kbn_core_root_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index 46145e7dafea3d..a10143986abeca 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index d18706056fc8c5..9e6177372823a1 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx index 976ac03873c077..7917619e885770 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-mocks'] --- import kbnCoreSavedObjectsApiServerMocksObj from './kbn_core_saved_objects_api_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.mdx b/api_docs/kbn_core_saved_objects_base_server_internal.mdx index c945b37884f049..af6bc48dcdbd37 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-internal'] --- import kbnCoreSavedObjectsBaseServerInternalObj from './kbn_core_saved_objects_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx index 64d3947380a897..694a759dc3be22 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-mocks'] --- import kbnCoreSavedObjectsBaseServerMocksObj from './kbn_core_saved_objects_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx index c14cbd07dcb33b..a6ef79c8e937ea 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser'] --- import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx index b2a5ee9c740c2f..53c090b7935934 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal'] --- import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index bc618bf1d5280f..f4c0a6735d14ff 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index c52c8874543747..2e6abf724a7174 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common'] --- import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx index 339f26f9512079..7077d3eea542d5 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-internal'] --- import kbnCoreSavedObjectsImportExportServerInternalObj from './kbn_core_saved_objects_import_export_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx index aba3efb9f39e6e..df126dcacdb257 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-mocks'] --- import kbnCoreSavedObjectsImportExportServerMocksObj from './kbn_core_saved_objects_import_export_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx index 92fc33c8a512d5..98ee89d06bd602 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-internal'] --- import kbnCoreSavedObjectsMigrationServerInternalObj from './kbn_core_saved_objects_migration_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx index 8a748b894289fa..47470a6051f4c0 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-mocks'] --- import kbnCoreSavedObjectsMigrationServerMocksObj from './kbn_core_saved_objects_migration_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index 2bf8adc73f0120..32557f52457f5e 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server'] --- import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_internal.mdx b/api_docs/kbn_core_saved_objects_server_internal.mdx index 751587b7a7143c..f507615660621c 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-internal'] --- import kbnCoreSavedObjectsServerInternalObj from './kbn_core_saved_objects_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_mocks.mdx b/api_docs/kbn_core_saved_objects_server_mocks.mdx index ba9afc922f5d2d..94dbc4d959ca3d 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-mocks'] --- import kbnCoreSavedObjectsServerMocksObj from './kbn_core_saved_objects_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_utils_server.mdx b/api_docs/kbn_core_saved_objects_utils_server.mdx index 3547870869976b..c3d1c9d0e47572 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index e755903cab5c2c..0f10c18a76c1a8 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common'] --- import kbnCoreStatusCommonObj from './kbn_core_status_common.devdocs.json'; diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index b660994a8e5770..7b1dec3519845c 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index b76e97cf6f4a25..b05da23d958636 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server'] --- import kbnCoreStatusServerObj from './kbn_core_status_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_internal.mdx b/api_docs/kbn_core_status_server_internal.mdx index 23ea6489fcf40e..ab60b33236ae55 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-internal'] --- import kbnCoreStatusServerInternalObj from './kbn_core_status_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_mocks.mdx b/api_docs/kbn_core_status_server_mocks.mdx index 4be2f0a68513e6..47380b1d44e6ad 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-mocks'] --- import kbnCoreStatusServerMocksObj from './kbn_core_status_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx index f9d2dc98b5ab42..51414b8a3caee7 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters'] --- import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx index 57b198a45efe20..eb987fcedaff6f 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser'] --- import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_kbn_server.mdx b/api_docs/kbn_core_test_helpers_kbn_server.mdx index 5df791a730448a..34c2ab50c9e8c0 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_model_versions.mdx b/api_docs/kbn_core_test_helpers_model_versions.mdx index 0caed2822c4b20..98af7ec16632f7 100644 --- a/api_docs/kbn_core_test_helpers_model_versions.mdx +++ b/api_docs/kbn_core_test_helpers_model_versions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-model-versions title: "@kbn/core-test-helpers-model-versions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-model-versions plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-model-versions'] --- import kbnCoreTestHelpersModelVersionsObj from './kbn_core_test_helpers_model_versions.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index 2c657268a5d787..455d5a22f78fad 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-so-type-serializer'] --- import kbnCoreTestHelpersSoTypeSerializerObj from './kbn_core_test_helpers_so_type_serializer.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_test_utils.mdx b/api_docs/kbn_core_test_helpers_test_utils.mdx index 636431f7bf687a..94935cd3f8577a 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-test-utils'] --- import kbnCoreTestHelpersTestUtilsObj from './kbn_core_test_helpers_test_utils.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index 9f5784d5b9c640..98d5fe78f1ce10 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index 64b447f427080c..36581891715fa5 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] --- import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx index 9d2855bfa8518b..e155dbb9f81160 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser'] --- import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx index f9d3245d82ead6..301eb06096fda5 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal'] --- import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx index 91b53edb813d82..2fd021aea6681b 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks'] --- import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx index 611c7b1032e3e7..958efda278745d 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common'] --- import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server.mdx b/api_docs/kbn_core_ui_settings_server.mdx index 9df78e54783bfa..b45c2767f06c80 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server'] --- import kbnCoreUiSettingsServerObj from './kbn_core_ui_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_internal.mdx b/api_docs/kbn_core_ui_settings_server_internal.mdx index c1f26fe313a7dd..ac9023d7377c27 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-internal'] --- import kbnCoreUiSettingsServerInternalObj from './kbn_core_ui_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_mocks.mdx b/api_docs/kbn_core_ui_settings_server_mocks.mdx index 5f84689ca7a3ea..28a4b18b2b66c6 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-mocks'] --- import kbnCoreUiSettingsServerMocksObj from './kbn_core_ui_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server.mdx b/api_docs/kbn_core_usage_data_server.mdx index a68e6da729d0b7..f2bdabe0f80aaa 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server'] --- import kbnCoreUsageDataServerObj from './kbn_core_usage_data_server.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_internal.mdx b/api_docs/kbn_core_usage_data_server_internal.mdx index 84d53652d3ef57..b1ae1969157de8 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-internal'] --- import kbnCoreUsageDataServerInternalObj from './kbn_core_usage_data_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_mocks.mdx b/api_docs/kbn_core_usage_data_server_mocks.mdx index bb30fde7b6ba31..e4292d8e1c151c 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index b1d3b8b2647ab9..2f1b69a0d9672c 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server'] --- import kbnCoreUserSettingsServerObj from './kbn_core_user_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_internal.mdx b/api_docs/kbn_core_user_settings_server_internal.mdx index 5982b088a67b5c..69b463e3c1b87f 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-internal'] --- import kbnCoreUserSettingsServerInternalObj from './kbn_core_user_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index 98456142fa228d..f9044784c1ba01 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-mocks'] --- import kbnCoreUserSettingsServerMocksObj from './kbn_core_user_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index c844f84771dbb2..d009d59533b558 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] --- import kbnCryptoObj from './kbn_crypto.devdocs.json'; diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx index 6ca93ee6cd8127..90f72f9bcb56ef 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_custom_icons.mdx b/api_docs/kbn_custom_icons.mdx index d0b256ca06698c..77afd949cb0105 100644 --- a/api_docs/kbn_custom_icons.mdx +++ b/api_docs/kbn_custom_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-custom-icons title: "@kbn/custom-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/custom-icons plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/custom-icons'] --- import kbnCustomIconsObj from './kbn_custom_icons.devdocs.json'; diff --git a/api_docs/kbn_custom_integrations.mdx b/api_docs/kbn_custom_integrations.mdx index 592f46b80a9226..19fb4dd69bde57 100644 --- a/api_docs/kbn_custom_integrations.mdx +++ b/api_docs/kbn_custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-custom-integrations title: "@kbn/custom-integrations" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/custom-integrations plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/custom-integrations'] --- import kbnCustomIntegrationsObj from './kbn_custom_integrations.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index a9616f0320a58a..c2636107ed2d6a 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index b4566e31857080..4893aa8c2653e8 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 9901ba85c631b6..f7e0b76cbc8e76 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_analytics.mdx b/api_docs/kbn_deeplinks_analytics.mdx index de417779892ebf..841b5395ce2783 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-analytics'] --- import kbnDeeplinksAnalyticsObj from './kbn_deeplinks_analytics.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_devtools.mdx b/api_docs/kbn_deeplinks_devtools.mdx index ab1fe7c3565ef0..334f446ad371f3 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index 0c8d3df2a61011..27c6505edec783 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-management'] --- import kbnDeeplinksManagementObj from './kbn_deeplinks_management.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_ml.mdx b/api_docs/kbn_deeplinks_ml.mdx index 3f5fce00d87668..6dfaeb0c0752e7 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-ml'] --- import kbnDeeplinksMlObj from './kbn_deeplinks_ml.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_observability.mdx b/api_docs/kbn_deeplinks_observability.mdx index 7a7c81abc68e28..a68c92b929de57 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-observability'] --- import kbnDeeplinksObservabilityObj from './kbn_deeplinks_observability.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_search.mdx b/api_docs/kbn_deeplinks_search.mdx index c87af96299e9c8..8c725464394169 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index ad6f9478e9ad3e..6780189ed5abe9 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-analytics'] --- import kbnDefaultNavAnalyticsObj from './kbn_default_nav_analytics.devdocs.json'; diff --git a/api_docs/kbn_default_nav_devtools.mdx b/api_docs/kbn_default_nav_devtools.mdx index 1ff3d6a0c29c2d..f138fc09911cfb 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-devtools'] --- import kbnDefaultNavDevtoolsObj from './kbn_default_nav_devtools.devdocs.json'; diff --git a/api_docs/kbn_default_nav_management.mdx b/api_docs/kbn_default_nav_management.mdx index 981516377d3b20..0b46d38a435aab 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-management'] --- import kbnDefaultNavManagementObj from './kbn_default_nav_management.devdocs.json'; diff --git a/api_docs/kbn_default_nav_ml.mdx b/api_docs/kbn_default_nav_ml.mdx index abdddd7ae7ceaf..b4b37fa3bb98ab 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-ml'] --- import kbnDefaultNavMlObj from './kbn_default_nav_ml.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index 9607746f811174..b7837f6fa78cb7 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] --- import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index b071b24947c9e3..cc4025ece54312 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] --- import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index 91deb5cd6acae8..c7ee0527405752 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] --- import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index 4afa160c819c89..73777f8fa2c2b3 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_discover_utils.mdx b/api_docs/kbn_discover_utils.mdx index 3ea72495146087..9e94736f581298 100644 --- a/api_docs/kbn_discover_utils.mdx +++ b/api_docs/kbn_discover_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-discover-utils title: "@kbn/discover-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/discover-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/discover-utils'] --- import kbnDiscoverUtilsObj from './kbn_discover_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 74cde01bba07b6..24e47b27351cd8 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index a50db44addd846..0ebe09e0224022 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_dom_drag_drop.mdx b/api_docs/kbn_dom_drag_drop.mdx index b5d1d4d6aa8f9c..a4b25b66f38dea 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dom-drag-drop'] --- import kbnDomDragDropObj from './kbn_dom_drag_drop.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index ba71492ecec06d..a7d7fcab4a56f8 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs.mdx b/api_docs/kbn_ecs.mdx index 06bfb551f0db34..dd9a04ea812d5c 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 769f84c7a571fb..2e56dd07656204 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_agent_utils.mdx b/api_docs/kbn_elastic_agent_utils.mdx index c9e17d49ca1447..58d9c08e10ce6b 100644 --- a/api_docs/kbn_elastic_agent_utils.mdx +++ b/api_docs/kbn_elastic_agent_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-agent-utils title: "@kbn/elastic-agent-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-agent-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-agent-utils'] --- import kbnElasticAgentUtilsObj from './kbn_elastic_agent_utils.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.devdocs.json b/api_docs/kbn_elastic_assistant.devdocs.json index 8b855265a22ca1..ea58540def0947 100644 --- a/api_docs/kbn_elastic_assistant.devdocs.json +++ b/api_docs/kbn_elastic_assistant.devdocs.json @@ -159,7 +159,7 @@ "label": "AssistantProvider", "description": [], "signature": [ - "({ actionTypeRegistry, alertsIndexPattern, assistantAvailability, assistantStreamingEnabled, assistantTelemetry, augmentMessageCodeBlocks, baseAllow, baseAllowReplacement, defaultAllow, defaultAllowReplacement, docLinks, basePath, basePromptContexts, baseQuickPrompts, baseSystemPrompts, children, getComments, http, getInitialConversations, modelEvaluatorEnabled, nameSpace, ragOnAlerts, setConversations, setDefaultAllow, setDefaultAllowReplacement, title, toasts, }: React.PropsWithChildren<", + "({ actionTypeRegistry, alertsIndexPattern, assistantAvailability, assistantStreamingEnabled, assistantTelemetry, augmentMessageCodeBlocks, baseAllow, baseAllowReplacement, defaultAllow, defaultAllowReplacement, docLinks, basePath, basePromptContexts, baseQuickPrompts, baseSystemPrompts, children, getComments, http, getInitialConversations, modelEvaluatorEnabled, nameSpace, setConversations, setDefaultAllow, setDefaultAllowReplacement, title, toasts, }: React.PropsWithChildren<", "AssistantProviderProps", ">) => JSX.Element" ], @@ -172,7 +172,7 @@ "id": "def-public.AssistantProvider.$1", "type": "CompoundType", "tags": [], - "label": "{\n actionTypeRegistry,\n alertsIndexPattern,\n assistantAvailability,\n assistantStreamingEnabled = false,\n assistantTelemetry,\n augmentMessageCodeBlocks,\n baseAllow,\n baseAllowReplacement,\n defaultAllow,\n defaultAllowReplacement,\n docLinks,\n basePath,\n basePromptContexts = [],\n baseQuickPrompts = [],\n baseSystemPrompts = BASE_SYSTEM_PROMPTS,\n children,\n getComments,\n http,\n getInitialConversations,\n modelEvaluatorEnabled = false,\n nameSpace = DEFAULT_ASSISTANT_NAMESPACE,\n ragOnAlerts = false,\n setConversations,\n setDefaultAllow,\n setDefaultAllowReplacement,\n title = DEFAULT_ASSISTANT_TITLE,\n toasts,\n}", + "label": "{\n actionTypeRegistry,\n alertsIndexPattern,\n assistantAvailability,\n assistantStreamingEnabled = false,\n assistantTelemetry,\n augmentMessageCodeBlocks,\n baseAllow,\n baseAllowReplacement,\n defaultAllow,\n defaultAllowReplacement,\n docLinks,\n basePath,\n basePromptContexts = [],\n baseQuickPrompts = [],\n baseSystemPrompts = BASE_SYSTEM_PROMPTS,\n children,\n getComments,\n http,\n getInitialConversations,\n modelEvaluatorEnabled = false,\n nameSpace = DEFAULT_ASSISTANT_NAMESPACE,\n setConversations,\n setDefaultAllow,\n setDefaultAllowReplacement,\n title = DEFAULT_ASSISTANT_TITLE,\n toasts,\n}", "description": [], "signature": [ "React.PropsWithChildren<", diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index 1838e84c5e82d0..a0f820ffdc2cfb 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant_common.mdx b/api_docs/kbn_elastic_assistant_common.mdx index 14d5b49ef145a2..d8b364df840c40 100644 --- a/api_docs/kbn_elastic_assistant_common.mdx +++ b/api_docs/kbn_elastic_assistant_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant-common title: "@kbn/elastic-assistant-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant-common'] --- import kbnElasticAssistantCommonObj from './kbn_elastic_assistant_common.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index e2300f88a31015..b6e27b5d90a447 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es'] --- import kbnEsObj from './kbn_es.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index 727c0410b35d15..39ecb08ef3bde2 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] --- import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json'; diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx index d5dcf9ba5f3087..1aaca7ccebd8d9 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors'] --- import kbnEsErrorsObj from './kbn_es_errors.devdocs.json'; diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index 83f290afe8d5dc..f4bec2cbc65e30 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index d106508e62a3f5..050b422128f554 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] --- import kbnEsTypesObj from './kbn_es_types.devdocs.json'; diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index 7f3ea3894a077a..ab5213b24291f0 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index a21c94b33bd722..bd6d149c45b951 100644 --- a/api_docs/kbn_event_annotation_common.mdx +++ b/api_docs/kbn_event_annotation_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-common title: "@kbn/event-annotation-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-common'] --- import kbnEventAnnotationCommonObj from './kbn_event_annotation_common.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_components.mdx b/api_docs/kbn_event_annotation_components.mdx index 4650387b4e8dec..7c263dc0988864 100644 --- a/api_docs/kbn_event_annotation_components.mdx +++ b/api_docs/kbn_event_annotation_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-components title: "@kbn/event-annotation-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-components plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-components'] --- import kbnEventAnnotationComponentsObj from './kbn_event_annotation_components.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index 736802ee4edf23..03b6437ca94390 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/expandable-flyout'] --- import kbnExpandableFlyoutObj from './kbn_expandable_flyout.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index 225f9154c0c877..1963f73f4175b0 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_field_utils.mdx b/api_docs/kbn_field_utils.mdx index 354ed95ff18342..4bf91783a344cb 100644 --- a/api_docs/kbn_field_utils.mdx +++ b/api_docs/kbn_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-utils title: "@kbn/field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-utils'] --- import kbnFieldUtilsObj from './kbn_field_utils.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 46fd82d33a3692..f9d3fea42ddf39 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 485a82f935345f..f4344f28802d70 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_ui_services.mdx b/api_docs/kbn_ftr_common_functional_ui_services.mdx index 58a04b102d2d4f..739bc173363f30 100644 --- a/api_docs/kbn_ftr_common_functional_ui_services.mdx +++ b/api_docs/kbn_ftr_common_functional_ui_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-ui-services title: "@kbn/ftr-common-functional-ui-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-ui-services plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-ui-services'] --- import kbnFtrCommonFunctionalUiServicesObj from './kbn_ftr_common_functional_ui_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index ced2d9b02baa12..48dbd3077ff4d6 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_generate_console_definitions.mdx b/api_docs/kbn_generate_console_definitions.mdx index acdd4ca7108fcd..5cb255c02b5d8b 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-console-definitions'] --- import kbnGenerateConsoleDefinitionsObj from './kbn_generate_console_definitions.devdocs.json'; diff --git a/api_docs/kbn_generate_csv.mdx b/api_docs/kbn_generate_csv.mdx index f9ab63c7b8454f..665c891f4bc472 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index b4cb4f54e3c907..767c62d947178b 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/guided-onboarding'] --- import kbnGuidedOnboardingObj from './kbn_guided_onboarding.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index 9a30535f9846c4..40102ffbddfb58 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index 2348a73dada969..a255305804769b 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_health_gateway_server.mdx b/api_docs/kbn_health_gateway_server.mdx index f1192c6392ba6a..14a9b7fdf681b5 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/health-gateway-server'] --- import kbnHealthGatewayServerObj from './kbn_health_gateway_server.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index 6df85d7c3fbf9b..9a5f3684577327 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index 97f335e2b29a91..7ec6dee933441c 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index a7b9c0e7965e7b..d0d44489b78293 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_i18n_react.mdx b/api_docs/kbn_i18n_react.mdx index b76d82f9c63a0c..50ccbbe5a0b928 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n-react'] --- import kbnI18nReactObj from './kbn_i18n_react.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index 063d2caa0ce095..4549adf06df965 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index e16c880e29b258..47b4cd89295f0a 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/infra-forge'] --- import kbnInfraForgeObj from './kbn_infra_forge.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index 736f247e927c05..cc6e0d6b60e44a 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 5ecb0dc6f48b31..cee10aaba33851 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 587266e89ce0e0..528cb31a980ef5 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_journeys.mdx b/api_docs/kbn_journeys.mdx index 5e097f4cad1ebd..20e97a380bb02a 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/journeys'] --- import kbnJourneysObj from './kbn_journeys.devdocs.json'; diff --git a/api_docs/kbn_json_ast.mdx b/api_docs/kbn_json_ast.mdx index 7a68f42df30f86..37fb589b59b279 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 538469a414ea9b..1c22f7fe8e6dec 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index f006aeac14ef46..4dcb648ebfa6cd 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_lens_embeddable_utils.mdx b/api_docs/kbn_lens_embeddable_utils.mdx index fa1b633c38df01..cda0b814df8be7 100644 --- a/api_docs/kbn_lens_embeddable_utils.mdx +++ b/api_docs/kbn_lens_embeddable_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-lens-embeddable-utils title: "@kbn/lens-embeddable-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/lens-embeddable-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/lens-embeddable-utils'] --- import kbnLensEmbeddableUtilsObj from './kbn_lens_embeddable_utils.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index c9e80ba261d71d..4ef82e3020b2a4 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index 77180e8b6218d4..d9150059869426 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index a5e8bbe0c175ed..2b62d134d70ca0 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_management_cards_navigation.mdx b/api_docs/kbn_management_cards_navigation.mdx index 2ade745aeb61ea..37b29203b154a9 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_settings_application.mdx b/api_docs/kbn_management_settings_application.mdx index 6dff98790c046f..f02a2d63d0eb67 100644 --- a/api_docs/kbn_management_settings_application.mdx +++ b/api_docs/kbn_management_settings_application.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-application title: "@kbn/management-settings-application" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-application plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-application'] --- import kbnManagementSettingsApplicationObj from './kbn_management_settings_application.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_category.mdx b/api_docs/kbn_management_settings_components_field_category.mdx index b5f6c56a0c6a1e..349f1f83598fc6 100644 --- a/api_docs/kbn_management_settings_components_field_category.mdx +++ b/api_docs/kbn_management_settings_components_field_category.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-category title: "@kbn/management-settings-components-field-category" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-category plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-category'] --- import kbnManagementSettingsComponentsFieldCategoryObj from './kbn_management_settings_components_field_category.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_input.mdx b/api_docs/kbn_management_settings_components_field_input.mdx index 5dee0c8129f84d..cf934ab6e44359 100644 --- a/api_docs/kbn_management_settings_components_field_input.mdx +++ b/api_docs/kbn_management_settings_components_field_input.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-input title: "@kbn/management-settings-components-field-input" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-input plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-input'] --- import kbnManagementSettingsComponentsFieldInputObj from './kbn_management_settings_components_field_input.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_row.mdx b/api_docs/kbn_management_settings_components_field_row.mdx index 9d0b0d59822603..5caac58100760b 100644 --- a/api_docs/kbn_management_settings_components_field_row.mdx +++ b/api_docs/kbn_management_settings_components_field_row.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-row title: "@kbn/management-settings-components-field-row" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-row plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-row'] --- import kbnManagementSettingsComponentsFieldRowObj from './kbn_management_settings_components_field_row.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_form.mdx b/api_docs/kbn_management_settings_components_form.mdx index 86db4fa4d568c9..c190b5fce6cf4a 100644 --- a/api_docs/kbn_management_settings_components_form.mdx +++ b/api_docs/kbn_management_settings_components_form.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-form title: "@kbn/management-settings-components-form" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-form plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-form'] --- import kbnManagementSettingsComponentsFormObj from './kbn_management_settings_components_form.devdocs.json'; diff --git a/api_docs/kbn_management_settings_field_definition.mdx b/api_docs/kbn_management_settings_field_definition.mdx index 5728b144297fb2..696e1b469bdc9a 100644 --- a/api_docs/kbn_management_settings_field_definition.mdx +++ b/api_docs/kbn_management_settings_field_definition.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-field-definition title: "@kbn/management-settings-field-definition" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-field-definition plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-field-definition'] --- import kbnManagementSettingsFieldDefinitionObj from './kbn_management_settings_field_definition.devdocs.json'; diff --git a/api_docs/kbn_management_settings_ids.mdx b/api_docs/kbn_management_settings_ids.mdx index bf887b0f0d4951..f1ecaceb348385 100644 --- a/api_docs/kbn_management_settings_ids.mdx +++ b/api_docs/kbn_management_settings_ids.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-ids title: "@kbn/management-settings-ids" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-ids plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-ids'] --- import kbnManagementSettingsIdsObj from './kbn_management_settings_ids.devdocs.json'; diff --git a/api_docs/kbn_management_settings_section_registry.mdx b/api_docs/kbn_management_settings_section_registry.mdx index 8d232226abb176..68b0368298511b 100644 --- a/api_docs/kbn_management_settings_section_registry.mdx +++ b/api_docs/kbn_management_settings_section_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-section-registry title: "@kbn/management-settings-section-registry" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-section-registry plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-section-registry'] --- import kbnManagementSettingsSectionRegistryObj from './kbn_management_settings_section_registry.devdocs.json'; diff --git a/api_docs/kbn_management_settings_types.mdx b/api_docs/kbn_management_settings_types.mdx index 52f8367985b17b..863330786164dc 100644 --- a/api_docs/kbn_management_settings_types.mdx +++ b/api_docs/kbn_management_settings_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-types title: "@kbn/management-settings-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-types plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-types'] --- import kbnManagementSettingsTypesObj from './kbn_management_settings_types.devdocs.json'; diff --git a/api_docs/kbn_management_settings_utilities.mdx b/api_docs/kbn_management_settings_utilities.mdx index b23991555ea24d..da1a517d31e629 100644 --- a/api_docs/kbn_management_settings_utilities.mdx +++ b/api_docs/kbn_management_settings_utilities.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-utilities title: "@kbn/management-settings-utilities" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-utilities plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-utilities'] --- import kbnManagementSettingsUtilitiesObj from './kbn_management_settings_utilities.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index 40723ca74a8881..5d5f115e466406 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] --- import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index 9527a07532e8aa..ac216ddf548f5a 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_maps_vector_tile_utils.mdx b/api_docs/kbn_maps_vector_tile_utils.mdx index d8f183ce4b63ed..5692ee22a846a3 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/maps-vector-tile-utils'] --- import kbnMapsVectorTileUtilsObj from './kbn_maps_vector_tile_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index c331dda348956d..f17511081fa034 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_anomaly_utils.mdx b/api_docs/kbn_ml_anomaly_utils.mdx index ef511ba7c9c7a3..347180a77cee11 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_category_validator.mdx b/api_docs/kbn_ml_category_validator.mdx index 1f1403134c7d08..af1d031567e812 100644 --- a/api_docs/kbn_ml_category_validator.mdx +++ b/api_docs/kbn_ml_category_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-category-validator title: "@kbn/ml-category-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-category-validator plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-category-validator'] --- import kbnMlCategoryValidatorObj from './kbn_ml_category_validator.devdocs.json'; diff --git a/api_docs/kbn_ml_chi2test.mdx b/api_docs/kbn_ml_chi2test.mdx index b4cce1b1f40561..3cbf602d154d9a 100644 --- a/api_docs/kbn_ml_chi2test.mdx +++ b/api_docs/kbn_ml_chi2test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-chi2test title: "@kbn/ml-chi2test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-chi2test plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-chi2test'] --- import kbnMlChi2testObj from './kbn_ml_chi2test.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index fb9f40daf38158..f5afb4de017bbe 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-frame-analytics-utils'] --- import kbnMlDataFrameAnalyticsUtilsObj from './kbn_ml_data_frame_analytics_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_grid.mdx b/api_docs/kbn_ml_data_grid.mdx index 663d847add458f..0f5ba21a0f5bdc 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-grid'] --- import kbnMlDataGridObj from './kbn_ml_data_grid.devdocs.json'; diff --git a/api_docs/kbn_ml_date_picker.mdx b/api_docs/kbn_ml_date_picker.mdx index 55d74f2dc9a788..489e63c15a26de 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-picker'] --- import kbnMlDatePickerObj from './kbn_ml_date_picker.devdocs.json'; diff --git a/api_docs/kbn_ml_date_utils.mdx b/api_docs/kbn_ml_date_utils.mdx index ee875c4b9b0869..551a9e49d943e2 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-utils'] --- import kbnMlDateUtilsObj from './kbn_ml_date_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_error_utils.mdx b/api_docs/kbn_ml_error_utils.mdx index 9625b2901c5a64..47451e35680427 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_in_memory_table.mdx b/api_docs/kbn_ml_in_memory_table.mdx index d4b84ca095d03f..c38642d7cba3c7 100644 --- a/api_docs/kbn_ml_in_memory_table.mdx +++ b/api_docs/kbn_ml_in_memory_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-in-memory-table title: "@kbn/ml-in-memory-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-in-memory-table plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-in-memory-table'] --- import kbnMlInMemoryTableObj from './kbn_ml_in_memory_table.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index 3e8055e22bfe96..0c0d081584ab85 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-defined'] --- import kbnMlIsDefinedObj from './kbn_ml_is_defined.devdocs.json'; diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index 9b6a1a8d56e4ae..a024c0684e33af 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_kibana_theme.mdx b/api_docs/kbn_ml_kibana_theme.mdx index d87dcee33b8345..750cbd94bda727 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-kibana-theme'] --- import kbnMlKibanaThemeObj from './kbn_ml_kibana_theme.devdocs.json'; diff --git a/api_docs/kbn_ml_local_storage.mdx b/api_docs/kbn_ml_local_storage.mdx index fb528775d6d6e5..38f29d405ce3e2 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-local-storage'] --- import kbnMlLocalStorageObj from './kbn_ml_local_storage.devdocs.json'; diff --git a/api_docs/kbn_ml_nested_property.mdx b/api_docs/kbn_ml_nested_property.mdx index 104c9bd08cbd00..42eda059d2b2e4 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-nested-property'] --- import kbnMlNestedPropertyObj from './kbn_ml_nested_property.devdocs.json'; diff --git a/api_docs/kbn_ml_number_utils.mdx b/api_docs/kbn_ml_number_utils.mdx index fa5d8a26da85c2..24e97c2a04c97d 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-number-utils'] --- import kbnMlNumberUtilsObj from './kbn_ml_number_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index f1ec133743bf93..837c83393f17e0 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-query-utils'] --- import kbnMlQueryUtilsObj from './kbn_ml_query_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_random_sampler_utils.mdx b/api_docs/kbn_ml_random_sampler_utils.mdx index d76ce7eb02acc8..9e12561cd2a4d4 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-random-sampler-utils'] --- import kbnMlRandomSamplerUtilsObj from './kbn_ml_random_sampler_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_route_utils.mdx b/api_docs/kbn_ml_route_utils.mdx index 1c4722fb1e2734..a0cc2d80293ffa 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-route-utils'] --- import kbnMlRouteUtilsObj from './kbn_ml_route_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_runtime_field_utils.mdx b/api_docs/kbn_ml_runtime_field_utils.mdx index dfdf19203f1941..cc6f3ef07fc43e 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-runtime-field-utils'] --- import kbnMlRuntimeFieldUtilsObj from './kbn_ml_runtime_field_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index e4cfbe7a1c1bb3..05d436af1a3cfa 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index 857f1f1f627f8c..62d4bf250d8127 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_ui_actions.mdx b/api_docs/kbn_ml_ui_actions.mdx index 161c34fe354465..2df8f82c09a0cd 100644 --- a/api_docs/kbn_ml_ui_actions.mdx +++ b/api_docs/kbn_ml_ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-ui-actions title: "@kbn/ml-ui-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-ui-actions plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-ui-actions'] --- import kbnMlUiActionsObj from './kbn_ml_ui_actions.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 8cd0569d7058b4..2f0a268ae7fb83 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 476a8ca11fe6ef..b8f17eb7c02c0b 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_object_versioning.mdx b/api_docs/kbn_object_versioning.mdx index e01ef66fd8acee..7ee3bc0c078803 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index d4885592b16373..e7d3a4e6d383b8 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_observability_alerting_test_data.mdx b/api_docs/kbn_observability_alerting_test_data.mdx index a933509a8fc3c5..329a9e98008d62 100644 --- a/api_docs/kbn_observability_alerting_test_data.mdx +++ b/api_docs/kbn_observability_alerting_test_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alerting-test-data title: "@kbn/observability-alerting-test-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alerting-test-data plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alerting-test-data'] --- import kbnObservabilityAlertingTestDataObj from './kbn_observability_alerting_test_data.devdocs.json'; diff --git a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx index aee6941054ce44..c2cc713a5bb491 100644 --- a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx +++ b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-get-padded-alert-time-range-util title: "@kbn/observability-get-padded-alert-time-range-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-get-padded-alert-time-range-util plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-get-padded-alert-time-range-util'] --- import kbnObservabilityGetPaddedAlertTimeRangeUtilObj from './kbn_observability_get_padded_alert_time_range_util.devdocs.json'; diff --git a/api_docs/kbn_openapi_bundler.mdx b/api_docs/kbn_openapi_bundler.mdx index 9c7d00cb1c1ce5..91280607182e66 100644 --- a/api_docs/kbn_openapi_bundler.mdx +++ b/api_docs/kbn_openapi_bundler.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-bundler title: "@kbn/openapi-bundler" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-bundler plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-bundler'] --- import kbnOpenapiBundlerObj from './kbn_openapi_bundler.devdocs.json'; diff --git a/api_docs/kbn_openapi_generator.mdx b/api_docs/kbn_openapi_generator.mdx index d7076d0b70c8c4..f5e546ddf03f39 100644 --- a/api_docs/kbn_openapi_generator.mdx +++ b/api_docs/kbn_openapi_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-generator title: "@kbn/openapi-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-generator plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-generator'] --- import kbnOpenapiGeneratorObj from './kbn_openapi_generator.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 40ec00d6629045..fe5a464b4cc1cb 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index 1c534416c68cb2..fa8b950a3b3c91 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_osquery_io_ts_types.mdx b/api_docs/kbn_osquery_io_ts_types.mdx index afb5c544aeb70e..9a8499d7fa2ffe 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_panel_loader.mdx b/api_docs/kbn_panel_loader.mdx index 2a3e058e47b17a..c81e3f19fe3a50 100644 --- a/api_docs/kbn_panel_loader.mdx +++ b/api_docs/kbn_panel_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-panel-loader title: "@kbn/panel-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/panel-loader plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/panel-loader'] --- import kbnPanelLoaderObj from './kbn_panel_loader.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index ca654854e531d5..e4bb88d5e6fde9 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index cb11ae38713d90..a763d264941c34 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index 1261d477deec46..178592e980485a 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_profiling_utils.mdx b/api_docs/kbn_profiling_utils.mdx index 4975684673070e..13d4799935447e 100644 --- a/api_docs/kbn_profiling_utils.mdx +++ b/api_docs/kbn_profiling_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-profiling-utils title: "@kbn/profiling-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/profiling-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/profiling-utils'] --- import kbnProfilingUtilsObj from './kbn_profiling_utils.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index bcb68a4999dfa9..ea845501b36a41 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/random-sampling'] --- import kbnRandomSamplingObj from './kbn_random_sampling.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index 72b5d45ef3804e..1d016920b2d608 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_common.mdx b/api_docs/kbn_react_kibana_context_common.mdx index 6734b12533be6f..514b1cab3ba739 100644 --- a/api_docs/kbn_react_kibana_context_common.mdx +++ b/api_docs/kbn_react_kibana_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-common title: "@kbn/react-kibana-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-common'] --- import kbnReactKibanaContextCommonObj from './kbn_react_kibana_context_common.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_render.mdx b/api_docs/kbn_react_kibana_context_render.mdx index 6eaef4024c13f0..1facb5f0a3c085 100644 --- a/api_docs/kbn_react_kibana_context_render.mdx +++ b/api_docs/kbn_react_kibana_context_render.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-render title: "@kbn/react-kibana-context-render" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-render plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-render'] --- import kbnReactKibanaContextRenderObj from './kbn_react_kibana_context_render.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_root.mdx b/api_docs/kbn_react_kibana_context_root.mdx index 97302f7e5ddefd..ebff472f208959 100644 --- a/api_docs/kbn_react_kibana_context_root.mdx +++ b/api_docs/kbn_react_kibana_context_root.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-root title: "@kbn/react-kibana-context-root" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-root plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-root'] --- import kbnReactKibanaContextRootObj from './kbn_react_kibana_context_root.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_styled.mdx b/api_docs/kbn_react_kibana_context_styled.mdx index 766912c60a09c6..ae49c055fd8c98 100644 --- a/api_docs/kbn_react_kibana_context_styled.mdx +++ b/api_docs/kbn_react_kibana_context_styled.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-styled title: "@kbn/react-kibana-context-styled" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-styled plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-styled'] --- import kbnReactKibanaContextStyledObj from './kbn_react_kibana_context_styled.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_theme.mdx b/api_docs/kbn_react_kibana_context_theme.mdx index 1d96d5a8693f96..7c454a5104bc98 100644 --- a/api_docs/kbn_react_kibana_context_theme.mdx +++ b/api_docs/kbn_react_kibana_context_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-theme title: "@kbn/react-kibana-context-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-theme plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-theme'] --- import kbnReactKibanaContextThemeObj from './kbn_react_kibana_context_theme.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_mount.mdx b/api_docs/kbn_react_kibana_mount.mdx index 3f0fd940b4577c..8a96da47741aca 100644 --- a/api_docs/kbn_react_kibana_mount.mdx +++ b/api_docs/kbn_react_kibana_mount.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-mount title: "@kbn/react-kibana-mount" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-mount plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-mount'] --- import kbnReactKibanaMountObj from './kbn_react_kibana_mount.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index 2e08a38bd8f2fc..5aa409dee31e17 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-file-maps'] --- import kbnRepoFileMapsObj from './kbn_repo_file_maps.devdocs.json'; diff --git a/api_docs/kbn_repo_linter.mdx b/api_docs/kbn_repo_linter.mdx index f462a62afa7693..13e22a31ac1cd0 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-linter'] --- import kbnRepoLinterObj from './kbn_repo_linter.devdocs.json'; diff --git a/api_docs/kbn_repo_path.mdx b/api_docs/kbn_repo_path.mdx index 9be75b489fe1eb..a9694fe2f6a7e0 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-path'] --- import kbnRepoPathObj from './kbn_repo_path.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index ec1cad8776d5cd..8443b28704703c 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_reporting_common.mdx b/api_docs/kbn_reporting_common.mdx index ae4b0db271aebe..5b34d4c7e10391 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv.mdx b/api_docs/kbn_reporting_export_types_csv.mdx index 93ff6845750a2e..5091c832939745 100644 --- a/api_docs/kbn_reporting_export_types_csv.mdx +++ b/api_docs/kbn_reporting_export_types_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv title: "@kbn/reporting-export-types-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv'] --- import kbnReportingExportTypesCsvObj from './kbn_reporting_export_types_csv.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv_common.mdx b/api_docs/kbn_reporting_export_types_csv_common.mdx index a4d9ea81b1c2c4..9a92686f923c77 100644 --- a/api_docs/kbn_reporting_export_types_csv_common.mdx +++ b/api_docs/kbn_reporting_export_types_csv_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv-common title: "@kbn/reporting-export-types-csv-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv-common'] --- import kbnReportingExportTypesCsvCommonObj from './kbn_reporting_export_types_csv_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf.mdx b/api_docs/kbn_reporting_export_types_pdf.mdx index e9d60015e69f14..a40fd62b9b3f73 100644 --- a/api_docs/kbn_reporting_export_types_pdf.mdx +++ b/api_docs/kbn_reporting_export_types_pdf.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf title: "@kbn/reporting-export-types-pdf" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf'] --- import kbnReportingExportTypesPdfObj from './kbn_reporting_export_types_pdf.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf_common.mdx b/api_docs/kbn_reporting_export_types_pdf_common.mdx index d71b6f36a07d24..1a9be4c53743eb 100644 --- a/api_docs/kbn_reporting_export_types_pdf_common.mdx +++ b/api_docs/kbn_reporting_export_types_pdf_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf-common title: "@kbn/reporting-export-types-pdf-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf-common'] --- import kbnReportingExportTypesPdfCommonObj from './kbn_reporting_export_types_pdf_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png.mdx b/api_docs/kbn_reporting_export_types_png.mdx index 43e24ba0b2f1f8..da649e07ca4a23 100644 --- a/api_docs/kbn_reporting_export_types_png.mdx +++ b/api_docs/kbn_reporting_export_types_png.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png title: "@kbn/reporting-export-types-png" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png'] --- import kbnReportingExportTypesPngObj from './kbn_reporting_export_types_png.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png_common.mdx b/api_docs/kbn_reporting_export_types_png_common.mdx index 180e38e7d74aa6..822346563c31b9 100644 --- a/api_docs/kbn_reporting_export_types_png_common.mdx +++ b/api_docs/kbn_reporting_export_types_png_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png-common title: "@kbn/reporting-export-types-png-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png-common'] --- import kbnReportingExportTypesPngCommonObj from './kbn_reporting_export_types_png_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_mocks_server.mdx b/api_docs/kbn_reporting_mocks_server.mdx index c8c95aba2fdb6f..905dfb25578d78 100644 --- a/api_docs/kbn_reporting_mocks_server.mdx +++ b/api_docs/kbn_reporting_mocks_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-mocks-server title: "@kbn/reporting-mocks-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-mocks-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-mocks-server'] --- import kbnReportingMocksServerObj from './kbn_reporting_mocks_server.devdocs.json'; diff --git a/api_docs/kbn_reporting_public.mdx b/api_docs/kbn_reporting_public.mdx index fe10766f2ff6a7..cf3602dde955ca 100644 --- a/api_docs/kbn_reporting_public.mdx +++ b/api_docs/kbn_reporting_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-public title: "@kbn/reporting-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-public plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-public'] --- import kbnReportingPublicObj from './kbn_reporting_public.devdocs.json'; diff --git a/api_docs/kbn_reporting_server.mdx b/api_docs/kbn_reporting_server.mdx index a7f540efabc238..6bf149f6821117 100644 --- a/api_docs/kbn_reporting_server.mdx +++ b/api_docs/kbn_reporting_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-server title: "@kbn/reporting-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-server'] --- import kbnReportingServerObj from './kbn_reporting_server.devdocs.json'; diff --git a/api_docs/kbn_resizable_layout.mdx b/api_docs/kbn_resizable_layout.mdx index 1f20773ed98cb9..1650103171192f 100644 --- a/api_docs/kbn_resizable_layout.mdx +++ b/api_docs/kbn_resizable_layout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-resizable-layout title: "@kbn/resizable-layout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/resizable-layout plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/resizable-layout'] --- import kbnResizableLayoutObj from './kbn_resizable_layout.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 4538e15c2dd2e6..7ed9fe78af28b7 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_router_utils.mdx b/api_docs/kbn_router_utils.mdx index 46792eff4da48d..3cd56fd6d76849 100644 --- a/api_docs/kbn_router_utils.mdx +++ b/api_docs/kbn_router_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-router-utils title: "@kbn/router-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/router-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/router-utils'] --- import kbnRouterUtilsObj from './kbn_router_utils.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index 2c87eebdfbf63b..2fce5484affd28 100644 --- a/api_docs/kbn_rrule.mdx +++ b/api_docs/kbn_rrule.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rrule title: "@kbn/rrule" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rrule plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rrule'] --- import kbnRruleObj from './kbn_rrule.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.devdocs.json b/api_docs/kbn_rule_data_utils.devdocs.json index 2dee374f7c5725..e4de662c8e2a83 100644 --- a/api_docs/kbn_rule_data_utils.devdocs.json +++ b/api_docs/kbn_rule_data_utils.devdocs.json @@ -1631,6 +1631,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/rule-data-utils", + "id": "def-common.ML_ANOMALY_DETECTION_RULE_TYPE_ID", + "type": "string", + "tags": [], + "label": "ML_ANOMALY_DETECTION_RULE_TYPE_ID", + "description": [], + "signature": [ + "\"xpack.ml.anomaly_detection_alert\"" + ], + "path": "packages/kbn-rule-data-utils/src/rule_types/stack_rules.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/rule-data-utils", "id": "def-common.OBSERVABILITY_THRESHOLD_RULE_TYPE_ID", @@ -1654,7 +1669,7 @@ "label": "RuleCreationValidConsumer", "description": [], "signature": [ - "\"observability\" | \"stackAlerts\" | \"logs\" | \"infrastructure\"" + "\"observability\" | \"stackAlerts\" | \"alerts\" | \"logs\" | \"infrastructure\"" ], "path": "packages/kbn-rule-data-utils/src/rule_types/index.ts", "deprecated": false, diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index fb82dfcadcaf71..63e1acbbaeb109 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/security-detections-response](https://github.com/orgs/elastic/ | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 119 | 0 | 116 | 0 | +| 120 | 0 | 117 | 0 | ## Common diff --git a/api_docs/kbn_saved_objects_settings.mdx b/api_docs/kbn_saved_objects_settings.mdx index af33349d307a50..4d1b2794d55130 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_search_api_panels.mdx b/api_docs/kbn_search_api_panels.mdx index 2a641830beae68..1185655dbb2562 100644 --- a/api_docs/kbn_search_api_panels.mdx +++ b/api_docs/kbn_search_api_panels.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-api-panels title: "@kbn/search-api-panels" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-api-panels plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-api-panels'] --- import kbnSearchApiPanelsObj from './kbn_search_api_panels.devdocs.json'; diff --git a/api_docs/kbn_search_connectors.mdx b/api_docs/kbn_search_connectors.mdx index ac28e4ba909945..203dd6254948a7 100644 --- a/api_docs/kbn_search_connectors.mdx +++ b/api_docs/kbn_search_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-connectors title: "@kbn/search-connectors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-connectors plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-connectors'] --- import kbnSearchConnectorsObj from './kbn_search_connectors.devdocs.json'; diff --git a/api_docs/kbn_search_errors.mdx b/api_docs/kbn_search_errors.mdx index 76f049106e4647..8b32ff505f4ecf 100644 --- a/api_docs/kbn_search_errors.mdx +++ b/api_docs/kbn_search_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-errors title: "@kbn/search-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-errors plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-errors'] --- import kbnSearchErrorsObj from './kbn_search_errors.devdocs.json'; diff --git a/api_docs/kbn_search_index_documents.mdx b/api_docs/kbn_search_index_documents.mdx index 67a450e95dc029..6f91fa8d4a6a4d 100644 --- a/api_docs/kbn_search_index_documents.mdx +++ b/api_docs/kbn_search_index_documents.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-index-documents title: "@kbn/search-index-documents" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-index-documents plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-index-documents'] --- import kbnSearchIndexDocumentsObj from './kbn_search_index_documents.devdocs.json'; diff --git a/api_docs/kbn_search_response_warnings.mdx b/api_docs/kbn_search_response_warnings.mdx index c8733af8f3b4f4..228d15c9a6e7f8 100644 --- a/api_docs/kbn_search_response_warnings.mdx +++ b/api_docs/kbn_search_response_warnings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-response-warnings title: "@kbn/search-response-warnings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-response-warnings plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-response-warnings'] --- import kbnSearchResponseWarningsObj from './kbn_search_response_warnings.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_common.mdx b/api_docs/kbn_security_plugin_types_common.mdx index 361e44f7525b91..0b44e768dfff99 100644 --- a/api_docs/kbn_security_plugin_types_common.mdx +++ b/api_docs/kbn_security_plugin_types_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-common title: "@kbn/security-plugin-types-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-common plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-common'] --- import kbnSecurityPluginTypesCommonObj from './kbn_security_plugin_types_common.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_public.mdx b/api_docs/kbn_security_plugin_types_public.mdx index c1eddbd21e6ecd..0e3a51f42b6a70 100644 --- a/api_docs/kbn_security_plugin_types_public.mdx +++ b/api_docs/kbn_security_plugin_types_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-public title: "@kbn/security-plugin-types-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-public plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-public'] --- import kbnSecurityPluginTypesPublicObj from './kbn_security_plugin_types_public.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_server.mdx b/api_docs/kbn_security_plugin_types_server.mdx index 1ee3409edb4411..95980a551449c2 100644 --- a/api_docs/kbn_security_plugin_types_server.mdx +++ b/api_docs/kbn_security_plugin_types_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-server title: "@kbn/security-plugin-types-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-server plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-server'] --- import kbnSecurityPluginTypesServerObj from './kbn_security_plugin_types_server.devdocs.json'; diff --git a/api_docs/kbn_security_solution_features.mdx b/api_docs/kbn_security_solution_features.mdx index 2275e43f86531e..0764c684a5846a 100644 --- a/api_docs/kbn_security_solution_features.mdx +++ b/api_docs/kbn_security_solution_features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-features title: "@kbn/security-solution-features" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-features plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-features'] --- import kbnSecuritySolutionFeaturesObj from './kbn_security_solution_features.devdocs.json'; diff --git a/api_docs/kbn_security_solution_navigation.mdx b/api_docs/kbn_security_solution_navigation.mdx index e98dcbc0fb3e18..ea6a20550eafc8 100644 --- a/api_docs/kbn_security_solution_navigation.mdx +++ b/api_docs/kbn_security_solution_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-navigation title: "@kbn/security-solution-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-navigation plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-navigation'] --- import kbnSecuritySolutionNavigationObj from './kbn_security_solution_navigation.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index 198fd8d906c6ac..aa199a8b3ba406 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-side-nav'] --- import kbnSecuritySolutionSideNavObj from './kbn_security_solution_side_nav.devdocs.json'; diff --git a/api_docs/kbn_security_solution_storybook_config.mdx b/api_docs/kbn_security_solution_storybook_config.mdx index a86bd69301014d..98dd38c141de6d 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-storybook-config'] --- import kbnSecuritySolutionStorybookConfigObj from './kbn_security_solution_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index d46b9573b02abb..a107a623ad228b 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_data_table.mdx b/api_docs/kbn_securitysolution_data_table.mdx index 752391b00c71e6..d311b80226c7cd 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-data-table'] --- import kbnSecuritysolutionDataTableObj from './kbn_securitysolution_data_table.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_ecs.mdx b/api_docs/kbn_securitysolution_ecs.mdx index 1c30c2dd9ddaeb..d1869f9a4816b0 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-ecs'] --- import kbnSecuritysolutionEcsObj from './kbn_securitysolution_ecs.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index c69cc00e9bd5d3..9c8f46c00fa4e4 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_exception_list_components.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index 485f91badfd291..33e35bdb985741 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_grouping.mdx b/api_docs/kbn_securitysolution_grouping.mdx index 99bcebd52620c4..b9cf2b0b9739ba 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-grouping'] --- import kbnSecuritysolutionGroupingObj from './kbn_securitysolution_grouping.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index daa59d3a14a8fe..46319a182d9269 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index dad69dd4f7d3c3..260270596e03b0 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index 457a7d0f43b9ac..83cf0e7c695406 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index 888396c1502592..f358714352b5b4 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index 6cd8f93dc42ce2..c3af10c0534b63 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index d6e71ec16ff109..09680f8121c3dc 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index ce41a5911691f4..3c036a6dd57f37 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index f1d90b86434766..02465aeb2b48c0 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index a17d58fef29578..1b521138d70b5e 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index 5bc2204e82bb74..11a94475369146 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index 7788a5d4355dd2..1ddc3e3ce890d0 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index 609f341dc1b05b..eb81380a5d4c11 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index 2cc9052e6efbb4..b7fd265e403064 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index 145a3a4e98f6cd..c1807025a970ea 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_common_settings.mdx b/api_docs/kbn_serverless_common_settings.mdx index 4d19913b46abcf..623fa4620616eb 100644 --- a/api_docs/kbn_serverless_common_settings.mdx +++ b/api_docs/kbn_serverless_common_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-common-settings title: "@kbn/serverless-common-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-common-settings plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-common-settings'] --- import kbnServerlessCommonSettingsObj from './kbn_serverless_common_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_observability_settings.mdx b/api_docs/kbn_serverless_observability_settings.mdx index 90e9414c322d84..64f4f2305ced14 100644 --- a/api_docs/kbn_serverless_observability_settings.mdx +++ b/api_docs/kbn_serverless_observability_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-observability-settings title: "@kbn/serverless-observability-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-observability-settings plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-observability-settings'] --- import kbnServerlessObservabilitySettingsObj from './kbn_serverless_observability_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index 4dae4a8365fb99..782e34ba4b4f33 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_search_settings.mdx b/api_docs/kbn_serverless_search_settings.mdx index 1f5140ac73696e..f5f47312a2239d 100644 --- a/api_docs/kbn_serverless_search_settings.mdx +++ b/api_docs/kbn_serverless_search_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-search-settings title: "@kbn/serverless-search-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-search-settings plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-search-settings'] --- import kbnServerlessSearchSettingsObj from './kbn_serverless_search_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_security_settings.mdx b/api_docs/kbn_serverless_security_settings.mdx index 5e1ef4e7cc4cd8..1ac366bfe562e4 100644 --- a/api_docs/kbn_serverless_security_settings.mdx +++ b/api_docs/kbn_serverless_security_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-security-settings title: "@kbn/serverless-security-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-security-settings plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-security-settings'] --- import kbnServerlessSecuritySettingsObj from './kbn_serverless_security_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index 5e737ffe67b0c2..fa32927d59d675 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-storybook-config'] --- import kbnServerlessStorybookConfigObj from './kbn_serverless_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index 34d9e1cd7c3f8f..1441ab5f319ae1 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_solution.mdx b/api_docs/kbn_shared_ux_avatar_solution.mdx index 0edcb0420cf0b3..656a38b53a56a6 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index b2a4991f0150db..7e49f604f850c7 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 731b7d47abda65..fcb72c805f2812 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index b402fab6533ba1..cff4b075ab221b 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index d2d7c19d98f93b..45b12b3750b493 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_chrome_navigation.mdx b/api_docs/kbn_shared_ux_chrome_navigation.mdx index 2ee426316121dd..241be1e2dc8a5c 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_error_boundary.mdx b/api_docs/kbn_shared_ux_error_boundary.mdx index 50108c9335524e..e55ced58eeebea 100644 --- a/api_docs/kbn_shared_ux_error_boundary.mdx +++ b/api_docs/kbn_shared_ux_error_boundary.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-error-boundary title: "@kbn/shared-ux-error-boundary" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-error-boundary plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-error-boundary'] --- import kbnSharedUxErrorBoundaryObj from './kbn_shared_ux_error_boundary.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index a60c0a9caec899..85318791c993f1 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-context'] --- import kbnSharedUxFileContextObj from './kbn_shared_ux_file_context.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image.mdx b/api_docs/kbn_shared_ux_file_image.mdx index 564d7c1f72c998..bf0f37a363d428 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image'] --- import kbnSharedUxFileImageObj from './kbn_shared_ux_file_image.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image_mocks.mdx b/api_docs/kbn_shared_ux_file_image_mocks.mdx index db69b2c21e993f..0114f454064a6c 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image-mocks'] --- import kbnSharedUxFileImageMocksObj from './kbn_shared_ux_file_image_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_mocks.mdx b/api_docs/kbn_shared_ux_file_mocks.mdx index ed36cadf1dd827..8166713a8fc1a3 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-mocks'] --- import kbnSharedUxFileMocksObj from './kbn_shared_ux_file_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_picker.mdx b/api_docs/kbn_shared_ux_file_picker.mdx index 9a7b32461ba39e..93d9c46622dbc4 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-picker'] --- import kbnSharedUxFilePickerObj from './kbn_shared_ux_file_picker.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_types.mdx b/api_docs/kbn_shared_ux_file_types.mdx index f10f62d557f53c..2150ad50b555fd 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-types'] --- import kbnSharedUxFileTypesObj from './kbn_shared_ux_file_types.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_upload.mdx b/api_docs/kbn_shared_ux_file_upload.mdx index cadb839de4d01e..8d53487db5291c 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-upload'] --- import kbnSharedUxFileUploadObj from './kbn_shared_ux_file_upload.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_util.mdx b/api_docs/kbn_shared_ux_file_util.mdx index d1ebebbf8a1e0a..0043a99a45cfe0 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-util'] --- import kbnSharedUxFileUtilObj from './kbn_shared_ux_file_util.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app.mdx b/api_docs/kbn_shared_ux_link_redirect_app.mdx index 4e23dbadfc9bda..f02a6548563987 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app'] --- import kbnSharedUxLinkRedirectAppObj from './kbn_shared_ux_link_redirect_app.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index 23c1ab42492420..017111547abd9b 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown.mdx b/api_docs/kbn_shared_ux_markdown.mdx index 4000466839f8f7..f971b9f5f20001 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown'] --- import kbnSharedUxMarkdownObj from './kbn_shared_ux_markdown.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown_mocks.mdx b/api_docs/kbn_shared_ux_markdown_mocks.mdx index 6fc345cdff8dc6..275ab12248e30d 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown-mocks'] --- import kbnSharedUxMarkdownMocksObj from './kbn_shared_ux_markdown_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index 4e0c87fcd147ca..b1f43e50f6f2a5 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index 02dd7e6dab7587..60ad579b6d45e4 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index 04b9041cfb4daf..3aac7dfb252d14 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index 8537917d2ff7a3..ec1aeb8bb099e2 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx index 096853f46f3c49..e3b2477e0a7344 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] --- import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx index 8bb57fa2a8302c..89e43d011ad580 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] --- import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx index 0a73e8c82489c9..21abb0c680ff27 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx index b3a4be7b334b7c..967bcac1dbb91f 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx index 038d4faba2241f..4c17331e53a35f 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] --- import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx index a8061ccfe81f24..67f4eaa9072856 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] --- import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index d30b04f051926c..129e716b310ac2 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index eb3833fa9b1e08..2cf47e4d6ae530 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index 51da2411721391..14e8a192349573 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_not_found.mdx b/api_docs/kbn_shared_ux_prompt_not_found.mdx index 2c03e16d1fc510..82e7dc484d482e 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-not-found'] --- import kbnSharedUxPromptNotFoundObj from './kbn_shared_ux_prompt_not_found.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router.mdx b/api_docs/kbn_shared_ux_router.mdx index ba28fe3f7d2dc6..15d52426fb4106 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router'] --- import kbnSharedUxRouterObj from './kbn_shared_ux_router.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router_mocks.mdx b/api_docs/kbn_shared_ux_router_mocks.mdx index 5709c448d789f2..bb9db8c3955485 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router-mocks'] --- import kbnSharedUxRouterMocksObj from './kbn_shared_ux_router_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_config.mdx b/api_docs/kbn_shared_ux_storybook_config.mdx index 9a2940efe64f9a..a0fbad4c9f3831 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-config'] --- import kbnSharedUxStorybookConfigObj from './kbn_shared_ux_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index fcc8046d13a633..9dd408ae04b732 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index 7c59a633a5dd47..80f255e05f2d22 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_slo_schema.mdx b/api_docs/kbn_slo_schema.mdx index ceb9a840c2a625..aec67816b98f75 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/slo-schema'] --- import kbnSloSchemaObj from './kbn_slo_schema.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index b9411bcd7e437a..91c8c4e1b9a0af 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 61a90c02e971a1..59844e84d6ba54 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index 5d042ac9453c0d..d0c05b71a4ebb9 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index 8c83d7b479f284..8305de18748938 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index dafa7e902090fa..da635921795853 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index 38873e11feae91..337ffc839be742 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index b6adb6aa52c70d..d06f76a0f9ef38 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index 4634783a3495b0..2d09bfa55c05a3 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index 855e9d75cb1472..fab964a0532048 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index a222ccab26b217..5b4925ec043d93 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_triggers_actions_ui_types.mdx b/api_docs/kbn_triggers_actions_ui_types.mdx index 27f68438ecc484..2e64f0a66076ce 100644 --- a/api_docs/kbn_triggers_actions_ui_types.mdx +++ b/api_docs/kbn_triggers_actions_ui_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-triggers-actions-ui-types title: "@kbn/triggers-actions-ui-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/triggers-actions-ui-types plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/triggers-actions-ui-types'] --- import kbnTriggersActionsUiTypesObj from './kbn_triggers_actions_ui_types.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index e51582dcdfc2e2..231cb6fa28b345 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ts-projects'] --- import kbnTsProjectsObj from './kbn_ts_projects.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index 26bd1db7ee89c4..a9fa5b5076f27b 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_actions_browser.mdx b/api_docs/kbn_ui_actions_browser.mdx index b8cba57bb09472..fa640cb01aee4d 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-actions-browser'] --- import kbnUiActionsBrowserObj from './kbn_ui_actions_browser.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 30e320001d442f..fd2e7f9e93986e 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-shared-deps-src'] --- import kbnUiSharedDepsSrcObj from './kbn_ui_shared_deps_src.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index c749f451f72644..9ebabf6d9866f9 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_data_table.mdx b/api_docs/kbn_unified_data_table.mdx index 4764ff63f7c4d4..e1c8ef91135e07 100644 --- a/api_docs/kbn_unified_data_table.mdx +++ b/api_docs/kbn_unified_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-data-table title: "@kbn/unified-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-data-table plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-data-table'] --- import kbnUnifiedDataTableObj from './kbn_unified_data_table.devdocs.json'; diff --git a/api_docs/kbn_unified_doc_viewer.mdx b/api_docs/kbn_unified_doc_viewer.mdx index 1b0ccd381712a2..905c287292f1d3 100644 --- a/api_docs/kbn_unified_doc_viewer.mdx +++ b/api_docs/kbn_unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-doc-viewer title: "@kbn/unified-doc-viewer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-doc-viewer plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-doc-viewer'] --- import kbnUnifiedDocViewerObj from './kbn_unified_doc_viewer.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index 2700f12fc973b1..153761a38bfdf8 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_unsaved_changes_badge.mdx b/api_docs/kbn_unsaved_changes_badge.mdx index cef793436ec50b..c7d55ba40d8b75 100644 --- a/api_docs/kbn_unsaved_changes_badge.mdx +++ b/api_docs/kbn_unsaved_changes_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unsaved-changes-badge title: "@kbn/unsaved-changes-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unsaved-changes-badge plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unsaved-changes-badge'] --- import kbnUnsavedChangesBadgeObj from './kbn_unsaved_changes_badge.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index fcac56c602b0e4..ca2c0f6143be7b 100644 --- a/api_docs/kbn_url_state.mdx +++ b/api_docs/kbn_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-url-state title: "@kbn/url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/url-state plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/url-state'] --- import kbnUrlStateObj from './kbn_url_state.devdocs.json'; diff --git a/api_docs/kbn_use_tracked_promise.mdx b/api_docs/kbn_use_tracked_promise.mdx index 70ee024c368f18..92e1bffc82f39c 100644 --- a/api_docs/kbn_use_tracked_promise.mdx +++ b/api_docs/kbn_use_tracked_promise.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-use-tracked-promise title: "@kbn/use-tracked-promise" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/use-tracked-promise plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/use-tracked-promise'] --- import kbnUseTrackedPromiseObj from './kbn_use_tracked_promise.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 900a4d6c7bce8a..d892f97529b62a 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index 98862238bb9097..547ba024933763 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index 819717c4d1ff90..3370cc57518c38 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index 65c46038f6aeb0..c6cb7073c859d7 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_visualization_ui_components.devdocs.json b/api_docs/kbn_visualization_ui_components.devdocs.json index 7390e6b1b8d428..fef2bfc2693e28 100644 --- a/api_docs/kbn_visualization_ui_components.devdocs.json +++ b/api_docs/kbn_visualization_ui_components.devdocs.json @@ -1945,39 +1945,6 @@ "returnComment": [], "initialIsOpen": false }, - { - "parentPluginId": "@kbn/visualization-ui-components", - "id": "def-public.TooltipWrapper", - "type": "Function", - "tags": [], - "label": "TooltipWrapper", - "description": [], - "signature": [ - "({ children, condition, tooltipContent, ...tooltipProps }: React.PropsWithChildren<TooltipWrapperProps>) => JSX.Element" - ], - "path": "packages/kbn-visualization-ui-components/components/tooltip_wrapper.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/visualization-ui-components", - "id": "def-public.TooltipWrapper.$1", - "type": "CompoundType", - "tags": [], - "label": "{\n children,\n condition,\n tooltipContent,\n ...tooltipProps\n}", - "description": [], - "signature": [ - "React.PropsWithChildren<TooltipWrapperProps>" - ], - "path": "packages/kbn-visualization-ui-components/components/tooltip_wrapper.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, { "parentPluginId": "@kbn/visualization-ui-components", "id": "def-public.useDebouncedValue", diff --git a/api_docs/kbn_visualization_ui_components.mdx b/api_docs/kbn_visualization_ui_components.mdx index ed530e49d0d3c2..04af4ac3d0c9ba 100644 --- a/api_docs/kbn_visualization_ui_components.mdx +++ b/api_docs/kbn_visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-ui-components title: "@kbn/visualization-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-ui-components plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-ui-components'] --- import kbnVisualizationUiComponentsObj from './kbn_visualization_ui_components.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 154 | 0 | 151 | 3 | +| 152 | 0 | 149 | 3 | ## Client diff --git a/api_docs/kbn_visualization_utils.devdocs.json b/api_docs/kbn_visualization_utils.devdocs.json index d76530afc1e288..649bfd18f772ab 100644 --- a/api_docs/kbn_visualization_utils.devdocs.json +++ b/api_docs/kbn_visualization_utils.devdocs.json @@ -67,6 +67,39 @@ ], "returnComment": [], "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/visualization-utils", + "id": "def-common.TooltipWrapper", + "type": "Function", + "tags": [], + "label": "TooltipWrapper", + "description": [], + "signature": [ + "({ children, condition, tooltipContent, ...tooltipProps }: React.PropsWithChildren<TooltipWrapperProps>) => JSX.Element" + ], + "path": "packages/kbn-visualization-utils/src/tooltip_wrapper.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/visualization-utils", + "id": "def-common.TooltipWrapper.$1", + "type": "CompoundType", + "tags": [], + "label": "{\n children,\n condition,\n tooltipContent,\n ...tooltipProps\n}", + "description": [], + "signature": [ + "React.PropsWithChildren<TooltipWrapperProps>" + ], + "path": "packages/kbn-visualization-utils/src/tooltip_wrapper.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false } ], "interfaces": [], diff --git a/api_docs/kbn_visualization_utils.mdx b/api_docs/kbn_visualization_utils.mdx index 3050f707cb63b4..dc0d5cb4fc5535 100644 --- a/api_docs/kbn_visualization_utils.mdx +++ b/api_docs/kbn_visualization_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-utils title: "@kbn/visualization-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-utils'] --- import kbnVisualizationUtilsObj from './kbn_visualization_utils.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2 | 0 | 1 | 0 | +| 4 | 0 | 3 | 0 | ## Common diff --git a/api_docs/kbn_xstate_utils.mdx b/api_docs/kbn_xstate_utils.mdx index 39f0156a7f3931..305e0f12b70c4e 100644 --- a/api_docs/kbn_xstate_utils.mdx +++ b/api_docs/kbn_xstate_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-xstate-utils title: "@kbn/xstate-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/xstate-utils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/xstate-utils'] --- import kbnXstateUtilsObj from './kbn_xstate_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 4f4441e0d5bcd6..8db7eb2fa794b4 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kbn_zod_helpers.mdx b/api_docs/kbn_zod_helpers.mdx index e31e880f0303cc..ce08383caf11dd 100644 --- a/api_docs/kbn_zod_helpers.mdx +++ b/api_docs/kbn_zod_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-zod-helpers title: "@kbn/zod-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/zod-helpers plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/zod-helpers'] --- import kbnZodHelpersObj from './kbn_zod_helpers.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 06bea3a9af2170..4ddd0b8f3b742b 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.devdocs.json b/api_docs/kibana_react.devdocs.json index 193309dd1a10c8..14271d81ea4be9 100644 --- a/api_docs/kibana_react.devdocs.json +++ b/api_docs/kibana_react.devdocs.json @@ -3182,35 +3182,35 @@ }, { "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/ingest_pipelines.ts" + "path": "x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/ingest_pipelines.ts" }, { "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/ingest_pipelines.ts" + "path": "x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/ingest_pipelines.ts" }, { "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/ingest_pipelines.ts" + "path": "x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/ingest_pipelines.ts" }, { "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/stored_scripts.ts" + "path": "x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.ts" }, { "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/stored_scripts.ts" + "path": "x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.ts" }, { "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/stored_scripts.ts" + "path": "x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.ts" }, { "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/saved_objects.ts" + "path": "x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/saved_objects.ts" }, { "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/explore/containers/risk_score/onboarding/api/saved_objects.ts" + "path": "x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/saved_objects.ts" }, { "plugin": "securitySolution", @@ -3491,6 +3491,39 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "kibanaReact", + "id": "def-public.useDarkMode", + "type": "Function", + "tags": [], + "label": "useDarkMode", + "description": [], + "signature": [ + "(defaultValue?: boolean | undefined) => boolean" + ], + "path": "src/plugins/kibana_react/public/dark_mode/use_dark_mode.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "kibanaReact", + "id": "def-public.useDarkMode.$1", + "type": "CompoundType", + "tags": [], + "label": "defaultValue", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/kibana_react/public/dark_mode/use_dark_mode.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "kibanaReact", "id": "def-public.useExecutionContext", diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index 3a736d65bad579..8c231df6323c3e 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sh | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 161 | 0 | 127 | 3 | +| 163 | 0 | 129 | 3 | ## Client diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index 4fecd5e7d96e48..65fc88d9e16b17 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index bcad5afe8964b7..0f579df94d0c8f 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 43a45ad70fb15e..baef297e564498 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 6a4c82b8a8794e..3da9361a4c785a 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index c545d98dace7ca..c93b37536c8ba1 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index 5cdcdabe6ece99..14b7ee7b6c5c5b 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/links.mdx b/api_docs/links.mdx index 96287b83998f40..20285f441e6fcf 100644 --- a/api_docs/links.mdx +++ b/api_docs/links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/links title: "links" image: https://source.unsplash.com/400x175/?github description: API docs for the links plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'links'] --- import linksObj from './links.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index c9858c1b336684..df7c23d2192c21 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/log_explorer.mdx b/api_docs/log_explorer.mdx index f7d80ed35744e9..1fd983ac3ed2ab 100644 --- a/api_docs/log_explorer.mdx +++ b/api_docs/log_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logExplorer title: "logExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the logExplorer plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logExplorer'] --- import logExplorerObj from './log_explorer.devdocs.json'; diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index 34f168ca6d1cdf..e43db323bc72e0 100644 --- a/api_docs/logs_shared.mdx +++ b/api_docs/logs_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsShared title: "logsShared" image: https://source.unsplash.com/400x175/?github description: API docs for the logsShared plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsShared'] --- import logsSharedObj from './logs_shared.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index fb75971d421803..eecf752d022122 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index 922773a9fa48e3..2469ccc7596517 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index 9759248cfe03ec..ef3712a07089d0 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/metrics_data_access.mdx b/api_docs/metrics_data_access.mdx index 9d4a25d840dfe1..3a41231e90ac81 100644 --- a/api_docs/metrics_data_access.mdx +++ b/api_docs/metrics_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/metricsDataAccess title: "metricsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the metricsDataAccess plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'metricsDataAccess'] --- import metricsDataAccessObj from './metrics_data_access.devdocs.json'; diff --git a/api_docs/ml.devdocs.json b/api_docs/ml.devdocs.json index 7006f03c266491..5bce2600d35f6c 100644 --- a/api_docs/ml.devdocs.json +++ b/api_docs/ml.devdocs.json @@ -2574,6 +2574,22 @@ "initialIsOpen": false } ], - "objects": [] + "objects": [ + { + "parentPluginId": "ml", + "id": "def-common.ML_ALERT_TYPES", + "type": "Object", + "tags": [], + "label": "ML_ALERT_TYPES", + "description": [], + "signature": [ + "{ readonly ANOMALY_DETECTION: \"xpack.ml.anomaly_detection_alert\"; readonly AD_JOBS_HEALTH: \"xpack.ml.anomaly_detection_jobs_health\"; }" + ], + "path": "x-pack/plugins/ml/common/constants/alerts.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ] } } \ No newline at end of file diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 39c8b7f0936bc0..c7d390bfa12ea0 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) for questi | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 150 | 3 | 64 | 33 | +| 151 | 3 | 65 | 33 | ## Client @@ -62,6 +62,9 @@ Contact [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) for questi ## Common +### Objects +<DocDefinitionList data={mlObj.common.objects}/> + ### Functions <DocDefinitionList data={mlObj.common.functions}/> diff --git a/api_docs/mock_idp_plugin.mdx b/api_docs/mock_idp_plugin.mdx index d50d6bd0f569e2..63ffa79a8d98c4 100644 --- a/api_docs/mock_idp_plugin.mdx +++ b/api_docs/mock_idp_plugin.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mockIdpPlugin title: "mockIdpPlugin" image: https://source.unsplash.com/400x175/?github description: API docs for the mockIdpPlugin plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mockIdpPlugin'] --- import mockIdpPluginObj from './mock_idp_plugin.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index e1e604ffd2fa3e..eebbef32efe94a 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index 49f02cdd7ef855..ac1aff11ff6b3a 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index 2606500208d222..07700bcdf64453 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 1a1a394eb8a864..400d230ed7bdc4 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/no_data_page.mdx b/api_docs/no_data_page.mdx index 1a945f3286452e..2a9b518bccbb3e 100644 --- a/api_docs/no_data_page.mdx +++ b/api_docs/no_data_page.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/noDataPage title: "noDataPage" image: https://source.unsplash.com/400x175/?github description: API docs for the noDataPage plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'noDataPage'] --- import noDataPageObj from './no_data_page.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index 511c367dfd527a..293b0e58322ae0 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.devdocs.json b/api_docs/observability.devdocs.json index deb64ecc9534ed..423280f403ac4c 100644 --- a/api_docs/observability.devdocs.json +++ b/api_docs/observability.devdocs.json @@ -14435,79 +14435,6 @@ } ] }, - { - "parentPluginId": "observability", - "id": "def-server.uiSettings.profilingUseLegacyCo2Calculation", - "type": "Object", - "tags": [], - "label": "[profilingUseLegacyCo2Calculation]", - "description": [], - "path": "x-pack/plugins/observability/server/ui_settings.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "observability", - "id": "def-server.uiSettings.profilingUseLegacyCo2Calculation.category", - "type": "Array", - "tags": [], - "label": "category", - "description": [], - "signature": [ - "string[]" - ], - "path": "x-pack/plugins/observability/server/ui_settings.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "observability", - "id": "def-server.uiSettings.profilingUseLegacyCo2Calculation.name", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "path": "x-pack/plugins/observability/server/ui_settings.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "observability", - "id": "def-server.uiSettings.profilingUseLegacyCo2Calculation.value", - "type": "boolean", - "tags": [], - "label": "value", - "description": [], - "signature": [ - "false" - ], - "path": "x-pack/plugins/observability/server/ui_settings.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "observability", - "id": "def-server.uiSettings.profilingUseLegacyCo2Calculation.schema", - "type": "Object", - "tags": [], - "label": "schema", - "description": [], - "signature": [ - { - "pluginId": "@kbn/config-schema", - "scope": "common", - "docId": "kibKbnConfigSchemaPluginApi", - "section": "def-common.Type", - "text": "Type" - }, - "<boolean>" - ], - "path": "x-pack/plugins/observability/server/ui_settings.ts", - "deprecated": false, - "trackAdoption": false - } - ] - }, { "parentPluginId": "observability", "id": "def-server.uiSettings.profilingAWSCostDiscountRate", @@ -16196,21 +16123,6 @@ "trackAdoption": false, "initialIsOpen": false }, - { - "parentPluginId": "observability", - "id": "def-common.profilingUseLegacyCo2Calculation", - "type": "string", - "tags": [], - "label": "profilingUseLegacyCo2Calculation", - "description": [], - "signature": [ - "\"observability:profilingUseLegacyCo2Calculation\"" - ], - "path": "x-pack/plugins/observability/common/ui_settings_keys.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, { "parentPluginId": "observability", "id": "def-common.ruleDetailsLocatorID", diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index 6d84e75abce28e..b147c10b8c87a6 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/ | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 609 | 2 | 600 | 17 | +| 603 | 2 | 594 | 17 | ## Client diff --git a/api_docs/observability_a_i_assistant.mdx b/api_docs/observability_a_i_assistant.mdx index b877662dc6996e..6b17caa652cb64 100644 --- a/api_docs/observability_a_i_assistant.mdx +++ b/api_docs/observability_a_i_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAIAssistant title: "observabilityAIAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAIAssistant plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistant'] --- import observabilityAIAssistantObj from './observability_a_i_assistant.devdocs.json'; diff --git a/api_docs/observability_log_explorer.mdx b/api_docs/observability_log_explorer.mdx index aba2a4083a869d..5dcc4481ae575a 100644 --- a/api_docs/observability_log_explorer.mdx +++ b/api_docs/observability_log_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityLogExplorer title: "observabilityLogExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityLogExplorer plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityLogExplorer'] --- import observabilityLogExplorerObj from './observability_log_explorer.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index 337c6c985de7c2..dab31df9f7f257 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityOnboarding'] --- import observabilityOnboardingObj from './observability_onboarding.devdocs.json'; diff --git a/api_docs/observability_shared.mdx b/api_docs/observability_shared.mdx index 9961c7ee45b199..731be74cb2e765 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityShared'] --- import observabilitySharedObj from './observability_shared.devdocs.json'; diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index 5901b5a78fe7ba..f35a869b128505 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/painless_lab.mdx b/api_docs/painless_lab.mdx index 76013e66cdf0e7..6fa1e15704e8a7 100644 --- a/api_docs/painless_lab.mdx +++ b/api_docs/painless_lab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/painlessLab title: "painlessLab" image: https://source.unsplash.com/400x175/?github description: API docs for the painlessLab plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'painlessLab'] --- import painlessLabObj from './painless_lab.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 4747b5e1d153cf..90f44afb4f312e 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 77945 | 234 | 66664 | 1633 | +| 77946 | 234 | 66665 | 1633 | ## Plugin Directory @@ -116,7 +116,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | <DocLink id="kibInspectorPluginApi" text="inspector"/> | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 123 | 2 | 96 | 4 | | <DocLink id="kibInteractiveSetupPluginApi" text="interactiveSetup"/> | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides UI and APIs for the interactive setup mode. | 28 | 0 | 18 | 0 | | <DocLink id="kibKibanaOverviewPluginApi" text="kibanaOverview"/> | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 6 | 0 | 6 | 0 | -| <DocLink id="kibKibanaReactPluginApi" text="kibanaReact"/> | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 161 | 0 | 127 | 3 | +| <DocLink id="kibKibanaReactPluginApi" text="kibanaReact"/> | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 163 | 0 | 129 | 3 | | kibanaUsageCollection | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | <DocLink id="kibKibanaUtilsPluginApi" text="kibanaUtils"/> | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 611 | 3 | 418 | 9 | | <DocLink id="kibKubernetesSecurityPluginApi" text="kubernetesSecurity"/> | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | - | 5 | 0 | 5 | 1 | @@ -133,7 +133,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | <DocLink id="kibMapsPluginApi" text="maps"/> | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 260 | 0 | 259 | 28 | | <DocLink id="kibMapsEmsPluginApi" text="mapsEms"/> | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 60 | 0 | 60 | 0 | | <DocLink id="kibMetricsDataAccessPluginApi" text="metricsDataAccess"/> | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | Exposes utilities for accessing metrics data | 104 | 8 | 104 | 7 | -| <DocLink id="kibMlPluginApi" text="ml"/> | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 150 | 3 | 64 | 33 | +| <DocLink id="kibMlPluginApi" text="ml"/> | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 151 | 3 | 65 | 33 | | <DocLink id="kibMockIdpPluginPluginApi" text="mockIdpPlugin"/> | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 25 | 0 | 19 | 0 | | <DocLink id="kibMonitoringPluginApi" text="monitoring"/> | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 15 | 3 | 13 | 1 | | <DocLink id="kibMonitoringCollectionPluginApi" text="monitoringCollection"/> | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 9 | 0 | 9 | 0 | @@ -141,7 +141,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | <DocLink id="kibNewsfeedPluginApi" text="newsfeed"/> | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 17 | 0 | 17 | 0 | | <DocLink id="kibNoDataPagePluginApi" text="noDataPage"/> | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 3 | 0 | 3 | 0 | | <DocLink id="kibNotificationsPluginApi" text="notifications"/> | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 1 | -| <DocLink id="kibObservabilityPluginApi" text="observability"/> | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 609 | 2 | 600 | 17 | +| <DocLink id="kibObservabilityPluginApi" text="observability"/> | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 603 | 2 | 594 | 17 | | <DocLink id="kibObservabilityAIAssistantPluginApi" text="observabilityAIAssistant"/> | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 75 | 0 | 73 | 13 | | <DocLink id="kibObservabilityLogExplorerPluginApi" text="observabilityLogExplorer"/> | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin exposes and registers observability log consumption features. | 18 | 0 | 18 | 1 | | <DocLink id="kibObservabilityOnboardingPluginApi" text="observabilityOnboarding"/> | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 14 | 0 | 14 | 0 | @@ -189,7 +189,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | <DocLink id="kibTimelinesPluginApi" text="timelines"/> | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | - | 240 | 1 | 196 | 17 | | <DocLink id="kibTransformPluginApi" text="transform"/> | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the transforms features provided by Elastic. Transforms enable you to convert existing Elasticsearch indices into summarized indices, which provide opportunities for new insights and analytics. | 4 | 0 | 4 | 1 | | translations | [@elastic/kibana-localization](https://github.com/orgs/elastic/teams/kibana-localization) | - | 0 | 0 | 0 | 0 | -| <DocLink id="kibTriggersActionsUiPluginApi" text="triggersActionsUi"/> | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 592 | 1 | 566 | 58 | +| <DocLink id="kibTriggersActionsUiPluginApi" text="triggersActionsUi"/> | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 595 | 1 | 569 | 58 | | <DocLink id="kibUiActionsPluginApi" text="uiActions"/> | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Adds UI Actions service to Kibana | 135 | 0 | 93 | 9 | | <DocLink id="kibUiActionsEnhancedPluginApi" text="uiActionsEnhanced"/> | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Extends UI Actions plugin with more functionality | 212 | 0 | 145 | 11 | | <DocLink id="kibUnifiedDocViewerPluginApi" text="unifiedDocViewer"/> | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains services reliant on the plugin lifecycle for the unified doc viewer component (see @kbn/unified-doc-viewer). | 10 | 0 | 7 | 2 | @@ -573,7 +573,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | <DocLink id="kibKbnRisonPluginApi" text="@kbn/rison"/> | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 13 | 2 | 8 | 0 | | <DocLink id="kibKbnRouterUtilsPluginApi" text="@kbn/router-utils"/> | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 2 | 0 | 1 | 0 | | <DocLink id="kibKbnRrulePluginApi" text="@kbn/rrule"/> | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 16 | 0 | 16 | 1 | -| <DocLink id="kibKbnRuleDataUtilsPluginApi" text="@kbn/rule-data-utils"/> | [@elastic/security-detections-response](https://github.com/orgs/elastic/teams/security-detections-response) | - | 119 | 0 | 116 | 0 | +| <DocLink id="kibKbnRuleDataUtilsPluginApi" text="@kbn/rule-data-utils"/> | [@elastic/security-detections-response](https://github.com/orgs/elastic/teams/security-detections-response) | - | 120 | 0 | 117 | 0 | | <DocLink id="kibKbnSavedObjectsSettingsPluginApi" text="@kbn/saved-objects-settings"/> | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 0 | | <DocLink id="kibKbnSearchApiPanelsPluginApi" text="@kbn/search-api-panels"/> | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 75 | 0 | 75 | 0 | | <DocLink id="kibKbnSearchConnectorsPluginApi" text="@kbn/search-connectors"/> | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 2649 | 0 | 2649 | 0 | @@ -679,8 +679,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | <DocLink id="kibKbnUtilityTypesPluginApi" text="@kbn/utility-types"/> | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 37 | 0 | 16 | 1 | | <DocLink id="kibKbnUtilityTypesJestPluginApi" text="@kbn/utility-types-jest"/> | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 2 | 0 | 2 | 0 | | <DocLink id="kibKbnUtilsPluginApi" text="@kbn/utils"/> | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 24 | 0 | 14 | 0 | -| <DocLink id="kibKbnVisualizationUiComponentsPluginApi" text="@kbn/visualization-ui-components"/> | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 154 | 0 | 151 | 3 | -| <DocLink id="kibKbnVisualizationUtilsPluginApi" text="@kbn/visualization-utils"/> | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 2 | 0 | 1 | 0 | +| <DocLink id="kibKbnVisualizationUiComponentsPluginApi" text="@kbn/visualization-ui-components"/> | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 152 | 0 | 149 | 3 | +| <DocLink id="kibKbnVisualizationUtilsPluginApi" text="@kbn/visualization-utils"/> | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 4 | 0 | 3 | 0 | | <DocLink id="kibKbnXstateUtilsPluginApi" text="@kbn/xstate-utils"/> | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 13 | 0 | 13 | 0 | | <DocLink id="kibKbnYarnLockValidatorPluginApi" text="@kbn/yarn-lock-validator"/> | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 6 | 0 | 2 | 0 | | <DocLink id="kibKbnZodHelpersPluginApi" text="@kbn/zod-helpers"/> | [@elastic/security-detection-rule-management](https://github.com/orgs/elastic/teams/security-detection-rule-management) | - | 18 | 0 | 9 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index c5fcf6bfdcb845..28f210fe2b8e2b 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index 316aac69a7a248..c1353b0f30b4a2 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/profiling_data_access.mdx b/api_docs/profiling_data_access.mdx index db31aaa30770b5..3ee22f24192a58 100644 --- a/api_docs/profiling_data_access.mdx +++ b/api_docs/profiling_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profilingDataAccess title: "profilingDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the profilingDataAccess plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profilingDataAccess'] --- import profilingDataAccessObj from './profiling_data_access.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index 0c3a29e2f02922..9e4a4cb3b80e1d 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index 0e0f3fa5e0d8bf..831dffcc293d21 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 6cd47a02f92ab7..2e832369da3c3d 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index d7de2b78ab759f..12b717b1436ce3 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index 4e93860f6f085c..a114d2f14e382f 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index aadb38dd6a1124..e7a2de7bb02601 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index e00b28a628f23f..91db479ca910c5 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index 93157b055943f1..b2ded45c12f3fb 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 28287a1053a899..cae0f7dda8a108 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index 7ddd453c5b9696..b5c9582279e05a 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index 4d2e24cbe2e679..e1cce405377548 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index 19dd5b85890a5f..cf1b7f7de337e4 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index 3e00d449b78b61..86ba37a57ea84e 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 0ede3f065f01e6..6144c2f5f9f86b 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.devdocs.json b/api_docs/security_solution.devdocs.json index 90e9ace7ef4dd4..c22d74cdd9d0e8 100644 --- a/api_docs/security_solution.devdocs.json +++ b/api_docs/security_solution.devdocs.json @@ -114,7 +114,7 @@ "label": "experimentalFeatures", "description": [], "signature": [ - "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly assistantStreamingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly expandableFlyoutInCreateRuleEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly assistantRagOnAlerts: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly alertSuppressionForThresholdRuleEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly entityAnalyticsAssetCriticalityEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly jsonPrebuiltRulesDiffingEnabled: boolean; }" + "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly assistantStreamingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly responseActionsSentinelOneV1Enabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly expandableFlyoutInCreateRuleEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly entityAnalyticsAssetCriticalityEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly jsonPrebuiltRulesDiffingEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/public/plugin.tsx", "deprecated": false, @@ -568,7 +568,7 @@ "\nExperimental flag needed to enable the link" ], "signature": [ - "\"tGridEnabled\" | \"tGridEventRenderedViewEnabled\" | \"excludePoliciesInFilterEnabled\" | \"kubernetesEnabled\" | \"chartEmbeddablesEnabled\" | \"donutChartEmbeddablesEnabled\" | \"alertsPreviewChartEmbeddablesEnabled\" | \"previewTelemetryUrlEnabled\" | \"insightsRelatedAlertsByProcessAncestry\" | \"extendedRuleExecutionLoggingEnabled\" | \"assistantStreamingEnabled\" | \"socTrendsEnabled\" | \"responseActionsEnabled\" | \"endpointResponseActionsEnabled\" | \"responseActionUploadEnabled\" | \"alertsPageChartsEnabled\" | \"alertTypeEnabled\" | \"expandableFlyoutInCreateRuleEnabled\" | \"alertsPageFiltersEnabled\" | \"assistantModelEvaluation\" | \"assistantRagOnAlerts\" | \"newUserDetailsFlyout\" | \"riskScoringPersistence\" | \"riskScoringRoutesEnabled\" | \"esqlRulesDisabled\" | \"protectionUpdatesEnabled\" | \"alertSuppressionForThresholdRuleEnabled\" | \"disableTimelineSaveTour\" | \"riskEnginePrivilegesRouteEnabled\" | \"entityAnalyticsAssetCriticalityEnabled\" | \"sentinelOneDataInAnalyzerEnabled\" | \"sentinelOneManualHostActionsEnabled\" | \"jsonPrebuiltRulesDiffingEnabled\" | undefined" + "\"tGridEnabled\" | \"tGridEventRenderedViewEnabled\" | \"excludePoliciesInFilterEnabled\" | \"kubernetesEnabled\" | \"chartEmbeddablesEnabled\" | \"donutChartEmbeddablesEnabled\" | \"alertsPreviewChartEmbeddablesEnabled\" | \"previewTelemetryUrlEnabled\" | \"insightsRelatedAlertsByProcessAncestry\" | \"extendedRuleExecutionLoggingEnabled\" | \"assistantStreamingEnabled\" | \"socTrendsEnabled\" | \"responseActionsEnabled\" | \"endpointResponseActionsEnabled\" | \"responseActionUploadEnabled\" | \"responseActionsSentinelOneV1Enabled\" | \"alertsPageChartsEnabled\" | \"alertTypeEnabled\" | \"expandableFlyoutInCreateRuleEnabled\" | \"alertsPageFiltersEnabled\" | \"assistantModelEvaluation\" | \"newUserDetailsFlyout\" | \"riskScoringPersistence\" | \"riskScoringRoutesEnabled\" | \"esqlRulesDisabled\" | \"protectionUpdatesEnabled\" | \"disableTimelineSaveTour\" | \"riskEnginePrivilegesRouteEnabled\" | \"entityAnalyticsAssetCriticalityEnabled\" | \"sentinelOneDataInAnalyzerEnabled\" | \"sentinelOneManualHostActionsEnabled\" | \"jsonPrebuiltRulesDiffingEnabled\" | undefined" ], "path": "x-pack/plugins/security_solution/public/common/links/types.ts", "deprecated": false, @@ -648,7 +648,7 @@ "\nExperimental flag needed to disable the link. Opposite of experimentalKey" ], "signature": [ - "\"tGridEnabled\" | \"tGridEventRenderedViewEnabled\" | \"excludePoliciesInFilterEnabled\" | \"kubernetesEnabled\" | \"chartEmbeddablesEnabled\" | \"donutChartEmbeddablesEnabled\" | \"alertsPreviewChartEmbeddablesEnabled\" | \"previewTelemetryUrlEnabled\" | \"insightsRelatedAlertsByProcessAncestry\" | \"extendedRuleExecutionLoggingEnabled\" | \"assistantStreamingEnabled\" | \"socTrendsEnabled\" | \"responseActionsEnabled\" | \"endpointResponseActionsEnabled\" | \"responseActionUploadEnabled\" | \"alertsPageChartsEnabled\" | \"alertTypeEnabled\" | \"expandableFlyoutInCreateRuleEnabled\" | \"alertsPageFiltersEnabled\" | \"assistantModelEvaluation\" | \"assistantRagOnAlerts\" | \"newUserDetailsFlyout\" | \"riskScoringPersistence\" | \"riskScoringRoutesEnabled\" | \"esqlRulesDisabled\" | \"protectionUpdatesEnabled\" | \"alertSuppressionForThresholdRuleEnabled\" | \"disableTimelineSaveTour\" | \"riskEnginePrivilegesRouteEnabled\" | \"entityAnalyticsAssetCriticalityEnabled\" | \"sentinelOneDataInAnalyzerEnabled\" | \"sentinelOneManualHostActionsEnabled\" | \"jsonPrebuiltRulesDiffingEnabled\" | undefined" + "\"tGridEnabled\" | \"tGridEventRenderedViewEnabled\" | \"excludePoliciesInFilterEnabled\" | \"kubernetesEnabled\" | \"chartEmbeddablesEnabled\" | \"donutChartEmbeddablesEnabled\" | \"alertsPreviewChartEmbeddablesEnabled\" | \"previewTelemetryUrlEnabled\" | \"insightsRelatedAlertsByProcessAncestry\" | \"extendedRuleExecutionLoggingEnabled\" | \"assistantStreamingEnabled\" | \"socTrendsEnabled\" | \"responseActionsEnabled\" | \"endpointResponseActionsEnabled\" | \"responseActionUploadEnabled\" | \"responseActionsSentinelOneV1Enabled\" | \"alertsPageChartsEnabled\" | \"alertTypeEnabled\" | \"expandableFlyoutInCreateRuleEnabled\" | \"alertsPageFiltersEnabled\" | \"assistantModelEvaluation\" | \"newUserDetailsFlyout\" | \"riskScoringPersistence\" | \"riskScoringRoutesEnabled\" | \"esqlRulesDisabled\" | \"protectionUpdatesEnabled\" | \"disableTimelineSaveTour\" | \"riskEnginePrivilegesRouteEnabled\" | \"entityAnalyticsAssetCriticalityEnabled\" | \"sentinelOneDataInAnalyzerEnabled\" | \"sentinelOneManualHostActionsEnabled\" | \"jsonPrebuiltRulesDiffingEnabled\" | undefined" ], "path": "x-pack/plugins/security_solution/public/common/links/types.ts", "deprecated": false, @@ -1913,7 +1913,7 @@ "label": "experimentalFeatures", "description": [], "signature": [ - "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly assistantStreamingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly expandableFlyoutInCreateRuleEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly assistantRagOnAlerts: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly alertSuppressionForThresholdRuleEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly entityAnalyticsAssetCriticalityEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly jsonPrebuiltRulesDiffingEnabled: boolean; }" + "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly assistantStreamingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly responseActionsSentinelOneV1Enabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly expandableFlyoutInCreateRuleEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly entityAnalyticsAssetCriticalityEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly jsonPrebuiltRulesDiffingEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/public/types.ts", "deprecated": false, @@ -3018,7 +3018,7 @@ "\nThe security solution generic experimental features" ], "signature": [ - "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly assistantStreamingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly expandableFlyoutInCreateRuleEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly assistantRagOnAlerts: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly alertSuppressionForThresholdRuleEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly entityAnalyticsAssetCriticalityEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly jsonPrebuiltRulesDiffingEnabled: boolean; }" + "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly assistantStreamingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly responseActionsSentinelOneV1Enabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly expandableFlyoutInCreateRuleEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly entityAnalyticsAssetCriticalityEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly jsonPrebuiltRulesDiffingEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/server/plugin_contract.ts", "deprecated": false, @@ -3194,7 +3194,7 @@ "label": "ExperimentalFeatures", "description": [], "signature": [ - "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly assistantStreamingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly expandableFlyoutInCreateRuleEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly assistantRagOnAlerts: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly alertSuppressionForThresholdRuleEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly entityAnalyticsAssetCriticalityEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly jsonPrebuiltRulesDiffingEnabled: boolean; }" + "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly assistantStreamingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly responseActionsSentinelOneV1Enabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly expandableFlyoutInCreateRuleEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly entityAnalyticsAssetCriticalityEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly jsonPrebuiltRulesDiffingEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/common/experimental_features.ts", "deprecated": false, @@ -3243,7 +3243,7 @@ "\nA list of allowed values that can be used in `xpack.securitySolution.enableExperimental`.\nThis object is then used to validate and parse the value entered." ], "signature": [ - "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly assistantStreamingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly expandableFlyoutInCreateRuleEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly assistantRagOnAlerts: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly alertSuppressionForThresholdRuleEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly entityAnalyticsAssetCriticalityEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly jsonPrebuiltRulesDiffingEnabled: boolean; }" + "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly assistantStreamingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly responseActionsSentinelOneV1Enabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly expandableFlyoutInCreateRuleEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly entityAnalyticsAssetCriticalityEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly jsonPrebuiltRulesDiffingEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/common/experimental_features.ts", "deprecated": false, diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index c35d33c5a18303..189a7784a3174f 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/security_solution_ess.mdx b/api_docs/security_solution_ess.mdx index 0c8033309906aa..bfd2536e418869 100644 --- a/api_docs/security_solution_ess.mdx +++ b/api_docs/security_solution_ess.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionEss title: "securitySolutionEss" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionEss plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionEss'] --- import securitySolutionEssObj from './security_solution_ess.devdocs.json'; diff --git a/api_docs/security_solution_serverless.mdx b/api_docs/security_solution_serverless.mdx index 52d425948f887e..08f805175de7eb 100644 --- a/api_docs/security_solution_serverless.mdx +++ b/api_docs/security_solution_serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionServerless title: "securitySolutionServerless" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionServerless plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionServerless'] --- import securitySolutionServerlessObj from './security_solution_serverless.devdocs.json'; diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index 5a8d4beb657894..57b66e0b486cc8 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverless'] --- import serverlessObj from './serverless.devdocs.json'; diff --git a/api_docs/serverless_observability.mdx b/api_docs/serverless_observability.mdx index 503bfed68c52f6..93eb5cc15402dc 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessObservability'] --- import serverlessObservabilityObj from './serverless_observability.devdocs.json'; diff --git a/api_docs/serverless_search.mdx b/api_docs/serverless_search.mdx index 1b254a56e0845f..798f274d69f37b 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 7df80b70f7d48b..ad823dad1f6bbe 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index 7df436cbd7e9f1..85658cea199377 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 65d446a3668992..10887a79951a8b 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index 3b217b70a5f84e..e8a511ae50d25f 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index 41fb5eba150b7e..c737cd5336e23c 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/stack_connectors.mdx b/api_docs/stack_connectors.mdx index db49c370487ca5..cd27ded3c46f5a 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index ae1bc369776341..a6c2e53ea15bce 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index bec624ee7bc0a1..753fcd38926ec7 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index 022872c85c626d..d9ae4f8c672b92 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index e89823beb2c2a8..86f1e74ab458ed 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 60093707708af5..633e612c8e969a 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/text_based_languages.mdx b/api_docs/text_based_languages.mdx index 856b1a94c8e2a5..465197b2c7ff1c 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'textBasedLanguages'] --- import textBasedLanguagesObj from './text_based_languages.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 5517b603b50168..98d0a30b57403b 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 66a6f9bbf7318d..da99b908218abb 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index aa7207521614e2..4d3664a40e6b47 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.devdocs.json b/api_docs/triggers_actions_ui.devdocs.json index fc734b95daecbc..999d1112edac7a 100644 --- a/api_docs/triggers_actions_ui.devdocs.json +++ b/api_docs/triggers_actions_ui.devdocs.json @@ -6474,7 +6474,7 @@ "label": "RuleCreationValidConsumer", "description": [], "signature": [ - "\"observability\" | \"stackAlerts\" | \"logs\" | \"infrastructure\"" + "\"observability\" | \"stackAlerts\" | \"alerts\" | \"logs\" | \"infrastructure\"" ], "path": "packages/kbn-rule-data-utils/src/rule_types/index.ts", "deprecated": false, @@ -9108,7 +9108,7 @@ "label": "buildAggregation", "description": [], "signature": [ - "({ timeSeries, aggType, aggField, termField, termSize, condition, topHitsSize, }: ", + "({ timeSeries, aggType, aggField, termField, termSize, sourceFieldsParams, condition, topHitsSize, }: ", { "pluginId": "triggersActionsUi", "scope": "common", @@ -9129,7 +9129,7 @@ "id": "def-common.buildAggregation.$1", "type": "Object", "tags": [], - "label": "{\n timeSeries,\n aggType,\n aggField,\n termField,\n termSize,\n condition,\n topHitsSize,\n}", + "label": "{\n timeSeries,\n aggType,\n aggField,\n termField,\n termSize,\n sourceFieldsParams,\n condition,\n topHitsSize,\n}", "description": [], "signature": [ { @@ -9392,7 +9392,7 @@ "label": "parseAggregationResults", "description": [], "signature": [ - "({ isCountAgg, isGroupAgg, esResult, resultLimit, }: ParseAggregationResultsOpts) => ", + "({ isCountAgg, isGroupAgg, esResult, resultLimit, sourceFieldsParams, generateSourceFieldsFromHits, }: ParseAggregationResultsOpts) => ", { "pluginId": "triggersActionsUi", "scope": "common", @@ -9410,7 +9410,7 @@ "id": "def-common.parseAggregationResults.$1", "type": "Object", "tags": [], - "label": "{\n isCountAgg,\n isGroupAgg,\n esResult,\n resultLimit,\n}", + "label": "{\n isCountAgg,\n isGroupAgg,\n esResult,\n resultLimit,\n sourceFieldsParams = [],\n generateSourceFieldsFromHits = false,\n}", "description": [], "signature": [ "ParseAggregationResultsOpts" @@ -9574,6 +9574,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-common.BuildAggregationOpts.sourceFieldsParams", + "type": "Array", + "tags": [], + "label": "sourceFieldsParams", + "description": [], + "signature": [ + "{ label: string; searchPath: string; }[] | undefined" + ], + "path": "x-pack/plugins/triggers_actions_ui/common/data/lib/build_agg.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-common.BuildAggregationOpts.topHitsSize", @@ -9813,6 +9827,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-common.ParsedAggregationGroup.sourceFields", + "type": "Array", + "tags": [], + "label": "sourceFields", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/triggers_actions_ui/common/data/lib/parse_aggregation_results.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-common.ParsedAggregationGroup.value", @@ -10070,6 +10098,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-common.MAX_SOURCE_FIELDS_TO_COPY", + "type": "number", + "tags": [], + "label": "MAX_SOURCE_FIELDS_TO_COPY", + "description": [], + "signature": [ + "10" + ], + "path": "x-pack/plugins/triggers_actions_ui/common/data/lib/build_agg.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-common.MetricResult", diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index 382c520ca566a8..6d7a8bc88a161b 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 592 | 1 | 566 | 58 | +| 595 | 1 | 569 | 58 | ## Client diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 1cecdd6add6b23..1224f6383b4690 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index f91f347581c573..876b0fc466deef 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_doc_viewer.mdx b/api_docs/unified_doc_viewer.mdx index a8145a03cb2165..70056b9b01ffd4 100644 --- a/api_docs/unified_doc_viewer.mdx +++ b/api_docs/unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedDocViewer title: "unifiedDocViewer" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedDocViewer plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedDocViewer'] --- import unifiedDocViewerObj from './unified_doc_viewer.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 0355b61632ed9d..6f7ec16cd0bdf3 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index ca4811c5b7480f..5f6b58b96d2119 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 7700de2fe347a1..35bf5267837ba4 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/uptime.mdx b/api_docs/uptime.mdx index d217285af03b66..a11db9463ac0e3 100644 --- a/api_docs/uptime.mdx +++ b/api_docs/uptime.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uptime title: "uptime" image: https://source.unsplash.com/400x175/?github description: API docs for the uptime plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uptime'] --- import uptimeObj from './uptime.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 0795f1f3e7f2fa..cac2ac365d7192 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index e354828fa73608..fdcb4c8d8bcf09 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index 54bbba1608ee52..87dc30d4380448 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index 99f394604f8443..2c1802606a6001 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index f1397d08f3774e..bd301cf9f8d34c 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index c27b5a2dbab324..3d80a2af2d473d 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index 82cc2e49381ae4..5934d52927063c 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index a21e7b3b2317f6..fa4c8939f85ff4 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index 90492ffa341061..5bd87964f6fe56 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index d9168065f45fd5..4af2533056b50c 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index 96ee0e109ece5b..69e5398f04e388 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 71faad7c2dad5f..43ab98c7f847f9 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index 6f6eb2244bdce9..ff8bff54153cae 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 71206e094e36fe..7b199a36b52fd8 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2023-12-21 +date: 2023-12-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From cf9ff4d3547781f1bac50170e024542c20d9efbf Mon Sep 17 00:00:00 2001 From: Robert Austin <robert.austin@elastic.co> Date: Fri, 22 Dec 2023 03:13:57 -0500 Subject: [PATCH 100/116] Asset criticality alert enrichment (#171241) ## Summary This will allow analysts to filter alerts by the analyst-defined criticality of the related host or user. This introduces two new kibana fields to alerts. These fields allow us to model the criticality of the alert's most relevant host and user, in context of analyst workflows. | field name | type | description | example | | -- | -- | -- | -- | | `kibana.alert.host.criticality_level` | keyword | Contains an enum describing the criticality of the host, as defined by the analyst in a previously used workflow. Used by analysts to filter alerts by host criticality. | 'very important' | | `kibana.alert.user.criticality_level` | keyword | Contains an enum describing the criticality of the user, as defined by the analyst in a previously used workflow. Used by analysts to filter alerts by user criticality. | 'very important' | ## Design Analysts can assign criticality to their assets. These are stored in the asset criticality index (`.asset-criticality.asset-criticality-${space}`). This PR will detect user names and host names in events, query the asset criticality index for the associated criticality (if any) and then add that value to the resulting alert under `kibana.alert.host.criticality_level` or `kibana.alert.user.criticality_level` ## Design Exploration ### What if we want to filter by other criticalities? We may want to allow analysts to filter on the criticality of other entities. For example, alerts can refer to multiple users and multiple hosts. Also, we may introduce other types of entities, e.g. IP addresses, files, registry keys. If we were to follow the same approach as we did here, that could lead to a mapping explosion if we had a lot. However: * we don't think we'll add very many classes of entities. less than 8 more. * we don't necessarily want to filter alerts by other ones. ### Using keyword vs nested or flattened We could use a flattened or nested field here to store more criticalities and have them all indexed. However we don't need to sort or order alerts by their entity's criticalities so we don't see a need. ### KQL support The fields we proposed here are of `keyword` type. This type of field works intuitively for KQL and since analyst workflows are the focus of this change, this lines up well. ## How to test until asset criticality UI is not enabled let's create a mapping for asset criticality and index some docs ``` PUT .asset-criticality.asset-criticality-default { "mappings": { "properties": { "id_value": { "type": "keyword" }, "id_field": { "type": "keyword" }, "criticality_level": { "type": "keyword" }, "@timestamp": { "type": "date" }, "updated_at": { "type": "date" } } } } ``` ``` POST .asset-criticality.asset-criticality-default/_doc { "id_field": "user.name", "id_value": "User 1", "criticality_level": "very important", "@timestamp": 1701860267617 } POST .asset-criticality.asset-criticality-default/_doc { "id_field": "host.name", "id_value": "Host 3", "criticality_level": "normal", "@timestamp": 1701860267617 } ``` Then create rules, which have alerts from events with `host.name` or `user.name` which match asset criticality documents. Then add fields to the alerts table, you should see some values in those columns <img width="1201" alt="Screenshot 2023-12-07 at 11 24 24" src="https://github.com/elastic/kibana/assets/7609147/fb8c07bf-4cc6-4273-95b0-34af9d3f2e72"> ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### Risk Matrix Delete this section if it is not applicable to this PR. Before closing this PR, invite QA, stakeholders, and other developers to identify risks that should be tested prior to the change/feature release. When forming the risk matrix, consider some of the following examples and how they may potentially impact the change: | Risk | Probability | Severity | Mitigation/Notes | |---------------------------|-------------|----------|-------------------------| | Multiple Spaces—unexpected behavior in non-default Kibana Space. | Low | High | Integration tests will verify that all features are still supported in non-default Kibana Space and when user switches between spaces. | | Multiple nodes—Elasticsearch polling might have race conditions when multiple Kibana nodes are polling for the same tasks. | High | Low | Tasks are idempotent, so executing them multiple times will not result in logical error, but will degrade performance. To test for this case we add plenty of unit tests around this logic and document manual testing procedure. | | Code should gracefully handle cases when feature X or plugin Y are disabled. | Medium | High | Unit tests will verify that any feature flag or plugin combination still results in our service operational. | | [See more potential risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) | ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: Nikita Khristinin <nkhristinin@gmail.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Khristinin Nikita <nikita.khristinin@elastic.co> --- .../src/schemas/generated/security_schema.ts | 2 + .../model/alerts/8.13.0/index.ts | 60 ++++++++ .../detection_engine/model/alerts/index.ts | 34 +++-- .../common/field_maps/8.13.0/alerts.ts | 33 ++++ .../common/field_maps/8.13.0/index.ts | 11 ++ .../common/field_maps/field_names.ts | 2 + .../common/field_maps/index.ts | 8 +- .../security_solution_detections/columns.ts | 16 ++ .../rule_types/factories/utils/build_alert.ts | 5 + .../utils/enrichments/__mocks__/alerts.ts | 4 + .../create_single_field_match_enrichment.ts | 16 +- .../enrichment_by_type/asset_criticality.ts | 90 +++++++++++ .../enrichment_by_type/host_risk.ts | 16 +- .../enrichment_by_type/user_risk.ts | 16 +- .../utils/enrichments/index.test.ts | 103 ++++++++++--- .../rule_types/utils/enrichments/index.ts | 65 ++++++-- .../rule_types/utils/enrichments/types.ts | 31 ++-- .../utils/enrichments/utils/events.ts | 30 +++- .../utils/enrichments/utils/is_index_exist.ts | 17 +++ .../utils/enrichments/utils/requests.test.ts | 41 +++++ .../utils/enrichments/utils/requests.ts | 8 +- .../es_archives/asset_criticality/data.json | 143 ++++++++++++++++++ .../asset_criticality/mappings.json | 32 ++++ .../config/ess/config.base.ts | 1 + .../configs/serverless.config.ts | 3 + .../execution_logic/eql.ts | 39 ++++- .../execution_logic/esql.ts | 39 +++++ .../execution_logic/machine_learning.ts | 20 +++ .../execution_logic/new_terms.ts | 26 ++++ .../execution_logic/query.ts | 25 +++ .../execution_logic/threat_match.ts | 44 ++++++ .../execution_logic/threshold.ts | 25 +++ 32 files changed, 897 insertions(+), 108 deletions(-) create mode 100644 x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.13.0/index.ts create mode 100644 x-pack/plugins/security_solution/common/field_maps/8.13.0/alerts.ts create mode 100644 x-pack/plugins/security_solution/common/field_maps/8.13.0/index.ts create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/asset_criticality.ts create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/is_index_exist.ts create mode 100644 x-pack/test/functional/es_archives/asset_criticality/data.json create mode 100644 x-pack/test/functional/es_archives/asset_criticality/mappings.json diff --git a/packages/kbn-alerts-as-data-utils/src/schemas/generated/security_schema.ts b/packages/kbn-alerts-as-data-utils/src/schemas/generated/security_schema.ts index 5b79568cb485bf..1d141def7f5114 100644 --- a/packages/kbn-alerts-as-data-utils/src/schemas/generated/security_schema.ts +++ b/packages/kbn-alerts-as-data-utils/src/schemas/generated/security_schema.ts @@ -131,6 +131,7 @@ const SecurityAlertOptional = rt.partial({ 'kibana.alert.flapping_history': schemaBooleanArray, 'kibana.alert.group.id': schemaString, 'kibana.alert.group.index': schemaNumber, + 'kibana.alert.host.criticality_level': schemaString, 'kibana.alert.last_detected': schemaDate, 'kibana.alert.maintenance_window_ids': schemaStringArray, 'kibana.alert.new_terms': schemaStringArray, @@ -193,6 +194,7 @@ const SecurityAlertOptional = rt.partial({ ), 'kibana.alert.time_range': schemaDateRange, 'kibana.alert.url': schemaString, + 'kibana.alert.user.criticality_level': schemaString, 'kibana.alert.workflow_assignee_ids': schemaStringArray, 'kibana.alert.workflow_reason': schemaString, 'kibana.alert.workflow_status': schemaString, diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.13.0/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.13.0/index.ts new file mode 100644 index 00000000000000..594dc685097db6 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/8.13.0/index.ts @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { AlertWithCommonFields800 } from '@kbn/rule-registry-plugin/common/schemas/8.0.0'; +import type { + ALERT_HOST_CRITICALITY, + ALERT_USER_CRITICALITY, +} from '../../../../../field_maps/field_names'; +import type { + Ancestor8120, + BaseFields8120, + EqlBuildingBlockFields8120, + EqlShellFields8120, + NewTermsFields8120, +} from '../8.12.0'; + +/* DO NOT MODIFY THIS SCHEMA TO ADD NEW FIELDS. These types represent the alerts that shipped in 8.13.0. +Any changes to these types should be bug fixes so the types more accurately represent the alerts from 8.13.0. +If you are adding new fields for a new release of Kibana, create a new sibling folder to this one +for the version to be released and add the field(s) to the schema in that folder. +Then, update `../index.ts` to import from the new folder that has the latest schemas, add the +new schemas to the union of all alert schemas, and re-export the new schemas as the `*Latest` schemas. +*/ + +export type { Ancestor8120 as Ancestor8130 }; + +export interface BaseFields8130 extends BaseFields8120 { + [ALERT_HOST_CRITICALITY]: string | undefined; + [ALERT_USER_CRITICALITY]: string | undefined; +} + +export interface WrappedFields8130<T extends BaseFields8130> { + _id: string; + _index: string; + _source: T; +} + +export type GenericAlert8130 = AlertWithCommonFields800<BaseFields8130>; + +export type EqlShellFields8130 = EqlShellFields8120 & BaseFields8130; + +export type EqlBuildingBlockFields8130 = EqlBuildingBlockFields8120 & BaseFields8130; + +export type NewTermsFields8130 = NewTermsFields8120 & BaseFields8130; + +export type NewTermsAlert8130 = NewTermsFields8120 & BaseFields8130; + +export type EqlBuildingBlockAlert8130 = AlertWithCommonFields800<EqlBuildingBlockFields8120>; + +export type EqlShellAlert8130 = AlertWithCommonFields800<EqlShellFields8130>; + +export type DetectionAlert8130 = + | GenericAlert8130 + | EqlShellAlert8130 + | EqlBuildingBlockAlert8130 + | NewTermsAlert8130; diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/index.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/index.ts index 742e5fd4ecfc1c..6bf7b1d5dfd7e0 100644 --- a/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/index.ts +++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/alerts/index.ts @@ -12,15 +12,16 @@ import type { DetectionAlert860 } from './8.6.0'; import type { DetectionAlert870 } from './8.7.0'; import type { DetectionAlert880 } from './8.8.0'; import type { DetectionAlert890 } from './8.9.0'; +import type { DetectionAlert8120 } from './8.12.0'; import type { - Ancestor8120, - BaseFields8120, - DetectionAlert8120, - EqlBuildingBlockFields8120, - EqlShellFields8120, - NewTermsFields8120, - WrappedFields8120, -} from './8.12.0'; + Ancestor8130, + BaseFields8130, + DetectionAlert8130, + EqlBuildingBlockFields8130, + EqlShellFields8130, + NewTermsFields8130, + WrappedFields8130, +} from './8.13.0'; // When new Alert schemas are created for new Kibana versions, add the DetectionAlert type from the new version // here, e.g. `export type DetectionAlert = DetectionAlert800 | DetectionAlert820` if a new schema is created in 8.2.0 @@ -31,14 +32,15 @@ export type DetectionAlert = | DetectionAlert870 | DetectionAlert880 | DetectionAlert890 - | DetectionAlert8120; + | DetectionAlert8120 + | DetectionAlert8130; export type { - Ancestor8120 as AncestorLatest, - BaseFields8120 as BaseFieldsLatest, - DetectionAlert8120 as DetectionAlertLatest, - WrappedFields8120 as WrappedFieldsLatest, - EqlBuildingBlockFields8120 as EqlBuildingBlockFieldsLatest, - EqlShellFields8120 as EqlShellFieldsLatest, - NewTermsFields8120 as NewTermsFieldsLatest, + Ancestor8130 as AncestorLatest, + BaseFields8130 as BaseFieldsLatest, + DetectionAlert8130 as DetectionAlertLatest, + WrappedFields8130 as WrappedFieldsLatest, + EqlBuildingBlockFields8130 as EqlBuildingBlockFieldsLatest, + EqlShellFields8130 as EqlShellFieldsLatest, + NewTermsFields8130 as NewTermsFieldsLatest, }; diff --git a/x-pack/plugins/security_solution/common/field_maps/8.13.0/alerts.ts b/x-pack/plugins/security_solution/common/field_maps/8.13.0/alerts.ts new file mode 100644 index 00000000000000..86c84092891b80 --- /dev/null +++ b/x-pack/plugins/security_solution/common/field_maps/8.13.0/alerts.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { alertsFieldMap840 } from '../8.4.0'; +import { ALERT_HOST_CRITICALITY, ALERT_USER_CRITICALITY } from '../field_names'; + +export const alertsFieldMap8130 = { + ...alertsFieldMap840, + /** + * Stores the criticality level for the host, as determined by analysts, in relation to the alert. + * The Criticality level is copied from the asset criticality index. + */ + [ALERT_HOST_CRITICALITY]: { + type: 'keyword', + array: false, + required: false, + }, + /** + * Stores the criticality level for the user, as determined by analysts, in relation to the alert. + * The Criticality level is copied from the asset criticality index. + */ + [ALERT_USER_CRITICALITY]: { + type: 'keyword', + array: false, + required: false, + }, +} as const; + +export type AlertsFieldMap8130 = typeof alertsFieldMap8130; diff --git a/x-pack/plugins/security_solution/common/field_maps/8.13.0/index.ts b/x-pack/plugins/security_solution/common/field_maps/8.13.0/index.ts new file mode 100644 index 00000000000000..291ca7f8dff822 --- /dev/null +++ b/x-pack/plugins/security_solution/common/field_maps/8.13.0/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { AlertsFieldMap8130 } from './alerts'; +import { alertsFieldMap8130 } from './alerts'; +export type { AlertsFieldMap8130 }; +export { alertsFieldMap8130 }; diff --git a/x-pack/plugins/security_solution/common/field_maps/field_names.ts b/x-pack/plugins/security_solution/common/field_maps/field_names.ts index 53ebfc5c188d10..6124cc08ebd2bb 100644 --- a/x-pack/plugins/security_solution/common/field_maps/field_names.ts +++ b/x-pack/plugins/security_solution/common/field_maps/field_names.ts @@ -17,6 +17,8 @@ export const ALERT_THRESHOLD_RESULT = `${ALERT_NAMESPACE}.threshold_result` as c export const ALERT_THRESHOLD_RESULT_COUNT = `${ALERT_THRESHOLD_RESULT}.count` as const; export const ALERT_NEW_TERMS = `${ALERT_NAMESPACE}.new_terms` as const; export const ALERT_NEW_TERMS_FIELDS = `${ALERT_RULE_PARAMETERS}.new_terms_fields` as const; +export const ALERT_HOST_CRITICALITY = `${ALERT_NAMESPACE}.host.criticality_level` as const; +export const ALERT_USER_CRITICALITY = `${ALERT_NAMESPACE}.user.criticality_level` as const; export const ALERT_ORIGINAL_EVENT = `${ALERT_NAMESPACE}.original_event` as const; export const ALERT_ORIGINAL_EVENT_ACTION = `${ALERT_ORIGINAL_EVENT}.action` as const; diff --git a/x-pack/plugins/security_solution/common/field_maps/index.ts b/x-pack/plugins/security_solution/common/field_maps/index.ts index c6780a33fc64ff..fe903776d1dd43 100644 --- a/x-pack/plugins/security_solution/common/field_maps/index.ts +++ b/x-pack/plugins/security_solution/common/field_maps/index.ts @@ -5,9 +5,9 @@ * 2.0. */ -import type { AlertsFieldMap840 } from './8.4.0'; -import { alertsFieldMap840 } from './8.4.0'; +import type { AlertsFieldMap8130 } from './8.13.0'; +import { alertsFieldMap8130 } from './8.13.0'; import type { RulesFieldMap } from './8.0.0/rules'; import { rulesFieldMap } from './8.0.0/rules'; -export type { AlertsFieldMap840 as AlertsFieldMap, RulesFieldMap }; -export { alertsFieldMap840 as alertsFieldMap, rulesFieldMap }; +export type { AlertsFieldMap8130 as AlertsFieldMap, RulesFieldMap }; +export { alertsFieldMap8130 as alertsFieldMap, rulesFieldMap }; diff --git a/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/columns.ts b/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/columns.ts index bfce8420964486..384c6bf955e51f 100644 --- a/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/columns.ts +++ b/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/columns.ts @@ -6,6 +6,10 @@ */ import type { EuiDataGridColumn } from '@elastic/eui'; +import { + ALERT_HOST_CRITICALITY, + ALERT_USER_CRITICALITY, +} from '../../../../common/field_maps/field_names'; import type { LicenseService } from '../../../../common/license'; import type { ColumnHeaderOptions } from '../../../../common/types'; @@ -72,6 +76,18 @@ const getBaseColumns = ( id: 'user.risk.calculated_level', } : null, + isPlatinumPlus + ? { + columnHeaderType: defaultColumnHeaderType, + id: ALERT_HOST_CRITICALITY, + } + : null, + isPlatinumPlus + ? { + columnHeaderType: defaultColumnHeaderType, + id: ALERT_USER_CRITICALITY, + } + : null, { columnHeaderType: defaultColumnHeaderType, id: 'process.name', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.ts index 846c714a9c099b..024f1b123ff997 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.ts @@ -80,6 +80,8 @@ import { ALERT_RULE_THREAT, ALERT_RULE_EXCEPTIONS_LIST, ALERT_RULE_IMMUTABLE, + ALERT_HOST_CRITICALITY, + ALERT_USER_CRITICALITY, } from '../../../../../../common/field_maps/field_names'; import type { CompleteRule, RuleParams } from '../../../rule_schema'; import { commonParamsCamelToSnake, typeSpecificCamelToSnake } from '../../../rule_management'; @@ -256,6 +258,9 @@ export const buildAlert = ( 'kibana.alert.rule.risk_score': params.riskScore, 'kibana.alert.rule.severity': params.severity, 'kibana.alert.rule.building_block_type': params.buildingBlockType, + // asset criticality fields will be enriched before ingestion + [ALERT_HOST_CRITICALITY]: undefined, + [ALERT_USER_CRITICALITY]: undefined, }; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/__mocks__/alerts.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/__mocks__/alerts.ts index e19e7ad1bc0eee..efbf39d815aeac 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/__mocks__/alerts.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/__mocks__/alerts.ts @@ -68,6 +68,8 @@ import { ALERT_RULE_TIMELINE_TITLE, ALERT_RULE_INDICES, ALERT_RULE_TIMESTAMP_OVERRIDE, + ALERT_HOST_CRITICALITY, + ALERT_USER_CRITICALITY, } from '../../../../../../../common/field_maps/field_names'; export const createAlert = ( @@ -194,6 +196,8 @@ export const createAlert = ( rule_name_override: undefined, timestamp_override: undefined, }, + [ALERT_HOST_CRITICALITY]: undefined, + [ALERT_USER_CRITICALITY]: undefined, ...data, }, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/create_single_field_match_enrichment.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/create_single_field_match_enrichment.ts index 982de01b8bae78..874556fb94dae2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/create_single_field_match_enrichment.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/create_single_field_match_enrichment.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { flatten, chunk } from 'lodash'; +import { chunk } from 'lodash'; import { searchEnrichments } from './search_enrichments'; import { makeSingleFieldMatchQuery } from './utils/requests'; import { getEventValue, getFieldValue } from './utils/events'; @@ -22,12 +22,14 @@ export const createSingleFieldMatchEnrichment: CreateFieldsMatchEnrichment = asy createEnrichmentFunction, name, enrichmentResponseFields, + extraFilters, }) => { try { logger.debug(`Enrichment ${name}: started`); - const eventsWithField = events.filter((event) => getEventValue(event, mappingField.eventField)); - const eventsMapByFieldValue = eventsWithField.reduce((acc, event) => { + const eventsToEnrich = events.filter((event) => getEventValue(event, mappingField.eventField)); + + const eventsMapByFieldValue = eventsToEnrich.reduce((acc, event) => { const eventFieldValue = getEventValue(event, mappingField.eventField); if (!eventFieldValue) return {}; @@ -39,6 +41,7 @@ export const createSingleFieldMatchEnrichment: CreateFieldsMatchEnrichment = asy }, {} as { [key: string]: typeof events }); const uniqueEventsValuesToSearchBy = Object.keys(eventsMapByFieldValue); + const chunksUniqueEventsValuesToSearchBy = chunk(uniqueEventsValuesToSearchBy, MAX_CLAUSES); const getAllEnrichment = chunksUniqueEventsValuesToSearchBy @@ -46,6 +49,7 @@ export const createSingleFieldMatchEnrichment: CreateFieldsMatchEnrichment = asy makeSingleFieldMatchQuery({ values: enrichmentValuesChunk, searchByField: mappingField.enrichmentField, + extraFilters, }) ) .filter((query) => query.query?.bool?.should?.length > 0) @@ -59,11 +63,9 @@ export const createSingleFieldMatchEnrichment: CreateFieldsMatchEnrichment = asy }) ); - const enrichmentsResults = (await Promise.allSettled(getAllEnrichment)) + const enrichments = (await Promise.allSettled(getAllEnrichment)) .filter((result) => result.status === 'fulfilled') - .map((result) => (result as PromiseFulfilledResult<EnrichmentType[]>)?.value); - - const enrichments = flatten(enrichmentsResults); + .flatMap((result) => (result as PromiseFulfilledResult<EnrichmentType[]>)?.value); if (enrichments.length === 0) { logger.debug(`Enrichment ${name}: no enrichment found`); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/asset_criticality.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/asset_criticality.ts new file mode 100644 index 00000000000000..e2bd3319062ae1 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/asset_criticality.ts @@ -0,0 +1,90 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { cloneDeep } from 'lodash'; +import { + ALERT_HOST_CRITICALITY, + ALERT_USER_CRITICALITY, +} from '../../../../../../../common/field_maps/field_names'; +import { createSingleFieldMatchEnrichment } from '../create_single_field_match_enrichment'; +import type { CreateCriticalityEnrichment, CreateEnrichmentFunction } from '../types'; +import { getFieldValue } from '../utils/events'; +import { getAssetCriticalityIndex } from '../../../../../../../common/entity_analytics/asset_criticality'; + +const enrichmentResponseFields = ['id_value', 'criticality_level']; + +const getExtraFiltersForEnrichment = (field: string) => [ + { + match: { + id_field: { + query: field, + }, + }, + }, +]; + +const createEnrichmentFactoryFunction = + ( + alertField: typeof ALERT_HOST_CRITICALITY | typeof ALERT_USER_CRITICALITY + ): CreateEnrichmentFunction => + (enrichment) => + (event) => { + const criticality = getFieldValue(enrichment, 'criticality_level'); + + if (!criticality) { + return event; + } + const newEvent = cloneDeep(event); + if (criticality && newEvent._source) { + newEvent._source[alertField] = criticality; + } + return newEvent; + }; + +export const createHostAssetCriticalityEnrichments: CreateCriticalityEnrichment = async ({ + services, + logger, + events, + spaceId, +}) => { + return createSingleFieldMatchEnrichment({ + name: 'Host Asset Criticality', + index: [getAssetCriticalityIndex(spaceId)], + services, + logger, + events, + mappingField: { + eventField: 'host.name', + enrichmentField: 'id_value', + }, + enrichmentResponseFields, + extraFilters: getExtraFiltersForEnrichment('host.name'), + createEnrichmentFunction: createEnrichmentFactoryFunction(ALERT_HOST_CRITICALITY), + }); +}; + +export const createUserAssetCriticalityEnrichments: CreateCriticalityEnrichment = async ({ + services, + logger, + events, + spaceId, +}) => { + return createSingleFieldMatchEnrichment({ + name: 'User Asset Criticality', + index: [getAssetCriticalityIndex(spaceId)], + services, + logger, + events, + mappingField: { + eventField: 'user.name', + enrichmentField: 'id_value', + }, + enrichmentResponseFields, + extraFilters: getExtraFiltersForEnrichment('user.name'), + createEnrichmentFunction: createEnrichmentFactoryFunction(ALERT_USER_CRITICALITY), + }); +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/host_risk.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/host_risk.ts index 6b18979c0d3c0d..1b34f6cb878595 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/host_risk.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/host_risk.ts @@ -10,23 +10,9 @@ import { cloneDeep } from 'lodash'; import { getHostRiskIndex } from '../../../../../../../common/search_strategy/security_solution/risk_score/common'; import { RiskScoreFields } from '../../../../../../../common/search_strategy/security_solution/risk_score/all'; import { createSingleFieldMatchEnrichment } from '../create_single_field_match_enrichment'; -import type { CreateRiskEnrichment, GetIsRiskScoreAvailable } from '../types'; +import type { CreateRiskEnrichment } from '../types'; import { getFieldValue } from '../utils/events'; -export const getIsHostRiskScoreAvailable: GetIsRiskScoreAvailable = async ({ - spaceId, - services, - isNewRiskScoreModuleInstalled, -}) => { - const isHostRiskScoreIndexExist = await services.scopedClusterClient.asCurrentUser.indices.exists( - { - index: getHostRiskIndex(spaceId, true, isNewRiskScoreModuleInstalled), - } - ); - - return isHostRiskScoreIndexExist; -}; - export const createHostRiskEnrichments: CreateRiskEnrichment = async ({ services, logger, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/user_risk.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/user_risk.ts index b0e8d87f3019fb..27ae894f281343 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/user_risk.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/user_risk.ts @@ -9,23 +9,9 @@ import { cloneDeep } from 'lodash'; import { getUserRiskIndex } from '../../../../../../../common/search_strategy/security_solution/risk_score/common'; import { RiskScoreFields } from '../../../../../../../common/search_strategy/security_solution/risk_score/all'; import { createSingleFieldMatchEnrichment } from '../create_single_field_match_enrichment'; -import type { CreateRiskEnrichment, GetIsRiskScoreAvailable } from '../types'; +import type { CreateRiskEnrichment } from '../types'; import { getFieldValue } from '../utils/events'; -export const getIsUserRiskScoreAvailable: GetIsRiskScoreAvailable = async ({ - services, - spaceId, - isNewRiskScoreModuleInstalled, -}) => { - const isUserRiskScoreIndexExist = await services.scopedClusterClient.asCurrentUser.indices.exists( - { - index: getUserRiskIndex(spaceId, true, isNewRiskScoreModuleInstalled), - } - ); - - return isUserRiskScoreIndexExist; -}; - export const createUserRiskEnrichments: CreateRiskEnrichment = async ({ services, logger, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.test.ts index 8f98b5bfe04b75..4c87c6f5a82720 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.test.ts @@ -11,26 +11,20 @@ import { enrichEvents } from '.'; import { searchEnrichments } from './search_enrichments'; import { ruleExecutionLogMock } from '../../../rule_monitoring/mocks'; import { createAlert } from './__mocks__/alerts'; -import { getIsHostRiskScoreAvailable } from './enrichment_by_type/host_risk'; -import { getIsUserRiskScoreAvailable } from './enrichment_by_type/user_risk'; +import { isIndexExist } from './utils/is_index_exist'; + +import { allowedExperimentalValues } from '../../../../../../common'; jest.mock('./search_enrichments', () => ({ searchEnrichments: jest.fn(), })); const mockSearchEnrichments = searchEnrichments as jest.Mock; -jest.mock('./enrichment_by_type/host_risk', () => ({ - ...jest.requireActual('./enrichment_by_type/host_risk'), - getIsHostRiskScoreAvailable: jest.fn(), -})); -const mockGetIsHostRiskScoreAvailable = getIsHostRiskScoreAvailable as jest.Mock; - -jest.mock('./enrichment_by_type/user_risk', () => ({ - ...jest.requireActual('./enrichment_by_type/user_risk'), - getIsUserRiskScoreAvailable: jest.fn(), +jest.mock('./utils/is_index_exist', () => ({ + isIndexExist: jest.fn(), })); -const mockGetIsUserRiskScoreAvailable = getIsUserRiskScoreAvailable as jest.Mock; +const mockIsIndexExist = isIndexExist as jest.Mock; const hostEnrichmentResponse = [ { @@ -66,6 +60,30 @@ const userEnrichmentResponse = [ }, ]; +const assetCriticalityUserResponse = [ + { + fields: { + id_value: ['user name 1'], + criticality_level: ['important'], + }, + }, +]; + +const assetCriticalityHostResponse = [ + { + fields: { + id_value: ['host name 2'], + criticality_level: ['very_important'], + }, + }, + { + fields: { + id_value: ['host name 1'], + criticality_level: ['low'], + }, + }, +]; + describe('enrichEvents', () => { let ruleExecutionLogger: ReturnType<typeof ruleExecutionLogMock.forExecutors.create>; let alertServices: RuleExecutorServicesMock; @@ -76,11 +94,13 @@ describe('enrichEvents', () => { ruleExecutionLogger = ruleExecutionLogMock.forExecutors.create(); alertServices = alertsMock.createRuleExecutorServices(); }); + afterEach(() => { + mockIsIndexExist.mockClear(); + }); it('return the same events, if risk indexes are not available', async () => { mockSearchEnrichments.mockImplementation(() => []); - mockGetIsUserRiskScoreAvailable.mockImplementation(() => false); - mockGetIsHostRiskScoreAvailable.mockImplementation(() => false); + mockIsIndexExist.mockImplementation(() => false); const events = [ createAlert('1', createEntity('host', 'host name')), createAlert('2', createEntity('user', 'user name')), @@ -97,8 +117,7 @@ describe('enrichEvents', () => { it('return the same events, if there no fields', async () => { mockSearchEnrichments.mockImplementation(() => []); - mockGetIsUserRiskScoreAvailable.mockImplementation(() => true); - mockGetIsHostRiskScoreAvailable.mockImplementation(() => true); + mockIsIndexExist.mockImplementation(() => true); const events = [createAlert('1'), createAlert('2')]; const enrichedEvents = await enrichEvents({ logger: ruleExecutionLogger, @@ -110,12 +129,11 @@ describe('enrichEvents', () => { expect(enrichedEvents).toEqual(events); }); - it('return enriched events', async () => { + it('return enriched events with risk score', async () => { mockSearchEnrichments .mockReturnValueOnce(hostEnrichmentResponse) .mockReturnValueOnce(userEnrichmentResponse); - mockGetIsUserRiskScoreAvailable.mockImplementation(() => true); - mockGetIsHostRiskScoreAvailable.mockImplementation(() => true); + mockIsIndexExist.mockImplementation(() => true); const enrichedEvents = await enrichEvents({ logger: ruleExecutionLogger, @@ -159,14 +177,57 @@ describe('enrichEvents', () => { ]); }); + it('return enriched events with asset criticality', async () => { + mockSearchEnrichments + .mockReturnValueOnce(assetCriticalityUserResponse) + .mockReturnValueOnce(assetCriticalityHostResponse); + + // disable risk score enrichments + mockIsIndexExist.mockImplementationOnce(() => false); + mockIsIndexExist.mockImplementationOnce(() => false); + mockIsIndexExist.mockImplementationOnce(() => false); + // enable for asset criticality + mockIsIndexExist.mockImplementation(() => true); + + const enrichedEvents = await enrichEvents({ + logger: ruleExecutionLogger, + services: alertServices, + events: [ + createAlert('1', { + ...createEntity('host', 'host name 1'), + ...createEntity('user', 'user name 1'), + }), + createAlert('2', createEntity('host', 'user name 1')), + ], + spaceId: 'default', + experimentalFeatures: { + ...allowedExperimentalValues, + entityAnalyticsAssetCriticalityEnabled: true, + }, + }); + + expect(enrichedEvents).toEqual([ + createAlert('1', { + ...createEntity('user', 'user name 1'), + ...createEntity('host', 'host name 1'), + + 'kibana.alert.host.criticality_level': 'low', + 'kibana.alert.user.criticality_level': 'important', + }), + createAlert('2', { + ...createEntity('host', 'user name 1'), + }), + ]); + }); + it('if some enrichments failed, another work as expected', async () => { mockSearchEnrichments .mockImplementationOnce(() => { throw new Error('1'); }) .mockImplementationOnce(() => userEnrichmentResponse); - mockGetIsUserRiskScoreAvailable.mockImplementation(() => true); - mockGetIsHostRiskScoreAvailable.mockImplementation(() => true); + mockIsIndexExist.mockImplementation(() => true); + mockIsIndexExist.mockImplementation(() => true); const enrichedEvents = await enrichEvents({ logger: ruleExecutionLogger, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.ts index a27cc55801820d..cfd51f21e20cd2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.ts @@ -5,21 +5,26 @@ * 2.0. */ -import { - createHostRiskEnrichments, - getIsHostRiskScoreAvailable, -} from './enrichment_by_type/host_risk'; +import { createHostRiskEnrichments } from './enrichment_by_type/host_risk'; + +import { createUserRiskEnrichments } from './enrichment_by_type/user_risk'; import { - createUserRiskEnrichments, - getIsUserRiskScoreAvailable, -} from './enrichment_by_type/user_risk'; + createHostAssetCriticalityEnrichments, + createUserAssetCriticalityEnrichments, +} from './enrichment_by_type/asset_criticality'; +import { getAssetCriticalityIndex } from '../../../../../../common/entity_analytics/asset_criticality'; import type { EnrichEventsFunction, EventsMapByEnrichments, CreateEnrichEventsFunction, } from './types'; import { applyEnrichmentsToEvents } from './utils/transforms'; +import { isIndexExist } from './utils/is_index_exist'; +import { + getHostRiskIndex, + getUserRiskIndex, +} from '../../../../../../common/search_strategy/security_solution/risk_score/common'; export const enrichEvents: EnrichEventsFunction = async ({ services, @@ -29,23 +34,30 @@ export const enrichEvents: EnrichEventsFunction = async ({ experimentalFeatures, }) => { try { - const enrichments = []; + const enrichments: Array<Promise<EventsMapByEnrichments>> = []; logger.debug('Alert enrichments started'); const isNewRiskScoreModuleAvailable = experimentalFeatures?.riskScoringRoutesEnabled ?? false; + const isAssetCriticalityEnabled = + experimentalFeatures?.entityAnalyticsAssetCriticalityEnabled ?? false; let isNewRiskScoreModuleInstalled = false; if (isNewRiskScoreModuleAvailable) { - isNewRiskScoreModuleInstalled = await getIsHostRiskScoreAvailable({ - spaceId, + isNewRiskScoreModuleInstalled = await isIndexExist({ services, - isNewRiskScoreModuleInstalled: true, + index: getHostRiskIndex(spaceId, true, true), }); } const [isHostRiskScoreIndexExist, isUserRiskScoreIndexExist] = await Promise.all([ - getIsHostRiskScoreAvailable({ spaceId, services, isNewRiskScoreModuleInstalled }), - getIsUserRiskScoreAvailable({ spaceId, services, isNewRiskScoreModuleInstalled }), + isIndexExist({ + services, + index: getHostRiskIndex(spaceId, true, isNewRiskScoreModuleInstalled), + }), + isIndexExist({ + services, + index: getUserRiskIndex(spaceId, true, isNewRiskScoreModuleInstalled), + }), ]); if (isHostRiskScoreIndexExist) { @@ -72,9 +84,34 @@ export const enrichEvents: EnrichEventsFunction = async ({ ); } + if (isAssetCriticalityEnabled) { + const assetCriticalityIndexExist = await isIndexExist({ + services, + index: getAssetCriticalityIndex(spaceId), + }); + if (assetCriticalityIndexExist) { + enrichments.push( + createUserAssetCriticalityEnrichments({ + services, + logger, + events, + spaceId, + }) + ); + enrichments.push( + createHostAssetCriticalityEnrichments({ + services, + logger, + events, + spaceId, + }) + ); + } + } + const allEnrichmentsResults = await Promise.allSettled(enrichments); - const allFulfilledEnrichmentsResults = allEnrichmentsResults + const allFulfilledEnrichmentsResults: EventsMapByEnrichments[] = allEnrichmentsResults .filter((result) => result.status === 'fulfilled') .map((result) => (result as PromiseFulfilledResult<EventsMapByEnrichments>)?.value); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/types.ts index 73c703235edcac..70f710630da37a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/types.ts @@ -6,6 +6,7 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; import type { Filter } from '@kbn/es-query'; import type { ExperimentalFeatures } from '../../../../../../common'; @@ -27,7 +28,6 @@ export type EnrichmentFunction = <T extends BaseFieldsLatest>( e: EventsForEnrichment<T> ) => EventsForEnrichment<T>; -// export interface EventsMapByEnrichments { [id: string]: EnrichmentFunction[]; } @@ -48,11 +48,6 @@ interface BasedEnrichParamters<T extends BaseFieldsLatest> { events: Array<EventsForEnrichment<T>>; } -interface SingleMappingField { - eventField: string; - enrichmentField: string; -} - export type GetEventValue = <T extends BaseFieldsLatest>( events: EventsForEnrichment<T>, path: string @@ -60,9 +55,10 @@ export type GetEventValue = <T extends BaseFieldsLatest>( export type GetFieldValue = (events: EnrichmentType, path: string) => string | undefined; -export type MakeSingleFieldMatchQuery = <T extends BaseFieldsLatest>(params: { +export type MakeSingleFieldMatchQuery = (params: { values: string[]; searchByField: string; + extraFilters?: QueryDslQueryContainer[]; }) => Filter; export type SearchEnrichments = (params: { @@ -79,6 +75,8 @@ export type GetIsRiskScoreAvailable = (params: { isNewRiskScoreModuleInstalled: boolean; }) => Promise<boolean>; +export type IsIndexExist = (params: { services: RuleServices; index: string }) => Promise<boolean>; + export type CreateRiskEnrichment = <T extends BaseFieldsLatest>( params: BasedEnrichParamters<T> & { spaceId: string; @@ -86,13 +84,28 @@ export type CreateRiskEnrichment = <T extends BaseFieldsLatest>( } ) => Promise<EventsMapByEnrichments>; +export type CreateCriticalityEnrichment = <T extends BaseFieldsLatest>( + params: BasedEnrichParamters<T> & { + spaceId: string; + } +) => Promise<EventsMapByEnrichments>; + +export type CreateEnrichmentFunction = (enrichmentDoc: EnrichmentType) => EnrichmentFunction; + export type CreateFieldsMatchEnrichment = <T extends BaseFieldsLatest>( params: BasedEnrichParamters<T> & { name: string; index: string[]; - mappingField: SingleMappingField; + mappingField: { + /** The field on events which contains the value we'll use to build a query. */ + eventField: string; + /** Used in a `match` query to find documents that match the values of `eventField`. */ + enrichmentField: string; + }; + /** Specifies which fields should be returned when querying the enrichment index. */ enrichmentResponseFields: string[]; - createEnrichmentFunction: (enrichmentDoc: EnrichmentType) => EnrichmentFunction; + createEnrichmentFunction: CreateEnrichmentFunction; + extraFilters?: QueryDslQueryContainer[]; } ) => Promise<EventsMapByEnrichments>; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/events.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/events.ts index 54eea14c6e94a5..b08b0f2b362b8e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/events.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/events.ts @@ -6,7 +6,8 @@ */ import { get } from 'lodash'; -import type { GetEventValue, GetFieldValue } from '../types'; +import type { BaseFieldsLatest } from '../../../../../../../common/api/detection_engine/model/alerts'; +import type { EventsForEnrichment, GetEventValue, GetFieldValue } from '../types'; export const getEventValue: GetEventValue = (event, path) => { const value = get(event, `_source.${path}`) || event?._source?.[path]; @@ -19,3 +20,30 @@ export const getEventValue: GetEventValue = (event, path) => { }; export const getFieldValue: GetFieldValue = (event, path) => get(event?.fields, path)?.[0]; + +/** Given an eventField, returns a map of values found in that field to the events that contain that value. */ +export function getEventsMapByFieldValue<T extends BaseFieldsLatest>( + events: Array<EventsForEnrichment<T>>, + eventField: string +): Record< + /** values found in mappingField.eventField */ string, + /** Array of events with the corresponding value */ typeof events +> { + const eventsWithField = events.filter((event) => getEventValue(event, eventField)); + + const eventsMapByFieldValue: Record< + /** values found in mappingField.eventField */ string, + /** Array of events with the corresponding value */ typeof events + > = eventsWithField.reduce((acc, event) => { + const eventFieldValue = getEventValue(event, eventField); + + if (!eventFieldValue) return {}; + + acc[eventFieldValue] ??= []; + acc[eventFieldValue].push(event); + + return acc; + }, {} as { [key: string]: typeof events }); + + return eventsMapByFieldValue; +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/is_index_exist.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/is_index_exist.ts new file mode 100644 index 00000000000000..eb7813c3504166 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/is_index_exist.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IsIndexExist } from '../types'; + +export const isIndexExist: IsIndexExist = async ({ services, index }) => { + const isAssetCriticalityIndexExist = + await services.scopedClusterClient.asInternalUser.indices.exists({ + index, + }); + + return isAssetCriticalityIndexExist; +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/requests.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/requests.test.ts index 8cae81c8ef3b09..b8f3253bb69f76 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/requests.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/requests.test.ts @@ -20,6 +20,7 @@ describe('makeSingleFieldMatchQuery', () => { query: { bool: { should: [], + filter: [], minimum_should_match: 1, }, }, @@ -58,6 +59,46 @@ describe('makeSingleFieldMatchQuery', () => { }, }, ], + filter: [], + minimum_should_match: 1, + }, + }, + }); + }); + + it('return query with extra filters', () => { + expect( + makeSingleFieldMatchQuery({ + values: [], + searchByField: 'host.name', + extraFilters: [ + { + match: { + id_field: { + query: 'host.name', + }, + }, + }, + ], + }) + ).toEqual({ + meta: { + alias: null, + negate: false, + disabled: false, + }, + query: { + bool: { + should: [], + filter: [ + { + match: { + id_field: { + query: 'host.name', + }, + }, + }, + ], minimum_should_match: 1, }, }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/requests.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/requests.ts index b4567481691b6b..704fb89812e4a7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/requests.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/utils/requests.ts @@ -7,7 +7,12 @@ import type { MakeSingleFieldMatchQuery } from '../types'; -export const makeSingleFieldMatchQuery: MakeSingleFieldMatchQuery = ({ values, searchByField }) => { +/** makes a query that gets back any documents with the given `values` in the `searchByField` */ +export const makeSingleFieldMatchQuery: MakeSingleFieldMatchQuery = ({ + values, + searchByField, + extraFilters, +}) => { const shouldClauses = values.map((value) => ({ match: { [searchByField]: { @@ -26,6 +31,7 @@ export const makeSingleFieldMatchQuery: MakeSingleFieldMatchQuery = ({ values, s query: { bool: { should: shouldClauses, + filter: extraFilters ?? [], minimum_should_match: 1, }, }, diff --git a/x-pack/test/functional/es_archives/asset_criticality/data.json b/x-pack/test/functional/es_archives/asset_criticality/data.json new file mode 100644 index 00000000000000..dae5bd12006a80 --- /dev/null +++ b/x-pack/test/functional/es_archives/asset_criticality/data.json @@ -0,0 +1,143 @@ +{ + "type": "doc", + "value": { + "index": ".asset-criticality.asset-criticality-default", + "id": "1", + "source": { + "id_field": "host.name", + "id_value": "suricata-zeek-sensor-toronto", + "criticality_level": "important", + "@timestamp": "2022-08-12T14:45:36.171Z", + "updated_at": "2022-08-12T14:45:36.171Z" + }, + "type": "_doc" + } +} + +{ + "type": "doc", + "value": { + "index": ".asset-criticality.asset-criticality-default", + "id": "2", + "source": { + "id_field": "host.name", + "id_value": "host-0", + "criticality_level": "very_important", + "@timestamp": "2022-08-12T14:45:36.171Z", + "updated_at": "2022-08-12T14:45:36.171Z" + }, + "type": "_doc" + } +} + +{ + "type": "doc", + "value": { + "index": ".asset-criticality.asset-criticality-default", + "id": "20", + "source": { + "id_field": "host.name", + "id_value": "zeek-newyork-sha-aa8df15", + "criticality_level": "normal", + "@timestamp": "2022-08-12T14:45:36.171Z", + "updated_at": "2022-08-12T14:45:36.171Z" + }, + "type": "_doc" + } +} + +{ + "type": "doc", + "value": { + "index": ".asset-criticality.asset-criticality-default", + "id": "21", + "source": { + "id_field": "host.name", + "id_value": "zeek-sensor-amsterdam", + "criticality_level": "low", + "@timestamp": "2022-08-12T14:45:36.171Z", + "updated_at": "2022-08-12T14:45:36.171Z" + }, + "type": "_doc" + } +} + +{ + "type": "doc", + "value": { + "index": ".asset-criticality.asset-criticality-default", + "id": "22", + "source": { + "id_field": "host.name", + "id_value": "suricata-sensor-london", + "criticality_level": "important", + "@timestamp": "2022-08-12T14:45:36.171Z", + "updated_at": "2022-08-12T14:45:36.171Z" + }, + "type": "_doc" + } +} + +{ + "type": "doc", + "value": { + "index": ".asset-criticality.asset-criticality-default", + "id": "3", + "source": { + "id_field": "user.name", + "id_value": "root", + "criticality_level": "very_important", + "@timestamp": "2022-08-12T14:45:36.171Z", + "updated_at": "2022-08-12T14:45:36.171Z" + }, + "type": "_doc" + } +} + +{ + "type": "doc", + "value": { + "index": ".asset-criticality.asset-criticality-default", + "id": "4", + "source": { + "id_field": "user.name", + "id_value": "User 2", + "criticality_level": "important", + "@timestamp": "2022-08-12T14:45:36.171Z", + "updated_at": "2022-08-12T14:45:36.171Z" + }, + "type": "_doc" + } +} + +{ + "type": "doc", + "value": { + "index": ".asset-criticality.asset-criticality-default", + "id": "5", + "source": { + "id_field": "host.name", + "id_value": "abc", + "criticality_level": "normal", + "@timestamp": "2022-08-12T14:45:36.171Z", + "updated_at": "2022-08-12T14:45:36.171Z" + }, + "type": "_doc" + } +} + +{ + "type": "doc", + "value": { + "index": ".asset-criticality.asset-criticality-default", + "id": "6", + "source": { + "id_field": "user.name", + "id_value": "abc", + "criticality_level": "not_important", + "@timestamp": "2022-08-12T14:45:36.171Z", + "updated_at": "2022-08-12T14:45:36.171Z" + }, + "type": "_doc" + } +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/asset_criticality/mappings.json b/x-pack/test/functional/es_archives/asset_criticality/mappings.json new file mode 100644 index 00000000000000..94fe5389706b20 --- /dev/null +++ b/x-pack/test/functional/es_archives/asset_criticality/mappings.json @@ -0,0 +1,32 @@ +{ + "type": "index", + "value": { + "index": ".asset-criticality.asset-criticality-default", + "mappings": { + "properties": { + "id_value": { + "type": "keyword" + }, + "id_field": { + "type": "keyword" + }, + "criticality_level": { + "type": "keyword" + }, + "@timestamp": { + "type": "date" + }, + "updated_at": { + "type": "date" + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "0-1", + "number_of_replicas": "0", + "number_of_shards": "1" + } + } + } +} \ No newline at end of file diff --git a/x-pack/test/security_solution_api_integration/config/ess/config.base.ts b/x-pack/test/security_solution_api_integration/config/ess/config.base.ts index b4fbdba6de4c46..89e6df3c68cd25 100644 --- a/x-pack/test/security_solution_api_integration/config/ess/config.base.ts +++ b/x-pack/test/security_solution_api_integration/config/ess/config.base.ts @@ -81,6 +81,7 @@ export function createTestConfig(options: CreateTestConfigOptions, testFiles?: s 'previewTelemetryUrlEnabled', 'riskScoringPersistence', 'riskScoringRoutesEnabled', + 'entityAnalyticsAssetCriticalityEnabled', ])}`, '--xpack.task_manager.poll_interval=1000', `--xpack.actions.preconfigured=${JSON.stringify({ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/configs/serverless.config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/configs/serverless.config.ts index 7bcb663699d68f..1f43395efcd902 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/configs/serverless.config.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/configs/serverless.config.ts @@ -16,5 +16,8 @@ export default createTestConfig({ 'testing_ignored.constant', '/testing_regex*/', ])}`, // See tests within the file "ignore_fields.ts" which use these values in "alertIgnoreFields" + `--xpack.securitySolution.enableExperimental=${JSON.stringify([ + 'entityAnalyticsAssetCriticalityEnabled', + ])}`, ], }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/eql.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/eql.ts index db5a924b48a05f..03af11e239c68b 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/eql.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/eql.ts @@ -41,6 +41,13 @@ import { import { FtrProviderContext } from '../../../../../ftr_provider_context'; import { EsArchivePathBuilder } from '../../../../../es_archive_path_builder'; +/** + * Specific AGENT_ID to use for some of the tests. If the archiver changes and you see errors + * here, update this to a new value of a chosen auditbeat record and update the tests values. + */ +const AGENT_ID = 'a1d7b39c-f898-4dbe-a761-efb61939302d'; +const specificQueryForTests = `configuration where agent.id=="${AGENT_ID}"`; + export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertest'); const esArchiver = getService('esArchiver'); @@ -73,7 +80,7 @@ export default ({ getService }: FtrProviderContext) => { it('generates a correctly formatted alert from EQL non-sequence queries', async () => { const rule: EqlRuleCreateProps = { ...getEqlRuleForAlertTesting(['auditbeat-*']), - query: 'configuration where agent.id=="a1d7b39c-f898-4dbe-a761-efb61939302d"', + query: specificQueryForTests, }; const createdRule = await createRule(supertest, log, rule); const alerts = await getOpenAlerts(supertest, log, es, createdRule); @@ -88,7 +95,7 @@ export default ({ getService }: FtrProviderContext) => { agent: { ephemeral_id: '0010d67a-14f7-41da-be30-489fea735967', hostname: 'suricata-zeek-sensor-toronto', - id: 'a1d7b39c-f898-4dbe-a761-efb61939302d', + id: AGENT_ID, type: 'auditbeat', version: '8.0.0', }, @@ -196,7 +203,7 @@ export default ({ getService }: FtrProviderContext) => { it('uses the provided event_category_override', async () => { const rule: EqlRuleCreateProps = { ...getEqlRuleForAlertTesting(['auditbeat-*']), - query: 'config_change where agent.id=="a1d7b39c-f898-4dbe-a761-efb61939302d"', + query: `config_change where agent.id=="${AGENT_ID}"`, event_category_override: 'auditd.message_type', }; const { previewId } = await previewRule({ supertest, rule }); @@ -542,7 +549,7 @@ export default ({ getService }: FtrProviderContext) => { it('generates alerts when an index name contains special characters to encode', async () => { const rule: EqlRuleCreateProps = { ...getEqlRuleForAlertTesting(['auditbeat-*', '<my-index-{now/d}*>']), - query: 'configuration where agent.id=="a1d7b39c-f898-4dbe-a761-efb61939302d"', + query: specificQueryForTests, }; const { previewId } = await previewRule({ supertest, rule }); const previewAlerts = await getPreviewAlerts({ es, previewId }); @@ -607,7 +614,7 @@ export default ({ getService }: FtrProviderContext) => { it('should be enriched with host risk score', async () => { const rule: EqlRuleCreateProps = { ...getEqlRuleForAlertTesting(['auditbeat-*']), - query: 'configuration where agent.id=="a1d7b39c-f898-4dbe-a761-efb61939302d"', + query: specificQueryForTests, }; const { previewId } = await previewRule({ supertest, rule }); const previewAlerts = await getPreviewAlerts({ es, previewId }); @@ -620,5 +627,27 @@ export default ({ getService }: FtrProviderContext) => { expect(fullAlert?.host?.risk?.calculated_score_norm).to.eql(96); }); }); + + describe('with asset criticality', async () => { + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/asset_criticality'); + }); + + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/asset_criticality'); + }); + + it('should be enriched alert with criticality_level', async () => { + const rule: EqlRuleCreateProps = { + ...getEqlRuleForAlertTesting(['auditbeat-*']), + query: specificQueryForTests, + }; + + const { previewId } = await previewRule({ supertest, rule }); + const previewAlerts = await getPreviewAlerts({ es, previewId }); + const fullAlert = previewAlerts[0]._source; + expect(fullAlert?.['kibana.alert.host.criticality_level']).to.eql('important'); + }); + }); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/esql.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/esql.ts index cb0f31ad254600..caf649896abf3a 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/esql.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/esql.ts @@ -859,6 +859,45 @@ export default ({ getService }: FtrProviderContext) => { }); }); + describe('with asset criticality', async () => { + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/asset_criticality'); + }); + + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/asset_criticality'); + }); + + it('should be enriched alert with criticality_level', async () => { + const id = uuidv4(); + const interval: [string, string] = ['2020-10-28T06:00:00.000Z', '2020-10-28T06:10:00.000Z']; + const doc1 = { host: { name: 'host-0' } }; + + await indexEnhancedDocuments({ documents: [doc1], interval, id }); + + const rule: EsqlRuleCreateProps = { + ...getCreateEsqlRulesSchemaMock('rule-1', true), + query: `from ecs_compliant ${internalIdPipe(id)} | where host.name=="host-0"`, + from: 'now-1h', + interval: '1h', + }; + + const { previewId } = await previewRule({ + supertest, + rule, + timeframeEnd: new Date('2020-10-28T06:30:00.000Z'), + }); + + const previewAlerts = await getPreviewAlerts({ es, previewId }); + + expect(previewAlerts.length).toBe(1); + + expect(previewAlerts[0]?._source?.['kibana.alert.host.criticality_level']).toBe( + 'very_important' + ); + }); + }); + describe('ECS fields validation', () => { it('creates alert if ECS field has multifields', async () => { const id = uuidv4(); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/machine_learning.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/machine_learning.ts index d58227377f116d..8787a51871125a 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/machine_learning.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/machine_learning.ts @@ -273,5 +273,25 @@ export default ({ getService }: FtrProviderContext) => { expect(fullAlert?.host?.risk?.calculated_score_norm).toBe(1); }); }); + + describe('with asset criticality', async () => { + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/asset_criticality'); + }); + + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/asset_criticality'); + }); + + it('should be enriched alert with criticality_level', async () => { + const { previewId } = await previewRule({ supertest, rule }); + const previewAlerts = await getPreviewAlerts({ es, previewId }); + expect(previewAlerts.length).toBe(1); + const fullAlert = previewAlerts[0]._source; + + expect(fullAlert?.['kibana.alert.host.criticality_level']).toBe('normal'); + expect(fullAlert?.['kibana.alert.user.criticality_level']).toBe('very_important'); + }); + }); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/new_terms.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/new_terms.ts index 8a47aeaa89bdcd..9aea83afb95d00 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/new_terms.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/new_terms.ts @@ -1040,5 +1040,31 @@ export default ({ getService }: FtrProviderContext) => { expect(previewAlerts[0]?._source?.host?.risk?.calculated_score_norm).to.eql(23); }); }); + + describe('with asset criticality', async () => { + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/asset_criticality'); + }); + + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/asset_criticality'); + }); + + it('should be enriched alert with criticality_level', async () => { + const rule: NewTermsRuleCreateProps = { + ...getCreateNewTermsRulesSchemaMock('rule-1', true), + new_terms_fields: ['host.name'], + from: '2019-02-19T20:42:00.000Z', + history_window_start: '2019-01-19T20:42:00.000Z', + }; + + const { previewId } = await previewRule({ supertest, rule }); + const previewAlerts = await getPreviewAlerts({ es, previewId }); + const fullAlert = previewAlerts[0]._source; + + expect(fullAlert?.['kibana.alert.host.criticality_level']).to.eql('normal'); + expect(fullAlert?.['kibana.alert.user.criticality_level']).to.eql('very_important'); + }); + }); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/query.ts index 19c02fe389fe4c..38930bafa564ea 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/query.ts @@ -280,6 +280,31 @@ export default ({ getService }: FtrProviderContext) => { }); }); + describe('with asset criticality', async () => { + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/asset_criticality'); + }); + + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/asset_criticality'); + }); + + it('should be enriched alert with criticality_level', async () => { + const rule: QueryRuleCreateProps = { + ...getRuleForAlertTesting(['auditbeat-*']), + query: `_id:${ID}`, + }; + const { previewId } = await previewRule({ supertest, rule }); + const previewAlerts = await getPreviewAlerts({ es, previewId }); + expect(previewAlerts[0]?._source?.['kibana.alert.host.criticality_level']).to.eql( + 'important' + ); + expect(previewAlerts[0]?._source?.['kibana.alert.user.criticality_level']).to.eql( + 'very_important' + ); + }); + }); + /** * Here we test the functionality of Severity and Risk Score overrides (also called "mappings" * in the code). If the rule specifies a mapping, then the final Severity or Risk Score diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/threat_match.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/threat_match.ts index 9b6c525b5e3516..734583d009ca38 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/threat_match.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/threat_match.ts @@ -1623,5 +1623,49 @@ export default ({ getService }: FtrProviderContext) => { expect(fullAlert?.host?.risk?.calculated_score_norm).to.eql(70); }); }); + + describe('with asset criticality', async () => { + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/asset_criticality'); + }); + + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/asset_criticality'); + }); + + it('should be enriched alert with criticality_level', async () => { + const rule: ThreatMatchRuleCreateProps = createThreatMatchRule({ + query: '*:*', + threat_query: 'source.ip: "188.166.120.93"', // narrow things down with a query to a specific source ip + threat_mapping: [ + // We match host.name against host.name + { + entries: [ + { + field: 'host.name', + value: 'host.name', + type: 'mapping', + }, + ], + }, + ], + }); + + const { previewId } = await previewRule({ supertest, rule }); + const previewAlerts = await getPreviewAlerts({ es, previewId, size: 100 }); + expect(previewAlerts.length).equal(88); + const fullSource = previewAlerts.find( + (alert) => + (alert._source?.[ALERT_ANCESTORS] as Ancestor[])[0].id === '7yJ-B2kBR346wHgnhlMn' + ); + const fullAlert = fullSource?._source; + if (!fullAlert) { + return expect(fullAlert).to.be.ok(); + } + + expect(fullAlert?.['kibana.alert.host.criticality_level']).to.eql('low'); + expect(fullAlert?.['kibana.alert.user.criticality_level']).to.eql('very_important'); + }); + }); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/threshold.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/threshold.ts index 5edee29c02dc6d..dce4886bc1ba57 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/threshold.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/execution_logic/threshold.ts @@ -430,5 +430,30 @@ export default ({ getService }: FtrProviderContext) => { expect(previewAlerts[1]?._source?.host?.risk?.calculated_score_norm).toEqual(96); }); }); + + describe('with asset criticality', async () => { + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/asset_criticality'); + }); + + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/asset_criticality'); + }); + + it('should be enriched alert with criticality_level', async () => { + const rule: ThresholdRuleCreateProps = { + ...getThresholdRuleForAlertTesting(['auditbeat-*']), + threshold: { + field: 'host.name', + value: 100, + }, + }; + const { previewId } = await previewRule({ supertest, rule }); + const previewAlerts = await getPreviewAlerts({ es, previewId, sort: ['host.name'] }); + const fullAlert = previewAlerts[0]?._source; + + expect(fullAlert?.['kibana.alert.host.criticality_level']).toEqual('important'); + }); + }); }); }; From a636dcb11efeecc2021ae47dfbd5c92ce62d787a Mon Sep 17 00:00:00 2001 From: Gloria Hornero <gloria.hornero@elastic.co> Date: Fri, 22 Dec 2023 09:34:56 +0100 Subject: [PATCH 101/116] [Security Solution] Adding conditional execution on ci for Security Solution cypress tests (#173815) ## Summary With the aim of preventing our tests from blocking PRs on teams introducing changes not related with our basecode and saving buildkite time execution, PRs the security solution Cypress tests are going to be executed just when a change is introduced on the listed dependencies in `.buildkite/scripts/pipelines/pull_request/pipeline.ts`. The execution of our tests on every change in the `on-merge` pipeline is going to be maintained, in that way, we are going to be aware of any possible issue we may miss and our flaky tests are going to continue being tracked in github --------- Co-authored-by: Steph Milovic <stephanie.milovic@elastic.co> --- .buildkite/pipelines/pull_request/base.yml | 192 ------------------ .../security_solution/ai_assistant.yml | 24 +++ .../{ => security_solution}/cypress_burn.yml | 0 .../defend_workflows.yml | 0 .../security_solution/detection_engine.yml | 48 +++++ .../security_solution/entity_analytics.yml | 24 +++ .../security_solution/explore.yml | 24 +++ .../security_solution/investigations.yml | 24 +++ .../security_solution/rule_management.yml | 48 +++++ .../pipelines/pull_request/pipeline.ts | 52 ++++- 10 files changed, 242 insertions(+), 194 deletions(-) create mode 100644 .buildkite/pipelines/pull_request/security_solution/ai_assistant.yml rename .buildkite/pipelines/pull_request/{ => security_solution}/cypress_burn.yml (100%) rename .buildkite/pipelines/pull_request/{ => security_solution}/defend_workflows.yml (100%) create mode 100644 .buildkite/pipelines/pull_request/security_solution/detection_engine.yml create mode 100644 .buildkite/pipelines/pull_request/security_solution/entity_analytics.yml create mode 100644 .buildkite/pipelines/pull_request/security_solution/explore.yml create mode 100644 .buildkite/pipelines/pull_request/security_solution/investigations.yml create mode 100644 .buildkite/pipelines/pull_request/security_solution/rule_management.yml diff --git a/.buildkite/pipelines/pull_request/base.yml b/.buildkite/pipelines/pull_request/base.yml index 6011d1d78a6963..03019a107df9ef 100644 --- a/.buildkite/pipelines/pull_request/base.yml +++ b/.buildkite/pipelines/pull_request/base.yml @@ -57,198 +57,6 @@ steps: - exit_status: '*' limit: 1 - - command: .buildkite/scripts/steps/functional/security_serverless_entity_analytics.sh - label: 'Serverless Entity Analytics - Security Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 2 - retry: - automatic: - - exit_status: '*' - limit: 1 - - - command: .buildkite/scripts/steps/functional/security_serverless_explore.sh - label: 'Serverless Explore - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 4 - retry: - automatic: - - exit_status: '*' - limit: 1 - - - command: .buildkite/scripts/steps/functional/security_serverless_investigations.sh - label: 'Serverless Investigations - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 8 - retry: - automatic: - - exit_status: '*' - limit: 1 - - - command: .buildkite/scripts/steps/functional/security_serverless_rule_management.sh - label: 'Serverless Rule Management - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 8 - retry: - automatic: - - exit_status: '*' - limit: 1 - - - command: .buildkite/scripts/steps/functional/security_serverless_rule_management_prebuilt_rules.sh - label: 'Serverless Rule Management - Prebuilt Rules - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 4 - retry: - automatic: - - exit_status: '*' - limit: 1 - - - command: .buildkite/scripts/steps/functional/security_serverless_detection_engine.sh - label: 'Serverless Detection Engine - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 6 - retry: - automatic: - - exit_status: '*' - limit: 1 - - - command: .buildkite/scripts/steps/functional/security_serverless_detection_engine_exceptions.sh - label: 'Serverless Detection Engine - Exceptions - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 6 - retry: - automatic: - - exit_status: '*' - limit: 1 - - - command: .buildkite/scripts/steps/functional/security_serverless_ai_assistant.sh - label: 'Serverless AI Assistant - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 1 - retry: - automatic: - - exit_status: '*' - limit: 1 - - - command: .buildkite/scripts/steps/functional/security_solution_entity_analytics.sh - label: 'Entity Analytics - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 2 - retry: - automatic: - - exit_status: '*' - limit: 1 - - - command: .buildkite/scripts/steps/functional/security_solution_explore.sh - label: 'Explore - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 4 - retry: - automatic: - - exit_status: '*' - limit: 1 - - - command: .buildkite/scripts/steps/functional/security_solution_rule_management.sh - label: 'Rule Management - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 8 - retry: - automatic: - - exit_status: '*' - limit: 1 - - - command: .buildkite/scripts/steps/functional/security_solution_rule_management_prebuilt_rules.sh - label: 'Rule Management - Prebuilt Rules - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 6 - retry: - automatic: - - exit_status: '*' - limit: 1 - - - command: .buildkite/scripts/steps/functional/security_solution_detection_engine.sh - label: 'Detection Engine - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 8 - retry: - automatic: - - exit_status: '*' - limit: 1 - - - command: .buildkite/scripts/steps/functional/security_solution_detection_engine_exceptions.sh - label: 'Detection Engine - Exceptions - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 6 - retry: - automatic: - - exit_status: '*' - limit: 1 - - - command: .buildkite/scripts/steps/functional/security_solution_ai_assistant.sh - label: 'AI Assistant - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 1 - retry: - automatic: - - exit_status: '*' - limit: 1 - - - command: .buildkite/scripts/steps/functional/security_solution_investigations.sh - label: 'Investigations - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 60 - parallelism: 8 - retry: - automatic: - - exit_status: '*' - limit: 1 - - command: .buildkite/scripts/steps/functional/threat_intelligence.sh label: 'Threat Intelligence Cypress Tests' agents: diff --git a/.buildkite/pipelines/pull_request/security_solution/ai_assistant.yml b/.buildkite/pipelines/pull_request/security_solution/ai_assistant.yml new file mode 100644 index 00000000000000..3de3ece499a6e9 --- /dev/null +++ b/.buildkite/pipelines/pull_request/security_solution/ai_assistant.yml @@ -0,0 +1,24 @@ +steps: + - command: .buildkite/scripts/steps/functional/security_serverless_ai_assistant.sh + label: 'Serverless AI Assistant - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 1 + retry: + automatic: + - exit_status: '*' + limit: 1 + + - command: .buildkite/scripts/steps/functional/security_solution_ai_assistant.sh + label: 'AI Assistant - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 1 + retry: + automatic: + - exit_status: '*' + limit: 1 diff --git a/.buildkite/pipelines/pull_request/cypress_burn.yml b/.buildkite/pipelines/pull_request/security_solution/cypress_burn.yml similarity index 100% rename from .buildkite/pipelines/pull_request/cypress_burn.yml rename to .buildkite/pipelines/pull_request/security_solution/cypress_burn.yml diff --git a/.buildkite/pipelines/pull_request/defend_workflows.yml b/.buildkite/pipelines/pull_request/security_solution/defend_workflows.yml similarity index 100% rename from .buildkite/pipelines/pull_request/defend_workflows.yml rename to .buildkite/pipelines/pull_request/security_solution/defend_workflows.yml diff --git a/.buildkite/pipelines/pull_request/security_solution/detection_engine.yml b/.buildkite/pipelines/pull_request/security_solution/detection_engine.yml new file mode 100644 index 00000000000000..6196e2e2515223 --- /dev/null +++ b/.buildkite/pipelines/pull_request/security_solution/detection_engine.yml @@ -0,0 +1,48 @@ +steps: + - command: .buildkite/scripts/steps/functional/security_serverless_detection_engine.sh + label: 'Serverless Detection Engine - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 6 + retry: + automatic: + - exit_status: '*' + limit: 1 + + - command: .buildkite/scripts/steps/functional/security_serverless_detection_engine_exceptions.sh + label: 'Serverless Detection Engine - Exceptions - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 6 + retry: + automatic: + - exit_status: '*' + limit: 1 + + - command: .buildkite/scripts/steps/functional/security_solution_detection_engine.sh + label: 'Detection Engine - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 8 + retry: + automatic: + - exit_status: '*' + limit: 1 + + - command: .buildkite/scripts/steps/functional/security_solution_detection_engine_exceptions.sh + label: 'Detection Engine - Exceptions - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 6 + retry: + automatic: + - exit_status: '*' + limit: 1 diff --git a/.buildkite/pipelines/pull_request/security_solution/entity_analytics.yml b/.buildkite/pipelines/pull_request/security_solution/entity_analytics.yml new file mode 100644 index 00000000000000..482107467884c6 --- /dev/null +++ b/.buildkite/pipelines/pull_request/security_solution/entity_analytics.yml @@ -0,0 +1,24 @@ +steps: + - command: .buildkite/scripts/steps/functional/security_serverless_entity_analytics.sh + label: 'Serverless Entity Analytics - Security Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 2 + retry: + automatic: + - exit_status: '*' + limit: 1 + + - command: .buildkite/scripts/steps/functional/security_solution_entity_analytics.sh + label: 'Entity Analytics - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 2 + retry: + automatic: + - exit_status: '*' + limit: 1 diff --git a/.buildkite/pipelines/pull_request/security_solution/explore.yml b/.buildkite/pipelines/pull_request/security_solution/explore.yml new file mode 100644 index 00000000000000..5acd56ebe7f06a --- /dev/null +++ b/.buildkite/pipelines/pull_request/security_solution/explore.yml @@ -0,0 +1,24 @@ +steps: + - command: .buildkite/scripts/steps/functional/security_solution_explore.sh + label: 'Explore - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 4 + retry: + automatic: + - exit_status: '*' + limit: 1 + + - command: .buildkite/scripts/steps/functional/security_serverless_explore.sh + label: 'Serverless Explore - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 4 + retry: + automatic: + - exit_status: '*' + limit: 1 \ No newline at end of file diff --git a/.buildkite/pipelines/pull_request/security_solution/investigations.yml b/.buildkite/pipelines/pull_request/security_solution/investigations.yml new file mode 100644 index 00000000000000..0390f5dfec8e75 --- /dev/null +++ b/.buildkite/pipelines/pull_request/security_solution/investigations.yml @@ -0,0 +1,24 @@ +steps: + - command: .buildkite/scripts/steps/functional/security_solution_investigations.sh + label: 'Investigations - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 8 + retry: + automatic: + - exit_status: '*' + limit: 1 + + - command: .buildkite/scripts/steps/functional/security_serverless_investigations.sh + label: 'Serverless Investigations - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 8 + retry: + automatic: + - exit_status: '*' + limit: 1 \ No newline at end of file diff --git a/.buildkite/pipelines/pull_request/security_solution/rule_management.yml b/.buildkite/pipelines/pull_request/security_solution/rule_management.yml new file mode 100644 index 00000000000000..e36f77ec60988a --- /dev/null +++ b/.buildkite/pipelines/pull_request/security_solution/rule_management.yml @@ -0,0 +1,48 @@ +steps: + - command: .buildkite/scripts/steps/functional/security_serverless_rule_management.sh + label: 'Serverless Rule Management - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 8 + retry: + automatic: + - exit_status: '*' + limit: 1 + + - command: .buildkite/scripts/steps/functional/security_serverless_rule_management_prebuilt_rules.sh + label: 'Serverless Rule Management - Prebuilt Rules - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 4 + retry: + automatic: + - exit_status: '*' + limit: 1 + + - command: .buildkite/scripts/steps/functional/security_solution_rule_management.sh + label: 'Rule Management - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 8 + retry: + automatic: + - exit_status: '*' + limit: 1 + + - command: .buildkite/scripts/steps/functional/security_solution_rule_management_prebuilt_rules.sh + label: 'Rule Management - Prebuilt Rules - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 60 + parallelism: 6 + retry: + automatic: + - exit_status: '*' + limit: 1 \ No newline at end of file diff --git a/.buildkite/scripts/pipelines/pull_request/pipeline.ts b/.buildkite/scripts/pipelines/pull_request/pipeline.ts index 0a305f49a811fc..f9eab6138834c8 100644 --- a/.buildkite/scripts/pipelines/pull_request/pipeline.ts +++ b/.buildkite/scripts/pipelines/pull_request/pipeline.ts @@ -176,7 +176,9 @@ const uploadPipeline = (pipelineContent: string | object) => { GITHUB_PR_LABELS.includes('ci:cypress-burn') || GITHUB_PR_LABELS.includes('ci:all-cypress-suites') ) { - pipeline.push(getPipeline('.buildkite/pipelines/pull_request/cypress_burn.yml')); + pipeline.push( + getPipeline('.buildkite/pipelines/pull_request/security_solution/cypress_burn.yml') + ); } if ( @@ -189,7 +191,53 @@ const uploadPipeline = (pipelineContent: string | object) => { ])) || GITHUB_PR_LABELS.includes('ci:all-cypress-suites') ) { - pipeline.push(getPipeline('.buildkite/pipelines/pull_request/defend_workflows.yml')); + pipeline.push( + getPipeline('.buildkite/pipelines/pull_request/security_solution/defend_workflows.yml') + ); + } + + if ( + (await doAnyChangesMatch([ + /^package.json/, + /^packages\/kbn-securitysolution-.*/, + /^x-pack\/plugins\/alerting/, + /^x-pack\/plugins\/data_views\/common/, + /^x-pack\/plugins\/lists/, + /^x-pack\/plugins\/rule_registry\/common/, + /^x-pack\/plugins\/security_solution/, + /^x-pack\/plugins\/security_solution_ess/, + /^x-pack\/plugins\/security_solution_serverless/, + /^x-pack\/plugins\/task_manager/, + /^x-pack\/plugins\/timelines/, + /^x-pack\/plugins\/triggers_actions_ui\/public\/application\/sections\/action_connector_form/, + /^x-pack\/plugins\/triggers_actions_ui\/public\/application\/context\/actions_connectors_context\.tsx/, + /^x-pack\/plugins\/triggers_actions_ui\/server\/connector_types\/openai/, + /^x-pack\/plugins\/triggers_actions_ui\/server\/connector_types\/bedrock/, + /^x-pack\/plugins\/usage_collection\/public/, + /^x-pack\/plugins\/elastic_assistant/, + /^x-pack\/packages\/security-solution/, + /^x-pack\/packages\/kbn-elastic-assistant/, + /^x-pack\/packages\/kbn-elastic-assistant-common/, + /^x-pack\/test\/security_solution_cypress/, + ])) || + GITHUB_PR_LABELS.includes('ci:all-cypress-suites') + ) { + pipeline.push( + getPipeline('.buildkite/pipelines/pull_request/security_solution/ai_assistant.yml') + ); + pipeline.push( + getPipeline('.buildkite/pipelines/pull_request/security_solution/detection_engine.yml') + ); + pipeline.push( + getPipeline('.buildkite/pipelines/pull_request/security_solution/entity_analytics.yml') + ); + pipeline.push(getPipeline('.buildkite/pipelines/pull_request/security_solution/explore.yml')); + pipeline.push( + getPipeline('.buildkite/pipelines/pull_request/security_solution/investigations.yml') + ); + pipeline.push( + getPipeline('.buildkite/pipelines/pull_request/security_solution/rule_management.yml') + ); } pipeline.push(getPipeline('.buildkite/pipelines/pull_request/post_build.yml')); From 1131932cd0ec24283a8c62973e09ee3ab20edfb4 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet <pierre.gayvallet@elastic.co> Date: Fri, 22 Dec 2023 10:40:20 +0100 Subject: [PATCH 102/116] rolling file appender: fix next rolling time for DST (#173811) ## Summary Fix https://github.com/elastic/kibana/issues/173808 ### Release Note Fix a bug that could cause the `rollingFile` log appender to not properly rotate files on DST switch days. --- .../get_next_rolling_time.test.ts | 23 +++++++++++++++++++ .../time_interval/get_next_rolling_time.ts | 6 +++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/packages/core/logging/core-logging-server-internal/src/appenders/rolling_file/policies/time_interval/get_next_rolling_time.test.ts b/packages/core/logging/core-logging-server-internal/src/appenders/rolling_file/policies/time_interval/get_next_rolling_time.test.ts index 197d3757f13862..4d61172b7d156d 100644 --- a/packages/core/logging/core-logging-server-internal/src/appenders/rolling_file/policies/time_interval/get_next_rolling_time.test.ts +++ b/packages/core/logging/core-logging-server-internal/src/appenders/rolling_file/policies/time_interval/get_next_rolling_time.test.ts @@ -22,6 +22,29 @@ const formattedRollingTime = (date: string, duration: string, modulate: boolean) ).format(format); describe('getNextRollingTime', () => { + describe('DST', () => { + it('returns the correct date when entering DST', () => { + expect(formattedRollingTime('2023-03-11 23:59:59:999', '24h', true)).toEqual( + '2023-03-12 00:00:00:000' + ); + }); + it('returns the correct date within DST', () => { + expect(formattedRollingTime('2023-06-15 23:59:59:999', '24h', true)).toEqual( + '2023-06-16 00:00:00:000' + ); + }); + it('returns the correct date when exiting DST', () => { + expect(formattedRollingTime('2023-11-05 23:59:59:999', '24h', true)).toEqual( + '2023-11-06 00:00:00:000' + ); + }); + it('returns the correct date outside of DST', () => { + expect(formattedRollingTime('2023-01-07 23:59:59:999', '24h', true)).toEqual( + '2023-01-08 00:00:00:000' + ); + }); + }); + describe('when `modulate` is false', () => { it('increments the current time by the interval', () => { expect(formattedRollingTime('2010-10-20 04:27:12:000', '15m', false)).toEqual( diff --git a/packages/core/logging/core-logging-server-internal/src/appenders/rolling_file/policies/time_interval/get_next_rolling_time.ts b/packages/core/logging/core-logging-server-internal/src/appenders/rolling_file/policies/time_interval/get_next_rolling_time.ts index 343bd97cb8dffb..a31a01e881188f 100644 --- a/packages/core/logging/core-logging-server-internal/src/appenders/rolling_file/policies/time_interval/get_next_rolling_time.ts +++ b/packages/core/logging/core-logging-server-internal/src/appenders/rolling_file/policies/time_interval/get_next_rolling_time.ts @@ -23,8 +23,10 @@ export const getNextRollingTime = ( const increment = interval.get(incrementedUnit) - (currentMoment.get(incrementedUnit) % interval.get(incrementedUnit)); - const incrementInMs = moment.duration(increment, incrementedUnit).asMilliseconds(); - return currentMoment.startOf(incrementedUnit).toDate().getTime() + incrementInMs; + const nextRollingMoment = currentMoment + .startOf(incrementedUnit) + .add(increment, incrementedUnit); + return nextRollingMoment.toDate().getTime(); } else { return currentTime + interval.asMilliseconds(); } From acba49451c0169fc3cd5de765493de10dcd0c24e Mon Sep 17 00:00:00 2001 From: Marco Liberati <dej611@users.noreply.github.com> Date: Fri, 22 Dec 2023 11:26:22 +0100 Subject: [PATCH 103/116] [ES|QL] Add readme to library (#173899) ## Summary Add a readme that explains: * folder structure * how all things work * how to add/fix it in case of changed/added functions/commands/options/etc... --- packages/kbn-monaco/src/esql/lib/README.md | 128 +++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 packages/kbn-monaco/src/esql/lib/README.md diff --git a/packages/kbn-monaco/src/esql/lib/README.md b/packages/kbn-monaco/src/esql/lib/README.md new file mode 100644 index 00000000000000..b30082f710596a --- /dev/null +++ b/packages/kbn-monaco/src/esql/lib/README.md @@ -0,0 +1,128 @@ +# ES|QL utility library + +## Folder structure + +This library enables all the advanced features for ES|QL within Monaco, as validation, autocomplete, hover, etc... +The package is structure as follow: + +``` +|- antlr // => contains the ES|QL grammar files and various compilation assets +|- lib +| |- ast +| | | autocomplete // => the autocomplete/suggest logic +| | | definitions // => static assets to define all components behaviour of a ES|QL query: commands, functions, etc... +| | | hover // => hover logic +| | | signature // => signature service logic +| | | validation // => the validation logic +| | ast_factory.ts // => binding to the Antlr that generates the AST data structure +| | ast_errors.ts // => error translation utility from raw Antlr to something understandable (somewhat) +| | ... // => miscellaneas utilities to work with AST +| |- monaco // => some high level interfaces to work with +| | | esql_ast_provider.ts // => the API to work with validation, autocomplete, etc... +| | | ... +| antlr_facade.ts // => getParser and getLexer utilities +|- worker // => some Monaco utilities that runs in a WebWorker +language.ts // => ES|QL language definition for Monaco with API that expose all features to it +``` + +### Syntax highlight support + +In general the syntax highlight works out of the box, but in case of new tokens added it is required to add them into the `esql_theme.ts` file to color them. +There's also a special | (pipe) handling in case of multi-line with some offset applied to the token location indexes to fix some grammar problems with multi-line. In case of issues with highlight look into the `esql_token_provider.ts` file. + +### How does it work + +The general idea of this package is to provide all ES|QL features on top of a custom compact AST definition (all data structure types defined in `./ast/types.ts`) which is designed to be resilient to many grammar changes. +The pipeline is the following: + +``` +Antlr grammar files +=> Compiled grammar files (.ts assets in the antlr folder) +=> AST Factory (Antlr Parser tree => custom AST) +=> featureFn( AST, Definitions, ESQLCallbacks ) +``` + +Each feature function works with the combination of the AST and the definition files: the former describe the current statement in a easy to traverse way, while the definitions describe what's the expected behaviour of each node in the AST node (i.e. what arguments should it accept? How many arguments? etc...). +ESQLCallbacks are a set of utilities to retrieve context metadata like fields/index/policies list and policies metadata. + +While AST requires the grammar to be compiled to be updated, definitions are static files which can be dynamically updated without running the ANTLR compile task. + +#### AST + +The AST is generated by 2 files: `ast_factory.ts` and its buddy `ast_walker.ts`: +* `ast_factory.ts` is a binding to Antlr and access the Parser tree +* Parser tree is passed over to `ast_walker` to append new AST nodes + +In general Antlr is resilient to grammar errors, in the sense that it can produe a Parser tree up to the point of the error, then stops. This is useful to perform partial tasks even with broken queries and this means that a partial AST can be produced even with an invalid query. + +#### Validation + +Validation takes an AST as input and generates a list of messages to show to the user. +The validation function leverages the definition files to check if the current AST is respecting the defined behaviour. +Most of the logic rely purely on the definitions, but in some specific cases some ad-hoc conditions are defined within the code for specific commands/options. + +#### Autocomplete + +The autocomplete/suggest task takes a query as input together with the current cursor position, then produces internally an AST to work with, to generate a list of suggestions for the given query. +Note that autocomplete works most of the time with incomplete/invalid queries, so some logic to manipulate the query into something valid (see the `EDITOR_MARKER` or the `countBracketsUnclosed` functions for more). + +Once the AST is produced there's a `getAstContext` function that finds the cursor position node (and its parent command), together with some hint like the type of current context: `expression`, `function`, `newCommand`, `option`. +The most complex case is the `expression` as it can cover a moltitude of cases. The function is highly commented in order to identify the specific cases, but there's probably some obscure area still to comment/clarify. + +#### Hover + +The hover logic leverages the same `getAstContext` function as autocomplete but its logic is way simpler as it picks the right definition based on context and produces a set of strings for the tooltip. + +#### Signature + +No signature implementation has been added yet, but it will likely work as hover if/when implemented. + +### Keeping ES|QL up to date + +In general when operating on changes here use the `yarn kbn watch` in a terminal window to make sure changes are correctly compiled. + +#### How to add new functions + +When a new function is added to ES|QL, this can be of one of these types: + +* Built-in function (+, -, in, like, etc...) +* Aggregation type (`STATS` only) +* Math type (`EVAL`, `WHERE`, etc...) + +For each function type there's a specific file to update within the `definitions` folder: +* Built-in function => `builtin.ts` +* Aggregation type => `aggs.ts` +* Math type => `functions.ts` + +All function definitions are of the `FunctionDefinition` type and it's quite easy to add new ones. + +While validation tests for Aggregation and Math type will be automatically generated, for the Built-in type new tests needs to be added for both validation and autocomplete. + +#### How to add new commands/options + +When a new command/option is added to ES|QL it is done via a grammar update. +Therefore adding them requires a two step phase: +* Update the grammar with the new one + * add/fix all AST generator bindings in case of new/changed TOKENS in the `lexer` grammar file +* Update the definition files for commands/options + +To update the grammar: +1. start by copying the source grammar `lexer` and `parser` files +2. make sure to fix all the case insensitive occurrencies in `lexer` file (all non-symbol strings like `"something"` into `S O M E T H I N G`). +3. run the script into the `package.json` to compile the ES|QL grammar. +4. open the `ast_factory.ts` file and add a new `exit<Command/Option>` method +5. write some code in the `ast_walker/ts` to translate the Antlr Parser tree into the custom AST (there are already few utilites for that, but sometimes it is required to write some more code if the `parser` introduced a new flow) + * pro tip: use the `http://lab.antlr.org/` to visualize/debug the parser tree for a given statement (copy and paste the grammar files there) +6. if a new quoted/unquoted identifier token gets added open the `ast_helpers.ts` and manually add the ids of the new tokens in the `getQuotedText` and `getUnquotedText` functions - please make sure to leave a comment on the token name + +To update the definitions: +1. open either the `commands.ts` or `option.ts` file and add a new entry +2. write new tests for validation and autocomplete + +#### Debug and fix grammar changes (tokens, etc...) + +On TOKEN renaming or with subtle `lexer` grammar changes it can happens that test breaks, this can be happen for two main issues: +* A TOKEN name changed so the `ast_walker.ts` doesn't find it any more. Go there and rename the TOKEN name. +* TOKEN order changed and tests started failing. This probably generated some TOKEN id reorder and there are two functions in `ast_helpers.ts` who rely on hardcoded ids: `getQuotedText` and `getUnquotedText`. + * to fix this just look at the commented tokens and update the ids. If a new token add it and leave a comment to point to the new token name. + * This choice was made to reduce the bundle size, as importing the `esql_parser` adds some hundreds of Kbs to the bundle otherwise. \ No newline at end of file From b5cd85c21fa60c121c30219666a89135c9a95124 Mon Sep 17 00:00:00 2001 From: Dima Arnautov <dmitrii.arnautov@elastic.co> Date: Fri, 22 Dec 2023 12:23:50 +0100 Subject: [PATCH 104/116] [ML] Enable Trained models functional tests (#173517) ## Summary Closes https://github.com/elastic/kibana/issues/168899 Closes https://github.com/elastic/kibana/issues/168492 Closes https://github.com/elastic/kibana/issues/156243 Enables Trained models functional tests ### Checklist - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed (https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4664) --- .../model_management/deployment_setup.tsx | 3 + .../model_management/model_list.ts | 255 +++++++++--------- .../test/functional/services/ml/common_ui.ts | 14 +- .../services/ml/trained_models_table.ts | 50 +++- 4 files changed, 189 insertions(+), 133 deletions(-) diff --git a/x-pack/plugins/ml/public/application/model_management/deployment_setup.tsx b/x-pack/plugins/ml/public/application/model_management/deployment_setup.tsx index 102af34d3e95da..7482f66fd44602 100644 --- a/x-pack/plugins/ml/public/application/model_management/deployment_setup.tsx +++ b/x-pack/plugins/ml/public/application/model_management/deployment_setup.tsx @@ -92,6 +92,7 @@ export const DeploymentSetup: FC<DeploymentSetupProps> = ({ id, label: id, value, + 'data-test-subj': `mlModelsStartDeploymentModalThreadsPerAllocation_${id}`, }; }), [maxSingleMlNodeProcessors] @@ -215,6 +216,7 @@ export const DeploymentSetup: FC<DeploymentSetupProps> = ({ defaultMessage: 'low', } ), + 'data-test-subj': 'mlModelsStartDeploymentModalLowPriority', }, { id: 'normal', @@ -225,6 +227,7 @@ export const DeploymentSetup: FC<DeploymentSetupProps> = ({ defaultMessage: 'normal', } ), + 'data-test-subj': 'mlModelsStartDeploymentModalNormalPriority', }, ]} data-test-subj={'mlModelsStartDeploymentModalPriority'} diff --git a/x-pack/test/functional/apps/ml/short_tests/model_management/model_list.ts b/x-pack/test/functional/apps/ml/short_tests/model_management/model_list.ts index ebcdfbeb4b1706..c1c32114ea2359 100644 --- a/x-pack/test/functional/apps/ml/short_tests/model_management/model_list.ts +++ b/x-pack/test/functional/apps/ml/short_tests/model_management/model_list.ts @@ -17,8 +17,7 @@ export default function ({ getService }: FtrProviderContext) { id: model.name, })); - // FLAKY: https://github.com/elastic/kibana/issues/165084 - describe.skip('trained models', function () { + describe('trained models', function () { // 'Created at' will be different on each run, // so we will just assert that the value is in the expected timestamp format. const builtInModelData = { @@ -112,12 +111,6 @@ export default function ({ getService }: FtrProviderContext) { await ml.api.cleanMlIndices(); await ml.api.deleteIndices(modelWithPipelineAndDestIndexExpectedValues.index); - await ml.api.deleteIngestPipeline(modelWithoutPipelineDataExpectedValues.name, false); - await ml.api.deleteIngestPipeline( - modelWithoutPipelineDataExpectedValues.duplicateName, - false - ); - // Need to delete index before ingest pipeline, else it will give error await ml.api.deleteIngestPipeline(modelWithPipelineAndDestIndex.modelId); await ml.testResources.deleteDataViewByTitle( @@ -188,122 +181,141 @@ export default function ({ getService }: FtrProviderContext) { await ml.trainedModelsTable.assertPipelinesTabContent(false); }); - it('deploys the trained model with default values', async () => { - await ml.testExecution.logTestStep('should display the trained model in the table'); - await ml.trainedModelsTable.filterWithSearchString(modelWithoutPipelineData.modelId, 1); - await ml.testExecution.logTestStep( - 'should show collapsed actions menu for the model in the table' - ); - await ml.trainedModelsTable.assertModelCollapsedActionsButtonExists( - modelWithoutPipelineData.modelId, - true - ); - await ml.testExecution.logTestStep('should show deploy action for the model in the table'); - await ml.trainedModelsTable.assertModelDeployActionButtonEnabled( - modelWithoutPipelineData.modelId, - true - ); - await ml.testExecution.logTestStep('should open the deploy model flyout'); - await ml.trainedModelsTable.clickDeployAction(modelWithoutPipelineData.modelId); - await ml.testExecution.logTestStep('should complete the deploy model Details step'); - await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutDetails({ - name: modelWithoutPipelineDataExpectedValues.name, - description: modelWithoutPipelineDataExpectedValues.description, - // If no metadata is provided, the target field will default to empty string - targetField: '', + // FLAKY: https://github.com/elastic/kibana/issues/165084 + describe.skip('DFA model deployment', () => { + after(async () => { + await ml.api.deleteIngestPipeline(modelWithoutPipelineDataExpectedValues.name, false); + await ml.api.deleteIngestPipeline( + modelWithoutPipelineDataExpectedValues.duplicateName, + false + ); }); - await ml.testExecution.logTestStep('should complete the deploy model Pipeline Config step'); - await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutPipelineConfig({ - inferenceConfig: modelWithoutPipelineDataExpectedValues.inferenceConfig, - fieldMap: modelWithoutPipelineDataExpectedValues.fieldMap, - }); - await ml.testExecution.logTestStep( - 'should complete the deploy model pipeline On Failure step' - ); - await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutOnFailure( - getDefaultOnFailureConfiguration() - ); - await ml.testExecution.logTestStep( - 'should complete the deploy model pipeline Create pipeline step' - ); - await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutCreateStep({ - description: modelWithoutPipelineDataExpectedValues.description, - processors: [ - { - inference: { - model_id: modelWithoutPipelineData.modelId, - ignore_failure: false, - inference_config: modelWithoutPipelineDataExpectedValues.inferenceConfig, - on_failure: getDefaultOnFailureConfiguration(), - }, - }, - ], - }); - }); - it('deploys the trained model with custom values', async () => { - await ml.testExecution.logTestStep('should display the trained model in the table'); - await ml.trainedModelsTable.filterWithSearchString(modelWithoutPipelineData.modelId, 1); - await ml.testExecution.logTestStep( - 'should not show collapsed actions menu for the model in the table' - ); - await ml.trainedModelsTable.assertModelCollapsedActionsButtonExists( - modelWithoutPipelineData.modelId, - true - ); - await ml.testExecution.logTestStep('should show deploy action for the model in the table'); - await ml.trainedModelsTable.assertModelDeployActionButtonExists( - modelWithoutPipelineData.modelId, - false - ); - await ml.testExecution.logTestStep('should open the deploy model flyout'); - await ml.trainedModelsTable.clickDeployAction(modelWithoutPipelineData.modelId); - await ml.testExecution.logTestStep('should complete the deploy model Details step'); - await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutDetails( - { - name: modelWithoutPipelineDataExpectedValues.duplicateName, - description: modelWithoutPipelineDataExpectedValues.duplicateDescription, - targetField: 'myTargetField', - }, - true - ); - await ml.testExecution.logTestStep('should complete the deploy model Pipeline Config step'); - await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutPipelineConfig( - { + it.skip('deploys the trained model with default values', async () => { + await ml.testExecution.logTestStep('should display the trained model in the table'); + await ml.trainedModelsTable.filterWithSearchString(modelWithoutPipelineData.modelId, 1); + await ml.testExecution.logTestStep( + 'should show collapsed actions menu for the model in the table' + ); + await ml.trainedModelsTable.assertModelCollapsedActionsButtonExists( + modelWithoutPipelineData.modelId, + true + ); + await ml.testExecution.logTestStep( + 'should show deploy action for the model in the table' + ); + await ml.trainedModelsTable.assertModelDeployActionButtonEnabled( + modelWithoutPipelineData.modelId, + true + ); + await ml.testExecution.logTestStep('should open the deploy model flyout'); + await ml.trainedModelsTable.clickDeployAction(modelWithoutPipelineData.modelId); + await ml.testExecution.logTestStep('should complete the deploy model Details step'); + await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutDetails({ + name: modelWithoutPipelineDataExpectedValues.name, + description: modelWithoutPipelineDataExpectedValues.description, + // If no metadata is provided, the target field will default to empty string + targetField: '', + }); + await ml.testExecution.logTestStep( + 'should complete the deploy model Pipeline Config step' + ); + await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutPipelineConfig({ inferenceConfig: modelWithoutPipelineDataExpectedValues.inferenceConfig, - editedInferenceConfig: modelWithoutPipelineDataExpectedValues.editedInferenceConfig, fieldMap: modelWithoutPipelineDataExpectedValues.fieldMap, - editedFieldMap: modelWithoutPipelineDataExpectedValues.editedFieldMap, - }, - true - ); - await ml.testExecution.logTestStep( - 'should complete the deploy model pipeline On Failure step' - ); - await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutOnFailure( - getDefaultOnFailureConfiguration(), - true - ); - await ml.testExecution.logTestStep( - 'should complete the deploy model pipeline Create pipeline step' - ); - await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutCreateStep({ - description: modelWithoutPipelineDataExpectedValues.duplicateDescription, - processors: [ - { - inference: { - field_map: { - incoming_field: 'old_field', + }); + await ml.testExecution.logTestStep( + 'should complete the deploy model pipeline On Failure step' + ); + await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutOnFailure( + getDefaultOnFailureConfiguration() + ); + await ml.testExecution.logTestStep( + 'should complete the deploy model pipeline Create pipeline step' + ); + await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutCreateStep({ + description: modelWithoutPipelineDataExpectedValues.description, + processors: [ + { + inference: { + model_id: modelWithoutPipelineData.modelId, + ignore_failure: false, + inference_config: modelWithoutPipelineDataExpectedValues.inferenceConfig, + on_failure: getDefaultOnFailureConfiguration(), }, - ignore_failure: true, - if: "ctx?.network?.name == 'Guest'", - model_id: modelWithoutPipelineData.modelId, - inference_config: modelWithoutPipelineDataExpectedValues.inferenceConfigDuplicate, - tag: 'tag', - target_field: 'myTargetField', }, + ], + }); + }); + + it.skip('deploys the trained model with custom values', async () => { + await ml.testExecution.logTestStep('should display the trained model in the table'); + await ml.trainedModelsTable.filterWithSearchString(modelWithoutPipelineData.modelId, 1); + await ml.testExecution.logTestStep( + 'should not show collapsed actions menu for the model in the table' + ); + await ml.trainedModelsTable.assertModelCollapsedActionsButtonExists( + modelWithoutPipelineData.modelId, + true + ); + await ml.testExecution.logTestStep( + 'should show deploy action for the model in the table' + ); + await ml.trainedModelsTable.assertModelDeployActionButtonExists( + modelWithoutPipelineData.modelId, + false + ); + await ml.testExecution.logTestStep('should open the deploy model flyout'); + await ml.trainedModelsTable.clickDeployAction(modelWithoutPipelineData.modelId); + await ml.testExecution.logTestStep('should complete the deploy model Details step'); + await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutDetails( + { + name: modelWithoutPipelineDataExpectedValues.duplicateName, + description: modelWithoutPipelineDataExpectedValues.duplicateDescription, + targetField: 'myTargetField', + }, + true + ); + await ml.testExecution.logTestStep( + 'should complete the deploy model Pipeline Config step' + ); + await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutPipelineConfig( + { + inferenceConfig: modelWithoutPipelineDataExpectedValues.inferenceConfig, + editedInferenceConfig: modelWithoutPipelineDataExpectedValues.editedInferenceConfig, + fieldMap: modelWithoutPipelineDataExpectedValues.fieldMap, + editedFieldMap: modelWithoutPipelineDataExpectedValues.editedFieldMap, }, - ], + true + ); + await ml.testExecution.logTestStep( + 'should complete the deploy model pipeline On Failure step' + ); + await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutOnFailure( + getDefaultOnFailureConfiguration(), + true + ); + await ml.testExecution.logTestStep( + 'should complete the deploy model pipeline Create pipeline step' + ); + await ml.deployDFAModelFlyout.completeTrainedModelsInferenceFlyoutCreateStep({ + description: modelWithoutPipelineDataExpectedValues.duplicateDescription, + processors: [ + { + inference: { + field_map: { + incoming_field: 'old_field', + }, + ignore_failure: true, + if: "ctx?.network?.name == 'Guest'", + model_id: modelWithoutPipelineData.modelId, + inference_config: modelWithoutPipelineDataExpectedValues.inferenceConfigDuplicate, + tag: 'tag', + target_field: 'myTargetField', + }, + }, + ], + }); }); }); @@ -418,7 +430,7 @@ export default function ({ getService }: FtrProviderContext) { ); }); - it('navigates to data drift', async () => { + it.skip('navigates to data drift', async () => { await ml.testExecution.logTestStep('should show the model map in the expanded row'); await ml.trainedModelsTable.ensureRowIsExpanded(modelWithPipelineAndDestIndex.modelId); await ml.trainedModelsTable.assertModelsMapTabContent(); @@ -450,8 +462,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.navigation.navigateToTrainedModels(); }); - // FLAKY: https://github.com/elastic/kibana/issues/168899 - describe.skip('with imported models', function () { + describe('with imported models', function () { before(async () => { await ml.navigation.navigateToTrainedModels(); }); @@ -475,8 +486,10 @@ export default function ({ getService }: FtrProviderContext) { }); it(`stops deployment of the imported model ${model.id}`, async () => { + // Wait for the model to be deployed before stopping it. + await ml.testExecution.logTestStep('should have a Deployed state'); + await ml.trainedModelsTable.assertModelState(model.id, 'Deployed'); await ml.trainedModelsTable.stopDeployment(model.id); - await ml.trainedModelsTable.assertModelDeleteActionButtonEnabled(model.id, true); }); it(`deletes the imported model ${model.id}`, async () => { diff --git a/x-pack/test/functional/services/ml/common_ui.ts b/x-pack/test/functional/services/ml/common_ui.ts index 14a0c8efc05897..dc4836ed6f34c9 100644 --- a/x-pack/test/functional/services/ml/common_ui.ts +++ b/x-pack/test/functional/services/ml/common_ui.ts @@ -363,15 +363,21 @@ export function MachineLearningCommonUIProvider({ }); }, - async selectButtonGroupValue(inputTestSubj: string, value: string) { + async selectButtonGroupValue(inputTestSubj: string, value: string, valueTestSubj?: string) { await retry.tryForTime(5000, async () => { // The input element can not be clicked directly. // Instead, we need to click the corresponding label - const fieldSetElement = await testSubjects.find(inputTestSubj); + let labelElement: WebElementWrapper; - const labelElement = await fieldSetElement.findByCssSelector(`label[title="${value}"]`); - await labelElement.click(); + if (valueTestSubj) { + await testSubjects.click(valueTestSubj); + labelElement = await testSubjects.find(valueTestSubj); + } else { + const fieldSetElement = await testSubjects.find(inputTestSubj); + labelElement = await fieldSetElement.findByCssSelector(`label[title="${value}"]`); + await labelElement.click(); + } const labelClasses = await labelElement.getAttribute('class'); expect(labelClasses).to.contain( diff --git a/x-pack/test/functional/services/ml/trained_models_table.ts b/x-pack/test/functional/services/ml/trained_models_table.ts index 1053d8a990e445..a186c531703be2 100644 --- a/x-pack/test/functional/services/ml/trained_models_table.ts +++ b/x-pack/test/functional/services/ml/trained_models_table.ts @@ -52,6 +52,7 @@ export function TrainedModelsTableProvider( description: string; modelTypes: string[]; createdAt: string; + state: string; } = { id: $tr .findTestSubject('mlModelsTableColumnId') @@ -64,6 +65,11 @@ export function TrainedModelsTableProvider( .text() .trim(), modelTypes, + state: $tr + .findTestSubject('mlModelsTableColumnDeploymentState') + .find('.euiTableCellContent') + .text() + .trim(), createdAt: $tr .findTestSubject('mlModelsTableColumnCreatedAt') .find('.euiTableCellContent') @@ -193,12 +199,17 @@ export function TrainedModelsTableProvider( public async toggleActionsContextMenu(modelId: string, expectOpen = true) { await testSubjects.click(this.rowSelector(modelId, 'euiCollapsedItemActionsButton')); - const panelElement = await find.byCssSelector('.euiContextMenuPanel'); - const isDisplayed = await panelElement.isDisplayed(); - expect(isDisplayed).to.eql( - expectOpen, - `Expected the action context menu for '${modelId}' to be ${expectOpen ? 'open' : 'closed'}` - ); + + await retry.tryForTime(5 * 1000, async () => { + const panelElement = await find.byCssSelector('.euiContextMenuPanel'); + const isDisplayed = await panelElement.isDisplayed(); + expect(isDisplayed).to.eql( + expectOpen, + `Expected the action context menu for '${modelId}' to be ${ + expectOpen ? 'open' : 'closed' + }` + ); + }); } public async assertModelDeleteActionButtonExists(modelId: string, expectedValue: boolean) { @@ -510,14 +521,18 @@ export function TrainedModelsTableProvider( public async setPriority(value: 'low' | 'normal') { await mlCommonUI.selectButtonGroupValue( 'mlModelsStartDeploymentModalPriority', - value.toString() + value.toString(), + value === 'normal' + ? 'mlModelsStartDeploymentModalNormalPriority' + : 'mlModelsStartDeploymentModalLowPriority' ); } public async setThreadsPerAllocation(value: number) { await mlCommonUI.selectButtonGroupValue( 'mlModelsStartDeploymentModalThreadsPerAllocation', - value.toString() + value.toString(), + `mlModelsStartDeploymentModalThreadsPerAllocation_${value}` ); } @@ -540,6 +555,25 @@ export function TrainedModelsTableProvider( `Deployment for "${modelId}" has been started successfully.` ); await this.waitForModelsToLoad(); + + await retry.tryForTime( + 5 * 1000, + async () => { + await this.assertModelState(modelId, 'Deployed'); + }, + async () => { + await this.refreshModelsTable(); + } + ); + } + + public async assertModelState(modelId: string, expectedValue = 'Deployed') { + const rows = await this.parseModelsTable(); + const modelRow = rows.find((row) => row.id === modelId); + expect(modelRow?.state).to.eql( + expectedValue, + `Expected trained model row state to be '${expectedValue}' (got '${modelRow?.state!}')` + ); } public async stopDeployment(modelId: string) { From 31b7380c107550774bbb93d643a9446434f8b0a9 Mon Sep 17 00:00:00 2001 From: Dario Gieselaar <dario.gieselaar@elastic.co> Date: Fri, 22 Dec 2023 12:54:44 +0100 Subject: [PATCH 105/116] [Obs AI Assistant] Fall back to request.url for kibana fn (#173717) Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Justin Kambic <jk@elastic.co> --- .../server/functions/kibana.ts | 40 ++++++++++++++----- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/observability_ai_assistant/server/functions/kibana.ts b/x-pack/plugins/observability_ai_assistant/server/functions/kibana.ts index 49516e28c38e81..3fab9cd7aeb569 100644 --- a/x-pack/plugins/observability_ai_assistant/server/functions/kibana.ts +++ b/x-pack/plugins/observability_ai_assistant/server/functions/kibana.ts @@ -6,7 +6,8 @@ */ import axios from 'axios'; -import { format } from 'url'; +import { format, parse } from 'url'; +import { castArray, first, pick, pickBy } from 'lodash'; import type { FunctionRegistrationParameters } from '.'; export function registerKibanaFunction({ @@ -51,18 +52,14 @@ export function registerKibanaFunction({ ({ arguments: { method, pathname, body, query } }, signal) => { const { request } = resources; - const { - protocol, - host, - username, - password, - pathname: pathnameFromRequest, - } = request.rewrittenUrl!; + const { protocol, host, pathname: pathnameFromRequest } = request.rewrittenUrl || request.url; + + const origin = first(castArray(request.headers.origin)); + const nextUrl = { host, protocol, - username, - password, + ...(origin ? pick(parse(origin), 'host', 'protocol') : {}), pathname: pathnameFromRequest.replace( '/internal/observability_ai_assistant/chat/complete', pathname @@ -70,9 +67,30 @@ export function registerKibanaFunction({ query, }; + const copiedHeaderNames = [ + 'accept-encoding', + 'accept-language', + 'accept', + 'content-type', + 'cookie', + 'kbn-build-number', + 'kbn-version', + 'origin', + 'referer', + 'user-agent', + 'x-elastic-internal-origin', + 'x-kbn-context', + ]; + + const headers = pickBy(request.headers, (value, key) => { + return ( + copiedHeaderNames.includes(key.toLowerCase()) || key.toLowerCase().startsWith('sec-') + ); + }); + return axios({ method, - headers: request.headers, + headers, url: format(nextUrl), data: body ? JSON.stringify(body) : undefined, signal, From fc997b1544203e5b49e18252327555296491b74c Mon Sep 17 00:00:00 2001 From: Dario Gieselaar <dario.gieselaar@elastic.co> Date: Fri, 22 Dec 2023 13:00:17 +0100 Subject: [PATCH 106/116] [Obs AI Assistant] Include `search-*` when recalling documents (#173710) Include `search-*` indices when recalling documents from the knowledge base. General approach: - use the current user, not the internal user. the latter will ~never have access to `search-*` - use `_field_caps` to look for sparse_vector field types - `ml.inference.` is a hard-coded prefix, so we can strip that and `_expanded.predicted_value` to get the original field name - only include documents that have the same model ID as we are using for our regular recalls - if the request fails for whatever reason (which is fine, users might not have access to `search-*`), just ignore it and log it with log level debug - we serialize the entire document - some other non-vectorized metadata can also be important for the LLM to make decisions - sort all documents (kb + `search-*`) by score and return the first 20 - count the amount of tokens, don't send over more than 4000 tokens to the LLM to keep response time down. drop the remaining documents on the floor and log it. --- .../server/functions/index.ts | 1 + .../server/functions/recall.ts | 16 +- .../server/service/client/index.test.ts | 39 ++- .../server/service/client/index.ts | 26 +- .../server/service/index.ts | 5 +- .../service/knowledge_base_service/index.ts | 233 ++++++++++++++---- 6 files changed, 244 insertions(+), 76 deletions(-) diff --git a/x-pack/plugins/observability_ai_assistant/server/functions/index.ts b/x-pack/plugins/observability_ai_assistant/server/functions/index.ts index b25e69c53689cf..12075a56942f6e 100644 --- a/x-pack/plugins/observability_ai_assistant/server/functions/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/functions/index.ts @@ -34,6 +34,7 @@ export const registerFunctions: ChatRegistrationFunction = async ({ resources, signal, }; + return client.getKnowledgeBaseStatus().then((response) => { const isReady = response.ready; diff --git a/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts b/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts index 5b6de5b0cc6f19..0624b2f64f970b 100644 --- a/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts +++ b/x-pack/plugins/observability_ai_assistant/server/functions/recall.ts @@ -11,20 +11,18 @@ import dedent from 'dedent'; import * as t from 'io-ts'; import { last, omit } from 'lodash'; import { lastValueFrom } from 'rxjs'; +import { FunctionRegistrationParameters } from '.'; import { MessageRole, type Message } from '../../common/types'; import { concatenateOpenAiChunks } from '../../common/utils/concatenate_openai_chunks'; import { processOpenAiStream } from '../../common/utils/process_openai_stream'; import type { ObservabilityAIAssistantClient } from '../service/client'; -import type { RegisterFunction } from '../service/types'; import { streamIntoObservable } from '../service/util/stream_into_observable'; export function registerRecallFunction({ client, registerFunction, -}: { - client: ObservabilityAIAssistantClient; - registerFunction: RegisterFunction; -}) { + resources, +}: FunctionRegistrationParameters) { registerFunction( { name: 'recall', @@ -99,6 +97,10 @@ export function registerRecallFunction({ queries, }); + resources.logger.debug(`Received ${suggestions.length} suggestions`); + + resources.logger.debug(JSON.stringify(suggestions, null, 2)); + if (suggestions.length === 0) { return { content: [] as unknown as Serializable, @@ -115,6 +117,9 @@ export function registerRecallFunction({ signal, }); + resources.logger.debug(`Received ${relevantDocuments.length} relevant documents`); + resources.logger.debug(JSON.stringify(relevantDocuments, null, 2)); + return { content: relevantDocuments as unknown as Serializable, }; @@ -254,7 +259,6 @@ async function scoreSuggestions({ }) ).pipe(processOpenAiStream(), concatenateOpenAiChunks()) ); - const scoreFunctionRequest = decodeOrThrow(scoreFunctionRequestRt)(response); const { scores } = decodeOrThrow(jsonRt.pipe(scoreFunctionArgumentsRt))( scoreFunctionRequest.message.function_call.arguments diff --git a/x-pack/plugins/observability_ai_assistant/server/service/client/index.test.ts b/x-pack/plugins/observability_ai_assistant/server/service/client/index.test.ts index 0349e5ec899f99..7cffaa64d16d31 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/client/index.test.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/client/index.test.ts @@ -77,12 +77,23 @@ describe('Observability AI Assistant service', () => { execute: jest.fn(), } as any; - const esClientMock: DeeplyMockedKeys<ElasticsearchClient> = { + const internalUserEsClientMock: DeeplyMockedKeys<ElasticsearchClient> = { search: jest.fn(), index: jest.fn(), update: jest.fn(), } as any; + const currentUserEsClientMock: DeeplyMockedKeys<ElasticsearchClient> = { + search: jest.fn().mockResolvedValue({ + hits: { + hits: [], + }, + }), + fieldCaps: jest.fn().mockResolvedValue({ + fields: [], + }), + } as any; + const knowledgeBaseServiceMock: DeeplyMockedKeys<KnowledgeBaseService> = { recall: jest.fn(), } as any; @@ -91,6 +102,7 @@ describe('Observability AI Assistant service', () => { log: jest.fn(), error: jest.fn(), debug: jest.fn(), + trace: jest.fn(), } as any; const functionClientMock: DeeplyMockedKeys<ChatFunctionClient> = { @@ -108,7 +120,10 @@ describe('Observability AI Assistant service', () => { return new ObservabilityAIAssistantClient({ actionsClient: actionsClientMock, - esClient: esClientMock, + esClient: { + asInternalUser: internalUserEsClientMock, + asCurrentUser: currentUserEsClientMock, + }, knowledgeBaseService: knowledgeBaseServiceMock, logger: loggerMock, namespace: 'default', @@ -334,7 +349,7 @@ describe('Observability AI Assistant service', () => { type: StreamingChatResponseEventType.ConversationCreate, }); - expect(esClientMock.index).toHaveBeenCalledWith({ + expect(internalUserEsClientMock.index).toHaveBeenCalledWith({ index: '.kibana-observability-ai-assistant-conversations', refresh: true, document: { @@ -386,7 +401,7 @@ describe('Observability AI Assistant service', () => { }); }); - describe('when completig a conversation with an initial conversation id', () => { + describe('when completing a conversation with an initial conversation id', () => { let stream: Readable; let dataHandler: jest.Mock; @@ -402,7 +417,7 @@ describe('Observability AI Assistant service', () => { }; }); - esClientMock.search.mockImplementation(async () => { + internalUserEsClientMock.search.mockImplementation(async () => { return { hits: { hits: [ @@ -430,7 +445,7 @@ describe('Observability AI Assistant service', () => { } as any; }); - esClientMock.update.mockImplementationOnce(async () => { + internalUserEsClientMock.update.mockImplementationOnce(async () => { return {} as any; }); @@ -464,7 +479,7 @@ describe('Observability AI Assistant service', () => { type: StreamingChatResponseEventType.ConversationUpdate, }); - expect(esClientMock.update).toHaveBeenCalledWith({ + expect(internalUserEsClientMock.update).toHaveBeenCalledWith({ refresh: true, index: '.kibana-observability-ai-assistant-conversations', id: 'my-es-document-id', @@ -573,8 +588,8 @@ describe('Observability AI Assistant service', () => { }); it('does not create or update the conversation', async () => { - expect(esClientMock.index).not.toHaveBeenCalled(); - expect(esClientMock.update).not.toHaveBeenCalled(); + expect(internalUserEsClientMock.index).not.toHaveBeenCalled(); + expect(internalUserEsClientMock.update).not.toHaveBeenCalled(); }); }); @@ -816,9 +831,11 @@ describe('Observability AI Assistant service', () => { }, }); - expect(esClientMock.index).toHaveBeenCalled(); + expect(internalUserEsClientMock.index).toHaveBeenCalled(); - expect((esClientMock.index.mock.lastCall![0] as any).document.messages).toEqual([ + expect( + (internalUserEsClientMock.index.mock.lastCall![0] as any).document.messages + ).toEqual([ { '@timestamp': expect.any(String), message: { diff --git a/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts b/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts index 9423977428d664..fafb7606a27695 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts @@ -53,7 +53,10 @@ export class ObservabilityAIAssistantClient { private readonly dependencies: { actionsClient: PublicMethodsOf<ActionsClient>; namespace: string; - esClient: ElasticsearchClient; + esClient: { + asInternalUser: ElasticsearchClient; + asCurrentUser: ElasticsearchClient; + }; resources: ObservabilityAIAssistantResourceNames; logger: Logger; user: { @@ -67,7 +70,7 @@ export class ObservabilityAIAssistantClient { private getConversationWithMetaFields = async ( conversationId: string ): Promise<SearchHit<Conversation> | undefined> => { - const response = await this.dependencies.esClient.search<Conversation>({ + const response = await this.dependencies.esClient.asInternalUser.search<Conversation>({ index: this.dependencies.resources.aliases.conversations, query: { bool: { @@ -113,7 +116,7 @@ export class ObservabilityAIAssistantClient { throw notFound(); } - await this.dependencies.esClient.delete({ + await this.dependencies.esClient.asInternalUser.delete({ id: conversation._id, index: conversation._index, refresh: true, @@ -407,7 +410,7 @@ export class ObservabilityAIAssistantClient { }; this.dependencies.logger.debug(`Sending conversation to connector`); - this.dependencies.logger.debug(JSON.stringify(request, null, 2)); + this.dependencies.logger.trace(JSON.stringify(request, null, 2)); const executeResult = await this.dependencies.actionsClient.execute({ actionId: connectorId, @@ -428,17 +431,15 @@ export class ObservabilityAIAssistantClient { ? (executeResult.data as Readable) : (executeResult.data as CreateChatCompletionResponse); - if (response instanceof PassThrough) { - signal.addEventListener('abort', () => { - response.end(); - }); + if (response instanceof Readable) { + signal.addEventListener('abort', () => response.destroy()); } return response as any; }; find = async (options?: { query?: string }): Promise<{ conversations: Conversation[] }> => { - const response = await this.dependencies.esClient.search<Conversation>({ + const response = await this.dependencies.esClient.asInternalUser.search<Conversation>({ index: this.dependencies.resources.aliases.conversations, allow_no_indices: true, query: { @@ -475,7 +476,7 @@ export class ObservabilityAIAssistantClient { this.getConversationUpdateValues(new Date().toISOString()) ); - await this.dependencies.esClient.update({ + await this.dependencies.esClient.asInternalUser.update({ id: document._id, index: document._index, doc: updatedConversation, @@ -547,7 +548,7 @@ export class ObservabilityAIAssistantClient { this.getConversationUpdateValues(new Date().toISOString()) ); - await this.dependencies.esClient.update({ + await this.dependencies.esClient.asInternalUser.update({ id: document._id, index: document._index, doc: { conversation: { title } }, @@ -570,7 +571,7 @@ export class ObservabilityAIAssistantClient { this.getConversationUpdateValues(now) ); - await this.dependencies.esClient.index({ + await this.dependencies.esClient.asInternalUser.index({ index: this.dependencies.resources.aliases.conversations, document: createdConversation, refresh: true, @@ -591,6 +592,7 @@ export class ObservabilityAIAssistantClient { user: this.dependencies.user, queries, contexts, + asCurrentUser: this.dependencies.esClient.asCurrentUser, }); }; diff --git a/x-pack/plugins/observability_ai_assistant/server/service/index.ts b/x-pack/plugins/observability_ai_assistant/server/service/index.ts index 1068f1bd90cc53..3d999b090f9cf6 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/index.ts @@ -277,7 +277,10 @@ export class ObservabilityAIAssistantService { return new ObservabilityAIAssistantClient({ actionsClient: await plugins.actions.getActionsClientWithRequest(request), namespace: spaceId, - esClient: coreStart.elasticsearch.client.asInternalUser, + esClient: { + asInternalUser: coreStart.elasticsearch.client.asInternalUser, + asCurrentUser: coreStart.elasticsearch.client.asScoped(request).asCurrentUser, + }, resources: this.resourceNames, logger: this.logger, user: { diff --git a/x-pack/plugins/observability_ai_assistant/server/service/knowledge_base_service/index.ts b/x-pack/plugins/observability_ai_assistant/server/service/knowledge_base_service/index.ts index dd44675c800ca0..e4c4efb168d030 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/knowledge_base_service/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/knowledge_base_service/index.ts @@ -12,7 +12,8 @@ import type { Logger } from '@kbn/logging'; import type { TaskManagerStartContract } from '@kbn/task-manager-plugin/server'; import pLimit from 'p-limit'; import pRetry from 'p-retry'; -import { map } from 'lodash'; +import { map, orderBy } from 'lodash'; +import { encode } from 'gpt-tokenizer'; import { ELSER_MODEL_ID, INDEX_QUEUED_DOCUMENTS_TASK_ID, @@ -34,8 +35,8 @@ export interface RecalledEntry { id: string; text: string; score: number | null; - is_correction: boolean; - labels: Record<string, string>; + is_correction?: boolean; + labels?: Record<string, string>; } function isAlreadyExistsError(error: Error) { @@ -291,64 +292,204 @@ export class KnowledgeBaseService { } }; + private async recallFromKnowledgeBase({ + queries, + contexts, + namespace, + user, + modelId, + }: { + queries: string[]; + contexts?: string[]; + namespace: string; + user: { name: string }; + modelId: string; + }): Promise<RecalledEntry[]> { + const query = { + bool: { + should: queries.map((text) => ({ + text_expansion: { + 'ml.tokens': { + model_text: text, + model_id: modelId, + }, + } as unknown as QueryDslTextExpansionQuery, + })), + filter: [ + ...getAccessQuery({ + user, + namespace, + }), + ...getCategoryQuery({ contexts }), + ], + }, + }; + + const response = await this.dependencies.esClient.search< + Pick<KnowledgeBaseEntry, 'text' | 'is_correction' | 'labels'> + >({ + index: [this.dependencies.resources.aliases.kb], + query, + size: 20, + _source: { + includes: ['text', 'is_correction', 'labels'], + }, + }); + + return response.hits.hits.map((hit) => ({ + ...hit._source!, + score: hit._score!, + id: hit._id, + })); + } + + private async recallFromConnectors({ + queries, + asCurrentUser, + modelId, + }: { + queries: string[]; + asCurrentUser: ElasticsearchClient; + modelId: string; + }): Promise<RecalledEntry[]> { + const ML_INFERENCE_PREFIX = 'ml.inference.'; + + const fieldCaps = await asCurrentUser.fieldCaps({ + index: 'search*', + fields: `${ML_INFERENCE_PREFIX}*`, + allow_no_indices: true, + types: ['sparse_vector'], + filters: '-metadata,-parent', + }); + + const fieldsWithVectors = Object.keys(fieldCaps.fields).map((field) => + field.replace('_expanded.predicted_value', '').replace(ML_INFERENCE_PREFIX, '') + ); + + if (!fieldsWithVectors.length) { + return []; + } + + const esQueries = fieldsWithVectors.flatMap((field) => { + const vectorField = `${ML_INFERENCE_PREFIX}${field}_expanded.predicted_value`; + const modelField = `${ML_INFERENCE_PREFIX}${field}_expanded.model_id`; + + return queries.map((query) => { + return { + bool: { + should: [ + { + text_expansion: { + [vectorField]: { + model_text: query, + model_id: modelId, + }, + } as unknown as QueryDslTextExpansionQuery, + }, + ], + filter: [ + { + term: { + [modelField]: modelId, + }, + }, + ], + }, + }; + }); + }); + + const response = await asCurrentUser.search<unknown>({ + index: 'search-*', + query: { + bool: { + should: esQueries, + }, + }, + size: 20, + _source: { + exclude: ['_*', 'ml*'], + }, + }); + + return response.hits.hits.map((hit) => ({ + text: JSON.stringify(hit._source), + score: hit._score!, + is_correction: false, + id: hit._id, + })); + } + recall = async ({ user, queries, contexts, namespace, + asCurrentUser, }: { queries: string[]; contexts?: string[]; user: { name: string }; namespace: string; + asCurrentUser: ElasticsearchClient; }): Promise<{ entries: RecalledEntry[]; }> => { - try { - const query = { - bool: { - should: queries.map((text) => ({ - text_expansion: { - 'ml.tokens': { - model_text: text, - model_id: ELSER_MODEL_ID, - }, - } as unknown as QueryDslTextExpansionQuery, - })), - filter: [ - ...getAccessQuery({ - user, - namespace, - }), - ...getCategoryQuery({ contexts }), - ], - }, - }; - - const response = await this.dependencies.esClient.search< - Pick<KnowledgeBaseEntry, 'text' | 'is_correction' | 'labels'> - >({ - index: [this.dependencies.resources.aliases.kb], - query, - size: 20, - _source: { - includes: ['text', 'is_correction', 'labels'], - }, - }); - - return { - entries: response.hits.hits.map((hit) => ({ - ...hit._source!, - score: hit._score!, - id: hit._id, - })), - }; - } catch (error) { - if (isAlreadyExistsError(error)) { - throwKnowledgeBaseNotReady(error.body); + const modelId = ELSER_MODEL_ID; + + const [documentsFromKb, documentsFromConnectors] = await Promise.all([ + this.recallFromKnowledgeBase({ + user, + queries, + contexts, + namespace, + modelId, + }).catch((error) => { + if (isAlreadyExistsError(error)) { + throwKnowledgeBaseNotReady(error.body); + } + throw error; + }), + this.recallFromConnectors({ + asCurrentUser, + queries, + modelId, + }).catch((error) => { + this.dependencies.logger.debug('Error getting data from search indices'); + this.dependencies.logger.debug(error); + return []; + }), + ]); + + const sortedEntries = orderBy( + documentsFromKb.concat(documentsFromConnectors), + 'score', + 'desc' + ).slice(0, 20); + + const MAX_TOKENS = 4000; + + let tokenCount = 0; + + const returnedEntries: RecalledEntry[] = []; + + for (const entry of sortedEntries) { + returnedEntries.push(entry); + tokenCount += encode(entry.text).length; + if (tokenCount >= MAX_TOKENS) { + break; } - throw error; } + + if (returnedEntries.length <= sortedEntries.length) { + this.dependencies.logger.debug( + `Dropped ${sortedEntries.length - returnedEntries.length} entries because of token limit` + ); + } + + return { + entries: returnedEntries, + }; }; getEntries = async ({ From 29232d2fad4eb3fed0ad37d6a039cef27c48dd0f Mon Sep 17 00:00:00 2001 From: Gerard Soldevila <gerard.soldevila@elastic.co> Date: Fri, 22 Dec 2023 14:27:31 +0100 Subject: [PATCH 107/116] Reduce verbosity of `plugins-service` logger (#173909) ## Summary Part of https://github.com/elastic/kibana-team/issues/702 This PR aims at grouping all `Plugin "foo" is disabled` messages, as well as messages informing of plugins that are disabled because of their dependencies. --- .../src/plugins_service.test.ts | 44 +++---------------- .../src/plugins_service.ts | 23 +++++++--- 2 files changed, 25 insertions(+), 42 deletions(-) diff --git a/packages/core/plugins/core-plugins-server-internal/src/plugins_service.test.ts b/packages/core/plugins/core-plugins-server-internal/src/plugins_service.test.ts index 42f560588197d5..2185bfe13fb19d 100644 --- a/packages/core/plugins/core-plugins-server-internal/src/plugins_service.test.ts +++ b/packages/core/plugins/core-plugins-server-internal/src/plugins_service.test.ts @@ -462,40 +462,10 @@ describe('PluginsService', () => { expect(loggingSystemMock.collect(logger).info).toMatchInlineSnapshot(` Array [ Array [ - "Plugin \\"explicitly-disabled-plugin-preboot\\" is disabled.", + "The following plugins are disabled: \\"explicitly-disabled-plugin-preboot,explicitly-disabled-plugin-standard,another-explicitly-disabled-plugin-preboot,another-explicitly-disabled-plugin-standard\\".", ], Array [ - "Plugin \\"explicitly-disabled-plugin-standard\\" is disabled.", - ], - Array [ - "Plugin \\"plugin-with-missing-required-deps-preboot\\" has been disabled since the following direct or transitive dependencies are missing, disabled, or have incompatible types: [missing-plugin-preboot]", - ], - Array [ - "Plugin \\"plugin-with-missing-required-deps-standard\\" has been disabled since the following direct or transitive dependencies are missing, disabled, or have incompatible types: [missing-plugin-standard]", - ], - Array [ - "Plugin \\"plugin-with-disabled-transitive-dep-preboot\\" has been disabled since the following direct or transitive dependencies are missing, disabled, or have incompatible types: [another-explicitly-disabled-plugin-preboot]", - ], - Array [ - "Plugin \\"plugin-with-disabled-transitive-dep-standard\\" has been disabled since the following direct or transitive dependencies are missing, disabled, or have incompatible types: [another-explicitly-disabled-plugin-standard]", - ], - Array [ - "Plugin \\"another-explicitly-disabled-plugin-preboot\\" is disabled.", - ], - Array [ - "Plugin \\"another-explicitly-disabled-plugin-standard\\" is disabled.", - ], - Array [ - "Plugin \\"plugin-with-disabled-nested-transitive-dep-preboot\\" has been disabled since the following direct or transitive dependencies are missing, disabled, or have incompatible types: [plugin-with-disabled-transitive-dep-preboot]", - ], - Array [ - "Plugin \\"plugin-with-disabled-nested-transitive-dep-standard\\" has been disabled since the following direct or transitive dependencies are missing, disabled, or have incompatible types: [plugin-with-disabled-transitive-dep-standard]", - ], - Array [ - "Plugin \\"plugin-with-missing-nested-dep-preboot\\" has been disabled since the following direct or transitive dependencies are missing, disabled, or have incompatible types: [plugin-with-missing-required-deps-preboot]", - ], - Array [ - "Plugin \\"plugin-with-missing-nested-dep-standard\\" has been disabled since the following direct or transitive dependencies are missing, disabled, or have incompatible types: [plugin-with-missing-required-deps-standard]", + "Plugins \\"plugin-with-missing-required-deps-preboot,plugin-with-missing-required-deps-standard,plugin-with-disabled-transitive-dep-preboot,plugin-with-disabled-transitive-dep-standard,plugin-with-disabled-nested-transitive-dep-preboot,plugin-with-disabled-nested-transitive-dep-standard,plugin-with-missing-nested-dep-preboot,plugin-with-missing-nested-dep-standard\\" have been disabled since the following direct or transitive dependencies are missing, disabled, or have incompatible types: [missing-plugin-preboot,missing-plugin-standard,another-explicitly-disabled-plugin-preboot,another-explicitly-disabled-plugin-standard,plugin-with-disabled-transitive-dep-preboot,plugin-with-disabled-transitive-dep-standard,plugin-with-missing-required-deps-preboot,plugin-with-missing-required-deps-standard].", ], ] `); @@ -538,12 +508,12 @@ describe('PluginsService', () => { await pluginsService.preboot(prebootDeps); expect(loggingSystemMock.collect(logger).info).toMatchInlineSnapshot(` - Array [ Array [ - "Plugin \\"plugin-with-missing-required-deps-preboot\\" has been disabled since the following direct or transitive dependencies are missing, disabled, or have incompatible types: [missing-plugin-preboot]", - ], - ] - `); + Array [ + "Plugins \\"plugin-with-missing-required-deps-preboot\\" have been disabled since the following direct or transitive dependencies are missing, disabled, or have incompatible types: [missing-plugin-preboot].", + ], + ] + `); }); }); diff --git a/packages/core/plugins/core-plugins-server-internal/src/plugins_service.ts b/packages/core/plugins/core-plugins-server-internal/src/plugins_service.ts index 03327b1d7be522..a5f7bfaef7d732 100644 --- a/packages/core/plugins/core-plugins-server-internal/src/plugins_service.ts +++ b/packages/core/plugins/core-plugins-server-internal/src/plugins_service.ts @@ -327,6 +327,10 @@ export class PluginsService } // Add the plugins to the Plugin System if enabled and its dependencies are met + const disabledPlugins = []; + const disabledDependants = []; + const disabledDependantsCauses = new Set<string>(); + for (const [pluginName, { plugin, isEnabled }] of pluginEnableStatuses) { this.validatePluginDependencies(plugin, pluginEnableStatuses); @@ -339,17 +343,26 @@ export class PluginsService this.standardPluginsSystem.addPlugin(plugin); } } else if (isEnabled) { - this.log.info( - `Plugin "${pluginName}" has been disabled since the following direct or transitive dependencies are missing, disabled, or have incompatible types: [${pluginEnablement.missingOrIncompatibleDependencies.join( - ', ' - )}]` + disabledDependants.push(pluginName); + pluginEnablement.missingOrIncompatibleDependencies.forEach((dependency) => + disabledDependantsCauses.add(dependency) ); } else { - this.log.info(`Plugin "${pluginName}" is disabled.`); + disabledPlugins.push(pluginName); } } this.log.debug(`Discovered ${pluginEnableStatuses.size} plugins.`); + if (disabledPlugins.length) { + this.log.info(`The following plugins are disabled: "${disabledPlugins}".`); + } + if (disabledDependants.length) { + this.log.info( + `Plugins "${disabledDependants}" have been disabled since the following direct or transitive dependencies are missing, disabled, or have incompatible types: [${Array.from( + disabledDependantsCauses + )}].` + ); + } } /** Throws an error if the plugin's dependencies are invalid. */ From f8100a8f80dc957ad574d9570f1781ba148990fb Mon Sep 17 00:00:00 2001 From: Coen Warmer <coen.warmer@gmail.com> Date: Fri, 22 Dec 2023 15:11:55 +0100 Subject: [PATCH 108/116] Add generativeAIForObservability feature for stack connectors (#173826) Resolves https://github.com/elastic/obs-ai-assistant-team/issues/126 ## Summary This adds a a feature id called `generativeAIForObservability` and adds it to the OpenAI connector. That way the Add Connector Flyout can show only the connectors Observability currently supports. https://github.com/elastic/kibana/assets/535564/378beef1-50de-44c4-9a06-c35bbf5680d8 --- .../actions/common/connector_feature_config.ts | 15 +++++++++++++++ .../public/components/chat/welcome_message.tsx | 3 ++- .../server/connector_types/openai/index.ts | 10 ++++++++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/actions/common/connector_feature_config.ts b/x-pack/plugins/actions/common/connector_feature_config.ts index 61a67087da9fad..fb61ff35da6b7d 100644 --- a/x-pack/plugins/actions/common/connector_feature_config.ts +++ b/x-pack/plugins/actions/common/connector_feature_config.ts @@ -26,6 +26,7 @@ export const CasesConnectorFeatureId = 'cases'; export const UptimeConnectorFeatureId = 'uptime'; export const SecurityConnectorFeatureId = 'siem'; export const GenerativeAIConnectorFeatureId = 'generativeAI'; +export const GenerativeAIForObservabilityConnectorFeatureId = 'generativeAIForObservability'; const compatibilityGenerativeAI = i18n.translate( 'xpack.actions.availableConnectorFeatures.compatibility.generativeAI', @@ -34,6 +35,13 @@ const compatibilityGenerativeAI = i18n.translate( } ); +const compatibilityGenerativeAIForObservability = i18n.translate( + 'xpack.actions.availableConnectorFeatures.compatibility.generativeAIForObservability', + { + defaultMessage: 'Generative AI For Observability', + } +); + const compatibilityAlertingRules = i18n.translate( 'xpack.actions.availableConnectorFeatures.compatibility.alertingRules', { @@ -86,12 +94,19 @@ export const GenerativeAIFeature: ConnectorFeatureConfig = { compatibility: compatibilityGenerativeAI, }; +export const GenerativeAIForObservabilityFeature: ConnectorFeatureConfig = { + id: GenerativeAIForObservabilityConnectorFeatureId, + name: compatibilityGenerativeAIForObservability, + compatibility: compatibilityGenerativeAIForObservability, +}; + const AllAvailableConnectorFeatures = { [AlertingConnectorFeature.id]: AlertingConnectorFeature, [CasesConnectorFeature.id]: CasesConnectorFeature, [UptimeConnectorFeature.id]: UptimeConnectorFeature, [SecuritySolutionFeature.id]: SecuritySolutionFeature, [GenerativeAIFeature.id]: GenerativeAIFeature, + [GenerativeAIForObservabilityFeature.id]: GenerativeAIForObservabilityFeature, }; export function areValidFeatures(ids: string[]) { diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/welcome_message.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/welcome_message.tsx index bae4cf0d5a92ee..bf514691f7d930 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/welcome_message.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/welcome_message.tsx @@ -17,6 +17,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import type { ActionConnector } from '@kbn/triggers-actions-ui-plugin/public'; +import { GenerativeAIForObservabilityConnectorFeatureId } from '@kbn/actions-plugin/common'; import type { UseKnowledgeBaseResult } from '../../hooks/use_knowledge_base'; import type { UseGenAIConnectorsResult } from '../../hooks/use_genai_connectors'; import ctaImage from '../../assets/elastic_ai_assistant.png'; @@ -121,7 +122,7 @@ export function WelcomeMessage({ {connectorFlyoutOpen ? ( <ConnectorFlyout - featureId="generativeAI" + featureId={GenerativeAIForObservabilityConnectorFeatureId} onConnectorCreated={onConnectorCreated} onClose={() => setConnectorFlyoutOpen(false)} /> diff --git a/x-pack/plugins/stack_connectors/server/connector_types/openai/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/openai/index.ts index 9184b14b4f9c75..6852a83a9ee3f0 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/openai/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/openai/index.ts @@ -10,7 +10,10 @@ import { SubActionConnectorType, ValidatorType, } from '@kbn/actions-plugin/server/sub_action_framework/types'; -import { GenerativeAIConnectorFeatureId } from '@kbn/actions-plugin/common'; +import { + GenerativeAIConnectorFeatureId, + GenerativeAIForObservabilityConnectorFeatureId, +} from '@kbn/actions-plugin/common'; import { urlAllowListValidator } from '@kbn/actions-plugin/server'; import { ValidatorServices } from '@kbn/actions-plugin/server/types'; import { assertURL } from '@kbn/actions-plugin/server/sub_action_framework/helpers/validators'; @@ -33,7 +36,10 @@ export const getConnectorType = (): SubActionConnectorType<Config, Secrets> => ( secrets: SecretsSchema, }, validators: [{ type: ValidatorType.CONFIG, validator: configValidator }], - supportedFeatureIds: [GenerativeAIConnectorFeatureId], + supportedFeatureIds: [ + GenerativeAIConnectorFeatureId, + GenerativeAIForObservabilityConnectorFeatureId, + ], minimumLicenseRequired: 'enterprise' as const, renderParameterTemplates, }); From fb68236c6393659395cb9d29f16e87ddb220ad7c Mon Sep 17 00:00:00 2001 From: Julia Rechkunova <julia.rechkunova@elastic.co> Date: Fri, 22 Dec 2023 15:26:43 +0100 Subject: [PATCH 109/116] [Discover] Unskip histogram tests (#173910) - Closes https://github.com/elastic/kibana/issues/173586 150x https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4670 --- test/functional/apps/discover/group1/_discover_histogram.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/functional/apps/discover/group1/_discover_histogram.ts b/test/functional/apps/discover/group1/_discover_histogram.ts index bdaf14fca96e46..72ad1854a605ed 100644 --- a/test/functional/apps/discover/group1/_discover_histogram.ts +++ b/test/functional/apps/discover/group1/_discover_histogram.ts @@ -33,8 +33,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const log = getService('log'); const queryBar = getService('queryBar'); - // FLAKY: https://github.com/elastic/kibana/issues/173586 - describe.skip('discover histogram', function describeIndexTests() { + describe('discover histogram', function describeIndexTests() { before(async () => { await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await esArchiver.load('test/functional/fixtures/es_archiver/long_window_logstash'); @@ -295,7 +294,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // now remove the query await queryBar.clearQuery(); - await queryBar.submitQuery(); + await queryBar.clickQuerySubmitButton(); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.discover.waitUntilSearchingHasFinished(); // check no error state expect(await PageObjects.discover.isChartVisible()).to.be(true); From 3ce865c199f054d79712baea741380c78809c42d Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin <aleh.zasypkin@elastic.co> Date: Fri, 22 Dec 2023 15:48:04 +0100 Subject: [PATCH 110/116] Bump `semver` package version to `5.7.2`. (#173918) ## Summary Bump `semver` package version to `^5.7.2` and `^7.5.4`. --- package.json | 2 +- yarn.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 998d54ad9eb79a..82c701c2771300 100644 --- a/package.json +++ b/package.json @@ -1080,7 +1080,7 @@ "rxjs": "^7.5.5", "safe-squel": "^5.12.5", "seedrandom": "^3.0.5", - "semver": "^7.5.3", + "semver": "^7.5.4", "set-value": "^4.1.0", "source-map-support": "^0.5.19", "stats-lite": "^2.2.0", diff --git a/yarn.lock b/yarn.lock index bf07d32acc0c74..349f8e8b34d9c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10020,9 +10020,9 @@ "@types/ws" "*" "@types/semver@^7", "@types/semver@^7.3.12": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" - integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== + version "7.5.3" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.3.tgz#9a726e116beb26c24f1ccd6850201e1246122e04" + integrity sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw== "@types/serve-index@^1.9.1": version "1.9.1" @@ -27142,9 +27142,9 @@ semver-diff@^3.1.1: semver "^6.3.0" "semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== semver@5.6.0: version "5.6.0" From e6d1c3d320feaffa062ef911e91222193ac73e42 Mon Sep 17 00:00:00 2001 From: Coen Warmer <coen.warmer@gmail.com> Date: Fri, 22 Dec 2023 16:56:59 +0100 Subject: [PATCH 111/116] Fix for code rendering in messages, code prompt function selecting (#173920) ## Summary Fixes code rendering in Chat items. Also fixed bug with selecting functions. --- .../public/components/chat/chat_item.tsx | 34 ++++++----- ...chat_item_content_inline_prompt_editor.tsx | 59 ++++++++++++++----- .../components/chat/chat_item_controls.tsx | 18 +++--- .../components/chat/chat_prompt_editor.tsx | 26 +++++--- .../chat/chat_prompt_editor_function.tsx | 10 +++- .../public/components/chat/chat_timeline.tsx | 4 +- .../components/chat/function_list_popover.tsx | 2 +- .../public/hooks/use_json_editor_model.ts | 16 +++-- .../get_timeline_items_from_conversation.tsx | 15 ++--- .../public/utils/safe_json_parse.ts | 14 +++++ 10 files changed, 132 insertions(+), 66 deletions(-) create mode 100644 x-pack/plugins/observability_ai_assistant/public/utils/safe_json_parse.ts diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item.tsx index fc5552d008fa7d..9f581b31795f14 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item.tsx @@ -12,7 +12,6 @@ import { EuiComment, EuiErrorBoundary, EuiPanel, - EuiSpacer, useGeneratedHtmlId, } from '@elastic/eui'; import { ChatItemActions } from './chat_item_actions'; @@ -27,7 +26,7 @@ import type { Feedback } from '../feedback_buttons'; import type { ChatActionClickHandler } from './types'; import type { TelemetryEventTypeWithPayload } from '../../analytics'; -export interface ChatItemProps extends ChatTimelineItem { +export interface ChatItemProps extends Omit<ChatTimelineItem, 'message'> { onActionClick: ChatActionClickHandler; onEditSubmit: (message: Message) => void; onFeedbackClick: (feedback: Feedback) => void; @@ -36,15 +35,19 @@ export interface ChatItemProps extends ChatTimelineItem { onStopGeneratingClick: () => void; } -const normalMessageClassName = css` - .euiCommentEvent__body { - padding: 0; - } - +const moreCompactHeaderClassName = css` .euiCommentEvent__header > .euiPanel { padding-top: 4px; padding-bottom: 4px; } +`; + +const normalMessageClassName = css` + ${moreCompactHeaderClassName} + + .euiCommentEvent__body { + padding: 0; + } /* targets .*euiTimelineItemEvent-top, makes sure text properly wraps and doesn't overflow */ > :last-child { @@ -74,12 +77,13 @@ const noPanelMessageClassName = css` export function ChatItem({ actions: { canCopy, canEdit, canGiveFeedback, canRegenerate }, content, + function_call: functionCall, + role, currentUser, display: { collapsed }, element, error, loading, - message, title, onActionClick, onEditSubmit, @@ -96,10 +100,13 @@ export function ChatItem({ const actions = [canCopy, collapsed, canCopy].filter(Boolean); const noBodyMessageClassName = css` + ${moreCompactHeaderClassName} + .euiCommentEvent__body { padding: 0; height: ${expanded ? 'fit-content' : '0px'}; overflow: hidden; + border: none; } `; @@ -132,7 +139,9 @@ export function ChatItem({ <ChatItemContentInlinePromptEditor editing={editing} loading={loading} - message={message} + functionCall={functionCall} + content={content} + role={role} onSubmit={handleInlineEditSubmit} onActionClick={onActionClick} onSendTelemetry={onSendTelemetry} @@ -147,7 +156,6 @@ export function ChatItem({ forceState={expanded ? 'open' : 'closed'} onToggle={handleToggleExpand} > - <EuiSpacer size="s" /> {contentElement} </EuiAccordion> ); @@ -155,10 +163,8 @@ export function ChatItem({ return ( <EuiComment - timelineAvatar={ - <ChatItemAvatar loading={loading} currentUser={currentUser} role={message.message.role} /> - } - username={getRoleTranslation(message.message.role)} + timelineAvatar={<ChatItemAvatar loading={loading} currentUser={currentUser} role={role} />} + username={getRoleTranslation(role)} event={title} actions={ <ChatItemActions diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_content_inline_prompt_editor.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_content_inline_prompt_editor.tsx index 05f21ba92bb629..a01032e8711c51 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_content_inline_prompt_editor.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_content_inline_prompt_editor.tsx @@ -6,6 +6,8 @@ */ import React from 'react'; +import { EuiPanel } from '@elastic/eui'; +import { css } from '@emotion/css'; import { MessageText } from '../message_panel/message_text'; import { ChatPromptEditor } from './chat_prompt_editor'; import type { Message } from '../../../common'; @@ -15,34 +17,59 @@ import type { TelemetryEventTypeWithPayload } from '../../analytics'; interface Props { editing: boolean; loading: boolean; - message: Message; + role: Message['message']['role']; + content: Message['message']['content']; + functionCall: Message['message']['function_call']; onActionClick: ChatActionClickHandler; onSendTelemetry: (eventWithPayload: TelemetryEventTypeWithPayload) => void; onSubmit: (message: Message) => void; } + +const textContainerClassName = css` + padding: 4px 0; +`; + +const editorContainerClassName = css` + padding: 12px 0; +`; + export function ChatItemContentInlinePromptEditor({ editing, loading, - message, + functionCall, + content, + role, onActionClick, onSendTelemetry, onSubmit, }: Props) { return !editing ? ( - <MessageText - content={message.message.content || ''} - loading={loading} - onActionClick={onActionClick} - /> + <EuiPanel + paddingSize="none" + hasBorder={false} + hasShadow={false} + className={textContainerClassName} + > + <MessageText content={content || ''} loading={loading} onActionClick={onActionClick} /> + </EuiPanel> ) : ( - <ChatPromptEditor - disabled={false} - hidden={false} - loading={false} - initialMessage={message} - onChangeHeight={() => {}} - onSubmit={onSubmit} - onSendTelemetry={onSendTelemetry} - /> + <EuiPanel + paddingSize="none" + hasBorder={false} + hasShadow={false} + className={editorContainerClassName} + > + <ChatPromptEditor + disabled={false} + hidden={false} + loading={false} + initialFunctionCall={functionCall} + initialContent={content} + initialRole={role} + onChangeHeight={() => {}} + onSubmit={onSubmit} + onSendTelemetry={onSendTelemetry} + /> + </EuiPanel> ); } diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_controls.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_controls.tsx index d828b0330d69c6..2d2743488f766d 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_controls.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_controls.tsx @@ -6,18 +6,17 @@ */ import React from 'react'; -import { - EuiFlexGroup, - EuiFlexItem, - EuiHorizontalRule, - EuiPanel, - EuiSpacer, - useEuiTheme, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, EuiPanel, useEuiTheme } from '@elastic/eui'; +import { css } from '@emotion/css'; import { Feedback, FeedbackButtons } from '../feedback_buttons'; import { RegenerateResponseButton } from '../buttons/regenerate_response_button'; import { StopGeneratingButton } from '../buttons/stop_generating_button'; +const containerClassName = css` + padding-top: 4px; + padding-bottom: 4px; +`; + export function ChatItemControls({ error, loading, @@ -65,9 +64,8 @@ export function ChatItemControls({ return controls ? ( <> - <EuiSpacer size="s" /> <EuiHorizontalRule margin="none" color={euiTheme.colors.lightestShade} /> - <EuiPanel hasShadow={false} paddingSize="s"> + <EuiPanel hasShadow={false} paddingSize="s" className={containerClassName}> {controls} </EuiPanel> </> diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_prompt_editor.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_prompt_editor.tsx index 4d0c2e86fc0b36..4b35d1ee11432e 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_prompt_editor.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_prompt_editor.tsx @@ -20,7 +20,9 @@ export interface ChatPromptEditorProps { disabled: boolean; hidden: boolean; loading: boolean; - initialMessage?: Message; + initialRole?: Message['message']['role']; + initialFunctionCall?: Message['message']['function_call']; + initialContent?: Message['message']['content']; onChangeHeight: (height: number) => void; onSendTelemetry: (eventWithPayload: TelemetryEventTypeWithPayload) => void; onSubmit: (message: Message) => void; @@ -30,21 +32,31 @@ export function ChatPromptEditor({ disabled, hidden, loading, - initialMessage, + initialRole, + initialFunctionCall, + initialContent, onChangeHeight, onSendTelemetry, onSubmit, }: ChatPromptEditorProps) { const containerRef = useRef<HTMLDivElement>(null); - const isFocusTrapEnabled = Boolean(initialMessage?.message); + const isFocusTrapEnabled = Boolean(initialContent || initialFunctionCall); - const [innerMessage, setInnerMessage] = useState<Message['message'] | undefined>( - initialMessage?.message + const [mode, setMode] = useState<'prompt' | 'function'>( + initialFunctionCall?.name ? 'function' : 'prompt' ); - const [mode, setMode] = useState<'prompt' | 'function'>( - initialMessage?.message.function_call?.name ? 'function' : 'prompt' + const initialInnerMessage = initialRole + ? { + role: initialRole, + content: initialContent ?? '', + ...(initialFunctionCall ? { function_call: initialFunctionCall } : {}), + } + : undefined; + + const [innerMessage, setInnerMessage] = useState<Message['message'] | undefined>( + initialInnerMessage ); const handleChangeMessageInner = (newInnerMessage: Message['message']) => { diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_prompt_editor_function.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_prompt_editor_function.tsx index b3ec4609e5d2de..33f467be26cb23 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_prompt_editor_function.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_prompt_editor_function.tsx @@ -9,6 +9,7 @@ import { CodeEditor } from '@kbn/kibana-react-plugin/public'; import { i18n } from '@kbn/i18n'; import usePrevious from 'react-use/lib/usePrevious'; import { EuiCode, EuiPanel } from '@elastic/eui'; +import { css } from '@emotion/css'; import { useJsonEditorModel } from '../../hooks/use_json_editor_model'; import { type Message, MessageRole } from '../../../common'; @@ -17,6 +18,11 @@ export interface Props { functionPayload?: string; onChange: (message: Message['message']) => void; } + +const functionNameClassName = css` + display: inline-block; +`; + export function ChatPromptEditorFunction({ functionName, functionPayload, onChange }: Props) { const [functionEditorLineCount, setFunctionEditorLineCount] = useState<number>(0); @@ -67,8 +73,8 @@ export function ChatPromptEditorFunction({ functionName, functionPayload, onChan }, [functionName, functionPayload, initialJsonString, onChange, previousPayload]); return ( - <EuiPanel paddingSize="none"> - <EuiCode>{functionName}</EuiCode> + <EuiPanel paddingSize="none" hasShadow={false} hasBorder> + <EuiCode className={functionNameClassName}>{functionName}</EuiCode> <CodeEditor aria-label={i18n.translate( 'xpack.observabilityAiAssistant.chatPromptEditor.codeEditor.payloadEditorLabel', diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_timeline.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_timeline.tsx index 8b1067064e20c5..afee49619fd248 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_timeline.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_timeline.tsx @@ -9,6 +9,7 @@ import React, { ReactNode, useMemo } from 'react'; import { css } from '@emotion/css'; import { EuiCommentList } from '@elastic/eui'; import type { AuthenticatedUser } from '@kbn/security-plugin/common'; +import { omit } from 'lodash'; import type { Feedback } from '../feedback_buttons'; import type { Message } from '../../../common'; import type { UseKnowledgeBaseResult } from '../../hooks/use_knowledge_base'; @@ -42,6 +43,7 @@ export interface ChatTimelineItem currentUser?: Pick<AuthenticatedUser, 'username' | 'full_name'>; error?: any; message: Message; + functionCall?: Message['message']['function_call']; } export interface ChatTimelineProps { @@ -128,7 +130,7 @@ export function ChatTimeline({ <ChatItem // use index, not id to prevent unmounting of component when message is persisted key={index} - {...item} + {...omit(item, 'message')} onActionClick={onActionClick} onFeedbackClick={(feedback) => { onFeedback(item.message, feedback); diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/function_list_popover.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/function_list_popover.tsx index fdc3171ae03cfe..e3c5f27e7bfe76 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/function_list_popover.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/function_list_popover.tsx @@ -180,7 +180,7 @@ export function FunctionListPopover({ }} singleSelection onChange={(options) => { - const selectedFunction = options.filter((fn) => fn.checked !== 'off'); + const selectedFunction = options.filter((fn) => !('checked' in fn)); if (selectedFunction && selectedFunction.length === 1) { handleSelectFunction({ ...selectedFunction[0], checked: 'on' }); } diff --git a/x-pack/plugins/observability_ai_assistant/public/hooks/use_json_editor_model.ts b/x-pack/plugins/observability_ai_assistant/public/hooks/use_json_editor_model.ts index 44122614abd5da..230d0065e29c3b 100644 --- a/x-pack/plugins/observability_ai_assistant/public/hooks/use_json_editor_model.ts +++ b/x-pack/plugins/observability_ai_assistant/public/hooks/use_json_editor_model.ts @@ -4,10 +4,11 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { useEffect, useMemo, useState } from 'react'; import { monaco } from '@kbn/monaco'; -import { useMemo } from 'react'; import { createInitializedObject } from '../utils/create_initialized_object'; import { useObservabilityAIAssistantChatService } from './use_observability_ai_assistant_chat_service'; +import { safeJsonParse } from '../utils/safe_json_parse'; const { editor, languages, Uri } = monaco; @@ -25,6 +26,13 @@ export const useJsonEditorModel = ({ const functionDefinition = chatService.getFunctions().find((func) => func.name === functionName); + const [initialJsonValue, setInitialJsonValue] = useState<string | undefined>(initialJson); + + useEffect(() => { + setInitialJsonValue(initialJson); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [functionName]); + return useMemo(() => { if (!functionDefinition) { return {}; @@ -32,8 +40,8 @@ export const useJsonEditorModel = ({ const schema = { ...functionDefinition.parameters }; - const initialJsonString = initialJson - ? initialJson + const initialJsonString = initialJsonValue + ? JSON.stringify(safeJsonParse(initialJsonValue), null, 4) // prettify the json : functionDefinition.parameters.properties ? JSON.stringify(createInitializedObject(functionDefinition.parameters), null, 4) : ''; @@ -58,5 +66,5 @@ export const useJsonEditorModel = ({ } return { model, initialJsonString }; - }, [functionDefinition, initialJson]); + }, [functionDefinition, initialJsonValue]); }; diff --git a/x-pack/plugins/observability_ai_assistant/public/utils/get_timeline_items_from_conversation.tsx b/x-pack/plugins/observability_ai_assistant/public/utils/get_timeline_items_from_conversation.tsx index e8851a7ceddd8c..2b910211ba5fd2 100644 --- a/x-pack/plugins/observability_ai_assistant/public/utils/get_timeline_items_from_conversation.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/utils/get_timeline_items_from_conversation.tsx @@ -16,14 +16,7 @@ import type { ChatTimelineItem } from '../components/chat/chat_timeline'; import { RenderFunction } from '../components/render_function'; import type { ObservabilityAIAssistantChatService } from '../types'; import { ChatState } from '../hooks/use_chat'; - -function safeParse(jsonStr: string) { - try { - return JSON.parse(jsonStr); - } catch (err) { - return jsonStr; - } -} +import { safeJsonParse } from './safe_json_parse'; function convertMessageToMarkdownCodeBlock(message: Message['message']) { let value: object; @@ -31,7 +24,7 @@ function convertMessageToMarkdownCodeBlock(message: Message['message']) { if (!message.name) { const name = message.function_call?.name; const args = message.function_call?.arguments - ? safeParse(message.function_call.arguments) + ? safeJsonParse(message.function_call.arguments) : undefined; value = { @@ -41,9 +34,9 @@ function convertMessageToMarkdownCodeBlock(message: Message['message']) { } else { const content = message.role !== MessageRole.Assistant && message.content - ? safeParse(message.content) + ? safeJsonParse(message.content) : message.content; - const data = message.data ? safeParse(message.data) : undefined; + const data = message.data ? safeJsonParse(message.data) : undefined; value = omitBy( { content, diff --git a/x-pack/plugins/observability_ai_assistant/public/utils/safe_json_parse.ts b/x-pack/plugins/observability_ai_assistant/public/utils/safe_json_parse.ts new file mode 100644 index 00000000000000..a4f2dfa5c25036 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/public/utils/safe_json_parse.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export function safeJsonParse(jsonStr: string) { + try { + return JSON.parse(jsonStr); + } catch (err) { + return jsonStr; + } +} From 151ece6b9e88ccddea1d0b0aa8cdb0a28ce74c9e Mon Sep 17 00:00:00 2001 From: Xavier Mouligneau <xavier.mouligneau@elastic.co> Date: Fri, 22 Dec 2023 11:07:08 -0500 Subject: [PATCH 112/116] [RAM] Add cases functionality for ML (#172217) ## Summary Fix -> https://github.com/elastic/kibana/issues/171150 ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/cases/common/index.ts | 1 + .../cases/public/components/app/index.tsx | 2 +- .../components/case_view_activity.tsx | 11 +--- .../components/case_view_alerts.test.tsx | 37 +++++++++-- .../case_view/components/case_view_alerts.tsx | 53 ++++++++++------ .../case_view/components/helpers.test.ts | 57 +---------------- .../case_view/components/helpers.ts | 33 ---------- .../user_actions/comment/show_alert.test.tsx | 24 +++++++- .../user_actions/comment/show_alert.tsx | 18 ++++-- .../public/components/user_actions/types.ts | 4 +- .../cases/public/containers/api.test.tsx | 36 ++++++++--- x-pack/plugins/cases/public/containers/api.ts | 43 ++++++++++--- .../cases/public/containers/constants.ts | 4 +- .../plugins/cases/public/containers/types.ts | 17 ++++++ .../containers/use_get_feature_ids.test.tsx | 26 ++++++-- .../public/containers/use_get_feature_ids.tsx | 61 ++++++++++++++++--- .../alert_actions.tsx | 16 +++-- .../register_alerts_table_configuration.tsx | 10 +++ x-pack/plugins/ml/tsconfig.json | 1 + .../get_alerts_table_configuration.tsx | 1 + .../alert_table_config_registry.test.ts | 53 +++++++++++++++- .../alert_table_config_registry.ts | 15 +++++ .../sections/alerts_table/alerts_table.tsx | 6 +- .../sections/alerts_table/cases/cell.tsx | 4 +- .../cases/use_case_view_navigation.test.ts | 17 ++++++ .../cases/use_case_view_navigation.ts | 12 ++-- .../sections/alerts_table/types.ts | 1 + .../common/lib/kibana/kibana_react.mock.ts | 1 + .../triggers_actions_ui/public/types.ts | 2 + 29 files changed, 385 insertions(+), 181 deletions(-) diff --git a/x-pack/plugins/cases/common/index.ts b/x-pack/plugins/cases/common/index.ts index fc32ee0d360b2f..ead81710c451db 100644 --- a/x-pack/plugins/cases/common/index.ts +++ b/x-pack/plugins/cases/common/index.ts @@ -37,6 +37,7 @@ export { CaseSeverity } from './types/domain'; export { APP_ID, + FEATURE_ID, CASES_URL, SECURITY_SOLUTION_OWNER, OBSERVABILITY_OWNER, diff --git a/x-pack/plugins/cases/public/components/app/index.tsx b/x-pack/plugins/cases/public/components/app/index.tsx index c5e4c87417a1b8..a4416959ae81ee 100644 --- a/x-pack/plugins/cases/public/components/app/index.tsx +++ b/x-pack/plugins/cases/public/components/app/index.tsx @@ -43,7 +43,7 @@ const CasesAppComponent: React.FC<CasesAppProps> = ({ useFetchAlertData: () => [false, {}], permissions: userCapabilities.generalCases, basePath: '/', - features: { alerts: { enabled: false } }, + features: { alerts: { enabled: true, sync: false } }, })} </Wrapper> ); diff --git a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.tsx b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.tsx index 0ba1f2214bfc00..1c579eaf08848e 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.tsx +++ b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.tsx @@ -89,15 +89,6 @@ export const CaseViewActivity = ({ const { data: currentUserProfile, isFetching: isLoadingCurrentUserProfile } = useGetCurrentUserProfile(); - const onShowAlertDetails = useCallback( - (alertId: string, index: string) => { - if (showAlertDetails) { - showAlertDetails(alertId, index); - } - }, - [showAlertDetails] - ); - const { onUpdateField, isLoading, loadingKey } = useOnUpdateField({ caseData, }); @@ -221,7 +212,7 @@ export const CaseViewActivity = ({ data={caseData} casesConfiguration={casesConfiguration} actionsNavigation={actionsNavigation} - onShowAlertDetails={onShowAlertDetails} + onShowAlertDetails={showAlertDetails} onUpdateField={onUpdateField} statusActionButton={ permissions.update ? ( diff --git a/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.test.tsx b/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.test.tsx index b85dbe7564cf9b..165f974e8be2e6 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.test.tsx @@ -14,6 +14,7 @@ import { createAppMockRenderer } from '../../../common/mock'; import type { CaseUI } from '../../../../common'; import { CaseViewAlerts } from './case_view_alerts'; import * as api from '../../../containers/api'; +import type { FeatureIdsResponse } from '../../../containers/types'; jest.mock('../../../containers/api'); @@ -30,6 +31,13 @@ describe('CaseUI View Page activity tab', () => { appMockRender = createAppMockRenderer(); appMockRender.coreStart.triggersActionsUi.getAlertsStateTable = getAlertsStateTableMock.mockReturnValue(<div data-test-subj="alerts-table" />); + appMockRender.coreStart.triggersActionsUi.alertsTableConfigurationRegistry.register({ + id: 'case-details-alerts-observability', + columns: [], + ruleTypeIds: ['log-threshold'], + }); + }); + afterEach(() => { jest.clearAllMocks(); }); @@ -46,7 +54,7 @@ describe('CaseUI View Page activity tab', () => { expect(getAlertsStateTableMock).toHaveBeenCalledWith({ alertsTableConfigurationRegistry: expect.anything(), configurationId: 'securitySolution-case', - featureIds: ['siem', 'observability'], + featureIds: ['siem'], id: 'case-details-alerts-securitySolution', query: { ids: { @@ -60,7 +68,13 @@ describe('CaseUI View Page activity tab', () => { it('should call the alerts table with correct props for observability', async () => { const getFeatureIdsMock = jest.spyOn(api, 'getFeatureIds'); - getFeatureIdsMock.mockResolvedValueOnce(['observability']); + getFeatureIdsMock.mockResolvedValueOnce({ + aggregations: { + consumer: { buckets: [{ doc_count: 1, key: 'observability' }] }, + producer: { buckets: [] }, + ruleTypeIds: { buckets: [{ doc_count: 1, key: 'log-threshold' }] }, + }, + } as unknown as FeatureIdsResponse); appMockRender.render( <CaseViewAlerts caseData={{ @@ -73,7 +87,7 @@ describe('CaseUI View Page activity tab', () => { await waitFor(async () => { expect(getAlertsStateTableMock).toHaveBeenCalledWith({ alertsTableConfigurationRegistry: expect.anything(), - configurationId: 'observability', + configurationId: 'case-details-alerts-observability', featureIds: ['observability'], id: 'case-details-alerts-observability', query: { @@ -86,12 +100,23 @@ describe('CaseUI View Page activity tab', () => { }); }); - it('should call the getFeatureIds with the correct registration context', async () => { + it('should call the getFeatureIds with the correct alert ID', async () => { const getFeatureIdsMock = jest.spyOn(api, 'getFeatureIds'); - appMockRender.render(<CaseViewAlerts caseData={caseData} />); + appMockRender.render( + <CaseViewAlerts + caseData={{ + ...caseData, + owner: OBSERVABILITY_OWNER, + }} + /> + ); await waitFor(async () => { expect(getFeatureIdsMock).toHaveBeenCalledWith({ - query: { registrationContext: ['matchme'] }, + query: { + ids: { + values: ['alert-id-1'], + }, + }, signal: expect.anything(), }); }); diff --git a/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.tsx b/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.tsx index 44487fe4f4a0e7..59914fcae85a26 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.tsx +++ b/x-pack/plugins/cases/public/components/case_view/components/case_view_alerts.tsx @@ -8,10 +8,12 @@ import React, { useMemo } from 'react'; import { EuiFlexItem, EuiFlexGroup, EuiProgress } from '@elastic/eui'; +import type { ValidFeatureId } from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names'; +import { AlertConsumers } from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names'; import { SECURITY_SOLUTION_OWNER } from '../../../../common/constants'; import type { CaseUI } from '../../../../common'; import { useKibana } from '../../../common/lib/kibana'; -import { getManualAlertIds, getRegistrationContextFromAlerts } from './helpers'; +import { getManualAlertIds } from './helpers'; import { useGetFeatureIds } from '../../../containers/use_get_feature_ids'; import { CaseViewAlertsEmpty } from './case_view_alerts_empty'; import { CaseViewTabs } from '../case_view_tabs'; @@ -22,34 +24,49 @@ interface CaseViewAlertsProps { export const CaseViewAlerts = ({ caseData }: CaseViewAlertsProps) => { const { triggersActionsUi } = useKibana().services; + const alertIds = getManualAlertIds(caseData.comments); const alertIdsQuery = useMemo( () => ({ ids: { - values: getManualAlertIds(caseData.comments), + values: alertIds, }, }), - [caseData.comments] + [alertIds] ); - const alertRegistrationContexts = useMemo( - () => getRegistrationContextFromAlerts(caseData.comments), - [caseData.comments] + const { isLoading: isLoadingAlertFeatureIds, data: alertData } = useGetFeatureIds( + alertIds, + caseData.owner !== SECURITY_SOLUTION_OWNER ); - const { isLoading: isLoadingAlertFeatureIds, data: alertFeatureIds } = - useGetFeatureIds(alertRegistrationContexts); - const configId = - caseData.owner === SECURITY_SOLUTION_OWNER ? `${caseData.owner}-case` : caseData.owner; + caseData.owner === SECURITY_SOLUTION_OWNER + ? `${caseData.owner}-case` + : !isLoadingAlertFeatureIds + ? triggersActionsUi.alertsTableConfigurationRegistry.getAlertConfigIdPerRuleTypes( + alertData?.ruleTypeIds ?? [] + ) + : ''; - const alertStateProps = { - alertsTableConfigurationRegistry: triggersActionsUi.alertsTableConfigurationRegistry, - configurationId: configId, - id: `case-details-alerts-${caseData.owner}`, - featureIds: alertFeatureIds ?? [], - query: alertIdsQuery, - showAlertStatusWithFlapping: caseData.owner !== SECURITY_SOLUTION_OWNER, - }; + const alertStateProps = useMemo( + () => ({ + alertsTableConfigurationRegistry: triggersActionsUi.alertsTableConfigurationRegistry, + configurationId: configId, + id: `case-details-alerts-${caseData.owner}`, + featureIds: (caseData.owner === SECURITY_SOLUTION_OWNER + ? [AlertConsumers.SIEM] + : alertData?.featureIds ?? []) as ValidFeatureId[], + query: alertIdsQuery, + showAlertStatusWithFlapping: caseData.owner !== SECURITY_SOLUTION_OWNER, + }), + [ + triggersActionsUi.alertsTableConfigurationRegistry, + configId, + caseData.owner, + alertData?.featureIds, + alertIdsQuery, + ] + ); if (alertIdsQuery.ids.values.length === 0) { return ( diff --git a/x-pack/plugins/cases/public/components/case_view/components/helpers.test.ts b/x-pack/plugins/cases/public/components/case_view/components/helpers.test.ts index fba878ef1061a0..b9905635f39441 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/helpers.test.ts +++ b/x-pack/plugins/cases/public/components/case_view/components/helpers.test.ts @@ -6,7 +6,7 @@ */ import { alertComment } from '../../../containers/mock'; -import { getManualAlertIds, getRegistrationContextFromAlerts } from './helpers'; +import { getManualAlertIds } from './helpers'; const comment = { ...alertComment, @@ -24,62 +24,7 @@ const comment3 = { alertId: ['nested1', 'nested2', 'nested3'], }; -const commentSiemSignal = { - ...alertComment, - alertId: 'alert-id-siem', - index: '.siem-signals-default-000008', -}; - -const commentIsBad = { - ...alertComment, - alertId: 'alert-id-bad', - index: 'bad-siem-signals-default-000008', -}; - -const multipleIndices = { - ...alertComment, - alertId: ['test-id-1', 'test-id-2', 'test-id-3', 'test-id-4', 'test-id-5', 'test-id-6'], - index: [ - '.internal.alerts-security.alerts-default-000001', - '.internal.alerts-observability.logs.alerts-default-000001', - '.internal.alerts-observability.uptime.alerts-default-000001', - '.internal.alerts-observability.metrics.alerts-default-000001', - '.internal.alerts-observability.apm.alerts-space2-000001', - '.internal.alerts-observability.logs.alerts-space1-000001', - ], -}; - describe('Case view helpers', () => { - describe('getRegistrationContextFromAlerts', () => { - it('returns the correct registration context', () => { - const result = getRegistrationContextFromAlerts([comment, comment2, multipleIndices]); - expect(result).toEqual([ - 'matchme', - 'another', - 'security', - 'observability.logs', - 'observability.uptime', - 'observability.metrics', - 'observability.apm', - ]); - }); - - it('dedupes contexts', () => { - const result = getRegistrationContextFromAlerts([comment, comment]); - expect(result).toEqual(['matchme']); - }); - - it('returns the correct registration when find a .siem-signals* index', () => { - const result = getRegistrationContextFromAlerts([commentSiemSignal, comment2]); - expect(result).toEqual(['security', 'another']); - }); - - it('returns empty when the index is not formatted as expected', () => { - const result = getRegistrationContextFromAlerts([commentIsBad]); - expect(result).toEqual([]); - }); - }); - describe('getManualAlertIds', () => { it('returns the alert ids', () => { const result = getManualAlertIds([comment, comment2]); diff --git a/x-pack/plugins/cases/public/components/case_view/components/helpers.ts b/x-pack/plugins/cases/public/components/case_view/components/helpers.ts index d393054e30f781..73778f0348f06e 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/helpers.ts +++ b/x-pack/plugins/cases/public/components/case_view/components/helpers.ts @@ -19,36 +19,3 @@ export const getManualAlertIds = (comments: AttachmentUI[]): string[] => { }, new Set<string>()); return Array.from(dedupeAlerts); }; - -export const getRegistrationContextFromAlerts = (comments: AttachmentUI[]): string[] => { - const dedupeRegistrationContext = comments.reduce( - (registrationContexts, comment: AttachmentUI) => { - if (comment.type === AttachmentType.alert) { - const indices = Array.isArray(comment.index) ? comment.index : [comment.index]; - indices.forEach((index) => { - // That's legacy code, we created some index alias so everything should work as expected - if (index.startsWith('.siem-signals')) { - registrationContexts.add('security'); - } else { - const registrationContext = getRegistrationContextFromIndex(index); - if (registrationContext) { - registrationContexts.add(registrationContext); - } - } - }); - return registrationContexts; - } - return registrationContexts; - }, - new Set<string>() - ); - return Array.from(dedupeRegistrationContext); -}; - -export const getRegistrationContextFromIndex = (indexName: string): string | null => { - const found = indexName.match(/\.alerts-(.*?).alerts/); - if (found && found.length > 1) { - return `${found[1]}`; - } - return null; -}; diff --git a/x-pack/plugins/cases/public/components/user_actions/comment/show_alert.test.tsx b/x-pack/plugins/cases/public/components/user_actions/comment/show_alert.test.tsx index 2e26b0f03ea82e..3fea0295740d29 100644 --- a/x-pack/plugins/cases/public/components/user_actions/comment/show_alert.test.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/comment/show_alert.test.tsx @@ -9,6 +9,7 @@ import React from 'react'; import type { ReactWrapper } from 'enzyme'; import { mount } from 'enzyme'; import { UserActionShowAlert } from './show_alert'; +import { useCaseViewNavigation, useCaseViewParams } from '../../../common/navigation'; const props = { id: 'action-id', @@ -17,12 +18,25 @@ const props = { onShowAlertDetails: jest.fn(), }; +jest.mock('../../../common/lib/kibana'); +jest.mock('../../../common/navigation/hooks'); + +const useCaseViewParamsMock = useCaseViewParams as jest.Mock; +const useCaseViewNavigationMock = useCaseViewNavigation as jest.Mock; + describe('UserActionShowAlert ', () => { let wrapper: ReactWrapper; const onShowAlertDetails = jest.fn(); + const navigateToCaseView = jest.fn(); beforeAll(() => { wrapper = mount(<UserActionShowAlert {...props} onShowAlertDetails={onShowAlertDetails} />); + useCaseViewParamsMock.mockReturnValue({ detailName: 'case-id' }); + useCaseViewNavigationMock.mockReturnValue({ navigateToCaseView }); + }); + + beforeEach(() => { + jest.clearAllMocks(); }); it('it renders', async () => { @@ -31,8 +45,16 @@ describe('UserActionShowAlert ', () => { ).toBeTruthy(); }); - it('it calls onClick', async () => { + it('it calls onShowAlertDetails onClick when is defined', async () => { wrapper.find('button[data-test-subj="comment-action-show-alert-action-id"]').simulate('click'); expect(onShowAlertDetails).toHaveBeenCalledWith('alert-id', 'alert-index'); + expect(navigateToCaseView).toBeCalledTimes(0); + }); + + it('it calls navigateToCaseView onClick when onShowAlertDetails is undefined', async () => { + wrapper = mount(<UserActionShowAlert {...{ ...props, onShowAlertDetails: undefined }} />); + wrapper.find('button[data-test-subj="comment-action-show-alert-action-id"]').simulate('click'); + expect(navigateToCaseView).toHaveBeenCalledWith({ detailName: 'case-id', tabId: 'alerts' }); + expect(onShowAlertDetails).toBeCalledTimes(0); }); }); diff --git a/x-pack/plugins/cases/public/components/user_actions/comment/show_alert.tsx b/x-pack/plugins/cases/public/components/user_actions/comment/show_alert.tsx index 48a6bff3fd5576..a0a5c7d24bec9c 100644 --- a/x-pack/plugins/cases/public/components/user_actions/comment/show_alert.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/comment/show_alert.tsx @@ -8,12 +8,14 @@ import React, { memo, useCallback } from 'react'; import { EuiToolTip, EuiButtonIcon } from '@elastic/eui'; import * as i18n from '../translations'; +import { useCaseViewNavigation, useCaseViewParams } from '../../../common/navigation'; +import { CASE_VIEW_PAGE_TABS } from '../../../../common/types'; interface UserActionShowAlertProps { id: string; alertId: string; index: string; - onShowAlertDetails: (alertId: string, index: string) => void; + onShowAlertDetails?: (alertId: string, index: string) => void; } const UserActionShowAlertComponent = ({ @@ -22,10 +24,16 @@ const UserActionShowAlertComponent = ({ index, onShowAlertDetails, }: UserActionShowAlertProps) => { - const onClick = useCallback( - () => onShowAlertDetails(alertId, index), - [alertId, index, onShowAlertDetails] - ); + const { navigateToCaseView } = useCaseViewNavigation(); + const { detailName } = useCaseViewParams(); + + const onClick = useCallback(() => { + if (onShowAlertDetails) { + onShowAlertDetails(alertId, index); + } else { + navigateToCaseView({ detailName, tabId: CASE_VIEW_PAGE_TABS.ALERTS }); + } + }, [alertId, detailName, index, navigateToCaseView, onShowAlertDetails]); return ( <EuiToolTip position="top" content={<p>{i18n.SHOW_ALERT_TOOLTIP}</p>}> diff --git a/x-pack/plugins/cases/public/components/user_actions/types.ts b/x-pack/plugins/cases/public/components/user_actions/types.ts index 8e1377c4f0f285..cafbedf9c2cb54 100644 --- a/x-pack/plugins/cases/public/components/user_actions/types.ts +++ b/x-pack/plugins/cases/public/components/user_actions/types.ts @@ -36,7 +36,7 @@ export interface UserActionTreeProps { getRuleDetailsHref?: RuleDetailsNavigation['href']; actionsNavigation?: ActionsNavigation; onRuleDetailsClick?: RuleDetailsNavigation['onClick']; - onShowAlertDetails: (alertId: string, index: string) => void; + onShowAlertDetails?: (alertId: string, index: string) => void; onUpdateField: ({ key, value, onSuccess, onError }: OnUpdateFields) => void; statusActionButton: JSX.Element | null; useFetchAlertData: UseFetchAlertData; @@ -76,7 +76,7 @@ export interface UserActionBuilderArgs { handleSaveComment: ({ id, version }: { id: string; version: string }, content: string) => void; handleDeleteComment: (id: string, successToasterTitle: string) => void; handleManageQuote: (quote: string) => void; - onShowAlertDetails: (alertId: string, index: string) => void; + onShowAlertDetails?: (alertId: string, index: string) => void; getRuleDetailsHref?: RuleDetailsNavigation['href']; onRuleDetailsClick?: RuleDetailsNavigation['onClick']; } diff --git a/x-pack/plugins/cases/public/containers/api.test.tsx b/x-pack/plugins/cases/public/containers/api.test.tsx index 5b00fabbbbf500..e2e0897d75ada4 100644 --- a/x-pack/plugins/cases/public/containers/api.test.tsx +++ b/x-pack/plugins/cases/public/containers/api.test.tsx @@ -84,7 +84,8 @@ const mockKibanaServices = KibanaServices.get as jest.Mock; jest.mock('../common/lib/kibana'); const fetchMock = jest.fn(); -mockKibanaServices.mockReturnValue({ http: { fetch: fetchMock } }); +const postMock = jest.fn(); +mockKibanaServices.mockReturnValue({ http: { fetch: fetchMock, post: postMock } }); describe('Cases API', () => { describe('deleteCases', () => { @@ -1051,22 +1052,43 @@ describe('Cases API', () => { describe('getFeatureIds', () => { beforeEach(() => { - fetchMock.mockClear(); - fetchMock.mockResolvedValue(['siem', 'observability']); + postMock.mockClear(); + postMock.mockResolvedValue({ + consumer: { + buckets: [{ key: 'observability', doc_count: 1 }], + }, + producer: { + buckets: [], + }, + ruleTypeIds: { + buckets: [{ key: 'apm.threshold', doc_count: 1 }], + }, + }); }); it('should be called with correct check url, method, signal', async () => { const resp = await getFeatureIds({ - query: { registrationContext: ['security', 'observability.logs'] }, + query: { ids: { values: ['alert_id_1', 'alert_id_2'] } }, signal: abortCtrl.signal, }); - expect(fetchMock).toHaveBeenCalledWith(`${BASE_RAC_ALERTS_API_PATH}/_feature_ids`, { - query: { registrationContext: ['security', 'observability.logs'] }, + expect(postMock).toHaveBeenCalledWith(`${BASE_RAC_ALERTS_API_PATH}/find`, { + body: '{"aggs":{"consumer":{"terms":{"field":"kibana.alert.rule.consumer","size":100}},"producer":{"terms":{"field":"kibana.alert.rule.producer","size":100}},"ruleTypeIds":{"terms":{"field":"kibana.alert.rule.rule_type_id","size":100}}},"query":{"ids":{"values":["alert_id_1","alert_id_2"]}}}', + method: 'POST', signal: abortCtrl.signal, }); - expect(resp).toEqual(['siem', 'observability']); + expect(resp).toEqual({ + consumer: { + buckets: [{ key: 'observability', doc_count: 1 }], + }, + producer: { + buckets: [], + }, + ruleTypeIds: { + buckets: [{ key: 'apm.threshold', doc_count: 1 }], + }, + }); }); }); diff --git a/x-pack/plugins/cases/public/containers/api.ts b/x-pack/plugins/cases/public/containers/api.ts index c15b41cb458a75..eeeffc6f4e4244 100644 --- a/x-pack/plugins/cases/public/containers/api.ts +++ b/x-pack/plugins/cases/public/containers/api.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { ValidFeatureId } from '@kbn/rule-data-utils'; +import { ALERT_RULE_CONSUMER, ALERT_RULE_PRODUCER, ALERT_RULE_TYPE_ID } from '@kbn/rule-data-utils'; import { BASE_RAC_ALERTS_API_PATH } from '@kbn/rule-registry-plugin/common/constants'; import type { User } from '../../common/types/domain'; import { AttachmentType } from '../../common/types/domain'; @@ -73,6 +73,7 @@ import { import type { ActionLicense, CaseUI, + FeatureIdsResponse, SingleCaseMetrics, SingleCaseMetricsFeature, UserActionUI, @@ -511,16 +512,40 @@ export const getFeatureIds = async ({ query, signal, }: { - query: { registrationContext: string[] }; + query: { + ids: { + values: string[]; + }; + }; signal?: AbortSignal; -}): Promise<ValidFeatureId[]> => { - return KibanaServices.get().http.fetch<ValidFeatureId[]>( - `${BASE_RAC_ALERTS_API_PATH}/_feature_ids`, - { - signal, +}): Promise<FeatureIdsResponse> => { + return KibanaServices.get().http.post<FeatureIdsResponse>(`${BASE_RAC_ALERTS_API_PATH}/find`, { + method: 'POST', + body: JSON.stringify({ + aggs: { + consumer: { + terms: { + field: ALERT_RULE_CONSUMER, + size: 100, + }, + }, + producer: { + terms: { + field: ALERT_RULE_PRODUCER, + size: 100, + }, + }, + ruleTypeIds: { + terms: { + field: ALERT_RULE_TYPE_ID, + size: 100, + }, + }, + }, query, - } - ); + }), + signal, + }); }; export const getCaseConnectors = async ( diff --git a/x-pack/plugins/cases/public/containers/constants.ts b/x-pack/plugins/cases/public/containers/constants.ts index 224ea2c8bd04cc..76d95a8bd03750 100644 --- a/x-pack/plugins/cases/public/containers/constants.ts +++ b/x-pack/plugins/cases/public/containers/constants.ts @@ -46,8 +46,8 @@ export const casesQueriesKeys = { license: () => [...casesQueriesKeys.connectors, 'license'] as const, tags: () => [...casesQueriesKeys.all, 'tags'] as const, categories: () => [...casesQueriesKeys.all, 'categories'] as const, - alertFeatureIds: (alertRegistrationContexts: string[]) => - [...casesQueriesKeys.alerts, 'features', alertRegistrationContexts] as const, + alertFeatureIds: (alertIds: string[]) => + [...casesQueriesKeys.alerts, 'features', alertIds] as const, configuration: (params: unknown) => [...casesQueriesKeys.all, 'configuration', params] as const, }; diff --git a/x-pack/plugins/cases/public/containers/types.ts b/x-pack/plugins/cases/public/containers/types.ts index 62a5f9299498e0..d23d18c6e7896a 100644 --- a/x-pack/plugins/cases/public/containers/types.ts +++ b/x-pack/plugins/cases/public/containers/types.ts @@ -5,4 +5,21 @@ * 2.0. */ +import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; + export * from '../../common/ui'; + +export type FeatureIdsResponse = estypes.SearchResponse< + unknown, + { + consumer: { + buckets: Array<{ key: string; doc_count: number }>; + }; + producer: { + buckets: Array<{ key: string; doc_count: number }>; + }; + ruleTypeIds: { + buckets: Array<{ key: string; doc_count: number }>; + }; + } +>; diff --git a/x-pack/plugins/cases/public/containers/use_get_feature_ids.test.tsx b/x-pack/plugins/cases/public/containers/use_get_feature_ids.test.tsx index 298abb5d133e78..9446007e367d58 100644 --- a/x-pack/plugins/cases/public/containers/use_get_feature_ids.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_feature_ids.test.tsx @@ -32,7 +32,7 @@ describe('useGetFeaturesIds', () => { it('returns the features ids correctly', async () => { const spy = jest.spyOn(api, 'getFeatureIds').mockRejectedValue([]); - const { waitForNextUpdate } = renderHook(() => useGetFeatureIds(['context1']), { + const { waitForNextUpdate } = renderHook(() => useGetFeatureIds(['alert-id-1'], true), { wrapper: appMockRender.AppWrapper, }); @@ -40,12 +40,26 @@ describe('useGetFeaturesIds', () => { await waitFor(() => { expect(spy).toHaveBeenCalledWith({ - query: { registrationContext: ['context1'] }, + query: { + ids: { + values: ['alert-id-1'], + }, + }, signal: expect.any(AbortSignal), }); }); }); + it('never call API if disable', async () => { + const spyMock = jest.spyOn(api, 'getFeatureIds'); + + renderHook(() => useGetFeatureIds(['alert-id-1'], false), { + wrapper: appMockRender.AppWrapper, + }); + + expect(spyMock).toHaveBeenCalledTimes(0); + }); + it('shows a toast error when the api return an error', async () => { (useToasts as jest.Mock).mockReturnValue({ addError }); @@ -53,7 +67,7 @@ describe('useGetFeaturesIds', () => { .spyOn(api, 'getFeatureIds') .mockRejectedValue(new Error('Something went wrong')); - const { waitForNextUpdate } = renderHook(() => useGetFeatureIds(['context1']), { + const { waitForNextUpdate } = renderHook(() => useGetFeatureIds(['alert-id-1'], true), { wrapper: appMockRender.AppWrapper, }); @@ -61,7 +75,11 @@ describe('useGetFeaturesIds', () => { await waitFor(() => { expect(spy).toHaveBeenCalledWith({ - query: { registrationContext: ['context1'] }, + query: { + ids: { + values: ['alert-id-1'], + }, + }, signal: expect.any(AbortSignal), }); expect(addError).toHaveBeenCalled(); diff --git a/x-pack/plugins/cases/public/containers/use_get_feature_ids.tsx b/x-pack/plugins/cases/public/containers/use_get_feature_ids.tsx index 2c4df495b33d15..07d52edfd319a2 100644 --- a/x-pack/plugins/cases/public/containers/use_get_feature_ids.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_feature_ids.tsx @@ -6,28 +6,75 @@ */ import { useQuery } from '@tanstack/react-query'; -import type { ValidFeatureId } from '@kbn/rule-data-utils'; +import { isValidFeatureId } from '@kbn/rule-data-utils'; +import { useMemo } from 'react'; import type { ServerError } from '../types'; import { useCasesToast } from '../common/use_cases_toast'; import * as i18n from './translations'; import { getFeatureIds } from './api'; import { casesQueriesKeys } from './constants'; +import type { FeatureIdsResponse } from './types'; -export const useGetFeatureIds = (alertRegistrationContexts: string[]) => { - const { showErrorToast } = useCasesToast(); +interface UseGetFeatureIdsResponse { + featureIds: string[]; + ruleTypeIds: string[]; +} + +const transformResponseToFeatureIds = (data: FeatureIdsResponse): UseGetFeatureIdsResponse => { + const localFeatureIds = new Set<string>(); + data?.aggregations?.consumer?.buckets?.forEach( + ({ key, doc_count: docCount }: { key: string; doc_count: number }) => { + if (docCount > 0 && isValidFeatureId(key)) { + localFeatureIds.add(key); + } + } + ); + data?.aggregations?.producer?.buckets?.forEach( + ({ key, doc_count: docCount }: { key: string; doc_count: number }) => { + if (docCount > 0 && isValidFeatureId(key)) { + localFeatureIds.add(key); + } + } + ); + const ruleTypeIds = + data?.aggregations?.ruleTypeIds?.buckets + ?.filter(({ doc_count: docCount }: { doc_count: number }) => docCount > 0) + .map(({ key }: { key: string }) => key) ?? []; - return useQuery<ValidFeatureId[], ServerError>( - casesQueriesKeys.alertFeatureIds(alertRegistrationContexts), + return { featureIds: [...localFeatureIds], ruleTypeIds }; +}; + +export const useGetFeatureIds = (alertIds: string[], enabled: boolean) => { + const { showErrorToast } = useCasesToast(); + const { data, isInitialLoading, isLoading } = useQuery< + FeatureIdsResponse, + ServerError, + UseGetFeatureIdsResponse + >( + casesQueriesKeys.alertFeatureIds(alertIds), ({ signal }) => { - const query = { registrationContext: alertRegistrationContexts }; - return getFeatureIds({ query, signal }); + return getFeatureIds({ + query: { + ids: { + values: alertIds, + }, + }, + signal, + }); }, { + select: transformResponseToFeatureIds, + enabled, onError: (error: ServerError) => { showErrorToast(error, { title: i18n.ERROR_TITLE }); }, } ); + + return useMemo( + () => ({ data, isLoading: (isInitialLoading || isLoading) && enabled }), + [data, enabled, isInitialLoading, isLoading] + ); }; export type UseGetFeatureIds = typeof useGetFeatureIds; diff --git a/x-pack/plugins/ml/public/alerting/anomaly_detection_alerts_table/alert_actions.tsx b/x-pack/plugins/ml/public/alerting/anomaly_detection_alerts_table/alert_actions.tsx index 395c4361d48813..0ba523793d86c9 100644 --- a/x-pack/plugins/ml/public/alerting/anomaly_detection_alerts_table/alert_actions.tsx +++ b/x-pack/plugins/ml/public/alerting/anomaly_detection_alerts_table/alert_actions.tsx @@ -16,19 +16,17 @@ import { import React, { useCallback, useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { CaseAttachmentsWithoutOwner } from '@kbn/cases-plugin/public'; -import { AttachmentType } from '@kbn/cases-plugin/common'; +import { AttachmentType, APP_ID as CASE_APP_ID } from '@kbn/cases-plugin/common'; import { ALERT_RULE_NAME, ALERT_RULE_UUID, ALERT_UUID } from '@kbn/rule-data-utils'; import type { AlertActionsProps } from '@kbn/triggers-actions-ui-plugin/public/types'; import { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; import { PLUGIN_ID } from '../../../common/constants/app'; import { useMlKibana } from '../../application/contexts/kibana'; -const CASES_ACTIONS_ENABLED = false; - export function AlertActions(props: AlertActionsProps) { const { alert, refresh } = props; const { cases, triggersActionsUi } = useMlKibana().services; - const casesPrivileges = cases?.helpers.canUseCases(); + const casesPrivileges = cases?.helpers.canUseCases([CASE_APP_ID]); const [isPopoverOpen, setIsPopoverOpen] = useState<boolean>(false); @@ -64,8 +62,8 @@ export function AlertActions(props: AlertActionsProps) { refresh(); }, [refresh]); - const createCaseFlyout = cases!.hooks.useCasesAddToNewCaseFlyout({ onSuccess }); - const selectCaseModal = cases!.hooks.useCasesAddToExistingCaseModal({ onSuccess }); + const createCaseFlyout = cases?.hooks?.useCasesAddToNewCaseFlyout({ onSuccess }); + const selectCaseModal = cases?.hooks?.useCasesAddToExistingCaseModal({ onSuccess }); const closeActionsPopover = () => { setIsPopoverOpen(false); @@ -76,12 +74,12 @@ export function AlertActions(props: AlertActionsProps) { }; const handleAddToNewCaseClick = () => { - createCaseFlyout.open({ attachments: caseAttachments }); + createCaseFlyout?.open({ attachments: caseAttachments }); closeActionsPopover(); }; const handleAddToExistingCaseClick = () => { - selectCaseModal.open({ getAttachments: () => caseAttachments }); + selectCaseModal?.open({ getAttachments: () => caseAttachments }); closeActionsPopover(); }; @@ -101,7 +99,7 @@ export function AlertActions(props: AlertActionsProps) { ); const actionsMenuItems = [ - ...(CASES_ACTIONS_ENABLED && casesPrivileges?.create && casesPrivileges.read + ...(casesPrivileges && casesPrivileges?.create && casesPrivileges.read ? [ <EuiContextMenuItem data-test-subj="add-to-existing-case-action" diff --git a/x-pack/plugins/ml/public/alerting/anomaly_detection_alerts_table/register_alerts_table_configuration.tsx b/x-pack/plugins/ml/public/alerting/anomaly_detection_alerts_table/register_alerts_table_configuration.tsx index 708c73572e209a..92ef8e46821d1d 100644 --- a/x-pack/plugins/ml/public/alerting/anomaly_detection_alerts_table/register_alerts_table_configuration.tsx +++ b/x-pack/plugins/ml/public/alerting/anomaly_detection_alerts_table/register_alerts_table_configuration.tsx @@ -24,11 +24,14 @@ import { ALERT_STATUS, } from '@kbn/rule-data-utils'; import type { FieldFormatsRegistry } from '@kbn/field-formats-plugin/common'; +import { APP_ID as CASE_APP_ID, FEATURE_ID as CASE_GENERAL_ID } from '@kbn/cases-plugin/common'; +import { MANAGEMENT_APP_ID } from '@kbn/deeplinks-management/constants'; import { getAlertFlyout } from './use_alerts_flyout'; import { ALERT_ANOMALY_DETECTION_JOB_ID, ALERT_ANOMALY_SCORE, ALERT_ANOMALY_TIMESTAMP, + ML_ALERT_TYPES, } from '../../../common/constants/alerts'; import { getAlertFormatters, getRenderCellValue } from './render_cell_value'; import { AlertActions } from './alert_actions'; @@ -119,6 +122,12 @@ export function registerAlertsTableConfiguration( const config: AlertsTableConfigurationRegistry = { id: ML_ALERTS_CONFIG_ID, + cases: { + appId: MANAGEMENT_APP_ID, + featureId: CASE_GENERAL_ID, + owner: [CASE_APP_ID], + syncAlerts: false, + }, columns, useInternalFlyout: getAlertFlyout(columns, getAlertFormatters(fieldFormats)), getRenderCellValue: getRenderCellValue(fieldFormats), @@ -128,6 +137,7 @@ export function registerAlertsTableConfiguration( return <AlertActions {...props} />; }, }), + ruleTypeIds: [ML_ALERT_TYPES.ANOMALY_DETECTION], }; triggersActionsUi.alertsTableConfigurationRegistry.register(config); diff --git a/x-pack/plugins/ml/tsconfig.json b/x-pack/plugins/ml/tsconfig.json index f1383ef078c89f..6b6deb51c3c9a1 100644 --- a/x-pack/plugins/ml/tsconfig.json +++ b/x-pack/plugins/ml/tsconfig.json @@ -113,5 +113,6 @@ "@kbn/securitysolution-ecs", "@kbn/ml-data-view-utils", "@kbn/ml-creation-wizard-utils", + "@kbn/deeplinks-management", ], } diff --git a/x-pack/plugins/observability/public/components/alerts_table/get_alerts_table_configuration.tsx b/x-pack/plugins/observability/public/components/alerts_table/get_alerts_table_configuration.tsx index 7a88f9b90dc0bb..38eb92c2ff2674 100644 --- a/x-pack/plugins/observability/public/components/alerts_table/get_alerts_table_configuration.tsx +++ b/x-pack/plugins/observability/public/components/alerts_table/get_alerts_table_configuration.tsx @@ -54,4 +54,5 @@ export const getAlertsTableConfiguration = ( const { header, body, footer } = useGetAlertFlyoutComponents(observabilityRuleTypeRegistry); return { header, body, footer }; }, + ruleTypeIds: observabilityRuleTypeRegistry.list(), }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/alert_table_config_registry.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/alert_table_config_registry.test.ts index 1a28783239fb9b..e3d8331204f5ae 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/alert_table_config_registry.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/alert_table_config_registry.test.ts @@ -11,10 +11,11 @@ export const ExpressionComponent: React.FunctionComponent = () => { return null; }; -const getTestAlertTableConfig = (id?: string, iconClass?: string) => { +const getTestAlertTableConfig = (id?: string, ruleTypeIds?: string[]) => { return { id: id || 'test-alert-table-config', columns: [], + ...(ruleTypeIds ? { ruleTypeIds } : {}), }; }; @@ -131,3 +132,53 @@ describe('update()', () => { ); }); }); + +describe('getAlertConfigIdPerRuleTypes()', () => { + const alertTableConfigRegistry = new AlertTableConfigRegistry(); + beforeAll(() => { + alertTableConfigRegistry.register( + getTestAlertTableConfig('ml-alerts-table', ['xpack-ml-anomaly']) + ); + alertTableConfigRegistry.register( + getTestAlertTableConfig('o11y-alerts-table', [ + 'o11y-custom-threshold', + 'o11y-apm-threshold', + 'o11y-log-threshold', + 'o11y-metric-threshold', + ]) + ); + alertTableConfigRegistry.register(getTestAlertTableConfig('security-alerts-table', [])); + }); + + test('should return a config ID if match one ruleTypeId match with a configuration', () => { + const configId = alertTableConfigRegistry.getAlertConfigIdPerRuleTypes(['xpack-ml-anomaly']); + expect(configId).toEqual('ml-alerts-table'); + }); + + test('should return a config ID if more that one ruleTypeId match with a configuration', () => { + const configId = alertTableConfigRegistry.getAlertConfigIdPerRuleTypes([ + 'o11y-apm-threshold', + 'o11y-metric-threshold', + ]); + expect(configId).toEqual('o11y-alerts-table'); + }); + + test('should return the generic config ID if more that one ruleTypeId match with more than one configuration', () => { + const configId = alertTableConfigRegistry.getAlertConfigIdPerRuleTypes([ + 'o11y-apm-threshold', + 'o11y-metric-threshold', + 'ml-alerts-table', + ]); + expect(configId).toEqual('stackAlerts-generic-alert-table'); + }); + + test('should return the generic config ID if empty ruleTypeIds match with a configuration', () => { + const configId = alertTableConfigRegistry.getAlertConfigIdPerRuleTypes([]); + expect(configId).toEqual('stackAlerts-generic-alert-table'); + }); + + test('should return the generic config ID if an unknown ruleTypeId match with NO configuration', () => { + const configId = alertTableConfigRegistry.getAlertConfigIdPerRuleTypes(['unknown-threshold']); + expect(configId).toEqual('stackAlerts-generic-alert-table'); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/alert_table_config_registry.ts b/x-pack/plugins/triggers_actions_ui/public/application/alert_table_config_registry.ts index 42b10da236e166..6d5ddc28303fb3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/alert_table_config_registry.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/alert_table_config_registry.ts @@ -7,6 +7,7 @@ import { i18n } from '@kbn/i18n'; import { noop } from 'lodash'; +import { ALERT_TABLE_GENERIC_CONFIG_ID } from '../../common/alert_config'; import { AlertsTableConfigurationRegistry, AlertsTableConfigurationRegistryWithActions, @@ -91,4 +92,18 @@ export class AlertTableConfigRegistry { this.objectTypes.set(id, objectType); return this.objectTypes.get(id)!; } + + public getAlertConfigIdPerRuleTypes(ruleTypeIds: string[]): string { + const alertConfigs: string[] = []; + Array.from(this.objectTypes).forEach(([id, objectType]) => { + if (ruleTypeIds.every((ruleTypeId) => objectType.ruleTypeIds?.includes(ruleTypeId))) { + alertConfigs.push(id); + } + }); + if (alertConfigs.length === 1) { + return alertConfigs[0]; + } + // If there is more than one, we will return the generic alert configuration id + return ALERT_TABLE_GENERIC_CONFIG_ID; + } } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx index ed15fe62faa44e..5c6cd492b6f882 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/alerts_table.tsx @@ -159,7 +159,7 @@ const AlertsTable: React.FunctionComponent<AlertsTableProps> = (props: AlertsTab useActionsColumn({ options: props.alertsTableConfiguration.useActionsColumn, }); - + const casesConfig = props.alertsTableConfiguration.cases; const renderCellContext = props.alertsTableConfiguration.useFetchPageContext?.({ alerts, columns: props.columns, @@ -174,7 +174,7 @@ const AlertsTable: React.FunctionComponent<AlertsTableProps> = (props: AlertsTab clearSelection, } = useBulkActions({ alerts, - casesConfig: props.alertsTableConfiguration.cases, + casesConfig, query: props.query, useBulkActionsConfig: props.alertsTableConfiguration.useBulkActions, refresh: alertsRefresh, @@ -405,6 +405,7 @@ const AlertsTable: React.FunctionComponent<AlertsTableProps> = (props: AlertsTab cases={cases} maintenanceWindows={maintenanceWindows} showAlertStatusWithFlapping={showAlertStatusWithFlapping} + caseAppId={casesConfig?.appId} /> ); } @@ -422,6 +423,7 @@ const AlertsTable: React.FunctionComponent<AlertsTableProps> = (props: AlertsTab [ alerts, cases, + casesConfig?.appId, ecsAlertsData, isLoading, isLoadingCases, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/cases/cell.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/cases/cell.tsx index d71afe6ae0ea2c..005e6db83d1881 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/cases/cell.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/cases/cell.tsx @@ -27,8 +27,8 @@ const formatCase = (theCase: Case): CaseTooltipContentProps => ({ }); const CasesCellComponent: React.FC<CellComponentProps> = (props) => { - const { isLoading, alert, cases } = props; - const { navigateToCaseView } = useCaseViewNavigation(); + const { isLoading, alert, cases, caseAppId } = props; + const { navigateToCaseView } = useCaseViewNavigation(caseAppId); const caseIds = alert[ALERT_CASE_IDS] ?? []; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/cases/use_case_view_navigation.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/cases/use_case_view_navigation.test.ts index 49cb26dbe9d97a..904a8cae4eec79 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/cases/use_case_view_navigation.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/cases/use_case_view_navigation.test.ts @@ -41,4 +41,21 @@ describe('useCaseViewNavigation', () => { }); }); }); + + it('calls navigateToApp with correct arguments and bypass current app id', () => { + const { result, waitFor } = renderHook(() => useCaseViewNavigation('superAppId'), { + wrapper: appMockRender.AppWrapper, + }); + + act(() => { + result.current.navigateToCaseView({ caseId: 'test-id' }); + }); + + waitFor(() => { + expect(navigateToApp).toHaveBeenCalledWith('superAppId', { + deepLinkId: 'cases', + path: '/test-id', + }); + }); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/cases/use_case_view_navigation.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/cases/use_case_view_navigation.ts index 180b90448c90ed..23401994e9d21d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/cases/use_case_view_navigation.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/cases/use_case_view_navigation.ts @@ -13,26 +13,26 @@ import { useKibana } from '../../../../common/lib/kibana'; type NavigateToCaseView = (pathParams: { caseId: string }) => void; -const CASE_APP_ID = 'cases'; +const CASE_DEEP_LINK_ID = 'cases'; const generateCaseViewPath = (caseId: string): string => { return generatePath('/:caseId', { caseId }); }; -export const useCaseViewNavigation = () => { +export const useCaseViewNavigation = (appId?: string) => { const { application: { navigateToApp, currentAppId$ }, } = useKibana().services; - const appId = useObservable(currentAppId$); + const currentAppId = useObservable(currentAppId$) ?? ''; const navigateToCaseView = useCallback<NavigateToCaseView>( (pathParams) => - navigateToApp(appId ?? '', { - deepLinkId: CASE_APP_ID, + navigateToApp(appId ?? currentAppId, { + deepLinkId: CASE_DEEP_LINK_ID, path: generateCaseViewPath(pathParams.caseId), }), - [navigateToApp, appId] + [navigateToApp, appId, currentAppId] ); return { navigateToCaseView }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/types.ts index 7ab33d182148b2..6ee30b24decdc9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/types.ts @@ -29,6 +29,7 @@ export interface CellComponentProps { columnId: SystemCellId; isLoading: boolean; showAlertStatusWithFlapping: boolean; + caseAppId?: string; } export type CellComponent = React.FC<CellComponentProps>; diff --git a/x-pack/plugins/triggers_actions_ui/public/common/lib/kibana/kibana_react.mock.ts b/x-pack/plugins/triggers_actions_ui/public/common/lib/kibana/kibana_react.mock.ts index 435ca00219903d..8fa1e5591ce645 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/lib/kibana/kibana_react.mock.ts +++ b/x-pack/plugins/triggers_actions_ui/public/common/lib/kibana/kibana_react.mock.ts @@ -65,6 +65,7 @@ export const createStartServicesMock = (): TriggersAndActionsUiServices => { getActions: jest.fn(), list: jest.fn(), update: jest.fn(), + getAlertConfigIdPerRuleTypes: jest.fn(), } as AlertsTableConfigurationRegistryContract, charts: chartPluginMock.createStartContract(), isCloud: false, diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index 655a3e6de86620..b47d80a0839e50 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -690,6 +690,7 @@ export interface AlertsTableConfigurationRegistry { cases?: { featureId: string; owner: string[]; + appId?: string; syncAlerts?: boolean; }; columns: EuiDataGridColumn[]; @@ -708,6 +709,7 @@ export interface AlertsTableConfigurationRegistry { }; useFieldBrowserOptions?: UseFieldBrowserOptions; showInspectButton?: boolean; + ruleTypeIds?: string[]; useFetchPageContext?: PreFetchPageContext; } From 3e48dc0e87d306f9476f2f88f6e12e9f0885e67b Mon Sep 17 00:00:00 2001 From: Robert Oskamp <robert.oskamp@elastic.co> Date: Fri, 22 Dec 2023 17:14:58 +0100 Subject: [PATCH 113/116] Skip connectors overview serverless suite for MKI (#173931) ## Summary This PR skips the search project connectors overview test suite for MKI runs. Details about the failure in https://github.com/elastic/kibana/issues/173929 --- .../test_suites/search/connectors/connectors_overview.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/test_serverless/functional/test_suites/search/connectors/connectors_overview.ts b/x-pack/test_serverless/functional/test_suites/search/connectors/connectors_overview.ts index d5fedb8c545854..c185b3c3a0c981 100644 --- a/x-pack/test_serverless/functional/test_suites/search/connectors/connectors_overview.ts +++ b/x-pack/test_serverless/functional/test_suites/search/connectors/connectors_overview.ts @@ -16,6 +16,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const browser = getService('browser'); describe('connectors', function () { + // failsOnMKI, see https://github.com/elastic/kibana/issues/173929 + this.tags(['failsOnMKI']); before(async () => { await pageObjects.svlCommonPage.login(); await pageObjects.svlCommonNavigation.sidenav.clickLink({ From 4cdb3c9894cc9447d509260752e882d9a5cfce5c Mon Sep 17 00:00:00 2001 From: Aman <38116245+devamanv@users.noreply.github.com> Date: Sat, 23 Dec 2023 00:01:32 +0530 Subject: [PATCH 114/116] [Fleet] Add a handlebar helper to percent encode a given string (#173119) --- .../server/services/epm/agent/agent.test.ts | 55 +++++++++++++++++++ .../fleet/server/services/epm/agent/agent.ts | 16 ++++++ 2 files changed, 71 insertions(+) diff --git a/x-pack/plugins/fleet/server/services/epm/agent/agent.test.ts b/x-pack/plugins/fleet/server/services/epm/agent/agent.test.ts index 0ab728affd7517..e57b19c8478063 100644 --- a/x-pack/plugins/fleet/server/services/epm/agent/agent.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/agent/agent.test.ts @@ -384,3 +384,58 @@ paths: ); }); }); + +describe('encode', () => { + it('should correctly percent encode a string', () => { + const streamTemplate = ` + hosts: + - sqlserver://{{url_encode username}}:{{url_encode password}}@{{hosts}}`; + + const vars = { + username: { value: 'db_elastic_agent@?#:', type: 'text' }, + password: { value: 'dbelasticagent[!#@2023', type: 'password' }, + hosts: { value: 'localhost', type: 'text' }, + }; + + const output = compileTemplate(vars, streamTemplate); + expect(output).toEqual({ + hosts: ['sqlserver://db_elastic_agent%40%3F%23%3A:dbelasticagent%5B%21%23%402023@localhost'], + }); + }); + + it('should correctly encode parts of the URI of the form domain\\username', () => { + const streamTemplate = ` + hosts: + - sqlserver://{{url_encode username}}:{{url_encode password}}@{{hosts}}`; + + const vars = { + username: { value: 'domain\\username', type: 'text' }, + password: { value: 'dbelasticagent[!#@2023', type: 'password' }, + hosts: { value: 'localhost', type: 'text' }, + }; + + const output = compileTemplate(vars, streamTemplate); + expect(output).toEqual({ + hosts: ['sqlserver://domain%5Cusername:dbelasticagent%5B%21%23%402023@localhost'], + }); + }); + + it('should handle special characters which are not encoded by default', () => { + const streamTemplate = ` + hosts: + - sqlserver://{{url_encode username}}:{{url_encode password}}@{{hosts}}`; + + const vars = { + username: { value: 'db_elastic_agent', type: 'text' }, + password: { value: "Special Characters: ! * ( )'", type: 'password' }, + hosts: { value: 'localhost', type: 'text' }, + }; + + const output = compileTemplate(vars, streamTemplate); + expect(output).toEqual({ + hosts: [ + 'sqlserver://db_elastic_agent:Special%20Characters%3A%20%21%20%2A%20%28%20%29%27@localhost', + ], + }); + }); +}); diff --git a/x-pack/plugins/fleet/server/services/epm/agent/agent.ts b/x-pack/plugins/fleet/server/services/epm/agent/agent.ts index b58ab3e3fca0c3..abe2153bb800f0 100644 --- a/x-pack/plugins/fleet/server/services/epm/agent/agent.ts +++ b/x-pack/plugins/fleet/server/services/epm/agent/agent.ts @@ -140,6 +140,22 @@ function toJsonHelper(value: any) { } handlebars.registerHelper('to_json', toJsonHelper); +// urlEncodeHelper returns a string encoded as a URI component. +function urlEncodeHelper(input: string) { + let encodedString = encodeURIComponent(input); + // encodeURIComponent does not encode the characters -.!~*'(), known as "unreserved marks", + // which do not have a reserved purpose but are allowed in a URI "as is". So, these have are + // explicitly encoded. The following creates the sequences %27 %28 %29 %2A. Since the valid + // encoding of "*" is %2A, it is necessary to call toUpperCase() to properly encode. + encodedString = encodedString.replace( + /[!'()*]/g, + (char) => '%' + char.charCodeAt(0).toString(16).toUpperCase() + ); + + return encodedString; +} +handlebars.registerHelper('url_encode', urlEncodeHelper); + function replaceRootLevelYamlVariables(yamlVariables: { [k: string]: any }, yamlTemplate: string) { if (Object.keys(yamlVariables).length === 0 || !yamlTemplate) { return yamlTemplate; From fa47b572f3ecefc431d1327600c1e5dd804eafdf Mon Sep 17 00:00:00 2001 From: Steph Milovic <stephanie.milovic@elastic.co> Date: Fri, 22 Dec 2023 13:26:28 -0600 Subject: [PATCH 115/116] [Security solution] AI Assistant Telemetry for Knowledge Base (#173552) --- api_docs/elastic_assistant.devdocs.json | 8 +- .../alerts/settings/alerts_settings.test.tsx | 28 +- .../impl/alerts/settings/alerts_settings.tsx | 6 +- .../impl/assistant/api.test.tsx | 44 ++-- .../impl/assistant/api.tsx | 22 +- .../assistant_overlay/index.test.tsx | 1 + .../impl/assistant/helpers.test.ts | 30 +-- .../impl/assistant/helpers.ts | 16 +- .../select_system_prompt/index.test.tsx | 4 + .../quick_prompts/quick_prompts.test.tsx | 2 +- .../assistant/quick_prompts/quick_prompts.tsx | 4 +- .../use_settings_updater.test.tsx | 56 +++- .../use_settings_updater.tsx | 18 ++ .../impl/assistant/types.ts | 4 +- .../assistant/use_conversation/index.test.tsx | 40 +++ .../impl/assistant/use_conversation/index.tsx | 16 +- .../assistant/use_send_messages/index.tsx | 8 +- .../impl/assistant_context/constants.tsx | 4 +- .../impl/assistant_context/index.tsx | 2 +- .../impl/assistant_context/types.tsx | 11 +- .../knowledge_base_settings.test.tsx | 22 +- .../knowledge_base_settings.tsx | 20 +- .../server/__mocks__/request_context.ts | 2 + .../elasticsearch_store.test.ts | 34 ++- .../elasticsearch_store.ts | 23 +- .../execute_custom_llm_chain/index.test.ts | 14 +- .../execute_custom_llm_chain/index.ts | 6 +- .../executors/openai_functions_executor.ts | 2 + .../server/lib/langchain/executors/types.ts | 4 +- .../langchain/llm/actions_client_llm.test.ts | 2 +- .../lib/telemetry/event_based_telemetry.ts | 127 +++++++++ .../elastic_assistant/server/plugin.ts | 7 + .../server/routes/evaluate/post_evaluate.ts | 17 +- .../knowledge_base/delete_knowledge_base.ts | 11 +- .../get_knowledge_base_status.ts | 5 +- .../knowledge_base/post_knowledge_base.ts | 10 +- .../post_actions_connector_execute.test.ts | 246 +++++++++++++++++- .../routes/post_actions_connector_execute.ts | 33 ++- .../schemas/post_actions_connector_execute.ts | 3 +- .../plugins/elastic_assistant/server/types.ts | 4 +- .../plugins/elastic_assistant/tsconfig.json | 2 + .../use_assistant_telemetry/index.test.tsx | 1 + .../use_assistant_telemetry/index.tsx | 1 + .../public/common/lib/telemetry/constants.ts | 1 + .../telemetry/events/ai_assistant/index.ts | 34 +++ .../telemetry/events/ai_assistant/types.ts | 12 + .../lib/telemetry/events/telemetry_events.ts | 2 + .../lib/telemetry/telemetry_client.mock.ts | 1 + .../common/lib/telemetry/telemetry_client.ts | 9 + .../public/common/lib/telemetry/types.ts | 2 + .../alert_counts/alert_counts_tool.test.ts | 8 +- .../esql_language_knowledge_base_tool.test.ts | 24 +- .../esql_language_knowledge_base_tool.ts | 4 +- .../open_and_acknowledged_alerts_tool.test.ts | 8 +- .../tests/actions/connector_types/bedrock.ts | 3 +- 55 files changed, 851 insertions(+), 177 deletions(-) create mode 100644 x-pack/plugins/elastic_assistant/server/lib/telemetry/event_based_telemetry.ts diff --git a/api_docs/elastic_assistant.devdocs.json b/api_docs/elastic_assistant.devdocs.json index 0f18338ae23fe0..8e3cf379cc34f9 100644 --- a/api_docs/elastic_assistant.devdocs.json +++ b/api_docs/elastic_assistant.devdocs.json @@ -221,10 +221,10 @@ }, { "parentPluginId": "elasticAssistant", - "id": "def-server.AssistantToolParams.assistantLangChain", + "id": "def-server.AssistantToolParams.isEnabledKnowledgeBase", "type": "boolean", "tags": [], - "label": "assistantLangChain", + "label": "isEnabledKnowledgeBase", "description": [], "path": "x-pack/plugins/elastic_assistant/server/types.ts", "deprecated": false, @@ -1546,7 +1546,7 @@ "section": "def-common.KibanaRequest", "text": "KibanaRequest" }, - "<unknown, unknown, { params: { subActionParams: { messages: { role: \"user\" | \"system\" | \"assistant\"; content: string; }[]; } & { model?: string | undefined; n?: number | undefined; stop?: string | string[] | null | undefined; temperature?: number | undefined; }; subAction: string; }; alertsIndexPattern: string | undefined; allow: string[] | undefined; allowReplacement: string[] | undefined; assistantLangChain: boolean; replacements: { [x: string]: string; } | undefined; size: number | undefined; }, any>" + "<unknown, unknown, { params: { subActionParams: { messages: { role: \"user\" | \"system\" | \"assistant\"; content: string; }[]; } & { model?: string | undefined; n?: number | undefined; stop?: string | string[] | null | undefined; temperature?: number | undefined; }; subAction: string; }; alertsIndexPattern: string | undefined; allow: string[] | undefined; allowReplacement: string[] | undefined; isEnabledKnowledgeBase: boolean; replacements: { [x: string]: string; } | undefined; size: number | undefined; }, any>" ], "path": "x-pack/plugins/elastic_assistant/server/types.ts", "deprecated": false, @@ -1876,4 +1876,4 @@ "misc": [], "objects": [] } -} \ No newline at end of file +} diff --git a/x-pack/packages/kbn-elastic-assistant/impl/alerts/settings/alerts_settings.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/alerts/settings/alerts_settings.test.tsx index beb2bd77d85127..cfdbcdc4a86b97 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/alerts/settings/alerts_settings.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/alerts/settings/alerts_settings.test.tsx @@ -19,8 +19,8 @@ describe('AlertsSettings', () => { it('updates the knowledgeBase settings when the switch is toggled', () => { const knowledgeBase: KnowledgeBaseConfig = { - alerts: false, - assistantLangChain: false, + isEnabledRAGAlerts: false, + isEnabledKnowledgeBase: false, latestAlerts: DEFAULT_LATEST_ALERTS, }; const setUpdatedKnowledgeBaseSettings = jest.fn(); @@ -36,8 +36,8 @@ describe('AlertsSettings', () => { fireEvent.click(alertsSwitch); expect(setUpdatedKnowledgeBaseSettings).toHaveBeenCalledWith({ - alerts: true, - assistantLangChain: false, + isEnabledRAGAlerts: true, + isEnabledKnowledgeBase: false, latestAlerts: DEFAULT_LATEST_ALERTS, }); }); @@ -45,8 +45,8 @@ describe('AlertsSettings', () => { it('updates the knowledgeBase settings when the alerts range slider is changed', () => { const setUpdatedKnowledgeBaseSettings = jest.fn(); const knowledgeBase: KnowledgeBaseConfig = { - alerts: true, - assistantLangChain: false, + isEnabledRAGAlerts: true, + isEnabledKnowledgeBase: false, latestAlerts: DEFAULT_LATEST_ALERTS, }; @@ -61,17 +61,17 @@ describe('AlertsSettings', () => { fireEvent.change(rangeSlider, { target: { value: '10' } }); expect(setUpdatedKnowledgeBaseSettings).toHaveBeenCalledWith({ - alerts: true, - assistantLangChain: false, + isEnabledRAGAlerts: true, + isEnabledKnowledgeBase: false, latestAlerts: 10, }); }); - it('enables the alerts range slider when knowledgeBase.alerts is true', () => { + it('enables the alerts range slider when knowledgeBase.isEnabledRAGAlerts is true', () => { const setUpdatedKnowledgeBaseSettings = jest.fn(); const knowledgeBase: KnowledgeBaseConfig = { - alerts: true, // <-- true - assistantLangChain: false, + isEnabledRAGAlerts: true, // <-- true + isEnabledKnowledgeBase: false, latestAlerts: DEFAULT_LATEST_ALERTS, }; @@ -85,11 +85,11 @@ describe('AlertsSettings', () => { expect(screen.getByTestId('alertsRange')).not.toBeDisabled(); }); - it('disables the alerts range slider when knowledgeBase.alerts is false', () => { + it('disables the alerts range slider when knowledgeBase.isEnabledRAGAlerts is false', () => { const setUpdatedKnowledgeBaseSettings = jest.fn(); const knowledgeBase: KnowledgeBaseConfig = { - alerts: false, // <-- false - assistantLangChain: false, + isEnabledRAGAlerts: false, // <-- false + isEnabledKnowledgeBase: false, latestAlerts: DEFAULT_LATEST_ALERTS, }; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/alerts/settings/alerts_settings.tsx b/x-pack/packages/kbn-elastic-assistant/impl/alerts/settings/alerts_settings.tsx index 4e9bf8d2726ea2..6895d2f595e734 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/alerts/settings/alerts_settings.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/alerts/settings/alerts_settings.tsx @@ -40,7 +40,7 @@ const AlertsSettingsComponent = ({ knowledgeBase, setUpdatedKnowledgeBaseSetting (event: EuiSwitchEvent) => { setUpdatedKnowledgeBaseSettings({ ...knowledgeBase, - alerts: event.target.checked, + isEnabledRAGAlerts: event.target.checked, }); }, [knowledgeBase, setUpdatedKnowledgeBaseSettings] @@ -58,7 +58,7 @@ const AlertsSettingsComponent = ({ knowledgeBase, setUpdatedKnowledgeBaseSetting `} > <EuiSwitch - checked={knowledgeBase.alerts} + checked={knowledgeBase.isEnabledRAGAlerts} compressed data-test-subj="alertsSwitch" label={i18n.ALERTS_LABEL} @@ -81,7 +81,7 @@ const AlertsSettingsComponent = ({ knowledgeBase, setUpdatedKnowledgeBaseSetting aria-label={i18n.ALERTS_RANGE} compressed data-test-subj="alertsRange" - disabled={!knowledgeBase.alerts} + disabled={!knowledgeBase.isEnabledRAGAlerts} id={inputRangeSliderId} max={MAX_LATEST_ALERTS} min={MIN_LATEST_ALERTS} diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.test.tsx index 9119e024adcb29..4c71c1e63f8b3e 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.test.tsx @@ -35,9 +35,9 @@ const messages: Message[] = [ { content: 'This is a test', role: 'user', timestamp: new Date().toLocaleString() }, ]; const fetchConnectorArgs: FetchConnectorExecuteAction = { - alerts: false, + isEnabledRAGAlerts: false, apiConfig, - assistantLangChain: true, + isEnabledKnowledgeBase: true, assistantStreamingEnabled: true, http: mockHttp, messages, @@ -49,13 +49,13 @@ describe('API tests', () => { }); describe('fetchConnectorExecuteAction', () => { - it('calls the internal assistant API when assistantLangChain is true', async () => { + it('calls the internal assistant API when isEnabledKnowledgeBase is true', async () => { await fetchConnectorExecuteAction(fetchConnectorArgs); expect(mockHttp.fetch).toHaveBeenCalledWith( '/internal/elastic_assistant/actions/connector/foo/_execute', { - body: '{"params":{"subActionParams":{"model":"gpt-4","messages":[{"role":"user","content":"This is a test"}],"n":1,"stop":null,"temperature":0.2},"subAction":"invokeAI"},"assistantLangChain":true}', + body: '{"params":{"subActionParams":{"model":"gpt-4","messages":[{"role":"user","content":"This is a test"}],"n":1,"stop":null,"temperature":0.2},"subAction":"invokeAI"},"isEnabledKnowledgeBase":true,"isEnabledRAGAlerts":false}', headers: { 'Content-Type': 'application/json' }, method: 'POST', signal: undefined, @@ -63,10 +63,10 @@ describe('API tests', () => { ); }); - it('calls the actions connector api with streaming when assistantStreamingEnabled is true when assistantLangChain is false', async () => { + it('calls the actions connector api with streaming when assistantStreamingEnabled is true when isEnabledKnowledgeBase is false', async () => { const testProps: FetchConnectorExecuteAction = { ...fetchConnectorArgs, - assistantLangChain: false, + isEnabledKnowledgeBase: false, }; await fetchConnectorExecuteAction(testProps); @@ -74,7 +74,7 @@ describe('API tests', () => { expect(mockHttp.fetch).toHaveBeenCalledWith( '/internal/elastic_assistant/actions/connector/foo/_execute', { - body: '{"params":{"subActionParams":{"model":"gpt-4","messages":[{"role":"user","content":"This is a test"}],"n":1,"stop":null,"temperature":0.2},"subAction":"invokeStream"},"assistantLangChain":false}', + body: '{"params":{"subActionParams":{"model":"gpt-4","messages":[{"role":"user","content":"This is a test"}],"n":1,"stop":null,"temperature":0.2},"subAction":"invokeStream"},"isEnabledKnowledgeBase":false,"isEnabledRAGAlerts":false}', method: 'POST', asResponse: true, rawResponse: true, @@ -86,7 +86,7 @@ describe('API tests', () => { it('calls the actions connector with the expected optional request parameters', async () => { const testProps: FetchConnectorExecuteAction = { ...fetchConnectorArgs, - alerts: true, + isEnabledRAGAlerts: true, alertsIndexPattern: '.alerts-security.alerts-default', allow: ['a', 'b', 'c'], allowReplacement: ['b', 'c'], @@ -99,7 +99,7 @@ describe('API tests', () => { expect(mockHttp.fetch).toHaveBeenCalledWith( '/internal/elastic_assistant/actions/connector/foo/_execute', { - body: '{"params":{"subActionParams":{"model":"gpt-4","messages":[{"role":"user","content":"This is a test"}],"n":1,"stop":null,"temperature":0.2},"subAction":"invokeAI"},"assistantLangChain":true,"alertsIndexPattern":".alerts-security.alerts-default","allow":["a","b","c"],"allowReplacement":["b","c"],"replacements":{"auuid":"real.hostname"},"size":30}', + body: '{"params":{"subActionParams":{"model":"gpt-4","messages":[{"role":"user","content":"This is a test"}],"n":1,"stop":null,"temperature":0.2},"subAction":"invokeAI"},"isEnabledKnowledgeBase":true,"isEnabledRAGAlerts":true,"alertsIndexPattern":".alerts-security.alerts-default","allow":["a","b","c"],"allowReplacement":["b","c"],"replacements":{"auuid":"real.hostname"},"size":30}', headers: { 'Content-Type': 'application/json', }, @@ -109,10 +109,10 @@ describe('API tests', () => { ); }); - it('calls the actions connector api with invoke when assistantStreamingEnabled is false when assistantLangChain is false', async () => { + it('calls the actions connector api with invoke when assistantStreamingEnabled is false when isEnabledKnowledgeBase is false', async () => { const testProps: FetchConnectorExecuteAction = { ...fetchConnectorArgs, - assistantLangChain: false, + isEnabledKnowledgeBase: false, assistantStreamingEnabled: false, }; @@ -121,7 +121,7 @@ describe('API tests', () => { expect(mockHttp.fetch).toHaveBeenCalledWith( '/internal/elastic_assistant/actions/connector/foo/_execute', { - body: '{"params":{"subActionParams":{"model":"gpt-4","messages":[{"role":"user","content":"This is a test"}],"n":1,"stop":null,"temperature":0.2},"subAction":"invokeAI"},"assistantLangChain":false}', + body: '{"params":{"subActionParams":{"model":"gpt-4","messages":[{"role":"user","content":"This is a test"}],"n":1,"stop":null,"temperature":0.2},"subAction":"invokeAI"},"isEnabledKnowledgeBase":false,"isEnabledRAGAlerts":false}', method: 'POST', headers: { 'Content-Type': 'application/json', @@ -131,11 +131,11 @@ describe('API tests', () => { ); }); - it('calls the actions connector api with invoke when assistantStreamingEnabled is true when assistantLangChain is false and alerts is true', async () => { + it('calls the actions connector api with invoke when assistantStreamingEnabled is true when isEnabledKnowledgeBase is false and isEnabledRAGAlerts is true', async () => { const testProps: FetchConnectorExecuteAction = { ...fetchConnectorArgs, - assistantLangChain: false, - alerts: true, + isEnabledKnowledgeBase: false, + isEnabledRAGAlerts: true, }; await fetchConnectorExecuteAction(testProps); @@ -143,7 +143,7 @@ describe('API tests', () => { expect(mockHttp.fetch).toHaveBeenCalledWith( '/internal/elastic_assistant/actions/connector/foo/_execute', { - body: '{"params":{"subActionParams":{"model":"gpt-4","messages":[{"role":"user","content":"This is a test"}],"n":1,"stop":null,"temperature":0.2},"subAction":"invokeAI"},"assistantLangChain":false}', + body: '{"params":{"subActionParams":{"model":"gpt-4","messages":[{"role":"user","content":"This is a test"}],"n":1,"stop":null,"temperature":0.2},"subAction":"invokeAI"},"isEnabledKnowledgeBase":false,"isEnabledRAGAlerts":true}', method: 'POST', headers: { 'Content-Type': 'application/json', @@ -168,7 +168,7 @@ describe('API tests', () => { }); const testProps: FetchConnectorExecuteAction = { ...fetchConnectorArgs, - assistantLangChain: false, + isEnabledKnowledgeBase: false, assistantStreamingEnabled: false, }; @@ -186,7 +186,7 @@ describe('API tests', () => { const testProps: FetchConnectorExecuteAction = { ...fetchConnectorArgs, - assistantLangChain: false, + isEnabledKnowledgeBase: false, }; const result = await fetchConnectorExecuteAction(testProps); @@ -205,7 +205,7 @@ describe('API tests', () => { }); const testProps: FetchConnectorExecuteAction = { ...fetchConnectorArgs, - assistantLangChain: false, + isEnabledKnowledgeBase: false, }; const result = await fetchConnectorExecuteAction(testProps); @@ -225,7 +225,7 @@ describe('API tests', () => { expect(result).toEqual({ response: API_ERROR, isStream: false, isError: true }); }); - it('returns the value of the action_input property when assistantLangChain is true, and `content` has properly prefixed and suffixed JSON with the action_input property', async () => { + it('returns the value of the action_input property when isEnabledKnowledgeBase is true, and `content` has properly prefixed and suffixed JSON with the action_input property', async () => { const response = '```json\n{"action_input": "value from action_input"}\n```'; (mockHttp.fetch as jest.Mock).mockResolvedValue({ @@ -242,7 +242,7 @@ describe('API tests', () => { }); }); - it('returns the original content when assistantLangChain is true, and `content` has properly formatted JSON WITHOUT the action_input property', async () => { + it('returns the original content when isEnabledKnowledgeBase is true, and `content` has properly formatted JSON WITHOUT the action_input property', async () => { const response = '```json\n{"some_key": "some value"}\n```'; (mockHttp.fetch as jest.Mock).mockResolvedValue({ @@ -255,7 +255,7 @@ describe('API tests', () => { expect(result).toEqual({ response, isStream: false, isError: false }); }); - it('returns the original when assistantLangChain is true, and `content` is not JSON', async () => { + it('returns the original when isEnabledKnowledgeBase is true, and `content` is not JSON', async () => { const response = 'plain text content'; (mockHttp.fetch as jest.Mock).mockResolvedValue({ diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx index f186dab22f668f..f04b99c4e46e19 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx @@ -19,11 +19,11 @@ import { import { PerformEvaluationParams } from './settings/evaluation_settings/use_perform_evaluation'; export interface FetchConnectorExecuteAction { - alerts: boolean; + isEnabledRAGAlerts: boolean; alertsIndexPattern?: string; allow?: string[]; allowReplacement?: string[]; - assistantLangChain: boolean; + isEnabledKnowledgeBase: boolean; assistantStreamingEnabled: boolean; apiConfig: Conversation['apiConfig']; http: HttpSetup; @@ -45,11 +45,11 @@ export interface FetchConnectorExecuteResponse { } export const fetchConnectorExecuteAction = async ({ - alerts, + isEnabledRAGAlerts, alertsIndexPattern, allow, allowReplacement, - assistantLangChain, + isEnabledKnowledgeBase, assistantStreamingEnabled, http, messages, @@ -82,9 +82,9 @@ export const fetchConnectorExecuteAction = async ({ // tracked here: https://github.com/elastic/security-team/issues/7363 // In part 3 I will make enhancements to langchain to introduce streaming // Once implemented, invokeAI can be removed - const isStream = assistantStreamingEnabled && !assistantLangChain && !alerts; + const isStream = assistantStreamingEnabled && !isEnabledKnowledgeBase && !isEnabledRAGAlerts; const optionalRequestParams = getOptionalRequestParams({ - alerts, + isEnabledRAGAlerts, alertsIndexPattern, allow, allowReplacement, @@ -98,7 +98,8 @@ export const fetchConnectorExecuteAction = async ({ subActionParams: body, subAction: 'invokeStream', }, - assistantLangChain, + isEnabledKnowledgeBase, + isEnabledRAGAlerts, ...optionalRequestParams, } : { @@ -106,7 +107,8 @@ export const fetchConnectorExecuteAction = async ({ subActionParams: body, subAction: 'invokeAI', }, - assistantLangChain, + isEnabledKnowledgeBase, + isEnabledRAGAlerts, ...optionalRequestParams, }; @@ -187,8 +189,8 @@ export const fetchConnectorExecuteAction = async ({ return { response: hasParsableResponse({ - alerts, - assistantLangChain, + isEnabledRAGAlerts, + isEnabledKnowledgeBase, }) ? getFormattedMessageContent(response.data) : response.data, diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.test.tsx index 972d3d9099cd05..34d56d100cbae9 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.test.tsx @@ -15,6 +15,7 @@ const assistantTelemetry = { reportAssistantInvoked, reportAssistantMessageSent: () => {}, reportAssistantQuickPrompt: () => {}, + reportAssistantSettingToggled: () => {}, }; describe('AssistantOverlay', () => { beforeEach(() => { diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.test.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.test.ts index 8cd3c1479b46b5..b176a229bcca79 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.test.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.test.ts @@ -237,7 +237,7 @@ describe('getBlockBotConversation', () => { describe('getOptionalRequestParams', () => { it('should return an empty object when alerts is false', () => { const params = { - alerts: false, // <-- false + isEnabledRAGAlerts: false, // <-- false alertsIndexPattern: 'indexPattern', allow: ['a', 'b', 'c'], allowReplacement: ['b', 'c'], @@ -252,7 +252,7 @@ describe('getBlockBotConversation', () => { it('should return the optional request params when alerts is true', () => { const params = { - alerts: true, + isEnabledRAGAlerts: true, alertsIndexPattern: 'indexPattern', allow: ['a', 'b', 'c'], allowReplacement: ['b', 'c'], @@ -273,7 +273,7 @@ describe('getBlockBotConversation', () => { it('should return (only) the optional request params that are defined when some optional params are not provided', () => { const params = { - alerts: true, + isEnabledRAGAlerts: true, allow: ['a', 'b', 'c'], // all the others are undefined }; @@ -286,37 +286,37 @@ describe('getBlockBotConversation', () => { }); describe('hasParsableResponse', () => { - it('returns true when just assistantLangChain is true', () => { + it('returns true when just isEnabledKnowledgeBase is true', () => { const result = hasParsableResponse({ - alerts: false, - assistantLangChain: true, + isEnabledRAGAlerts: false, + isEnabledKnowledgeBase: true, }); expect(result).toBe(true); }); - it('returns true when just alerts is true', () => { + it('returns true when just isEnabledRAGAlerts is true', () => { const result = hasParsableResponse({ - alerts: true, - assistantLangChain: false, + isEnabledRAGAlerts: true, + isEnabledKnowledgeBase: false, }); expect(result).toBe(true); }); - it('returns true when both assistantLangChain and alerts are true', () => { + it('returns true when both isEnabledKnowledgeBase and isEnabledRAGAlerts are true', () => { const result = hasParsableResponse({ - alerts: true, - assistantLangChain: true, + isEnabledRAGAlerts: true, + isEnabledKnowledgeBase: true, }); expect(result).toBe(true); }); - it('returns false when both assistantLangChain and alerts are false', () => { + it('returns false when both isEnabledKnowledgeBase and isEnabledRAGAlerts are false', () => { const result = hasParsableResponse({ - alerts: false, - assistantLangChain: false, + isEnabledRAGAlerts: false, + isEnabledKnowledgeBase: false, }); expect(result).toBe(false); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts index 9149d4c84ca42b..f7ea3f52c8826d 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts @@ -97,14 +97,14 @@ interface OptionalRequestParams { } export const getOptionalRequestParams = ({ - alerts, + isEnabledRAGAlerts, alertsIndexPattern, allow, allowReplacement, replacements, size, }: { - alerts: boolean; + isEnabledRAGAlerts: boolean; alertsIndexPattern?: string; allow?: string[]; allowReplacement?: string[]; @@ -118,7 +118,7 @@ export const getOptionalRequestParams = ({ const optionalSize = size ? { size } : undefined; // the settings toggle must be enabled: - if (!alerts) { + if (!isEnabledRAGAlerts) { return {}; // don't send any optional params } @@ -132,9 +132,9 @@ export const getOptionalRequestParams = ({ }; export const hasParsableResponse = ({ - alerts, - assistantLangChain, + isEnabledRAGAlerts, + isEnabledKnowledgeBase, }: { - alerts: boolean; - assistantLangChain: boolean; -}): boolean => assistantLangChain || alerts; + isEnabledRAGAlerts: boolean; + isEnabledKnowledgeBase: boolean; +}): boolean => isEnabledKnowledgeBase || isEnabledRAGAlerts; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/select_system_prompt/index.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/select_system_prompt/index.test.tsx index cb1050c895b8e0..fc62c00a997272 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/select_system_prompt/index.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/select_system_prompt/index.test.tsx @@ -48,6 +48,10 @@ const mockUseAssistantContext = { }, ], setAllSystemPrompts: jest.fn(), + knowledgeBase: { + isEnabledRAGAlerts: false, + isEnabledKnowledgeBase: false, + }, }; jest.mock('../../../../assistant_context', () => { const original = jest.requireActual('../../../../assistant_context'); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompts.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompts.test.tsx index 517d52667c45a1..46e5ecfb76f393 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompts.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompts.test.tsx @@ -26,7 +26,7 @@ const mockUseAssistantContext = { promptContexts: {}, allQuickPrompts: MOCK_QUICK_PROMPTS, knowledgeBase: { - assistantLangChain: true, + isEnabledKnowledgeBase: true, }, }; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompts.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompts.tsx index f475f052f180bb..a4731ef54f801f 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompts.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompts.tsx @@ -41,7 +41,7 @@ export const QuickPrompts: React.FC<QuickPromptsProps> = React.memo( const contextFilteredQuickPrompts = useMemo(() => { const registeredPromptContextTitles = Object.values(promptContexts).map((pc) => pc.category); // If KB is enabled, include KNOWLEDGE_BASE_CATEGORY so KB dependent quick prompts are shown - if (knowledgeBase.assistantLangChain) { + if (knowledgeBase.isEnabledKnowledgeBase) { registeredPromptContextTitles.push(KNOWLEDGE_BASE_CATEGORY); } return allQuickPrompts.filter((quickPrompt) => { @@ -54,7 +54,7 @@ export const QuickPrompts: React.FC<QuickPromptsProps> = React.memo( }); } }); - }, [allQuickPrompts, knowledgeBase.assistantLangChain, promptContexts]); + }, [allQuickPrompts, knowledgeBase.isEnabledKnowledgeBase, promptContexts]); // Overflow state const [isOverflowPopoverOpen, setIsOverflowPopoverOpen] = useState(false); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/use_settings_updater/use_settings_updater.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/use_settings_updater/use_settings_updater.test.tsx index 975e5c8e27db73..af73fa31293b3e 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/use_settings_updater/use_settings_updater.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/use_settings_updater/use_settings_updater.test.tsx @@ -33,15 +33,18 @@ const setConversationsMock = jest.fn(); const setDefaultAllowMock = jest.fn(); const setDefaultAllowReplacementMock = jest.fn(); const setKnowledgeBaseMock = jest.fn(); - +const reportAssistantSettingToggled = jest.fn(); const mockValues = { + assistantTelemetry: { reportAssistantSettingToggled }, conversations: mockConversations, allSystemPrompts: mockSystemPrompts, allQuickPrompts: mockQuickPrompts, defaultAllow: initialDefaultAllow, defaultAllowReplacement: initialDefaultAllowReplacement, knowledgeBase: { - assistantLangChain: true, + isEnabledRAGAlerts: true, + isEnabledKnowledgeBase: true, + latestAlerts: DEFAULT_LATEST_ALERTS, }, setAllQuickPrompts: setAllQuickPromptsMock, setConversations: setConversationsMock, @@ -58,8 +61,8 @@ const updatedValues = { defaultAllow: ['allow2'], defaultAllowReplacement: ['replacement2'], knowledgeBase: { - alerts: false, - assistantLangChain: false, + isEnabledRAGAlerts: false, + isEnabledKnowledgeBase: false, latestAlerts: DEFAULT_LATEST_ALERTS, }, }; @@ -73,6 +76,9 @@ jest.mock('../../../assistant_context', () => { }); describe('useSettingsUpdater', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); it('should set all state variables to their initial values when resetSettings is called', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook(() => useSettingsUpdater()); @@ -144,4 +150,46 @@ describe('useSettingsUpdater', () => { expect(setKnowledgeBaseMock).toHaveBeenCalledWith(updatedValues.knowledgeBase); }); }); + it('should track which toggles have been updated when saveSettings is called', async () => { + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => useSettingsUpdater()); + await waitForNextUpdate(); + const { setUpdatedKnowledgeBaseSettings } = result.current; + + setUpdatedKnowledgeBaseSettings(updatedValues.knowledgeBase); + + result.current.saveSettings(); + expect(reportAssistantSettingToggled).toHaveBeenCalledWith({ + isEnabledKnowledgeBase: false, + isEnabledRAGAlerts: false, + }); + }); + }); + it('should track only toggles that updated', async () => { + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => useSettingsUpdater()); + await waitForNextUpdate(); + const { setUpdatedKnowledgeBaseSettings } = result.current; + + setUpdatedKnowledgeBaseSettings({ + ...updatedValues.knowledgeBase, + isEnabledKnowledgeBase: true, + }); + result.current.saveSettings(); + expect(reportAssistantSettingToggled).toHaveBeenCalledWith({ + isEnabledRAGAlerts: false, + }); + }); + }); + it('if no toggles update, do not track anything', async () => { + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => useSettingsUpdater()); + await waitForNextUpdate(); + const { setUpdatedKnowledgeBaseSettings } = result.current; + + setUpdatedKnowledgeBaseSettings(mockValues.knowledgeBase); + result.current.saveSettings(); + expect(reportAssistantSettingToggled).not.toHaveBeenCalledWith(); + }); + }); }); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/use_settings_updater/use_settings_updater.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/use_settings_updater/use_settings_updater.tsx index 0dfd6ebe2904c4..63c9d7217e947e 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/use_settings_updater/use_settings_updater.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/use_settings_updater/use_settings_updater.tsx @@ -34,6 +34,7 @@ export const useSettingsUpdater = (): UseSettingsUpdater => { const { allQuickPrompts, allSystemPrompts, + assistantTelemetry, conversations, defaultAllow, defaultAllowReplacement, @@ -92,10 +93,27 @@ export const useSettingsUpdater = (): UseSettingsUpdater => { setAllQuickPrompts(updatedQuickPromptSettings); setAllSystemPrompts(updatedSystemPromptSettings); setConversations(updatedConversationSettings); + const didUpdateKnowledgeBase = + knowledgeBase.isEnabledKnowledgeBase !== updatedKnowledgeBaseSettings.isEnabledKnowledgeBase; + const didUpdateRAGAlerts = + knowledgeBase.isEnabledRAGAlerts !== updatedKnowledgeBaseSettings.isEnabledRAGAlerts; + if (didUpdateKnowledgeBase || didUpdateRAGAlerts) { + assistantTelemetry?.reportAssistantSettingToggled({ + ...(didUpdateKnowledgeBase + ? { isEnabledKnowledgeBase: updatedKnowledgeBaseSettings.isEnabledKnowledgeBase } + : {}), + ...(didUpdateRAGAlerts + ? { isEnabledRAGAlerts: updatedKnowledgeBaseSettings.isEnabledRAGAlerts } + : {}), + }); + } setKnowledgeBase(updatedKnowledgeBaseSettings); setDefaultAllow(updatedDefaultAllow); setDefaultAllowReplacement(updatedDefaultAllowReplacement); }, [ + assistantTelemetry, + knowledgeBase.isEnabledRAGAlerts, + knowledgeBase.isEnabledKnowledgeBase, setAllQuickPrompts, setAllSystemPrompts, setConversations, diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/types.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/types.ts index 303aae0f6ff9c4..e7cb6f79f243ad 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/types.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/types.ts @@ -17,7 +17,7 @@ export interface Prompt { } export interface KnowledgeBaseConfig { - alerts: boolean; - assistantLangChain: boolean; + isEnabledRAGAlerts: boolean; + isEnabledKnowledgeBase: boolean; latestAlerts: number; } diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_conversation/index.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_conversation/index.test.tsx index 562a252bf81110..be94a164364aa4 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_conversation/index.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_conversation/index.test.tsx @@ -36,6 +36,9 @@ const mockConvo = { }; describe('useConversation', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); it('should append a message to an existing conversation when called with valid conversationId and message', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook(() => useConversation(), { @@ -63,6 +66,43 @@ describe('useConversation', () => { }); }); + it('should report telemetry when a message has been sent', async () => { + await act(async () => { + const reportAssistantMessageSent = jest.fn(); + const { result, waitForNextUpdate } = renderHook(() => useConversation(), { + wrapper: ({ children }) => ( + <TestProviders + providerContext={{ + getInitialConversations: () => ({ + [alertConvo.id]: alertConvo, + [welcomeConvo.id]: welcomeConvo, + }), + assistantTelemetry: { + reportAssistantInvoked: () => {}, + reportAssistantQuickPrompt: () => {}, + reportAssistantSettingToggled: () => {}, + reportAssistantMessageSent, + }, + }} + > + {children} + </TestProviders> + ), + }); + await waitForNextUpdate(); + result.current.appendMessage({ + conversationId: welcomeConvo.id, + message, + }); + expect(reportAssistantMessageSent).toHaveBeenCalledWith({ + conversationId: 'Welcome', + isEnabledKnowledgeBase: false, + isEnabledRAGAlerts: false, + role: 'user', + }); + }); + }); + it('should create a new conversation when called with valid conversationId and message', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook(() => useConversation(), { diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_conversation/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_conversation/index.tsx index 3bd9f3fcbff716..11a21641b1bd49 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_conversation/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_conversation/index.tsx @@ -75,7 +75,12 @@ interface UseConversation { } export const useConversation = (): UseConversation => { - const { allSystemPrompts, assistantTelemetry, setConversations } = useAssistantContext(); + const { + allSystemPrompts, + assistantTelemetry, + knowledgeBase: { isEnabledKnowledgeBase, isEnabledRAGAlerts }, + setConversations, + } = useAssistantContext(); /** * Removes the last message of conversation[] for a given conversationId @@ -140,7 +145,12 @@ export const useConversation = (): UseConversation => { */ const appendMessage = useCallback( ({ conversationId, message }: AppendMessageProps): Message[] => { - assistantTelemetry?.reportAssistantMessageSent({ conversationId, role: message.role }); + assistantTelemetry?.reportAssistantMessageSent({ + conversationId, + role: message.role, + isEnabledKnowledgeBase, + isEnabledRAGAlerts, + }); let messages: Message[] = []; setConversations((prev: Record<string, Conversation>) => { const prevConversation: Conversation | undefined = prev[conversationId]; @@ -161,7 +171,7 @@ export const useConversation = (): UseConversation => { }); return messages; }, - [assistantTelemetry, setConversations] + [isEnabledKnowledgeBase, isEnabledRAGAlerts, assistantTelemetry, setConversations] ); const appendReplacements = useCallback( diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_send_messages/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_send_messages/index.tsx index fb973d492a6517..eae7d7914e6a1a 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_send_messages/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_send_messages/index.tsx @@ -47,12 +47,12 @@ export const useSendMessages = (): UseSendMessages => { try { return await fetchConnectorExecuteAction({ - alerts: knowledgeBase.alerts, // settings toggle + isEnabledRAGAlerts: knowledgeBase.isEnabledRAGAlerts, // settings toggle alertsIndexPattern, allow: defaultAllow, allowReplacement: defaultAllowReplacement, apiConfig, - assistantLangChain: knowledgeBase.assistantLangChain, + isEnabledKnowledgeBase: knowledgeBase.isEnabledKnowledgeBase, assistantStreamingEnabled, http, replacements, @@ -69,8 +69,8 @@ export const useSendMessages = (): UseSendMessages => { assistantStreamingEnabled, defaultAllow, defaultAllowReplacement, - knowledgeBase.alerts, - knowledgeBase.assistantLangChain, + knowledgeBase.isEnabledRAGAlerts, + knowledgeBase.isEnabledKnowledgeBase, knowledgeBase.latestAlerts, ] ); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/constants.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/constants.tsx index 780a2a04a9728c..cc747a705b851f 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/constants.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/constants.tsx @@ -17,7 +17,7 @@ export const KNOWLEDGE_BASE_LOCAL_STORAGE_KEY = 'knowledgeBase'; export const DEFAULT_LATEST_ALERTS = 20; export const DEFAULT_KNOWLEDGE_BASE_SETTINGS: KnowledgeBaseConfig = { - alerts: false, - assistantLangChain: false, + isEnabledRAGAlerts: false, + isEnabledKnowledgeBase: false, latestAlerts: DEFAULT_LATEST_ALERTS, }; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx index 024a06fd7b314b..50a3211f74f3cd 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx @@ -321,7 +321,7 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({ docLinks, getComments, http, - knowledgeBase: localStorageKnowledgeBase ?? DEFAULT_KNOWLEDGE_BASE_SETTINGS, + knowledgeBase: { ...DEFAULT_KNOWLEDGE_BASE_SETTINGS, ...localStorageKnowledgeBase }, modelEvaluatorEnabled, promptContexts, nameSpace, diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/types.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/types.tsx index 982b74faabf8d3..bf95b7d400240a 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/types.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/types.tsx @@ -67,8 +67,17 @@ export interface Conversation { export interface AssistantTelemetry { reportAssistantInvoked: (params: { invokedBy: string; conversationId: string }) => void; - reportAssistantMessageSent: (params: { conversationId: string; role: string }) => void; + reportAssistantMessageSent: (params: { + conversationId: string; + role: string; + isEnabledKnowledgeBase: boolean; + isEnabledRAGAlerts: boolean; + }) => void; reportAssistantQuickPrompt: (params: { conversationId: string; promptTitle: string }) => void; + reportAssistantSettingToggled: (params: { + isEnabledKnowledgeBase?: boolean; + isEnabledRAGAlerts?: boolean; + }) => void; } export interface AssistantAvailability { diff --git a/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.test.tsx index 6e5d7e7b1b174b..20ab3aab4a26f7 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.test.tsx @@ -38,8 +38,8 @@ jest.mock('../assistant_context', () => { const setUpdatedKnowledgeBaseSettings = jest.fn(); const defaultProps = { knowledgeBase: { - assistantLangChain: true, - alerts: false, + isEnabledKnowledgeBase: true, + isEnabledRAGAlerts: false, latestAlerts: DEFAULT_LATEST_ALERTS, }, setUpdatedKnowledgeBaseSettings, @@ -117,16 +117,16 @@ describe('Knowledge base settings', () => { fireEvent.click(getByTestId('esqlEnableButton')); expect(mockSetup).toHaveBeenCalledWith('esql'); }); - it('On disable lang chain, set assistantLangChain to false', () => { + it('On disable lang chain, set isEnabledKnowledgeBase to false', () => { const { getByTestId } = render( <TestProviders> <KnowledgeBaseSettings {...defaultProps} /> </TestProviders> ); - fireEvent.click(getByTestId('assistantLangChainSwitch')); + fireEvent.click(getByTestId('isEnabledKnowledgeBaseSwitch')); expect(setUpdatedKnowledgeBaseSettings).toHaveBeenCalledWith({ - alerts: false, - assistantLangChain: false, + isEnabledRAGAlerts: false, + isEnabledKnowledgeBase: false, latestAlerts: DEFAULT_LATEST_ALERTS, }); @@ -138,17 +138,17 @@ describe('Knowledge base settings', () => { <KnowledgeBaseSettings {...defaultProps} knowledgeBase={{ - assistantLangChain: false, - alerts: false, + isEnabledKnowledgeBase: false, + isEnabledRAGAlerts: false, latestAlerts: DEFAULT_LATEST_ALERTS, }} /> </TestProviders> ); - fireEvent.click(getByTestId('assistantLangChainSwitch')); + fireEvent.click(getByTestId('isEnabledKnowledgeBaseSwitch')); expect(setUpdatedKnowledgeBaseSettings).toHaveBeenCalledWith({ - assistantLangChain: true, - alerts: false, + isEnabledKnowledgeBase: true, + isEnabledRAGAlerts: false, latestAlerts: DEFAULT_LATEST_ALERTS, }); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.tsx b/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.tsx index 5974bae6e5ab08..f30215eaac521b 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings.tsx @@ -63,11 +63,11 @@ export const KnowledgeBaseSettings: React.FC<Props> = React.memo( // Resource availability state const isLoadingKb = isLoading || isFetching || isSettingUpKB || isDeletingUpKB; - const isKnowledgeBaseAvailable = knowledgeBase.assistantLangChain && kbStatus?.elser_exists; + const isKnowledgeBaseAvailable = knowledgeBase.isEnabledKnowledgeBase && kbStatus?.elser_exists; const isESQLAvailable = - knowledgeBase.assistantLangChain && isKnowledgeBaseAvailable && isKnowledgeBaseEnabled; + knowledgeBase.isEnabledKnowledgeBase && isKnowledgeBaseAvailable && isKnowledgeBaseEnabled; // Prevent enabling if elser doesn't exist, but always allow to disable - const isSwitchDisabled = !kbStatus?.elser_exists && !knowledgeBase.assistantLangChain; + const isSwitchDisabled = !kbStatus?.elser_exists && !knowledgeBase.isEnabledKnowledgeBase; // Calculated health state for EuiHealth component const elserHealth = isElserEnabled ? 'success' : 'subdued'; @@ -75,13 +75,13 @@ export const KnowledgeBaseSettings: React.FC<Props> = React.memo( const esqlHealth = isESQLEnabled ? 'success' : 'subdued'; ////////////////////////////////////////////////////////////////////////////////////////// - // Main `Knowledge Base` switch, which toggles the `assistantLangChain` UI feature toggle + // Main `Knowledge Base` switch, which toggles the `isEnabledKnowledgeBase` UI feature toggle // setting that is saved to localstorage const onEnableAssistantLangChainChange = useCallback( (event: EuiSwitchEvent) => { setUpdatedKnowledgeBaseSettings({ ...knowledgeBase, - assistantLangChain: event.target.checked, + isEnabledKnowledgeBase: event.target.checked, }); // If enabling and ELSER exists, try to set up automatically @@ -92,16 +92,16 @@ export const KnowledgeBaseSettings: React.FC<Props> = React.memo( [kbStatus?.elser_exists, knowledgeBase, setUpdatedKnowledgeBaseSettings, setupKB] ); - const assistantLangChainSwitch = useMemo(() => { + const isEnabledKnowledgeBaseSwitch = useMemo(() => { return isLoadingKb ? ( <EuiLoadingSpinner size="s" /> ) : ( <EuiToolTip content={isSwitchDisabled && i18n.KNOWLEDGE_BASE_TOOLTIP} position={'right'}> <EuiSwitch showLabel={false} - data-test-subj="assistantLangChainSwitch" + data-test-subj="isEnabledKnowledgeBaseSwitch" disabled={isSwitchDisabled} - checked={knowledgeBase.assistantLangChain} + checked={knowledgeBase.isEnabledKnowledgeBase} onChange={onEnableAssistantLangChainChange} label={i18n.KNOWLEDGE_BASE_LABEL} compressed @@ -111,7 +111,7 @@ export const KnowledgeBaseSettings: React.FC<Props> = React.memo( }, [ isLoadingKb, isSwitchDisabled, - knowledgeBase.assistantLangChain, + knowledgeBase.isEnabledKnowledgeBase, onEnableAssistantLangChainChange, ]); @@ -221,7 +221,7 @@ export const KnowledgeBaseSettings: React.FC<Props> = React.memo( } `} > - {assistantLangChainSwitch} + {isEnabledKnowledgeBaseSwitch} </EuiFormRow> <EuiSpacer size="s" /> diff --git a/x-pack/plugins/elastic_assistant/server/__mocks__/request_context.ts b/x-pack/plugins/elastic_assistant/server/__mocks__/request_context.ts index 6f68d8f20de32d..750c13debb3fd5 100644 --- a/x-pack/plugins/elastic_assistant/server/__mocks__/request_context.ts +++ b/x-pack/plugins/elastic_assistant/server/__mocks__/request_context.ts @@ -26,6 +26,7 @@ export const createMockClients = () => { actions: actionsClientMock.create(), getRegisteredTools: jest.fn(), logger: loggingSystemMock.createLogger(), + telemetry: coreMock.createSetup().analytics, }, savedObjectsClient: core.savedObjects.client, @@ -75,6 +76,7 @@ const createElasticAssistantRequestContextMock = ( actions: clients.elasticAssistant.actions as unknown as ActionsPluginStart, getRegisteredTools: jest.fn(), logger: clients.elasticAssistant.logger, + telemetry: clients.elasticAssistant.telemetry, }; }; diff --git a/x-pack/plugins/elastic_assistant/server/lib/langchain/elasticsearch_store/elasticsearch_store.test.ts b/x-pack/plugins/elastic_assistant/server/lib/langchain/elasticsearch_store/elasticsearch_store.test.ts index 0dc1cd10499cc7..b38d4b82f48b4b 100644 --- a/x-pack/plugins/elastic_assistant/server/lib/langchain/elasticsearch_store/elasticsearch_store.test.ts +++ b/x-pack/plugins/elastic_assistant/server/lib/langchain/elasticsearch_store/elasticsearch_store.test.ts @@ -20,6 +20,11 @@ import { } from './elasticsearch_store'; import { mockMsearchResponse } from '../../../__mocks__/msearch_response'; import { mockQueryText } from '../../../__mocks__/query_text'; +import { coreMock } from '@kbn/core/server/mocks'; +import { + KNOWLEDGE_BASE_EXECUTION_ERROR_EVENT, + KNOWLEDGE_BASE_EXECUTION_SUCCESS_EVENT, +} from '../../telemetry/event_based_telemetry'; jest.mock('uuid', () => ({ v4: jest.fn(), @@ -36,10 +41,12 @@ jest.mock('@kbn/core/server', () => ({ const mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); const mockLogger = loggingSystemMock.createLogger(); +const reportEvent = jest.fn(); +const mockTelemetry = { ...coreMock.createSetup().analytics, reportEvent }; const KB_INDEX = '.elastic-assistant-kb'; const getElasticsearchStore = () => { - return new ElasticsearchStore(mockEsClient, KB_INDEX, mockLogger); + return new ElasticsearchStore(mockEsClient, KB_INDEX, mockLogger, mockTelemetry); }; describe('ElasticsearchStore', () => { @@ -415,5 +422,30 @@ describe('ElasticsearchStore', () => { ], }); }); + + it('Reports successful telemetry event', async () => { + mockEsClient.msearch.mockResolvedValue(mockMsearchResponse); + + await esStore.similaritySearch(mockQueryText); + + expect(reportEvent).toHaveBeenCalledWith(KNOWLEDGE_BASE_EXECUTION_SUCCESS_EVENT.eventType, { + model: '.elser_model_2', + resourceAccessed: 'esql', + responseTime: 142, + resultCount: 2, + }); + }); + + it('Reports error telemetry event', async () => { + mockEsClient.msearch.mockRejectedValue(new Error('Oh no!')); + + await esStore.similaritySearch(mockQueryText); + + expect(reportEvent).toHaveBeenCalledWith(KNOWLEDGE_BASE_EXECUTION_ERROR_EVENT.eventType, { + model: '.elser_model_2', + resourceAccessed: 'esql', + errorMessage: 'Oh no!', + }); + }); }); }); diff --git a/x-pack/plugins/elastic_assistant/server/lib/langchain/elasticsearch_store/elasticsearch_store.ts b/x-pack/plugins/elastic_assistant/server/lib/langchain/elasticsearch_store/elasticsearch_store.ts index 606fc458815247..4a7def926d2f36 100644 --- a/x-pack/plugins/elastic_assistant/server/lib/langchain/elasticsearch_store/elasticsearch_store.ts +++ b/x-pack/plugins/elastic_assistant/server/lib/langchain/elasticsearch_store/elasticsearch_store.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { ElasticsearchClient, Logger } from '@kbn/core/server'; +import { type AnalyticsServiceSetup, ElasticsearchClient, Logger } from '@kbn/core/server'; import { MappingTypeMapping } from '@elastic/elasticsearch/lib/api/types'; import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { Callbacks } from 'langchain/callbacks'; @@ -13,6 +13,7 @@ import { Document } from 'langchain/document'; import { VectorStore } from 'langchain/vectorstores/base'; import * as uuid from 'uuid'; +import { transformError } from '@kbn/securitysolution-es-utils'; import { ElasticsearchEmbeddings } from '../embeddings/elasticsearch_embeddings'; import { FlattenedHit, getFlattenedHits } from './helpers/get_flattened_hits'; import { getMsearchQueryBody } from './helpers/get_msearch_query_body'; @@ -25,6 +26,10 @@ import { KNOWLEDGE_BASE_INGEST_PIPELINE, } from '../../../routes/knowledge_base/constants'; import { getRequiredKbDocsTermsQueryDsl } from './helpers/get_required_kb_docs_terms_query_dsl'; +import { + KNOWLEDGE_BASE_EXECUTION_ERROR_EVENT, + KNOWLEDGE_BASE_EXECUTION_SUCCESS_EVENT, +} from '../../telemetry/event_based_telemetry'; interface CreatePipelineParams { id?: string; @@ -59,6 +64,7 @@ export class ElasticsearchStore extends VectorStore { private readonly esClient: ElasticsearchClient; private readonly index: string; private readonly logger: Logger; + private readonly telemetry: AnalyticsServiceSetup; private readonly model: string; private readonly kbResource: string; @@ -70,6 +76,7 @@ export class ElasticsearchStore extends VectorStore { esClient: ElasticsearchClient, index: string, logger: Logger, + telemetry: AnalyticsServiceSetup, model?: string, kbResource?: string | undefined ) { @@ -77,6 +84,7 @@ export class ElasticsearchStore extends VectorStore { this.esClient = esClient; this.index = index ?? KNOWLEDGE_BASE_INDEX_PATTERN; this.logger = logger; + this.telemetry = telemetry; this.model = model ?? '.elser_model_2'; this.kbResource = kbResource ?? ESQL_RESOURCE; } @@ -222,6 +230,13 @@ export class ElasticsearchStore extends VectorStore { return getFlattenedHits(maybeEsqlMsearchResponse); }); + this.telemetry.reportEvent(KNOWLEDGE_BASE_EXECUTION_SUCCESS_EVENT.eventType, { + model: this.model, + resourceAccessed: this.kbResource, + resultCount: results.length, + responseTime: result.took ?? 0, + }); + this.logger.debug( `Similarity search metadata source:\n${JSON.stringify( results.map((r) => r?.metadata?.source ?? '(missing metadata.source)'), @@ -232,6 +247,12 @@ export class ElasticsearchStore extends VectorStore { return results; } catch (e) { + const error = transformError(e); + this.telemetry.reportEvent(KNOWLEDGE_BASE_EXECUTION_ERROR_EVENT.eventType, { + model: this.model, + resourceAccessed: this.kbResource, + errorMessage: error.message, + }); this.logger.error(e); return []; } diff --git a/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.test.ts b/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.test.ts index 4dbc0fb53fc0d6..59c1aeca8081fd 100644 --- a/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.test.ts +++ b/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.test.ts @@ -7,6 +7,7 @@ import { PluginStartContract as ActionsPluginStart } from '@kbn/actions-plugin/server'; import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; +import { coreMock } from '@kbn/core/server/mocks'; import { KibanaRequest } from '@kbn/core/server'; import { loggerMock } from '@kbn/logging-mocks'; @@ -55,6 +56,7 @@ const mockRequest: KibanaRequest<unknown, unknown, any, any> = {} as KibanaReque const mockActions: ActionsPluginStart = {} as ActionsPluginStart; const mockLogger = loggerMock.create(); +const mockTelemetry = coreMock.createSetup().analytics; const esClientMock = elasticsearchServiceMock.createScopedClusterClient().asCurrentUser; describe('callAgentExecutor', () => { @@ -69,7 +71,7 @@ describe('callAgentExecutor', () => { it('creates an instance of ActionsClientLlm with the expected context from the request', async () => { await callAgentExecutor({ actions: mockActions, - assistantLangChain: true, + isEnabledKnowledgeBase: true, connectorId: mockConnectorId, esClient: esClientMock, langChainMessages, @@ -77,6 +79,7 @@ describe('callAgentExecutor', () => { onNewReplacements: jest.fn(), request: mockRequest, kbResource: ESQL_RESOURCE, + telemetry: mockTelemetry, }); expect(ActionsClientLlm).toHaveBeenCalledWith({ @@ -90,7 +93,7 @@ describe('callAgentExecutor', () => { it('kicks off the chain with (only) the last message', async () => { await callAgentExecutor({ actions: mockActions, - assistantLangChain: true, + isEnabledKnowledgeBase: true, connectorId: mockConnectorId, esClient: esClientMock, langChainMessages, @@ -98,6 +101,7 @@ describe('callAgentExecutor', () => { onNewReplacements: jest.fn(), request: mockRequest, kbResource: ESQL_RESOURCE, + telemetry: mockTelemetry, }); // We don't care about the `config` argument, so we use `expect.anything()` @@ -114,7 +118,7 @@ describe('callAgentExecutor', () => { await callAgentExecutor({ actions: mockActions, - assistantLangChain: true, + isEnabledKnowledgeBase: true, connectorId: mockConnectorId, esClient: esClientMock, langChainMessages: onlyOneMessage, @@ -122,6 +126,7 @@ describe('callAgentExecutor', () => { onNewReplacements: jest.fn(), request: mockRequest, kbResource: ESQL_RESOURCE, + telemetry: mockTelemetry, }); // We don't care about the `config` argument, so we use `expect.anything()` @@ -136,7 +141,7 @@ describe('callAgentExecutor', () => { it('returns the expected response body', async () => { const result: ResponseBody = await callAgentExecutor({ actions: mockActions, - assistantLangChain: true, + isEnabledKnowledgeBase: true, connectorId: mockConnectorId, esClient: esClientMock, langChainMessages, @@ -144,6 +149,7 @@ describe('callAgentExecutor', () => { onNewReplacements: jest.fn(), request: mockRequest, kbResource: ESQL_RESOURCE, + telemetry: mockTelemetry, }); expect(result).toEqual({ diff --git a/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.ts b/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.ts index d6868925cc667b..f44dcaae759283 100644 --- a/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.ts +++ b/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.ts @@ -30,7 +30,7 @@ export const callAgentExecutor = async ({ alertsIndexPattern, allow, allowReplacement, - assistantLangChain, + isEnabledKnowledgeBase, assistantTools = [], connectorId, elserId, @@ -43,6 +43,7 @@ export const callAgentExecutor = async ({ replacements, request, size, + telemetry, traceOptions, }: AgentExecutorParams): AgentExecutorResponse => { const llm = new ActionsClientLlm({ actions, connectorId, request, llmType, logger }); @@ -63,6 +64,7 @@ export const callAgentExecutor = async ({ esClient, KNOWLEDGE_BASE_INDEX_PATTERN, logger, + telemetry, elserId, kbResource ); @@ -77,7 +79,7 @@ export const callAgentExecutor = async ({ allow, allowReplacement, alertsIndexPattern, - assistantLangChain, + isEnabledKnowledgeBase, chain, esClient, modelExists, diff --git a/x-pack/plugins/elastic_assistant/server/lib/langchain/executors/openai_functions_executor.ts b/x-pack/plugins/elastic_assistant/server/lib/langchain/executors/openai_functions_executor.ts index 32c9c0988f4d4e..4a305808c835c6 100644 --- a/x-pack/plugins/elastic_assistant/server/lib/langchain/executors/openai_functions_executor.ts +++ b/x-pack/plugins/elastic_assistant/server/lib/langchain/executors/openai_functions_executor.ts @@ -36,6 +36,7 @@ export const callOpenAIFunctionsExecutor = async ({ request, elserId, kbResource, + telemetry, traceOptions, }: AgentExecutorParams): AgentExecutorResponse => { const llm = new ActionsClientLlm({ actions, connectorId, request, llmType, logger }); @@ -56,6 +57,7 @@ export const callOpenAIFunctionsExecutor = async ({ esClient, KNOWLEDGE_BASE_INDEX_PATTERN, logger, + telemetry, elserId, kbResource ); diff --git a/x-pack/plugins/elastic_assistant/server/lib/langchain/executors/types.ts b/x-pack/plugins/elastic_assistant/server/lib/langchain/executors/types.ts index e7824e2822f8a3..03554911216ebe 100644 --- a/x-pack/plugins/elastic_assistant/server/lib/langchain/executors/types.ts +++ b/x-pack/plugins/elastic_assistant/server/lib/langchain/executors/types.ts @@ -11,6 +11,7 @@ import { BaseMessage } from 'langchain/schema'; import { Logger } from '@kbn/logging'; import { KibanaRequest } from '@kbn/core-http-server'; import type { LangChainTracer } from 'langchain/callbacks'; +import type { AnalyticsServiceSetup } from '@kbn/core-analytics-server'; import { RequestBody, ResponseBody } from '../types'; import type { AssistantTool } from '../../../types'; @@ -19,7 +20,7 @@ export interface AgentExecutorParams { actions: ActionsPluginStart; allow?: string[]; allowReplacement?: string[]; - assistantLangChain: boolean; + isEnabledKnowledgeBase: boolean; assistantTools?: AssistantTool[]; connectorId: string; esClient: ElasticsearchClient; @@ -33,6 +34,7 @@ export interface AgentExecutorParams { size?: number; elserId?: string; traceOptions?: TraceOptions; + telemetry: AnalyticsServiceSetup; } export type AgentExecutorResponse = Promise<ResponseBody>; diff --git a/x-pack/plugins/elastic_assistant/server/lib/langchain/llm/actions_client_llm.test.ts b/x-pack/plugins/elastic_assistant/server/lib/langchain/llm/actions_client_llm.test.ts index 5c27cdef4d3e1f..f2cffe7c9d41b5 100644 --- a/x-pack/plugins/elastic_assistant/server/lib/langchain/llm/actions_client_llm.test.ts +++ b/x-pack/plugins/elastic_assistant/server/lib/langchain/llm/actions_client_llm.test.ts @@ -51,7 +51,7 @@ const mockRequest: KibanaRequest<unknown, unknown, RequestBody> = { }, subAction: 'invokeAI', }, - assistantLangChain: true, + isEnabledKnowledgeBase: true, }, } as KibanaRequest<unknown, unknown, RequestBody>; diff --git a/x-pack/plugins/elastic_assistant/server/lib/telemetry/event_based_telemetry.ts b/x-pack/plugins/elastic_assistant/server/lib/telemetry/event_based_telemetry.ts new file mode 100644 index 00000000000000..e9b87788d0f85e --- /dev/null +++ b/x-pack/plugins/elastic_assistant/server/lib/telemetry/event_based_telemetry.ts @@ -0,0 +1,127 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { EventTypeOpts } from '@kbn/analytics-client'; + +export const KNOWLEDGE_BASE_EXECUTION_SUCCESS_EVENT: EventTypeOpts<{ + model: string; + resourceAccessed: string; + resultCount: number; + responseTime: number; +}> = { + eventType: 'knowledge_base_execution_success', + schema: { + model: { + type: 'keyword', + _meta: { + description: 'ELSER model used to execute the knowledge base query', + }, + }, + resourceAccessed: { + type: 'keyword', + _meta: { + description: 'Which knowledge base resource was accessed', + }, + }, + resultCount: { + type: 'long', + _meta: { + description: 'Number of documents returned from Elasticsearch', + }, + }, + responseTime: { + type: 'long', + _meta: { + description: `How long it took for Elasticsearch to respond to the knowledge base query`, + }, + }, + }, +}; + +export const KNOWLEDGE_BASE_EXECUTION_ERROR_EVENT: EventTypeOpts<{ + model: string; + resourceAccessed: string; + errorMessage: string; +}> = { + eventType: 'knowledge_base_execution_error', + schema: { + model: { + type: 'keyword', + _meta: { + description: 'ELSER model used to execute the knowledge base query', + }, + }, + resourceAccessed: { + type: 'keyword', + _meta: { + description: 'Which knowledge base resource was accessed', + }, + }, + errorMessage: { + type: 'keyword', + _meta: { + description: 'Error message from Elasticsearch', + }, + }, + }, +}; + +export const INVOKE_ASSISTANT_SUCCESS_EVENT: EventTypeOpts<{ + isEnabledKnowledgeBase: boolean; + isEnabledRAGAlerts: boolean; +}> = { + eventType: 'invoke_assistant_success', + schema: { + isEnabledKnowledgeBase: { + type: 'boolean', + _meta: { + description: 'Is Knowledge Base enabled', + }, + }, + isEnabledRAGAlerts: { + type: 'boolean', + _meta: { + description: 'Is RAG Alerts enabled', + }, + }, + }, +}; + +export const INVOKE_ASSISTANT_ERROR_EVENT: EventTypeOpts<{ + errorMessage: string; + isEnabledKnowledgeBase: boolean; + isEnabledRAGAlerts: boolean; +}> = { + eventType: 'invoke_assistant_error', + schema: { + errorMessage: { + type: 'keyword', + _meta: { + description: 'Error message from Elasticsearch', + }, + }, + isEnabledKnowledgeBase: { + type: 'boolean', + _meta: { + description: 'Is Knowledge Base enabled', + }, + }, + isEnabledRAGAlerts: { + type: 'boolean', + _meta: { + description: 'Is RAG Alerts enabled', + }, + }, + }, +}; + +export const events: Array<EventTypeOpts<{ [key: string]: unknown }>> = [ + KNOWLEDGE_BASE_EXECUTION_SUCCESS_EVENT, + KNOWLEDGE_BASE_EXECUTION_ERROR_EVENT, + INVOKE_ASSISTANT_SUCCESS_EVENT, + INVOKE_ASSISTANT_ERROR_EVENT, +]; diff --git a/x-pack/plugins/elastic_assistant/server/plugin.ts b/x-pack/plugins/elastic_assistant/server/plugin.ts index bd06165e57284c..f142df46beb8b1 100755 --- a/x-pack/plugins/elastic_assistant/server/plugin.ts +++ b/x-pack/plugins/elastic_assistant/server/plugin.ts @@ -14,9 +14,11 @@ import { IContextProvider, KibanaRequest, SavedObjectsClientContract, + type AnalyticsServiceSetup, } from '@kbn/core/server'; import { once } from 'lodash'; +import { events } from './lib/telemetry/event_based_telemetry'; import { AssistantTool, ElasticAssistantPluginSetup, @@ -40,6 +42,7 @@ interface CreateRouteHandlerContextParams { core: CoreSetup<ElasticAssistantPluginStart, unknown>; logger: Logger; getRegisteredTools: GetRegisteredTools; + telemetry: AnalyticsServiceSetup; } export class ElasticAssistantPlugin @@ -61,6 +64,7 @@ export class ElasticAssistantPlugin core, logger, getRegisteredTools, + telemetry, }: CreateRouteHandlerContextParams): IContextProvider< ElasticAssistantRequestHandlerContext, typeof PLUGIN_ID @@ -72,6 +76,7 @@ export class ElasticAssistantPlugin actions: pluginsStart.actions, getRegisteredTools, logger, + telemetry, }; }; }; @@ -87,8 +92,10 @@ export class ElasticAssistantPlugin getRegisteredTools: (pluginName: string) => { return appContextService.getRegisteredTools(pluginName); }, + telemetry: core.analytics, }) ); + events.forEach((eventConfig) => core.analytics.registerEventType(eventConfig)); const getElserId: GetElser = once( async (request: KibanaRequest, savedObjectsClient: SavedObjectsClientContract) => { diff --git a/x-pack/plugins/elastic_assistant/server/routes/evaluate/post_evaluate.ts b/x-pack/plugins/elastic_assistant/server/routes/evaluate/post_evaluate.ts index f5ec4c4555a766..ff3291f6b703f9 100644 --- a/x-pack/plugins/elastic_assistant/server/routes/evaluate/post_evaluate.ts +++ b/x-pack/plugins/elastic_assistant/server/routes/evaluate/post_evaluate.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { IRouter, KibanaRequest, Logger } from '@kbn/core/server'; +import { IRouter, KibanaRequest } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; import { v4 as uuidv4 } from 'uuid'; @@ -53,9 +53,11 @@ export const postEvaluateRoute = ( query: buildRouteValidation(PostEvaluatePathQuery), }, }, + // TODO: Limit route based on experimental feature async (context, request, response) => { - // TODO: Limit route based on experimental feature - const logger: Logger = (await context.elasticAssistant).logger; + const assistantContext = await context.elasticAssistant; + const logger = assistantContext.logger; + const telemetry = assistantContext.telemetry; try { const evaluationId = uuidv4(); const { @@ -112,7 +114,8 @@ export const postEvaluateRoute = ( // Default ELSER model const elserId = await getElser(request, (await context.core).savedObjects.getClient()); - // Skeleton request to satisfy `subActionParams` spread in `ActionsClientLlm` + // Skeleton request from route to pass to the agents + // params will be passed to the actions executor const skeletonRequest: KibanaRequest<unknown, unknown, RequestBody> = { ...request, body: { @@ -127,7 +130,8 @@ export const postEvaluateRoute = ( }, replacements: {}, size: DEFAULT_SIZE, - assistantLangChain: true, + isEnabledKnowledgeBase: true, + isEnabledRAGAlerts: true, }, }; @@ -146,7 +150,7 @@ export const postEvaluateRoute = ( agentEvaluator: (langChainMessages, exampleId) => AGENT_EXECUTOR_MAP[agentName]({ actions, - assistantLangChain: true, + isEnabledKnowledgeBase: true, assistantTools, connectorId, esClient, @@ -156,6 +160,7 @@ export const postEvaluateRoute = ( logger, request: skeletonRequest, kbResource: ESQL_RESOURCE, + telemetry, traceOptions: { exampleId, projectName, diff --git a/x-pack/plugins/elastic_assistant/server/routes/knowledge_base/delete_knowledge_base.ts b/x-pack/plugins/elastic_assistant/server/routes/knowledge_base/delete_knowledge_base.ts index 3ce494f80ac4dc..235ea4eda4c0de 100644 --- a/x-pack/plugins/elastic_assistant/server/routes/knowledge_base/delete_knowledge_base.ts +++ b/x-pack/plugins/elastic_assistant/server/routes/knowledge_base/delete_knowledge_base.ts @@ -38,7 +38,9 @@ export const deleteKnowledgeBaseRoute = ( }, async (context, request, response) => { const resp = buildResponse(response); - const logger = (await context.elasticAssistant).logger; + const assistantContext = await context.elasticAssistant; + const logger = assistantContext.logger; + const telemetry = assistantContext.telemetry; try { const kbResource = @@ -46,7 +48,12 @@ export const deleteKnowledgeBaseRoute = ( // Get a scoped esClient for deleting the Knowledge Base index, pipeline, and documents const esClient = (await context.core).elasticsearch.client.asCurrentUser; - const esStore = new ElasticsearchStore(esClient, KNOWLEDGE_BASE_INDEX_PATTERN, logger); + const esStore = new ElasticsearchStore( + esClient, + KNOWLEDGE_BASE_INDEX_PATTERN, + logger, + telemetry + ); if (kbResource === ESQL_RESOURCE) { // For now, tearing down the Knowledge Base is fine, but will want to support removing specific assets based diff --git a/x-pack/plugins/elastic_assistant/server/routes/knowledge_base/get_knowledge_base_status.ts b/x-pack/plugins/elastic_assistant/server/routes/knowledge_base/get_knowledge_base_status.ts index c2c616939677d5..6cc683fd4d8b83 100644 --- a/x-pack/plugins/elastic_assistant/server/routes/knowledge_base/get_knowledge_base_status.ts +++ b/x-pack/plugins/elastic_assistant/server/routes/knowledge_base/get_knowledge_base_status.ts @@ -41,7 +41,9 @@ export const getKnowledgeBaseStatusRoute = ( }, async (context, request, response) => { const resp = buildResponse(response); - const logger = (await context.elasticAssistant).logger; + const assistantContext = await context.elasticAssistant; + const logger = assistantContext.logger; + const telemetry = assistantContext.telemetry; try { // Get a scoped esClient for finding the status of the Knowledge Base index, pipeline, and documents @@ -52,6 +54,7 @@ export const getKnowledgeBaseStatusRoute = ( esClient, KNOWLEDGE_BASE_INDEX_PATTERN, logger, + telemetry, elserId, kbResource ); diff --git a/x-pack/plugins/elastic_assistant/server/routes/knowledge_base/post_knowledge_base.ts b/x-pack/plugins/elastic_assistant/server/routes/knowledge_base/post_knowledge_base.ts index 2ac938d3db45aa..56812ee8d03059 100644 --- a/x-pack/plugins/elastic_assistant/server/routes/knowledge_base/post_knowledge_base.ts +++ b/x-pack/plugins/elastic_assistant/server/routes/knowledge_base/post_knowledge_base.ts @@ -40,17 +40,21 @@ export const postKnowledgeBaseRoute = ( }, async (context, request, response) => { const resp = buildResponse(response); - const logger = (await context.elasticAssistant).logger; + const assistantContext = await context.elasticAssistant; + const logger = assistantContext.logger; + const telemetry = assistantContext.telemetry; try { + const core = await context.core; // Get a scoped esClient for creating the Knowledge Base index, pipeline, and documents - const esClient = (await context.core).elasticsearch.client.asCurrentUser; - const elserId = await getElser(request, (await context.core).savedObjects.getClient()); + const esClient = core.elasticsearch.client.asCurrentUser; + const elserId = await getElser(request, core.savedObjects.getClient()); const kbResource = getKbResource(request); const esStore = new ElasticsearchStore( esClient, KNOWLEDGE_BASE_INDEX_PATTERN, logger, + telemetry, elserId, kbResource ); diff --git a/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.test.ts b/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.test.ts index 0f7d964eea480d..05a303db3c67ed 100644 --- a/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.test.ts +++ b/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.test.ts @@ -15,16 +15,26 @@ import { ElasticAssistantRequestHandlerContext } from '../types'; import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { coreMock } from '@kbn/core/server/mocks'; +import { + INVOKE_ASSISTANT_ERROR_EVENT, + INVOKE_ASSISTANT_SUCCESS_EVENT, +} from '../lib/telemetry/event_based_telemetry'; jest.mock('../lib/build_response', () => ({ buildResponse: jest.fn().mockImplementation((x) => x), })); jest.mock('../lib/executor', () => ({ - executeAction: jest.fn().mockImplementation((x) => ({ - connector_id: 'mock-connector-id', - data: mockActionResponse, - status: 'ok', - })), + executeAction: jest.fn().mockImplementation(async ({ connectorId }) => { + if (connectorId === 'mock-connector-id') { + return { + connector_id: 'mock-connector-id', + data: mockActionResponse, + status: 'ok', + }; + } else { + throw new Error('simulated error'); + } + }), })); jest.mock('../lib/langchain/execute_custom_llm_chain', () => ({ @@ -53,11 +63,13 @@ jest.mock('../lib/langchain/execute_custom_llm_chain', () => ({ ), })); +const reportEvent = jest.fn(); const mockContext = { elasticAssistant: { actions: jest.fn(), getRegisteredTools: jest.fn(() => []), logger: loggingSystemMock.createLogger(), + telemetry: { ...coreMock.createSetup().analytics, reportEvent }, }, core: { elasticsearch: { @@ -90,7 +102,8 @@ const mockRequest = { }, subAction: 'invokeAI', }, - assistantLangChain: true, + isEnabledKnowledgeBase: true, + isEnabledRAGAlerts: false, }, }; @@ -106,7 +119,7 @@ describe('postActionsConnectorExecuteRoute', () => { jest.clearAllMocks(); }); - it('returns the expected response when assistantLangChain=false', async () => { + it('returns the expected response when isEnabledKnowledgeBase=false', async () => { const mockRouter = { post: jest.fn().mockImplementation(async (_, handler) => { const result = await handler( @@ -115,7 +128,7 @@ describe('postActionsConnectorExecuteRoute', () => { ...mockRequest, body: { ...mockRequest.body, - assistantLangChain: false, + isEnabledKnowledgeBase: false, }, }, mockResponse @@ -137,7 +150,7 @@ describe('postActionsConnectorExecuteRoute', () => { ); }); - it('returns the expected response when assistantLangChain=true', async () => { + it('returns the expected response when isEnabledKnowledgeBase=true', async () => { const mockRouter = { post: jest.fn().mockImplementation(async (_, handler) => { const result = await handler(mockContext, mockRequest, mockResponse); @@ -181,4 +194,219 @@ describe('postActionsConnectorExecuteRoute', () => { mockGetElser ); }); + + it('reports success events to telemetry - kb on, RAG alerts off', async () => { + const mockRouter = { + post: jest.fn().mockImplementation(async (_, handler) => { + await handler(mockContext, mockRequest, mockResponse); + + expect(reportEvent).toHaveBeenCalledWith(INVOKE_ASSISTANT_SUCCESS_EVENT.eventType, { + isEnabledKnowledgeBase: true, + isEnabledRAGAlerts: false, + }); + }), + }; + + await postActionsConnectorExecuteRoute( + mockRouter as unknown as IRouter<ElasticAssistantRequestHandlerContext>, + mockGetElser + ); + }); + + it('reports success events to telemetry - kb on, RAG alerts on', async () => { + const ragRequest = { + ...mockRequest, + body: { + ...mockRequest.body, + allow: ['@timestamp'], + allowReplacement: ['host.name'], + replacements: {}, + isEnabledRAGAlerts: true, + }, + }; + + const mockRouter = { + post: jest.fn().mockImplementation(async (_, handler) => { + await handler(mockContext, ragRequest, mockResponse); + + expect(reportEvent).toHaveBeenCalledWith(INVOKE_ASSISTANT_SUCCESS_EVENT.eventType, { + isEnabledKnowledgeBase: true, + isEnabledRAGAlerts: true, + }); + }), + }; + + await postActionsConnectorExecuteRoute( + mockRouter as unknown as IRouter<ElasticAssistantRequestHandlerContext>, + mockGetElser + ); + }); + + it('reports success events to telemetry - kb off, RAG alerts on', async () => { + const req = { + ...mockRequest, + body: { + ...mockRequest.body, + isEnabledKnowledgeBase: false, + allow: ['@timestamp'], + allowReplacement: ['host.name'], + replacements: {}, + isEnabledRAGAlerts: true, + }, + }; + + const mockRouter = { + post: jest.fn().mockImplementation(async (_, handler) => { + await handler(mockContext, req, mockResponse); + + expect(reportEvent).toHaveBeenCalledWith(INVOKE_ASSISTANT_SUCCESS_EVENT.eventType, { + isEnabledKnowledgeBase: false, + isEnabledRAGAlerts: true, + }); + }), + }; + + await postActionsConnectorExecuteRoute( + mockRouter as unknown as IRouter<ElasticAssistantRequestHandlerContext>, + mockGetElser + ); + }); + + it('reports success events to telemetry - kb off, RAG alerts off', async () => { + const req = { + ...mockRequest, + body: { + ...mockRequest.body, + isEnabledKnowledgeBase: false, + }, + }; + + const mockRouter = { + post: jest.fn().mockImplementation(async (_, handler) => { + await handler(mockContext, req, mockResponse); + + expect(reportEvent).toHaveBeenCalledWith(INVOKE_ASSISTANT_SUCCESS_EVENT.eventType, { + isEnabledKnowledgeBase: false, + isEnabledRAGAlerts: false, + }); + }), + }; + + await postActionsConnectorExecuteRoute( + mockRouter as unknown as IRouter<ElasticAssistantRequestHandlerContext>, + mockGetElser + ); + }); + + it('reports error events to telemetry - kb on, RAG alerts off', async () => { + const requestWithBadConnectorId = { + ...mockRequest, + params: { connectorId: 'bad-connector-id' }, + }; + + const mockRouter = { + post: jest.fn().mockImplementation(async (_, handler) => { + await handler(mockContext, requestWithBadConnectorId, mockResponse); + + expect(reportEvent).toHaveBeenCalledWith(INVOKE_ASSISTANT_ERROR_EVENT.eventType, { + errorMessage: 'simulated error', + isEnabledKnowledgeBase: true, + isEnabledRAGAlerts: false, + }); + }), + }; + + await postActionsConnectorExecuteRoute( + mockRouter as unknown as IRouter<ElasticAssistantRequestHandlerContext>, + mockGetElser + ); + }); + + it('reports error events to telemetry - kb on, RAG alerts on', async () => { + const badRequest = { + ...mockRequest, + params: { connectorId: 'bad-connector-id' }, + body: { + ...mockRequest.body, + isEnabledRAGAlerts: true, + }, + }; + + const mockRouter = { + post: jest.fn().mockImplementation(async (_, handler) => { + await handler(mockContext, badRequest, mockResponse); + + expect(reportEvent).toHaveBeenCalledWith(INVOKE_ASSISTANT_ERROR_EVENT.eventType, { + errorMessage: 'simulated error', + isEnabledKnowledgeBase: true, + isEnabledRAGAlerts: true, + }); + }), + }; + + await postActionsConnectorExecuteRoute( + mockRouter as unknown as IRouter<ElasticAssistantRequestHandlerContext>, + mockGetElser + ); + }); + + it('reports error events to telemetry - kb off, RAG alerts on', async () => { + const badRequest = { + ...mockRequest, + params: { connectorId: 'bad-connector-id' }, + body: { + ...mockRequest.body, + isEnabledKnowledgeBase: false, + allow: ['@timestamp'], + allowReplacement: ['host.name'], + replacements: {}, + isEnabledRAGAlerts: true, + }, + }; + + const mockRouter = { + post: jest.fn().mockImplementation(async (_, handler) => { + await handler(mockContext, badRequest, mockResponse); + + expect(reportEvent).toHaveBeenCalledWith(INVOKE_ASSISTANT_ERROR_EVENT.eventType, { + errorMessage: 'simulated error', + isEnabledKnowledgeBase: false, + isEnabledRAGAlerts: true, + }); + }), + }; + + await postActionsConnectorExecuteRoute( + mockRouter as unknown as IRouter<ElasticAssistantRequestHandlerContext>, + mockGetElser + ); + }); + + it('reports error events to telemetry - kb off, RAG alerts off', async () => { + const badRequest = { + ...mockRequest, + params: { connectorId: 'bad-connector-id' }, + body: { + ...mockRequest.body, + isEnabledKnowledgeBase: false, + }, + }; + + const mockRouter = { + post: jest.fn().mockImplementation(async (_, handler) => { + await handler(mockContext, badRequest, mockResponse); + + expect(reportEvent).toHaveBeenCalledWith(INVOKE_ASSISTANT_ERROR_EVENT.eventType, { + errorMessage: 'simulated error', + isEnabledKnowledgeBase: false, + isEnabledRAGAlerts: false, + }); + }), + }; + + await postActionsConnectorExecuteRoute( + mockRouter as unknown as IRouter<ElasticAssistantRequestHandlerContext>, + mockGetElser + ); + }); }); diff --git a/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.ts b/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.ts index 9c1d8601da5320..533b4ddca4a48f 100644 --- a/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.ts +++ b/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.ts @@ -8,6 +8,10 @@ import { IRouter, Logger } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; +import { + INVOKE_ASSISTANT_ERROR_EVENT, + INVOKE_ASSISTANT_SUCCESS_EVENT, +} from '../lib/telemetry/event_based_telemetry'; import { executeAction } from '../lib/executor'; import { POST_ACTIONS_CONNECTOR_EXECUTE } from '../../common/constants'; import { @@ -39,7 +43,9 @@ export const postActionsConnectorExecuteRoute = ( }, async (context, request, response) => { const resp = buildResponse(response); - const logger: Logger = (await context.elasticAssistant).logger; + const assistantContext = await context.elasticAssistant; + const logger: Logger = assistantContext.logger; + const telemetry = assistantContext.telemetry; try { const connectorId = decodeURIComponent(request.params.connectorId); @@ -48,16 +54,25 @@ export const postActionsConnectorExecuteRoute = ( const actions = (await context.elasticAssistant).actions; // if not langchain, call execute action directly and return the response: - if (!request.body.assistantLangChain && !requestHasRequiredAnonymizationParams(request)) { + if ( + !request.body.isEnabledKnowledgeBase && + !requestHasRequiredAnonymizationParams(request) + ) { logger.debug('Executing via actions framework directly'); const result = await executeAction({ actions, request, connectorId }); + telemetry.reportEvent(INVOKE_ASSISTANT_SUCCESS_EVENT.eventType, { + isEnabledKnowledgeBase: request.body.isEnabledKnowledgeBase, + isEnabledRAGAlerts: request.body.isEnabledRAGAlerts, + }); return response.ok({ body: result, }); } // TODO: Add `traceId` to actions request when calling via langchain - logger.debug('Executing via langchain, assistantLangChain: true'); + logger.debug( + `Executing via langchain, isEnabledKnowledgeBase: ${request.body.isEnabledKnowledgeBase}, isEnabledRAGAlerts: ${request.body.isEnabledRAGAlerts}` + ); // Fetch any tools registered by the request's originating plugin const pluginName = getPluginNameFromRequest({ @@ -87,7 +102,7 @@ export const postActionsConnectorExecuteRoute = ( allow: request.body.allow, allowReplacement: request.body.allowReplacement, actions, - assistantLangChain: request.body.assistantLangChain, + isEnabledKnowledgeBase: request.body.isEnabledKnowledgeBase, assistantTools, connectorId, elserId, @@ -99,8 +114,13 @@ export const postActionsConnectorExecuteRoute = ( request, replacements: request.body.replacements, size: request.body.size, + telemetry, }); + telemetry.reportEvent(INVOKE_ASSISTANT_SUCCESS_EVENT.eventType, { + isEnabledKnowledgeBase: request.body.isEnabledKnowledgeBase, + isEnabledRAGAlerts: request.body.isEnabledRAGAlerts, + }); return response.ok({ body: { ...langChainResponseBody, @@ -110,6 +130,11 @@ export const postActionsConnectorExecuteRoute = ( } catch (err) { logger.error(err); const error = transformError(err); + telemetry.reportEvent(INVOKE_ASSISTANT_ERROR_EVENT.eventType, { + isEnabledKnowledgeBase: request.body.isEnabledKnowledgeBase, + isEnabledRAGAlerts: request.body.isEnabledRAGAlerts, + errorMessage: error.message, + }); return resp.error({ body: error.message, diff --git a/x-pack/plugins/elastic_assistant/server/schemas/post_actions_connector_execute.ts b/x-pack/plugins/elastic_assistant/server/schemas/post_actions_connector_execute.ts index cee6f31df6c71e..a03619e6a92f60 100644 --- a/x-pack/plugins/elastic_assistant/server/schemas/post_actions_connector_execute.ts +++ b/x-pack/plugins/elastic_assistant/server/schemas/post_actions_connector_execute.ts @@ -37,7 +37,8 @@ export const PostActionsConnectorExecuteBody = t.type({ alertsIndexPattern: t.union([t.string, t.undefined]), allow: t.union([t.array(t.string), t.undefined]), allowReplacement: t.union([t.array(t.string), t.undefined]), - assistantLangChain: t.boolean, + isEnabledKnowledgeBase: t.boolean, + isEnabledRAGAlerts: t.boolean, replacements: t.union([t.record(t.string, t.string), t.undefined]), size: t.union([t.number, t.undefined]), }); diff --git a/x-pack/plugins/elastic_assistant/server/types.ts b/x-pack/plugins/elastic_assistant/server/types.ts index 5be8a35a275b97..c45966b9b80a24 100755 --- a/x-pack/plugins/elastic_assistant/server/types.ts +++ b/x-pack/plugins/elastic_assistant/server/types.ts @@ -10,6 +10,7 @@ import type { PluginStartContract as ActionsPluginStart, } from '@kbn/actions-plugin/server'; import type { + AnalyticsServiceSetup, CustomRequestHandlerContext, KibanaRequest, Logger, @@ -57,6 +58,7 @@ export interface ElasticAssistantApiRequestHandlerContext { actions: ActionsPluginStart; getRegisteredTools: GetRegisteredTools; logger: Logger; + telemetry: AnalyticsServiceSetup; } /** @@ -88,7 +90,7 @@ export interface AssistantToolParams { alertsIndexPattern?: string; allow?: string[]; allowReplacement?: string[]; - assistantLangChain: boolean; + isEnabledKnowledgeBase: boolean; chain: RetrievalQAChain; esClient: ElasticsearchClient; modelExists: boolean; diff --git a/x-pack/plugins/elastic_assistant/tsconfig.json b/x-pack/plugins/elastic_assistant/tsconfig.json index 53616fc2dc2b07..2fd22f015ad8da 100644 --- a/x-pack/plugins/elastic_assistant/tsconfig.json +++ b/x-pack/plugins/elastic_assistant/tsconfig.json @@ -13,6 +13,7 @@ "../../../typings/**/*" ], "kbn_references": [ + "@kbn/analytics-client", "@kbn/core", "@kbn/core-http-server", "@kbn/licensing-plugin", @@ -32,6 +33,7 @@ "@kbn/stack-connectors-plugin", "@kbn/ml-plugin", "@kbn/apm-utils", + "@kbn/core-analytics-server", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/security_solution/public/assistant/use_assistant_telemetry/index.test.tsx b/x-pack/plugins/security_solution/public/assistant/use_assistant_telemetry/index.test.tsx index 2f1c9f58e95b85..a61a740394c7bf 100644 --- a/x-pack/plugins/security_solution/public/assistant/use_assistant_telemetry/index.test.tsx +++ b/x-pack/plugins/security_solution/public/assistant/use_assistant_telemetry/index.test.tsx @@ -27,6 +27,7 @@ const mockedTelemetry = { reportAssistantInvoked, reportAssistantMessageSent, reportAssistantQuickPrompt, + reportAssistantSettingToggled: () => {}, }; jest.mock('../use_conversation_store', () => { diff --git a/x-pack/plugins/security_solution/public/assistant/use_assistant_telemetry/index.tsx b/x-pack/plugins/security_solution/public/assistant/use_assistant_telemetry/index.tsx index 2a06b26a944200..b0896bfb7db665 100644 --- a/x-pack/plugins/security_solution/public/assistant/use_assistant_telemetry/index.tsx +++ b/x-pack/plugins/security_solution/public/assistant/use_assistant_telemetry/index.tsx @@ -43,5 +43,6 @@ export const useAssistantTelemetry = (): AssistantTelemetry => { reportTelemetry({ fn: telemetry.reportAssistantMessageSent, params }), reportAssistantQuickPrompt: (params) => reportTelemetry({ fn: telemetry.reportAssistantQuickPrompt, params }), + reportAssistantSettingToggled: (params) => telemetry.reportAssistantSettingToggled(params), }; }; diff --git a/x-pack/plugins/security_solution/public/common/lib/telemetry/constants.ts b/x-pack/plugins/security_solution/public/common/lib/telemetry/constants.ts index 9733e1454bfaaf..3ce4c5c6b47ebf 100644 --- a/x-pack/plugins/security_solution/public/common/lib/telemetry/constants.ts +++ b/x-pack/plugins/security_solution/public/common/lib/telemetry/constants.ts @@ -44,6 +44,7 @@ export enum TelemetryEventTypes { AssistantInvoked = 'Assistant Invoked', AssistantMessageSent = 'Assistant Message Sent', AssistantQuickPrompt = 'Assistant Quick Prompt', + AssistantSettingToggled = 'Assistant Setting Toggled', EntityDetailsClicked = 'Entity Details Clicked', EntityAlertsClicked = 'Entity Alerts Clicked', EntityRiskFiltered = 'Entity Risk Filtered', diff --git a/x-pack/plugins/security_solution/public/common/lib/telemetry/events/ai_assistant/index.ts b/x-pack/plugins/security_solution/public/common/lib/telemetry/events/ai_assistant/index.ts index 232cc5e0637718..38cf2a4aa2100b 100644 --- a/x-pack/plugins/security_solution/public/common/lib/telemetry/events/ai_assistant/index.ts +++ b/x-pack/plugins/security_solution/public/common/lib/telemetry/events/ai_assistant/index.ts @@ -45,6 +45,20 @@ export const assistantMessageSentEvent: TelemetryEvent = { optional: false, }, }, + isEnabledKnowledgeBase: { + type: 'boolean', + _meta: { + description: 'Is knowledge base enabled', + optional: false, + }, + }, + isEnabledRAGAlerts: { + type: 'boolean', + _meta: { + description: 'Is RAG on Alerts enabled', + optional: false, + }, + }, }, }; @@ -67,3 +81,23 @@ export const assistantQuickPrompt: TelemetryEvent = { }, }, }; + +export const assistantSettingToggledEvent: TelemetryEvent = { + eventType: TelemetryEventTypes.AssistantSettingToggled, + schema: { + isEnabledKnowledgeBase: { + type: 'boolean', + _meta: { + description: 'Is knowledge base enabled', + optional: true, + }, + }, + isEnabledRAGAlerts: { + type: 'boolean', + _meta: { + description: 'Is RAG on Alerts enabled', + optional: true, + }, + }, + }, +}; diff --git a/x-pack/plugins/security_solution/public/common/lib/telemetry/events/ai_assistant/types.ts b/x-pack/plugins/security_solution/public/common/lib/telemetry/events/ai_assistant/types.ts index 5f35a512851d4b..2ada1a90a5e2cf 100644 --- a/x-pack/plugins/security_solution/public/common/lib/telemetry/events/ai_assistant/types.ts +++ b/x-pack/plugins/security_solution/public/common/lib/telemetry/events/ai_assistant/types.ts @@ -16,6 +16,8 @@ export interface ReportAssistantInvokedParams { export interface ReportAssistantMessageSentParams { conversationId: string; role: string; + isEnabledKnowledgeBase: boolean; + isEnabledRAGAlerts: boolean; } export interface ReportAssistantQuickPromptParams { @@ -23,9 +25,15 @@ export interface ReportAssistantQuickPromptParams { promptTitle: string; } +export interface ReportAssistantSettingToggledParams { + isEnabledKnowledgeBase?: boolean; + isEnabledRAGAlerts?: boolean; +} + export type ReportAssistantTelemetryEventParams = | ReportAssistantInvokedParams | ReportAssistantMessageSentParams + | ReportAssistantSettingToggledParams | ReportAssistantQuickPromptParams; export type AssistantTelemetryEvent = @@ -33,6 +41,10 @@ export type AssistantTelemetryEvent = eventType: TelemetryEventTypes.AssistantInvoked; schema: RootSchema<ReportAssistantInvokedParams>; } + | { + eventType: TelemetryEventTypes.AssistantSettingToggled; + schema: RootSchema<ReportAssistantSettingToggledParams>; + } | { eventType: TelemetryEventTypes.AssistantMessageSent; schema: RootSchema<ReportAssistantMessageSentParams>; diff --git a/x-pack/plugins/security_solution/public/common/lib/telemetry/events/telemetry_events.ts b/x-pack/plugins/security_solution/public/common/lib/telemetry/events/telemetry_events.ts index 560e1ea39f08eb..1a330db7b82c28 100644 --- a/x-pack/plugins/security_solution/public/common/lib/telemetry/events/telemetry_events.ts +++ b/x-pack/plugins/security_solution/public/common/lib/telemetry/events/telemetry_events.ts @@ -18,6 +18,7 @@ import { } from './entity_analytics'; import { assistantInvokedEvent, + assistantSettingToggledEvent, assistantMessageSentEvent, assistantQuickPrompt, } from './ai_assistant'; @@ -138,6 +139,7 @@ export const telemetryEvents = [ assistantInvokedEvent, assistantMessageSentEvent, assistantQuickPrompt, + assistantSettingToggledEvent, entityClickedEvent, entityAlertsClickedEvent, entityRiskFilteredEvent, diff --git a/x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.mock.ts b/x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.mock.ts index 459992e5147993..e797c3a49a8e97 100644 --- a/x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.mock.ts +++ b/x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.mock.ts @@ -14,6 +14,7 @@ export const createTelemetryClientMock = (): jest.Mocked<TelemetryClientStart> = reportAssistantInvoked: jest.fn(), reportAssistantMessageSent: jest.fn(), reportAssistantQuickPrompt: jest.fn(), + reportAssistantSettingToggled: jest.fn(), reportEntityDetailsClicked: jest.fn(), reportEntityAlertsClicked: jest.fn(), reportEntityRiskFiltered: jest.fn(), diff --git a/x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts b/x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts index 86c8120bc0035b..04d0ebeaa5ae6a 100644 --- a/x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts +++ b/x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts @@ -23,6 +23,7 @@ import type { ReportAssistantInvokedParams, ReportAssistantMessageSentParams, ReportAssistantQuickPromptParams, + ReportAssistantSettingToggledParams, } from './types'; import { TelemetryEventTypes } from './constants'; @@ -54,10 +55,14 @@ export class TelemetryClient implements TelemetryClientStart { public reportAssistantMessageSent = ({ conversationId, + isEnabledKnowledgeBase, + isEnabledRAGAlerts, role, }: ReportAssistantMessageSentParams) => { this.analytics.reportEvent(TelemetryEventTypes.AssistantMessageSent, { conversationId, + isEnabledKnowledgeBase, + isEnabledRAGAlerts, role, }); }; @@ -72,6 +77,10 @@ export class TelemetryClient implements TelemetryClientStart { }); }; + public reportAssistantSettingToggled = (params: ReportAssistantSettingToggledParams) => { + this.analytics.reportEvent(TelemetryEventTypes.AssistantSettingToggled, params); + }; + public reportEntityDetailsClicked = ({ entity }: ReportEntityDetailsClickedParams) => { this.analytics.reportEvent(TelemetryEventTypes.EntityDetailsClicked, { entity, diff --git a/x-pack/plugins/security_solution/public/common/lib/telemetry/types.ts b/x-pack/plugins/security_solution/public/common/lib/telemetry/types.ts index cf7165323d0e99..c98e0eafcd4343 100644 --- a/x-pack/plugins/security_solution/public/common/lib/telemetry/types.ts +++ b/x-pack/plugins/security_solution/public/common/lib/telemetry/types.ts @@ -34,6 +34,7 @@ import type { ReportAssistantInvokedParams, ReportAssistantQuickPromptParams, ReportAssistantMessageSentParams, + ReportAssistantSettingToggledParams, } from './events/ai_assistant/types'; export * from './events/ai_assistant/types'; @@ -92,6 +93,7 @@ export interface TelemetryClientStart { reportAssistantInvoked(params: ReportAssistantInvokedParams): void; reportAssistantMessageSent(params: ReportAssistantMessageSentParams): void; reportAssistantQuickPrompt(params: ReportAssistantQuickPromptParams): void; + reportAssistantSettingToggled(params: ReportAssistantSettingToggledParams): void; reportEntityDetailsClicked(params: ReportEntityDetailsClickedParams): void; reportEntityAlertsClicked(params: ReportEntityAlertsClickedParams): void; diff --git a/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/alert_counts_tool.test.ts b/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/alert_counts_tool.test.ts index 90ef987e1f84d9..79b9c2e171f0a1 100644 --- a/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/alert_counts_tool.test.ts +++ b/x-pack/plugins/security_solution/server/assistant/tools/alert_counts/alert_counts_tool.test.ts @@ -22,7 +22,7 @@ describe('AlertCountsTool', () => { const replacements = { key: 'value' }; const request = { body: { - assistantLangChain: false, + isEnabledKnowledgeBase: false, alertsIndexPattern: '.alerts-security.alerts-default', allow: ['@timestamp', 'cloud.availability_zone', 'user.name'], allowReplacement: ['user.name'], @@ -30,11 +30,11 @@ describe('AlertCountsTool', () => { size: 20, }, } as unknown as KibanaRequest<unknown, unknown, RequestBody>; - const assistantLangChain = true; + const isEnabledKnowledgeBase = true; const chain = {} as unknown as RetrievalQAChain; const modelExists = true; const rest = { - assistantLangChain, + isEnabledKnowledgeBase, chain, modelExists, }; @@ -57,7 +57,7 @@ describe('AlertCountsTool', () => { it('returns false when the request is missing required anonymization parameters', () => { const requestMissingAnonymizationParams = { body: { - assistantLangChain: false, + isEnabledKnowledgeBase: false, alertsIndexPattern: '.alerts-security.alerts-default', size: 20, }, diff --git a/x-pack/plugins/security_solution/server/assistant/tools/esql_language_knowledge_base/esql_language_knowledge_base_tool.test.ts b/x-pack/plugins/security_solution/server/assistant/tools/esql_language_knowledge_base/esql_language_knowledge_base_tool.test.ts index 19e3bf7e7b40ac..c9605c902f0cae 100644 --- a/x-pack/plugins/security_solution/server/assistant/tools/esql_language_knowledge_base/esql_language_knowledge_base_tool.test.ts +++ b/x-pack/plugins/security_solution/server/assistant/tools/esql_language_knowledge_base/esql_language_knowledge_base_tool.test.ts @@ -19,7 +19,7 @@ describe('EsqlLanguageKnowledgeBaseTool', () => { } as unknown as ElasticsearchClient; const request = { body: { - assistantLangChain: false, + isEnabledKnowledgeBase: false, alertsIndexPattern: '.alerts-security.alerts-default', allow: ['@timestamp', 'cloud.availability_zone', 'user.name'], allowReplacement: ['user.name'], @@ -34,9 +34,9 @@ describe('EsqlLanguageKnowledgeBaseTool', () => { }; describe('isSupported', () => { - it('returns false if assistantLangChain is false', () => { + it('returns false if isEnabledKnowledgeBase is false', () => { const params = { - assistantLangChain: false, + isEnabledKnowledgeBase: false, modelExists: true, ...rest, }; @@ -46,7 +46,7 @@ describe('EsqlLanguageKnowledgeBaseTool', () => { it('returns false if modelExists is false (the ELSER model is not installed)', () => { const params = { - assistantLangChain: true, + isEnabledKnowledgeBase: true, modelExists: false, // <-- ELSER model is not installed ...rest, }; @@ -54,9 +54,9 @@ describe('EsqlLanguageKnowledgeBaseTool', () => { expect(ESQL_KNOWLEDGE_BASE_TOOL.isSupported(params)).toBe(false); }); - it('returns true if assistantLangChain and modelExists are true', () => { + it('returns true if isEnabledKnowledgeBase and modelExists are true', () => { const params = { - assistantLangChain: true, + isEnabledKnowledgeBase: true, modelExists: true, ...rest, }; @@ -66,9 +66,9 @@ describe('EsqlLanguageKnowledgeBaseTool', () => { }); describe('getTool', () => { - it('returns null if assistantLangChain is false', () => { + it('returns null if isEnabledKnowledgeBase is false', () => { const tool = ESQL_KNOWLEDGE_BASE_TOOL.getTool({ - assistantLangChain: false, + isEnabledKnowledgeBase: false, modelExists: true, ...rest, }); @@ -78,7 +78,7 @@ describe('EsqlLanguageKnowledgeBaseTool', () => { it('returns null if modelExists is false (the ELSER model is not installed)', () => { const tool = ESQL_KNOWLEDGE_BASE_TOOL.getTool({ - assistantLangChain: true, + isEnabledKnowledgeBase: true, modelExists: false, // <-- ELSER model is not installed ...rest, }); @@ -86,9 +86,9 @@ describe('EsqlLanguageKnowledgeBaseTool', () => { expect(tool).toBeNull(); }); - it('should return a Tool instance if assistantLangChain and modelExists are true', () => { + it('should return a Tool instance if isEnabledKnowledgeBase and modelExists are true', () => { const tool = ESQL_KNOWLEDGE_BASE_TOOL.getTool({ - assistantLangChain: true, + isEnabledKnowledgeBase: true, modelExists: true, ...rest, }); @@ -98,7 +98,7 @@ describe('EsqlLanguageKnowledgeBaseTool', () => { it('should return a tool with the expected tags', () => { const tool = ESQL_KNOWLEDGE_BASE_TOOL.getTool({ - assistantLangChain: true, + isEnabledKnowledgeBase: true, modelExists: true, ...rest, }) as DynamicTool; diff --git a/x-pack/plugins/security_solution/server/assistant/tools/esql_language_knowledge_base/esql_language_knowledge_base_tool.ts b/x-pack/plugins/security_solution/server/assistant/tools/esql_language_knowledge_base/esql_language_knowledge_base_tool.ts index 3dc7dfd8d976c6..968da6907c21fb 100644 --- a/x-pack/plugins/security_solution/server/assistant/tools/esql_language_knowledge_base/esql_language_knowledge_base_tool.ts +++ b/x-pack/plugins/security_solution/server/assistant/tools/esql_language_knowledge_base/esql_language_knowledge_base_tool.ts @@ -18,8 +18,8 @@ export const ESQL_KNOWLEDGE_BASE_TOOL: AssistantTool = { 'Call this for knowledge on how to build an ESQL query, or answer questions about the ES|QL query language.', sourceRegister: APP_UI_ID, isSupported: (params: AssistantToolParams): params is EsqlKnowledgeBaseToolParams => { - const { assistantLangChain, modelExists } = params; - return assistantLangChain && modelExists; + const { isEnabledKnowledgeBase, modelExists } = params; + return isEnabledKnowledgeBase && modelExists; }, getTool(params: AssistantToolParams) { if (!this.isSupported(params)) return null; diff --git a/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/open_and_acknowledged_alerts_tool.test.ts b/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/open_and_acknowledged_alerts_tool.test.ts index c74f0617231da7..019fc0075679f5 100644 --- a/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/open_and_acknowledged_alerts_tool.test.ts +++ b/x-pack/plugins/security_solution/server/assistant/tools/open_and_acknowledged_alerts/open_and_acknowledged_alerts_tool.test.ts @@ -24,7 +24,7 @@ describe('OpenAndAcknowledgedAlertsTool', () => { const replacements = { key: 'value' }; const request = { body: { - assistantLangChain: false, + isEnabledKnowledgeBase: false, alertsIndexPattern: '.alerts-security.alerts-default', allow: ['@timestamp', 'cloud.availability_zone', 'user.name'], allowReplacement: ['user.name'], @@ -32,11 +32,11 @@ describe('OpenAndAcknowledgedAlertsTool', () => { size: 20, }, } as unknown as KibanaRequest<unknown, unknown, RequestBody>; - const assistantLangChain = true; + const isEnabledKnowledgeBase = true; const chain = {} as unknown as RetrievalQAChain; const modelExists = true; const rest = { - assistantLangChain, + isEnabledKnowledgeBase, esClient, chain, modelExists, @@ -60,7 +60,7 @@ describe('OpenAndAcknowledgedAlertsTool', () => { it('returns false when the request is missing required anonymization parameters', () => { const requestMissingAnonymizationParams = { body: { - assistantLangChain: false, + isEnabledKnowledgeBase: false, alertsIndexPattern: '.alerts-security.alerts-default', size: 20, }, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts index 6787290f0b3967..14ec27598a60fb 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts @@ -436,7 +436,8 @@ export default function bedrockTest({ getService }: FtrProviderContext) { ], }, }, - assistantLangChain: false, + isEnabledKnowledgeBase: false, + isEnabledRAGAlerts: false, }) .pipe(passThrough); const responseBuffer: Uint8Array[] = []; From 29ead617005bf3c22995289b99f1cad60c0b1dc5 Mon Sep 17 00:00:00 2001 From: Milton Hultgren <milton.hultgren@elastic.co> Date: Fri, 22 Dec 2023 20:28:57 +0100 Subject: [PATCH 116/116] [Obs AI Assistant] Make KB use recommended ELSER model (#173543) This PR changes the hard coded ELSER model ID to instead be resolved during service `init` and Knowledge base setup using the ML plugin. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../services/get_shared_ml_services.ts | 1 + x-pack/plugins/ml/public/plugin.ts | 8 +++++- .../observability_ai_assistant/kibana.jsonc | 3 ++- .../public/hooks/use_knowledge_base.tsx | 6 ++++- .../public/types.ts | 3 +++ .../server/plugin.ts | 27 ++++++++++++++++++- .../server/service/index.ts | 13 ++++++--- .../service/knowledge_base_service/index.ts | 27 ++++++++++--------- .../server/types.ts | 12 ++++++++- .../observability_ai_assistant/tsconfig.json | 3 ++- 10 files changed, 80 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/ml/public/application/services/get_shared_ml_services.ts b/x-pack/plugins/ml/public/application/services/get_shared_ml_services.ts index 23ac82737044f3..44e6a5e5746e89 100644 --- a/x-pack/plugins/ml/public/application/services/get_shared_ml_services.ts +++ b/x-pack/plugins/ml/public/application/services/get_shared_ml_services.ts @@ -21,5 +21,6 @@ export function getMlSharedServices(httpStart: HttpStart) { return { elasticModels: new ElasticModels(mlApiServices.trainedModels), + mlApiServices, }; } diff --git a/x-pack/plugins/ml/public/plugin.ts b/x-pack/plugins/ml/public/plugin.ts index a4f0e6e2305417..b476ea10ac72de 100644 --- a/x-pack/plugins/ml/public/plugin.ts +++ b/x-pack/plugins/ml/public/plugin.ts @@ -69,6 +69,7 @@ import { } from '../common/constants/app'; import type { MlCapabilities } from './shared'; import { ElasticModels } from './application/services/elastic_models_service'; +import type { MlApiServices } from './application/services/ml_api_service'; export interface MlStartDependencies { cases?: CasesUiStart; @@ -283,7 +284,11 @@ export class MlPlugin implements Plugin<MlPluginSetup, MlPluginStart> { start( core: CoreStart, deps: MlStartDependencies - ): { locator?: LocatorPublic<MlLocatorParams>; elasticModels?: ElasticModels } { + ): { + locator?: LocatorPublic<MlLocatorParams>; + elasticModels?: ElasticModels; + mlApi?: MlApiServices; + } { setDependencyCache({ docLinks: core.docLinks!, basePath: core.http.basePath, @@ -295,6 +300,7 @@ export class MlPlugin implements Plugin<MlPluginSetup, MlPluginStart> { return { locator: this.locator, elasticModels: this.sharedMlServices?.elasticModels, + mlApi: this.sharedMlServices?.mlApiServices, }; } diff --git a/x-pack/plugins/observability_ai_assistant/kibana.jsonc b/x-pack/plugins/observability_ai_assistant/kibana.jsonc index cd2d4b788bc78b..4024a9361a3729 100644 --- a/x-pack/plugins/observability_ai_assistant/kibana.jsonc +++ b/x-pack/plugins/observability_ai_assistant/kibana.jsonc @@ -20,7 +20,8 @@ "share", "taskManager", "triggersActionsUi", - "dataViews" + "dataViews", + "ml" ], "requiredBundles": [ "kibanaReact", "kibanaUtils"], "optionalPlugins": [], diff --git a/x-pack/plugins/observability_ai_assistant/public/hooks/use_knowledge_base.tsx b/x-pack/plugins/observability_ai_assistant/public/hooks/use_knowledge_base.tsx index 4035a8461098c4..026de6b9ea1c4d 100644 --- a/x-pack/plugins/observability_ai_assistant/public/hooks/use_knowledge_base.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/hooks/use_knowledge_base.tsx @@ -30,6 +30,9 @@ export interface UseKnowledgeBaseResult { export function useKnowledgeBase(): UseKnowledgeBaseResult { const { notifications: { toasts }, + plugins: { + start: { ml }, + }, } = useKibana().services; const service = useObservabilityAIAssistant(); @@ -53,6 +56,7 @@ export function useKnowledgeBase(): UseKnowledgeBaseResult { .callApi('POST /internal/observability_ai_assistant/kb/setup', { signal: null, }) + .then(() => ml.mlApi?.savedObjects.syncSavedObjects()) .then(() => { status.refresh(); }) @@ -82,5 +86,5 @@ export function useKnowledgeBase(): UseKnowledgeBaseResult { isInstalling, installError, }; - }, [status, isInstalling, installError, service, toasts]); + }, [status, isInstalling, installError, service, ml.mlApi?.savedObjects, toasts]); } diff --git a/x-pack/plugins/observability_ai_assistant/public/types.ts b/x-pack/plugins/observability_ai_assistant/public/types.ts index 3c53243ffd48fe..59346dc0af8a2b 100644 --- a/x-pack/plugins/observability_ai_assistant/public/types.ts +++ b/x-pack/plugins/observability_ai_assistant/public/types.ts @@ -30,6 +30,7 @@ import type { LicensingPluginStart, ILicense } from '@kbn/licensing-plugin/publi import type { SharePluginStart } from '@kbn/share-plugin/public'; import { ForwardRefExoticComponent, RefAttributes } from 'react'; import { WithSuspenseExtendedDeps } from '@kbn/shared-ux-utility'; +import { MlPluginSetup, MlPluginStart } from '@kbn/ml-plugin/public'; import type { ContextDefinition, FunctionDefinition, @@ -106,6 +107,7 @@ export interface ObservabilityAIAssistantPluginSetupDependencies { observabilityShared: ObservabilitySharedPluginSetup; security: SecurityPluginSetup; triggersActionsUi: TriggersAndActionsUIPublicPluginSetup; + ml: MlPluginSetup; } export interface ObservabilityAIAssistantPluginStartDependencies { @@ -117,6 +119,7 @@ export interface ObservabilityAIAssistantPluginStartDependencies { security: SecurityPluginStart; share: SharePluginStart; triggersActionsUi: TriggersAndActionsUIPublicPluginStart; + ml: MlPluginStart; } export interface ObservabilityAIAssistantPluginSetup {} diff --git a/x-pack/plugins/observability_ai_assistant/server/plugin.ts b/x-pack/plugins/observability_ai_assistant/server/plugin.ts index 577edfeb1da0c3..e62a80619c6e40 100644 --- a/x-pack/plugins/observability_ai_assistant/server/plugin.ts +++ b/x-pack/plugins/observability_ai_assistant/server/plugin.ts @@ -12,13 +12,14 @@ import { Plugin, PluginInitializerContext, } from '@kbn/core/server'; -import { mapValues } from 'lodash'; +import { mapValues, once } from 'lodash'; import { i18n } from '@kbn/i18n'; import { CONNECTOR_TOKEN_SAVED_OBJECT_TYPE, ACTION_SAVED_OBJECT_TYPE, ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, } from '@kbn/actions-plugin/server/constants/saved_objects'; +import { firstValueFrom } from 'rxjs'; import { OBSERVABILITY_AI_ASSISTANT_FEATURE_ID } from '../common/feature'; import type { ObservabilityAIAssistantConfig } from './config'; import { registerServerRoutes } from './routes/register_routes'; @@ -105,10 +106,34 @@ export class ObservabilityAIAssistantPlugin }; }) as ObservabilityAIAssistantRouteHandlerResources['plugins']; + const getModelId = once(async () => { + // Using once to make sure the same model ID is used during service init and Knowledge base setup + + try { + // Wait for the ML plugin's dependency on the internal saved objects client to be ready + const [_, pluginsStart] = await core.getStartServices(); + + // Wait for the license to be available so the ML plugin's guards pass once we ask for ELSER stats + await firstValueFrom(pluginsStart.licensing.license$); + + const elserModelDefinition = await plugins.ml + .trainedModelsProvider({} as any, {} as any) // request, savedObjectsClient (but we fake it to use the internal user) + .getELSER(); + + return elserModelDefinition.model_id; + } catch (error) { + this.logger.error(`Failed to resolve ELSER model definition: ${error}`); + + // Fallback to ELSER v2 + return '.elser_model_2'; + } + }); + const service = (this.service = new ObservabilityAIAssistantService({ logger: this.logger.get('service'), core, taskManager: plugins.taskManager, + getModelId, })); service.register(registerFunctions); diff --git a/x-pack/plugins/observability_ai_assistant/server/service/index.ts b/x-pack/plugins/observability_ai_assistant/server/service/index.ts index 3d999b090f9cf6..324ee3ed26a007 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/index.ts @@ -66,8 +66,6 @@ export function createResourceNamesMap() { }; } -export const ELSER_MODEL_ID = '.elser_model_2'; - export const INDEX_QUEUED_DOCUMENTS_TASK_ID = 'observabilityAIAssistant:indexQueuedDocumentsTask'; export const INDEX_QUEUED_DOCUMENTS_TASK_TYPE = INDEX_QUEUED_DOCUMENTS_TASK_ID + 'Type'; @@ -84,6 +82,7 @@ type KnowledgeBaseEntryRequest = { id: string; labels?: Record<string, string> } export class ObservabilityAIAssistantService { private readonly core: CoreSetup<ObservabilityAIAssistantPluginStartDependencies>; private readonly logger: Logger; + private readonly getModelId: () => Promise<string>; private kbService?: KnowledgeBaseService; private readonly resourceNames: ObservabilityAIAssistantResourceNames = createResourceNamesMap(); @@ -94,13 +93,16 @@ export class ObservabilityAIAssistantService { logger, core, taskManager, + getModelId, }: { logger: Logger; core: CoreSetup<ObservabilityAIAssistantPluginStartDependencies>; taskManager: TaskManagerSetupContract; + getModelId: () => Promise<string>; }) { this.core = core; this.logger = logger; + this.getModelId = getModelId; taskManager.registerTaskDefinitions({ [INDEX_QUEUED_DOCUMENTS_TASK_TYPE]: { @@ -132,6 +134,8 @@ export class ObservabilityAIAssistantService { try { const [coreStart, pluginsStart] = await this.core.getStartServices(); + const elserModelId = await this.getModelId(); + const esClient = coreStart.elasticsearch.client.asInternalUser; await esClient.cluster.putComponentTemplate({ @@ -153,7 +157,7 @@ export class ObservabilityAIAssistantService { }, mappings: { _meta: { - model: ELSER_MODEL_ID, + model: elserModelId, }, }, }, @@ -186,7 +190,7 @@ export class ObservabilityAIAssistantService { processors: [ { inference: { - model_id: ELSER_MODEL_ID, + model_id: elserModelId, target_field: 'ml', field_map: { text: 'text_field', @@ -237,6 +241,7 @@ export class ObservabilityAIAssistantService { esClient, resources: this.resourceNames, taskManagerStart: pluginsStart.taskManager, + getModelId: this.getModelId, }); this.logger.info('Successfully set up index assets'); diff --git a/x-pack/plugins/observability_ai_assistant/server/service/knowledge_base_service/index.ts b/x-pack/plugins/observability_ai_assistant/server/service/knowledge_base_service/index.ts index e4c4efb168d030..7794ed477d173c 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/knowledge_base_service/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/knowledge_base_service/index.ts @@ -14,11 +14,7 @@ import pLimit from 'p-limit'; import pRetry from 'p-retry'; import { map, orderBy } from 'lodash'; import { encode } from 'gpt-tokenizer'; -import { - ELSER_MODEL_ID, - INDEX_QUEUED_DOCUMENTS_TASK_ID, - INDEX_QUEUED_DOCUMENTS_TASK_TYPE, -} from '..'; +import { INDEX_QUEUED_DOCUMENTS_TASK_ID, INDEX_QUEUED_DOCUMENTS_TASK_TYPE } from '..'; import { KnowledgeBaseEntry, KnowledgeBaseEntryRole } from '../../../common/types'; import type { ObservabilityAIAssistantResourceNames } from '../types'; import { getAccessQuery } from '../util/get_access_query'; @@ -29,6 +25,7 @@ interface Dependencies { resources: ObservabilityAIAssistantResourceNames; logger: Logger; taskManagerStart: TaskManagerStartContract; + getModelId: () => Promise<string>; } export interface RecalledEntry { @@ -81,13 +78,15 @@ export class KnowledgeBaseService { } setup = async () => { + const elserModelId = await this.dependencies.getModelId(); + const retryOptions = { factor: 1, minTimeout: 10000, retries: 12 }; const installModel = async () => { this.dependencies.logger.info('Installing ELSER model'); await this.dependencies.esClient.ml.putTrainedModel( { - model_id: ELSER_MODEL_ID, + model_id: elserModelId, input: { field_names: ['text_field'], }, @@ -101,7 +100,7 @@ export class KnowledgeBaseService { const getIsModelInstalled = async () => { const getResponse = await this.dependencies.esClient.ml.getTrainedModels({ - model_id: ELSER_MODEL_ID, + model_id: elserModelId, include: 'definition_status', }); @@ -132,7 +131,7 @@ export class KnowledgeBaseService { try { await this.dependencies.esClient.ml.startTrainedModelDeployment({ - model_id: ELSER_MODEL_ID, + model_id: elserModelId, wait_for: 'fully_allocated', }); } catch (error) { @@ -145,7 +144,7 @@ export class KnowledgeBaseService { await pRetry(async () => { const response = await this.dependencies.esClient.ml.getTrainedModelsStats({ - model_id: ELSER_MODEL_ID, + model_id: elserModelId, }); if ( @@ -269,9 +268,11 @@ export class KnowledgeBaseService { } status = async () => { + const elserModelId = await this.dependencies.getModelId(); + try { const modelStats = await this.dependencies.esClient.ml.getTrainedModelsStats({ - model_id: ELSER_MODEL_ID, + model_id: elserModelId, }); const elserModelStats = modelStats.trained_model_stats[0]; const deploymentState = elserModelStats.deployment_stats?.state; @@ -281,13 +282,13 @@ export class KnowledgeBaseService { ready: deploymentState === 'started' && allocationState === 'fully_allocated', deployment_state: deploymentState, allocation_state: allocationState, - model_name: ELSER_MODEL_ID, + model_name: elserModelId, }; } catch (error) { return { error: error instanceof errors.ResponseError ? error.body.error : String(error), ready: false, - model_name: ELSER_MODEL_ID, + model_name: elserModelId, }; } }; @@ -435,7 +436,7 @@ export class KnowledgeBaseService { }): Promise<{ entries: RecalledEntry[]; }> => { - const modelId = ELSER_MODEL_ID; + const modelId = await this.dependencies.getModelId(); const [documentsFromKb, documentsFromConnectors] = await Promise.all([ this.recallFromKnowledgeBase({ diff --git a/x-pack/plugins/observability_ai_assistant/server/types.ts b/x-pack/plugins/observability_ai_assistant/server/types.ts index 6e70663be3d8f8..ea2d3ee39e426f 100644 --- a/x-pack/plugins/observability_ai_assistant/server/types.ts +++ b/x-pack/plugins/observability_ai_assistant/server/types.ts @@ -17,7 +17,12 @@ import type { TaskManagerSetupContract, TaskManagerStartContract, } from '@kbn/task-manager-plugin/server'; -import { DataViewsServerPluginStart } from '@kbn/data-views-plugin/server'; +import type { + DataViewsServerPluginSetup, + DataViewsServerPluginStart, +} from '@kbn/data-views-plugin/server'; +import type { MlPluginSetup, MlPluginStart } from '@kbn/ml-plugin/server'; +import type { LicensingPluginSetup, LicensingPluginStart } from '@kbn/licensing-plugin/server'; import { ObservabilityAIAssistantService } from './service'; export interface ObservabilityAIAssistantPluginSetup { @@ -39,6 +44,9 @@ export interface ObservabilityAIAssistantPluginSetupDependencies { security: SecurityPluginSetup; features: FeaturesPluginSetup; taskManager: TaskManagerSetupContract; + dataViews: DataViewsServerPluginSetup; + ml: MlPluginSetup; + licensing: LicensingPluginSetup; } export interface ObservabilityAIAssistantPluginStartDependencies { actions: ActionsPluginStart; @@ -46,4 +54,6 @@ export interface ObservabilityAIAssistantPluginStartDependencies { features: FeaturesPluginStart; taskManager: TaskManagerStartContract; dataViews: DataViewsServerPluginStart; + ml: MlPluginStart; + licensing: LicensingPluginStart; } diff --git a/x-pack/plugins/observability_ai_assistant/tsconfig.json b/x-pack/plugins/observability_ai_assistant/tsconfig.json index 7a4c5d24d8f34a..bf6f8ae0ad30b7 100644 --- a/x-pack/plugins/observability_ai_assistant/tsconfig.json +++ b/x-pack/plugins/observability_ai_assistant/tsconfig.json @@ -55,7 +55,8 @@ "@kbn/dev-cli-runner", "@kbn/core-analytics-browser", "@kbn/core-http-browser", - "@kbn/security-plugin-types-common" + "@kbn/security-plugin-types-common", + "@kbn/ml-plugin" ], "exclude": ["target/**/*"] }