/* Ċ Ġ* ĠĠ ĠCopyright Ġ 2 0 1 9 ĠAmazon . com , ĠInc . Ġor Ġits Ġaffiliates . ĠAll ĠRights ĠReserved . Ċ Ġ* Ċ Ġ* ĠĠ ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "). Ċ Ġ* ĠĠ ĠYou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠĠ ĠA Ġcopy Ġof Ġthe ĠLicense Ġis Ġlocated Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠĠ Ġor Ġin Ġthe Ġ" license " Ġfile Ġaccompanying Ġthis Ġfile . ĠThis Ġfile Ġ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 . Ċ Ġ*/ Ċ Ċ package Ġcom . amazon . opend ist ro fore lastic search . alert ing . rest handler Ċ Ċ import Ġcom . amazon . opend ist ro fore lastic search . alert ing . alerts . Alert Indices Ċ import Ġcom . amazon . opend ist ro fore lastic search . alert ing . model . Alert Ċ import Ġcom . amazon . opend ist ro fore lastic search . alert ing . model . Alert . State . ACK NOW LED GED Ċ import Ġcom . amazon . opend ist ro fore lastic search . alert ing . model . Alert . State . ACTIVE Ċ import Ġcom . amazon . opend ist ro fore lastic search . alert ing . model . Alert . State . COMPLETED Ċ import Ġcom . amazon . opend ist ro fore lastic search . alert ing . model . Alert . State . ERROR Ċ import Ġcom . amazon . opend ist ro fore lastic search . alert ing . util . REFRESH Ċ import Ġcom . amazon . opend ist ro fore lastic search . alert ing . Alert ing Plugin Ċ import Ġcom . amazon . opend ist ro fore lastic search . alert ing . elastic api . optional Time Field Ċ import Ġorg . apache . logging . log 4 j . Log Manager Ċ import Ġorg . apache . logging . log 4 j . Logger Ċ import Ġorg . elasticsearch . action . ActionListener Ċ import Ġorg . elasticsearch . action . bulk . Bulk Request Ċ import Ġorg . elasticsearch . action . bulk . Bulk Response Ċ import Ġorg . elasticsearch . action . search . Search Request Ċ import Ġorg . elasticsearch . action . search . Search Response Ċ import Ġorg . elasticsearch . action . support . Write Request Ċ import Ġorg . elasticsearch . action . support . Write Request . Refresh Policy Ċ import Ġorg . elasticsearch . action . update . Update Request Ċ import Ġorg . elasticsearch . client . node . Node Client Ċ import Ġorg . elasticsearch . common . x content . Logging De precation Handler Ċ import Ġorg . elasticsearch . common . x content . X Content Builder Ċ import Ġorg . elasticsearch . common . x content . X Content Factory Ċ import Ġorg . elasticsearch . common . x content . X Content Helper Ċ import Ġorg . elasticsearch . common . x content . X Content Parser Ċ import Ġorg . elasticsearch . common . x content . X Content Parser Utils . ensure Expected Token Ċ import Ġorg . elasticsearch . common . x content . X ContentType Ċ import Ġorg . elasticsearch . index . query . Query Builders Ċ import Ġorg . elasticsearch . rest . Base Rest Handler Ċ import Ġorg . elasticsearch . rest . Base Rest Handler . Rest Channel Consumer Ċ import Ġorg . elasticsearch . rest . Bytes Rest Response Ċ import Ġorg . elasticsearch . rest . Rest Channel Ċ import Ġorg . elasticsearch . rest . RestController Ċ import Ġorg . elasticsearch . rest . Rest Request Ċ import Ġorg . elasticsearch . rest . Rest Request . Method . POST Ċ import Ġorg . elasticsearch . rest . Rest Status Ċ import Ġorg . elasticsearch . search . builder . Search Source Builder Ċ import Ġjava . io . IOException Ċ import Ġjava . time . Instant Ċ Ċ private Ġval Ġlog : ĠLogger Ġ= ĠLog Manager . getLogger ( Rest Ack nowledge Alert Action :: class . java ) Ċ Ċ /** Ċ Ġ* ĠThis Ġclass Ġconsists Ġof Ġthe ĠREST Ġhandler Ġto Ġacknowledge Ġalerts . Ċ Ġ* ĠThe Ġuser Ġprovides Ġthe Ġmonitor ID Ġto Ġwhich Ġthese Ġalerts Ġpert ain Ġand Ġin Ġthe Ġcontent Ġof Ġthe Ġrequest Ġprovides Ċ Ġ* Ġthe Ġids Ġto Ġthe Ġalerts Ġhe Ġwould Ġlike Ġto Ġacknowledge . Ċ Ġ*/ Ċ class ĠRest Ack nowledge Alert Action ( controller : ĠRest Controller ) Ġ: ĠBase Rest Handler () Ġ{ ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠAck nowledge Ġalerts ĊĠĠĠĠĠĠĠ Ġcontroller . register Handler ( POST , Ġ"${ Alert ing Plugin . MONITOR _ BASE _ URI }/{ monitor ID }/ _ ack nowledge / alerts ", Ġthis ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠgetName (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ" ack nowledge _ alert _ action " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġoverride Ġfun Ġprepare Request ( request : ĠRest Request , Ġclient : ĠNode Client ): ĠRest Channel Consumer Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmonitor Id Ġ= Ġrequest . param (" monitor ID ") ĊĠĠĠĠĠĠĠ Ġrequire (! monitor Id . isNull OrEmpty ()) Ġ{ Ġ" Missing Ġmonitor Ġid ." Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġalert Ids Ġ= Ġget Alert Ids ( request . content Parser ()) ĊĠĠĠĠĠĠĠ Ġrequire ( alert Ids . isNotEmpty ()) Ġ{ Ġ" You Ġmust Ġprovide Ġat Ġleast Ġone Ġalert Ġid ." Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġrefresh Policy Ġ= ĠRefresh Policy . parse ( request . param ( REFRESH , ĠRefresh Policy . IM MEDI ATE . value )) ĊĊĠĠĠĠĠĠĠ Ġreturn ĠRest Channel Consumer Ġ{ Ġchannel Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAck nowledge Handler ( client , Ġchannel , Ġmonitor Id , Ġalert Ids , Ġrefresh Policy ). start () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinner Ġclass ĠAck nowledge Handler ( ĊĠĠĠĠĠĠĠ Ġclient : ĠNode Client , ĊĠĠĠĠĠĠĠ Ġchannel : ĠRest Channel , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġmonitor Id : ĠString , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġalert Ids : ĠList < String >, ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġrefresh Policy : ĠWrite Request . Refresh Policy ? ĊĠĠĠ Ġ) Ġ: ĠAsync Action Handler ( client , Ġchannel ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġalerts Ġ= Ġmutable Map Of < String , ĠAlert >() ĊĊĠĠĠĠĠĠĠ Ġfun Ġstart () Ġ= Ġfind Active Alerts () ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġfind Active Alerts () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġquery Builder Ġ= ĠQuery Builders . bool Query () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter ( Query Builders . term Query ( Alert . MONITOR _ ID _ FIELD , Ġmonitor Id )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter ( Query Builders . terms Query ("_ id ", Ġalert Ids )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsearch Request Ġ= ĠSearch Request () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. indices ( Alert Indices . ALERT _ INDEX ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. routing ( monitor Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. source ( Search Source Builder (). query ( query Builder ). version ( true ). seq No And Primary Term ( true )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġclient . search ( search Request , ĠActionListener . wrap (:: on Search Response , Ġ:: on Failure )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġon Search Response ( response : ĠSearch Response ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġupdate Requests Ġ= Ġresponse . hits . flatMap Ġ{ Ġhit Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġx cp Ġ= ĠX Content Helper . create Parser ( channel . request (). x Content Registry , ĠLogging De precation Handler . INSTANCE , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhit . source Ref , ĠX ContentType . JSON ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġensure Expected Token ( X Content Parser . Token . START _ OBJECT , Ġx cp . nextToken (), Ġx cp :: getToken Location ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġalert Ġ= ĠAlert . parse ( x cp , Ġhit . id , Ġhit . version ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġalerts [ alert . id ] Ġ= Ġalert ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( alert . state Ġ== ĠACT IVE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Update Request ( Alert Indices . ALERT _ INDEX , Ġhit . id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. routing ( monitor Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set If Seq No ( hit . seq No ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set If Primary Term ( hit . primary Term ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. doc ( X Content Factory . json Builder (). start Object () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. field ( Alert . STATE _ FIELD , ĠACK NOW LED GED . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. optional Time Field ( Alert . ACK NOW LED GED _ TIME _ FIELD , ĠInstant . now ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. end Object ())) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġempty List () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Ack nowled ging Ġmonitor : Ġ$ monitor Id , Ġalerts : Ġ${ update Requests . map Ġ{ Ġit . id () Ġ}} ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠBulk Request (). add ( update Requests ). set Refresh Policy ( refresh Policy ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclient . bulk ( request , ĠActionListener . wrap (:: on Bulk Response , Ġ:: on Failure )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġon Bulk Response ( response : ĠBulk Response ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmissing Ġ= Ġalert Ids . to Mutable Set () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġacknowled ged Ġ= Ġmutable ListOf < Alert >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfailed Ġ= Ġmutable ListOf < Alert >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFirst Ġhandle Ġall Ġalerts Ġthat Ġaren 't Ġcurrently ĠACT IVE . ĠThese Ġcan 't Ġbe Ġacknowled ged . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġalerts . values . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . state Ġ!= ĠACT IVE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmissing . remove ( it . id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfailed . add ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNow Ġhandle Ġall Ġalerts Ġwe Ġtried Ġto Ġacknowledge ... ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . items . forEach Ġ{ Ġitem Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmissing . remove ( item . id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( item . is Failed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfailed . add ( alerts [ item . id ] !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġacknowled ged . add ( alerts [ item . id ] !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġchannel . send Response ( Bytes Rest Response ( Rest Status . OK , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse Builder ( channel . newBuilder (), Ġacknowled ged . toList (), Ġfailed . toList (), Ġmissing . toList ()))) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠParse Ġthe Ġrequest Ġcontent Ġand Ġreturn Ġa Ġlist Ġof Ġthe Ġalert Ġids Ġto Ġacknowledge ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġget Alert Ids ( x cp : ĠX Content Parser ): ĠList < String > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġids Ġ= Ġmutable ListOf < String >() ĊĠĠĠĠĠĠĠ Ġensure Expected Token ( X Content Parser . Token . START _ OBJECT , Ġx cp . nextToken (), Ġx cp :: getToken Location ) ĊĠĠĠĠĠĠĠ Ġwhile Ġ( x cp . nextToken () Ġ!= ĠX Content Parser . Token . END _ OBJECT ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠfieldName Ġ= Ġx cp . current Name () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġx cp . nextToken () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( fieldName ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" alerts " Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġensure Expected Token ( X Content Parser . Token . START _ ARRAY , Ġx cp . current Token (), Ġx cp :: getToken Location ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( x cp . nextToken () Ġ!= ĠX Content Parser . Token . END _ ARRAY ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġids . add ( x cp . text ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġids ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠBuild Ġthe Ġresponse Ġcontaining Ġthe Ġacknowled ged Ġalerts Ġand Ġthe Ġfailed Ġto Ġacknowledge Ġalerts . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġresponse Builder ( ĊĠĠĠĠĠĠĠ Ġbuilder : ĠX Content Builder , ĊĠĠĠĠĠĠĠ Ġacknowled ged Alerts : ĠList < Alert >, ĊĠĠĠĠĠĠĠ Ġfailed Alerts : ĠList < Alert >, ĊĠĠĠĠĠĠĠ Ġmissing : ĠList < String > ĊĠĠĠ Ġ): ĠX Content Builder Ġ{ ĊĠĠĠĠĠĠĠ Ġbuilder . start Object (). start Array (" success ") ĊĠĠĠĠĠĠĠ Ġacknowled ged Alerts . forEach Ġ{ Ġbuilder . value ( it . id ) Ġ} ĊĠĠĠĠĠĠĠ Ġbuilder . end Array (). start Array (" failed ") ĊĠĠĠĠĠĠĠ Ġfailed Alerts . forEach Ġ{ Ġbuild Failed Alert Ack nowledge Object ( builder , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġmissing . forEach Ġ{ Ġbuild Missing Alert Ack nowledge Object ( builder , Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġbuilder . end Array (). end Object () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġbuild Failed Alert Ack nowledge Object ( builder : ĠX Content Builder , Ġfailed Alert : ĠAlert ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbuilder . start Object () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. start Object ( failed Alert . id ) ĊĠĠĠĠĠĠĠ Ġval Ġreason Ġ= Ġwhen Ġ( failed Alert . state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠERROR Ġ-> Ġ" Alert Ġis Ġin Ġan Ġerror Ġstate Ġand Ġcan Ġnot Ġbe Ġacknowled ged ." ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCOMP LETED Ġ-> Ġ" Alert Ġhas Ġalready Ġcompleted Ġand Ġcan Ġnot Ġbe Ġacknowled ged ." ĊĠĠĠĠĠĠĠĠĠĠĠ ĠACK NOW LED GED Ġ-> Ġ" Alert Ġhas Ġalready Ġbeen Ġacknowled ged ." ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ" Alert Ġstate Ġunknown Ġand Ġcan Ġnot Ġbe Ġacknowled ged " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġbuilder . field (" failed _ reason ", Ġreason ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. end Object () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. end Object () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġbuild Missing Alert Ack nowledge Object ( builder : ĠX Content Builder , Ġalert ID : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbuilder . start Object () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. start Object ( alert ID ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. field (" failed _ reason ", Ġ" Alert : Ġ$ alert ID Ġdoes Ġnot Ġexist Ġ( it Ġmay Ġhave Ġalready Ġcompleted ). ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. end Object () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. end Object () ĊĠĠĠ Ġ} Ċ } Ċ