From 053f448b31bfce52622a7b7140ef0ee5ea83de5a Mon Sep 17 00:00:00 2001 From: Erik Amaru Ortiz Date: Mon, 3 Oct 2011 11:45:25 -0400 Subject: [PATCH] BUG 0000 Case Notes improvements --- .../skinEngine/base/css/pmos-xtheme-gray.css | 124 +++++++- workflow/engine/templates/app/main.js | 278 +++++++++++------- workflow/engine/templates/cases/casesList.js | 5 +- workflow/public_html/images/delete-icon.png | Bin 1235 -> 713 bytes workflow/public_html/images/notes.png | Bin 1541 -> 898 bytes 5 files changed, 303 insertions(+), 104 deletions(-) diff --git a/workflow/engine/skinEngine/base/css/pmos-xtheme-gray.css b/workflow/engine/skinEngine/base/css/pmos-xtheme-gray.css index d14b98292..a037855e0 100755 --- a/workflow/engine/skinEngine/base/css/pmos-xtheme-gray.css +++ b/workflow/engine/skinEngine/base/css/pmos-xtheme-gray.css @@ -916,6 +916,128 @@ antes funcionaba. clear:none; } +/*! + * Ext JS Library 3.3.3 + * Copyright(c) 2006-2011 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license + */ +/* StatusBar - structure */ +.x-statusbar .x-status-text { + cursor: default; +/* + height: 21px; + line-height: 21px; + padding: 0 4px; +*/ +} +.x-statusbar .x-status-busy { + padding-left: 25px !important; + background: transparent no-repeat 3px 2px; +} + +.x-toolbar div.xtb-text + +.x-statusbar .x-status-text-panel { + border-top: 1px solid; + border-right: 1px solid; + border-bottom: 1px solid; + border-left: 1px solid; + padding: 2px 8px 2px 5px; +} + +/* StatusBar word processor example styles */ + +#word-status .x-status-text-panel .spacer { + width: 60px; + font-size:0; + line-height:0; +} +#word-status .x-status-busy { + padding-left: 25px !important; + background: transparent no-repeat 3px 2px; +} +#word-status .x-status-saved { + padding-left: 25px !important; + background: transparent no-repeat 3px 2px; +} + +/* StatusBar form validation example styles */ + +.x-statusbar .x-status-error { + cursor: pointer; + padding-left: 25px !important; + background: transparent no-repeat 3px 2px; +} +.x-statusbar .x-status-valid { + padding-left: 25px !important; + background: transparent no-repeat 3px 2px; +} +.x-status-error-list { + font: 11px tahoma,arial,verdana,sans-serif; + position: absolute; + z-index: 9999; + border-top: 1px solid; + border-right: 1px solid; + border-bottom: 1px solid; + border-left: 1px solid; + padding: 5px 10px; +} +.x-status-error-list li { + cursor: pointer; + list-style: disc; + margin-left: 10px; +} +.x-status-error-list li a { + text-decoration: none; +} +.x-status-error-list li a:hover { + text-decoration: underline; +} + + +/* *********************************************************** */ +/* *********************************************************** */ +/* *********************************************************** */ + + +/* StatusBar - visual */ + +.x-statusbar .x-status-busy { + background-image: url(../images/ext/default/loading.gif); +} +.x-statusbar .x-status-text-panel { + border-color: #99bbe8 #fff #fff #99bbe8; +} + +/* StatusBar word processor example styles */ + +#word-status .x-status-text { + color: #777; +} +#word-status .x-status-busy { + background-image: url(../images/ext/default/saving.gif); +} +#word-status .x-status-saved { + background-image: url(../images/ext/default/saved.png); +} + +/* StatusBar form validation example styles */ + +.x-statusbar .x-status-error { + color: #C33; + background-image: url(../images/ext/default/exclamation.gif); +} +.x-statusbar .x-status-valid { + background-image: url(../images/ext/default/accept.png); +} +.x-status-error-list { + border-color: #C33; +} +.x-status-error-list li a { + color: #15428B; +} + .x-pm-startcase-btn { background-image:url(/images/start.png) !important; color: #000 !important; @@ -946,7 +1068,7 @@ antes funcionaba. .x-toolbar1 .x-btn-br { background-position: -3px -3px; } .x-toolbar1 .x-btn-bc { background-position: 0 -15px; } - +.x-text-plain { font-weight: bold; } /* Case Notes styles */ diff --git a/workflow/engine/templates/app/main.js b/workflow/engine/templates/app/main.js index 420394b82..fd069e8fb 100644 --- a/workflow/engine/templates/app/main.js +++ b/workflow/engine/templates/app/main.js @@ -1,6 +1,8 @@ -/* Case Notes - Start */ -var newNoteAreaActive = false; +var newNoteAreaActive; var caseNotesWindow; +var storeNotes; +var appUid; +var title; function closeCaseNotesWindow(){ if(Ext.get("caseNotesWindowPanel")){ @@ -8,14 +10,15 @@ function closeCaseNotesWindow(){ } } -function openCaseNotesWindow(appUid,modalSw) +function openCaseNotesWindow(appUid1, modalSw, appTitle) { - if(!appUid) appUid=""; - + Ext.QuickTips.init(); + appUid = !appUid1 ? "": appUid1; + title = appTitle; var startRecord=0; var loadSize=10; - var storeNotes = new Ext.data.JsonStore({ + storeNotes = new Ext.data.JsonStore({ url : '../appProxy/getNotesList?appUid='+appUid, root: 'notes', totalProperty: 'totalCount', @@ -41,16 +44,14 @@ function openCaseNotesWindow(appUid,modalSw) var panelNotes = new Ext.Panel({ id:'notesPanel', - frame:true, autoWidth:true, autoHeight:true, - collapsible:false, - items:[ + collapsible:false, + items:[ new Ext.DataView({ store: storeNotes, loadingtext:_('ID_CASE_NOTES_LOADING'), - // autoScroll:true, emptyText: _('ID_CASE_NOTES_EMPTY'), cls: 'x-cnotes-view', tpl: '' + @@ -100,7 +101,7 @@ function openCaseNotesWindow(appUid,modalSw) hidden:true, text:_('ID_CASE_NOTES_MORE'), align:'center', - handler:function() { + handler:function() { startRecord=startRecord+loadSize; limitRecord=startRecord+loadSize; storeNotes.load({ @@ -114,71 +115,6 @@ function openCaseNotesWindow(appUid,modalSw) ] }); - var tbar = [ - { - //xtype:'textfield', - xtype : 'textarea', - id : 'caseNoteText', - name : 'caseNoteText', - hideLabel : true, - blankText : '...', - //anchor: '100%', - width : 248, - grow : true, - maxLenght : 150, - allowBlank:true, - selectOnFocus:true, - height : 40, - growMin: 39, - growMax: 80 - }, - ' ', - { - cls: 'x-toolbar1', - text: _('ID_SEND'), - //iconCls: 'x-pm-notes-btn', - scale: 'large', - stype:'button', - iconAlign: 'top', - handler: function(){ - var noteText = Ext.getCmp('caseNoteText').getValue(); - - if (noteText == "") { - return false; - } - - newNoteHandler(); - - Ext.getCmp('caseNoteText').focus(); - Ext.getCmp('caseNoteText').reset(); - statusBarMessage( _('ID_CASES_NOTE_POSTING'), true); - Ext.Ajax.request({ - url : '../appProxy/postNote' , - params : { - appUid:appUid, - noteText:noteText - }, - success: function ( result, request ) { - var data = Ext.util.JSON.decode(result.responseText); - if(data.success=="success"){ - statusBarMessage( _('ID_CASES_NOTE_POST_SUCCESS'), false,true); - storeNotes.load(); - }else{ - statusBarMessage( _('ID_CASES_NOTE_POST_ERROR'), false,false); - Ext.MessageBox.alert(_('ID_CASES_NOTE_POST_ERROR'), data.message); - - } - }, - failure: function ( result, request) { - statusBarMessage( _('ID_CASES_NOTE_POST_FAILED'), false,false); - Ext.MessageBox.alert(_('ID_CASES_NOTE_POST_FAILED'), result.responseText); - } - }); - } - } - ]; - - caseNotesWindow = new Ext.Window({ title: _('ID_CASES_NOTES'), //Title of the Window id: 'caseNotesWindowPanel', //ID of the Window Panel @@ -193,6 +129,7 @@ function openCaseNotesWindow(appUid,modalSw) minWidth:300, minHeight:200, proxyDrag: true, + constrain: true, keys: { key: 27, fn : function(){ @@ -209,7 +146,53 @@ function openCaseNotesWindow(appUid,modalSw) } } ], - tbar:tbar, + tbar:[ + new Ext.form.TextArea({ + text : 'New Note', + xtype : 'textarea', + id : 'caseNoteText', + name : 'caseNoteText', + width : 280, + grow : true, + height : 40, + growMin: 40, + growMax: 80, + maxLengthText : 150, + allowBlank :true, + selectOnFocus :true, + enableKeyEvents: true, + listeners : { + scope : this, + keyup : updateTextCtr, + keydown: updateTextCtr + } + }) + ], + rowtbar: [ + [ + '->', + '150', + ' ', + { + id: 'sendBtn', + text: 'Send', + cls: 'x-toolbar1', + handler: sendNote + }, ' ', + { + id: 'addCancelBtn', + text: 'Cancel', + cls: 'x-toolbar1', + //iconCls: 'xx', + icon: '/images/add_notes.png', + handler: newNoteHandler, + tooltip: { + title: 'Add new note', + text: 'Case: ' + title + } + } + ] + ], bbar:[ new Ext.ux.StatusBar({ defaultText : _('ID_NOTES_READY'), @@ -219,19 +202,7 @@ function openCaseNotesWindow(appUid,modalSw) //iconCls: 'ready-icon', statusAlign: 'left', items: [] // any standard Toolbar items: - }), '->', - { - id: 'newNoteButton', - text: _('ID_NEW_NOTE'), - handler: newNoteHandler - }, - { - text: _('ID_CANCEL'), - handler: function() - { - caseNotesWindow.close(); - } - } + }) ], listeners: { show:function() { @@ -248,32 +219,102 @@ function openCaseNotesWindow(appUid,modalSw) } }); - caseNotesWindow.getTopToolbar().hide(); + newNoteAreaActive = false; caseNotesWindow.show(); + newNoteHandler(); +} + +function updateTextCtr(body, event) { + + ctr = document.getElementById('countChar').innerHTML; + + text = Ext.getCmp('caseNoteText').getValue(); + maxLength = 150; + + if (text.length > maxLength) { + Ext.getCmp('caseNoteText').setValue(Ext.getCmp('caseNoteText').getValue().substr(0,150)); + } + else { + document.getElementById('countChar').innerHTML = maxLength - text.length; + } } function newNoteHandler() { newNoteAreaActive = newNoteAreaActive ? false : true; if (newNoteAreaActive) { - Ext.getCmp('newNoteButton').setText(_('ID_CANCEL_NEW_NOTE')); + Ext.getCmp('addCancelBtn').setText(''); + Ext.getCmp('addCancelBtn').setTooltip({ + title: _('ID_CASES_NOTES_ADD'), + text: _('ID_CASE') +': '+ title + }); + + Ext.getCmp('addCancelBtn').setIcon('/images/comment_add.gif'); + + caseNotesWindow.getTopToolbar().hide(); + Ext.getCmp('sendBtn').hide(); + document.getElementById('countChar').style.display = 'none'; + caseNotesWindow.doLayout(); + } + else { + Ext.getCmp('addCancelBtn').setText(''); + Ext.getCmp('addCancelBtn').setTooltip({title: _('ID_CASES_NOTES_CANCEL')}); + Ext.getCmp('addCancelBtn').setIcon('/images/cancel.png'); + caseNotesWindow.getTopToolbar().show(); + Ext.getCmp('sendBtn').show(); + document.getElementById('countChar').style.display = 'block'; Ext.getCmp('caseNoteText').focus(); Ext.getCmp('caseNoteText').reset(); - } - else { - Ext.getCmp('newNoteButton').setText(_('ID_NEW_NOTE')); - caseNotesWindow.getTopToolbar().hide(); + document.getElementById('countChar').innerHTML = '150'; + caseNotesWindow.doLayout(); } + caseNotesWindow.doLayout(); } +function sendNote() +{ + var noteText = Ext.getCmp('caseNoteText').getValue(); + + if (noteText == "") { + return false; + } + + newNoteHandler(); + + Ext.getCmp('caseNoteText').focus(); + Ext.getCmp('caseNoteText').reset(); + statusBarMessage( _('ID_CASES_NOTE_POSTING'), true); + Ext.Ajax.request({ + url : '../appProxy/postNote' , + params : { + appUid : appUid, + noteText: noteText + }, + success: function ( result, request ) { + var data = Ext.util.JSON.decode(result.responseText); + if(data.success=="success"){ + statusBarMessage( _('ID_CASES_NOTE_POST_SUCCESS'), false,true); + storeNotes.load(); + } + else{ + statusBarMessage( _('ID_CASES_NOTE_POST_ERROR'), false,false); + Ext.MessageBox.alert(_('ID_CASES_NOTE_POST_ERROR'), data.message); + + } + }, + failure: function ( result, request) { + statusBarMessage( _('ID_CASES_NOTE_POST_FAILED'), false,false); + Ext.MessageBox.alert(_('ID_CASES_NOTE_POST_FAILED'), result.responseText); + } + }); +} + function statusBarMessage( msg, isLoading, success ) { - // console.log("Status Bar needed"); - // console.log(msg); var statusBar = Ext.getCmp('notesStatusPanel'); if( !statusBar ) return; - // console.log("Status bar acceced: "+msg); + if( isLoading ) { statusBar.showBusy(msg); } @@ -283,13 +324,13 @@ function statusBarMessage( msg, isLoading, success ) { if( success ) { statusBar.setStatus({ text: '' + msg, - //iconCls: 'success', + iconCls: 'x-status-valid', clear: true }); } else { statusBar.setStatus({ text: 'Error: ' + msg, - //iconCls: 'error', + iconCls: 'x-status-error', clear: true }); } @@ -297,7 +338,11 @@ function statusBarMessage( msg, isLoading, success ) { } + +//------------------------------------------------------------------------------------- + /* Case Notes - End */ + /* Case Summary - Start */ var openSummaryWindow = function(appUid, delIndex) { @@ -367,3 +412,34 @@ var openSummaryWindow = function(appUid, delIndex) }); } /* Case Summary - End*/ + + + +Ext.Panel.prototype.originalonRender = Ext.Panel.prototype.onRender; + +// override onRender method +Ext.Panel.prototype.onRender = function(ct, position) { + this.originalonRender(ct, position); + + // use the custom rowtbar argument to add it to this TopToolbar + if(this.tbar && this.rowtbar){ + var rowtbar = this.rowtbar; + if(!Ext.isArray(rowtbar)) + return; + + for(var i = 0; i < rowtbar.length; i ++) { + new Ext.Toolbar(rowtbar[i]).render(this.tbar); + } + } + + // use the custom rowbbar argument to add it to this BottomToolbar + if(this.bbar && this.rowbbar) { + var rowbbar = this.rowbbar; + if(!Ext.isArray(rowbbar)) + return; + + for(var i = 0; i < rowbbar.length; i ++) { + new Ext.Toolbar(rowbbar[i]).render(this.bbar); + } + } +} \ No newline at end of file diff --git a/workflow/engine/templates/cases/casesList.js b/workflow/engine/templates/cases/casesList.js index c19fa4258..6c4881ebd 100644 --- a/workflow/engine/templates/cases/casesList.js +++ b/workflow/engine/templates/cases/casesList.js @@ -375,8 +375,9 @@ Ext.onReady ( function() { }; function renderNote(val,p,r) { - appUid="'"+r.data['APP_UID']+"'"; - return ''; + appUid = r.data['APP_UID']; + title = r.data['APP_TITLE']; + return ''; } function showField (value,p,r) { diff --git a/workflow/public_html/images/delete-icon.png b/workflow/public_html/images/delete-icon.png index 8ef668c889419791f50824708d36cbe304b3d730..7640cd5f78e4ac283c79ac9be28640ea93efddf9 100755 GIT binary patch literal 713 zcmV;)0yh1LP) zw53{*2K3q+MFegEzPgS^xjHiL2?sfp2G-`R3c1Wrou<4SI{Ztq$T&5$qz^PGBIISwVOxDW&y% zPA?E~TQ8a{Z4;e)ys&NRg{7|t9M3^oTtb%kfqxc$*7Y--r1dw~(Hm4ew7%qcmrvk9!@q3$ATj0v_KGYOn4fdh;U& zkM;lQQ_3S2ied2h05%`lO(p%Lrf~3Qew@GCVe8_}ZRh$Ac~P2vgts3|@WoS@nKwg~ zRR;RbVsmRydK1OQeLG>aw+C6Rs=?p2*Nf`hODI(t!w+NZqtwrSu`%dlN=-%O{R?z@ zcYxOND!2m{3m_MYL_k3*bf(!kEoc-|qdCfvi)C2tMv&UWyrRLwl`=$GVaUIJg2Yq+ z{~C?aT!V*P0;IN|c2Fy)(vYe03f?{a)FMD*dQL?YX$K$zSSaSJP%1LRQn~xDw)NxC zT!UB6Rfzz;(Gl)vB{W;p7k@o}l0h%h;AJI^ju4?Egp-LPYGsA}pwAO07@2zES%g6! zV?VK?;QNmv9U;s%G3>NY+HJ;Q?*;?@$ClG7gq(8OFJ#A>t9;FAziu~k{%)rMWc^pQ zI-$nJI)p+!91yajEyr}l>6kPbxS-3dp?w{&*7!S4b_cmKkSTGfDcYsef_Qe-Yor!( vIC_Zl6C5RI9K<5QZFv{}NyTe<)!33K*Df00000NkvXXu0mjfS&>A7 literal 1235 zcmV;^1T6cBP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXZ1 z4+b$c;|h@g00dJ>L_t(I%UzVoZir2axhWda&TbkcPO>4ksT$1^fr0 z#&%O08spS&LrhE+=(rJ_?w(MS0vdRDO$ZI#YL(J_hJ4k*f|^7e5%BTLsGGNC z*Y@`_JUY#6p+@(xr@H4Ly=61$Z4Z)IvjW|T_}`Oc>OMZ=v_S0I zgB$_Sdm9Q=T#pqaQuWR#*1YgMD-Z4`xiUq=#6`T3VS-x|P{^ZcI?1+XS_~b(T%+g( zD+9!q2M|B}f~p&xjZs>sT-7ic(z)X)mc92jT>b_1&F5It8H~1WMBS%+eG)$~30gYP z;z?F_wNmyLnRCO<5?%w|5w{-dV)l4O={@V%{KWyx%oXy7K4el~&hooAlAOHC_}C(1 z{XI10=c!LlQEzNUDS=(IxLk3lNmU79lm1f7P&2a*Yj!+Jx>Zs7>NBpC5=3|IrRRxf zSr{3o)^#Vn?;jw(ZavP#ICgf4nimj7UrT6J#qjGPZ|OGNVP>P0EEjZlMC2fo?Vs zFDzhM6=>_i86Ckoa~490+0#ScuAQ`R>L;FvqASHxAPJQOIH4_D*F@2+Q&_4XB8@~> zt-`x>p2b54vCj=MbLdlscfCmN;t==&gEmUpNnItW-ModGa9!QFoL!oL>EZ1-y_unF31-{-(7y=kdf&fCG zuH?qR@t&zKmG|UIR?2KJ5xPbYN_@{J@IzD>`U-Uv_(&iw?L~&Se>Q-I1`Hqp7ywPd xS|PM21!603mr}|AvI=z!I0BsChjRHJ{{WRTOtC3fYw!R7002ovPDHLkV1j6sC$j(m diff --git a/workflow/public_html/images/notes.png b/workflow/public_html/images/notes.png index c9a04817c5c51e8eba5c1f39e63986341e2e8565..723e0624a86ba2141465df3f95cbb4bd9673f79b 100755 GIT binary patch delta 851 zcmV-Z1FZao41xzCiBL{Q4GJ0x0000DNk~Le0000G0000G2nGNE03Y-JVUZy|e+eBE z77b?ye>?yH0|H4zK~y-)b&@-8TxAf3pZU(&v)PNim#n=uyLRLto7g6V0)$Xx$p{KW z0ivP+A<7ic@C&HYAtB`lP=XK*MT7`K2oMPbB`82J@&zZ3yw9@4VgYe-1YyYu6LT4E-=FZ0#RC**F?Bn%&`+Vv!ZKZb)yR4k8=t3ng>7+|!72+sRL;(cC$g*?4t6Q}r+1P78r=nA?e; zYC)!oX%xY#Y78nUs>C58;5tU`ANBctyBQ3E(7Jd4=pY;f>@^BcSAShUkXU9U2 za1CRr1i7?_A4c?tA?}0Da0Vc>ileCNBOo5Fs#u6MLQ4=EA|eg`ybQFZtnq6tM2bA;abRnBGt{7=f71LZ@ ztI2Y|sPmPA=2D4xf1o!Ar9TP?!ic}?ZLY2Dhf$>N@~M-f6P}|kf2y}9^QlXtAbRiW z?R|-?+GiKavR&_R<>n4UKO~#-5J5c0fXd~=&fwERHW`eiy?p`L*n3d9bI|?h^7Xqf zonM;H&sTH$-ETGN^nJR0|Hs45;LCjGME~*W@kBo3ee>pvi#P5awCVIh++Wt~%vXwg z7eBfFfgePrR&TWWfAiXbY}8u3v9fS$6hs%^`S8l->e(4RHIb1@DdPjolymV#uC3L0 ze(^C@-v4ZBc5?h<;N`{HBIlQ;|E!$MzBXUYZ;A;2u1jD1%Db;VjmYuwfzha_JSGmW%bh?~-Wv)CvDLpqe&bhhLSGkOLLqzmW dz4N~?z(3wPjazJD5{v)<002ovPDHLkV1m*Kp;rI^ delta 1499 zcmV<11tj`{2ZanFiBL{Q4GJ0x0000DNk~Le0000U0000O2nGNE0PSf_zmXw6e+Uy4 z0T)LWO4a}X1%*jOK~zY`t(Mzw6jdC@zrS;4X0Nl`ZdUx-0{QR5553kk$%;su3@5`n@(OD~pXyWMv0JF`18=jX$2 zcS|TzjK5@)nUg)|^SgfM;KW!Ge<#M0_`hs4k-}&qb<6+J(nHCrMm^?NFU(})zbDdm zreMKw6@;LhZWMwr5I5zfzIOZG^_^2ezkZ5{##iH@w)C)2wA-2ShU==B8PuUkf?{6o z+YKfN2>W#?#mMBXv!>&{1K{?+C(fss2xT*1#D)iA=xz@|*F*yjfUkFef5A|Su~4uv zpSSSW)WY3L@!)Dp(gaVZi!24Hk%0~j#v_OXeGr16R6T0Ok^?O;fnaEoT~E>2Oc_P1 z=D%%lrRqQm0Yevvh5fJ`51zvSH(5;>GXn(ZQosxv)EN!HaTSUc$GsKs@A(4ObwyfW zA_6tC=`n*DtzQF8MD=DPe^IZo05l@#Qb3agLlZTuvY(sarBW_`Uk-IWg+Xj9It)#se`GsI=d49RbOgZl zU?HeAvrO>o1e+OE4Ff;!9+5T#B2`d zrWVV*EU!)QhMuS(Le#E#I5(BywVh!EeHsOQ8vKStp;AR^v5Y70Ux!V7?FjfZD6Rtl z5HEu(uGinLxnKrPeG)KGWyU|*++ zvy&NIPUcamx|p6TVj*vXnc*=vA_Y7KJk?lJfah`jT>-Age{fs{PjN%#2!dK7q<#0t z42TGi-?t6`ik_!FJUyOPCEIJ8L$T!k`VMs z6s%S%6$6q0DeGs1eHwg*M8$TRC(}xjxw${qT#UB`bpoPhP)EEiSn7#|J_rZ&2m0gY zjx$&0QK>oH+YutaE+7n9k4_5IT!otB0w81x7GGN|e^X*Mi<0GF>m6MY0OFICBd%LC zWH>~0@y@l;dxraC-v@m9fkVg6ztGni-Zq^sm?gVLWxJh+2V(H+f+|&)vz01JmP1x! zgi_fuU7XFTU&pRp+cMbUe`s@0LX#~?)ovoFDIz>81Q}8a3jp@+8u{Y*>FKNeYr@~2 zzC3RpfBt0xeO+PLn#5=#jiaMea6N^Nh#y3RPScNQ$S4kVN1sn+tuZMmAc*E}xPdI$ zmp@*{bB}Jksl;EomfQE~cNh0&i`DIWcMoGGUF1`VIf}OhQK-~To}J1Z4j8(zp(hd= zh?~im9=q#(B5HQkHzy~tXZ!lwxJzA1HJyC-_)#002ovPDHLkV1kEh Bw|@Wt