From 557d27551ebb0f2e0bc8bc303c258d3d81b1ab48 Mon Sep 17 00:00:00 2001 From: vitalif Date: Sun, 30 Sep 2012 22:42:53 +0000 Subject: [PATCH] Import original nicEdit --- nicEdit.js | 1637 ++++++++++++++++++++++++++++++++++++++++++++ nicEditorIcons.gif | Bin 0 -> 3716 bytes 2 files changed, 1637 insertions(+) create mode 100644 nicEdit.js create mode 100644 nicEditorIcons.gif diff --git a/nicEdit.js b/nicEdit.js new file mode 100644 index 0000000..c08b827 --- /dev/null +++ b/nicEdit.js @@ -0,0 +1,1637 @@ +/* NicEdit - Micro Inline WYSIWYG + * Copyright 2007-2008 Brian Kirchoff + * + * NicEdit is distributed under the terms of the MIT license + * For more information visit http://nicedit.com/ + * Do not remove this copyright message + */ +var bkExtend = function(){ + var args = arguments; + if (args.length == 1) args = [this, args[0]]; + for (var prop in args[1]) args[0][prop] = args[1][prop]; + return args[0]; +}; +function bkClass() { } +bkClass.prototype.construct = function() {}; +bkClass.extend = function(def) { + var classDef = function() { + if (arguments[0] !== bkClass) { return this.construct.apply(this, arguments); } + }; + var proto = new this(bkClass); + bkExtend(proto,def); + classDef.prototype = proto; + classDef.extend = this.extend; + return classDef; +}; + +var bkElement = bkClass.extend({ + construct : function(elm,d) { + if(typeof(elm) == "string") { + elm = (d || document).createElement(elm); + } + elm = $BK(elm); + return elm; + }, + + appendTo : function(elm) { + elm.appendChild(this); + return this; + }, + + appendBefore : function(elm) { + elm.parentNode.insertBefore(this,elm); + return this; + }, + + addEvent : function(type, fn) { + bkLib.addEvent(this,type,fn); + return this; + }, + + setContent : function(c) { + this.innerHTML = c; + return this; + }, + + pos : function() { + var curleft = curtop = 0; + var o = obj = this; + if (obj.offsetParent) { + do { + curleft += obj.offsetLeft; + curtop += obj.offsetTop; + } while (obj = obj.offsetParent); + } + var b = (!window.opera) ? parseInt(this.getStyle('border-width') || this.style.border) || 0 : 0; + return [curleft+b,curtop+b+this.offsetHeight]; + }, + + noSelect : function() { + bkLib.noSelect(this); + return this; + }, + + parentTag : function(t) { + var elm = this; + do { + if(elm && elm.nodeName && elm.nodeName.toUpperCase() == t) { + return elm; + } + elm = elm.parentNode; + } while(elm); + return false; + }, + + hasClass : function(cls) { + return this.className.match(new RegExp('(\\s|^)nicEdit-'+cls+'(\\s|$)')); + }, + + addClass : function(cls) { + if (!this.hasClass(cls)) { this.className += " nicEdit-"+cls }; + return this; + }, + + removeClass : function(cls) { + if (this.hasClass(cls)) { + this.className = this.className.replace(new RegExp('(\\s|^)nicEdit-'+cls+'(\\s|$)'),' '); + } + return this; + }, + + setStyle : function(st) { + var elmStyle = this.style; + for(var itm in st) { + switch(itm) { + case 'float': + elmStyle['cssFloat'] = elmStyle['styleFloat'] = st[itm]; + break; + case 'opacity': + elmStyle.opacity = st[itm]; + elmStyle.filter = "alpha(opacity=" + Math.round(st[itm]*100) + ")"; + break; + case 'className': + this.className = st[itm]; + break; + default: + //if(document.compatMode || itm != "cursor") { // Nasty Workaround for IE 5.5 + elmStyle[itm] = st[itm]; + //} + } + } + return this; + }, + + getStyle : function( cssRule, d ) { + var doc = (!d) ? document.defaultView : d; + if(this.nodeType == 1) + return (doc && doc.getComputedStyle) ? doc.getComputedStyle( this, null ).getPropertyValue(cssRule) : this.currentStyle[ bkLib.camelize(cssRule) ]; + }, + + remove : function() { + this.parentNode.removeChild(this); + return this; + }, + + setAttributes : function(at) { + for(var itm in at) { + this[itm] = at[itm]; + } + return this; + } +}); + +var bkLib = { + isMSIE : (navigator.appVersion.indexOf("MSIE") != -1), + + addEvent : function(obj, type, fn) { + (obj.addEventListener) ? obj.addEventListener( type, fn, false ) : obj.attachEvent("on"+type, fn); + }, + + toArray : function(iterable) { + var length = iterable.length, results = new Array(length); + while (length--) { results[length] = iterable[length] }; + return results; + }, + + noSelect : function(element) { + if(element.setAttribute && element.nodeName.toLowerCase() != 'input' && element.nodeName.toLowerCase() != 'textarea') { + element.setAttribute('unselectable','on'); + } + for(var i=0;i.nicEdit-main p { margin: 0; }<\/scr"+"ipt>"); + $BK("__ie_onload").onreadystatechange = function() { + if (this.readyState == "complete"){bkLib.domLoaded();} + }; + } + window.onload = bkLib.domLoaded; + } +}; + +function $BK(elm) { + if(typeof(elm) == "string") { + elm = document.getElementById(elm); + } + return (elm && !elm.appendTo) ? bkExtend(elm,bkElement.prototype) : elm; +} + +var bkEvent = { + addEvent : function(evType, evFunc) { + if(evFunc) { + this.eventList = this.eventList || {}; + this.eventList[evType] = this.eventList[evType] || []; + this.eventList[evType].push(evFunc); + } + return this; + }, + fireEvent : function() { + var args = bkLib.toArray(arguments), evType = args.shift(); + if(this.eventList && this.eventList[evType]) { + for(var i=0;i'); + } + this.instanceDoc = document.defaultView; + this.elm.addEvent('mousedown',this.selected.closureListener(this)).addEvent('keypress',this.keyDown.closureListener(this)).addEvent('focus',this.selected.closure(this)).addEvent('blur',this.blur.closure(this)).addEvent('keyup',this.selected.closure(this)); + this.ne.fireEvent('add',this); + }, + + remove : function() { + this.saveContent(); + if(this.copyElm || this.options.hasPanel) { + this.editorContain.remove(); + this.e.setStyle({'display' : 'block'}); + this.ne.removePanel(); + } + this.disable(); + this.ne.fireEvent('remove',this); + }, + + disable : function() { + this.elm.setAttribute('contentEditable','false'); + }, + + getSel : function() { + return (window.getSelection) ? window.getSelection() : document.selection; + }, + + getRng : function() { + var s = this.getSel(); + if(!s || s.rangeCount === 0) { return; } + return (s.rangeCount > 0) ? s.getRangeAt(0) : s.createRange(); + }, + + selRng : function(rng,s) { + if(window.getSelection) { + s.removeAllRanges(); + s.addRange(rng); + } else { + rng.select(); + } + }, + + selElm : function() { + var r = this.getRng(); + if(!r) { return; } + if(r.startContainer) { + var contain = r.startContainer; + if(r.cloneContents().childNodes.length == 1) { + for(var i=0;i'+((css) ? '' : '')+''+this.initialContent+''); + fd.close(); + this.frameDoc = fd; + + this.frameWin = $BK(this.elmFrame.contentWindow); + this.frameContent = $BK(this.frameWin.document.body).setStyle(this.savedStyles); + this.instanceDoc = this.frameWin.document.defaultView; + + this.heightUpdate(); + this.frameDoc.addEvent('mousedown', this.selected.closureListener(this)).addEvent('keyup',this.heightUpdate.closureListener(this)).addEvent('keydown',this.keyDown.closureListener(this)).addEvent('keyup',this.selected.closure(this)); + this.ne.fireEvent('add',this); + }, + + getElm : function() { + return this.frameContent; + }, + + setContent : function(c) { + this.content = c; + this.ne.fireEvent('set',this); + this.frameContent.innerHTML = this.content; + this.heightUpdate(); + }, + + getSel : function() { + return (this.frameWin) ? this.frameWin.getSelection() : this.frameDoc.selection; + }, + + heightUpdate : function() { + this.elmFrame.style.height = Math.max(this.frameContent.offsetHeight,this.initialHeight)+'px'; + }, + + nicCommand : function(cmd,args) { + this.frameDoc.execCommand(cmd,false,args); + setTimeout(this.heightUpdate.closure(this),100); + } + + +}); +var nicEditorPanel = bkClass.extend({ + construct : function(e,options,nicEditor) { + this.elm = e; + this.options = options; + this.ne = nicEditor; + this.panelButtons = new Array(); + this.buttonList = bkExtend([],this.ne.options.buttonList); + + this.panelContain = new bkElement('DIV').setStyle({overflow : 'hidden', width : '100%', border : '1px solid #cccccc', backgroundColor : '#efefef'}).addClass('panelContain'); + this.panelElm = new bkElement('DIV').setStyle({margin : '2px', marginTop : '0px', zoom : 1, overflow : 'hidden'}).addClass('panel').appendTo(this.panelContain); + this.panelContain.appendTo(e); + + var opt = this.ne.options; + var buttons = opt.buttons; + for(button in buttons) { + this.addButton(button,opt,true); + } + this.reorder(); + e.noSelect(); + }, + + addButton : function(buttonName,options,noOrder) { + var button = options.buttons[buttonName]; + var type = (button['type']) ? eval('(typeof('+button['type']+') == "undefined") ? null : '+button['type']+';') : nicEditorButton; + var hasButton = bkLib.inArray(this.buttonList,buttonName); + if(type && (hasButton || this.ne.options.fullPanel)) { + this.panelButtons.push(new type(this.panelElm,buttonName,options,this.ne)); + if(!hasButton) { + this.buttonList.push(buttonName); + } + } + }, + + findButton : function(itm) { + for(var i=0;i'+this.sel[itm]+''); + } + } +}); + +var nicEditorFontFamilySelect = nicEditorSelect.extend({ + sel : {'arial' : 'Arial','comic sans ms' : 'Comic Sans','courier new' : 'Courier New','georgia' : 'Georgia', 'helvetica' : 'Helvetica', 'impact' : 'Impact', 'times new roman' : 'Times', 'trebuchet ms' : 'Trebuchet', 'verdana' : 'Verdana'}, + + init : function() { + this.setDisplay('Font Family...'); + for(itm in this.sel) { + this.add(itm,''+this.sel[itm]+''); + } + } +}); + +var nicEditorFontFormatSelect = nicEditorSelect.extend({ + sel : {'p' : 'Paragraph', 'pre' : 'Pre', 'h6' : 'Heading 6', 'h5' : 'Heading 5', 'h4' : 'Heading 4', 'h3' : 'Heading 3', 'h2' : 'Heading 2', 'h1' : 'Heading 1'}, + + init : function() { + this.setDisplay('Font Format...'); + for(itm in this.sel) { + var tag = itm.toUpperCase(); + this.add('<'+tag+'>','<'+itm+' style="padding: 0px; margin: 0px;">'+this.sel[itm]+''); + } + } +}); + +nicEditors.registerPlugin(nicPlugin,nicSelectOptions); + + + +/* START CONFIG */ +var nicLinkOptions = { + buttons : { + 'link' : {name : 'Add Link', type : 'nicLinkButton', tags : ['A']}, + 'unlink' : {name : 'Remove Link', command : 'unlink', noActive : true} + } +}; +/* END CONFIG */ + +var nicLinkButton = nicEditorAdvancedButton.extend({ + addPane : function() { + this.ln = this.ne.selectedInstance.selElm().parentTag('A'); + this.addForm({ + '' : {type : 'title', txt : 'Add/Edit Link'}, + 'href' : {type : 'text', txt : 'URL', value : 'http://', style : {width: '150px'}}, + 'title' : {type : 'text', txt : 'Title'}, + 'target' : {type : 'select', txt : 'Open In', options : {'' : 'Current Window', '_blank' : 'New Window'},style : {width : '100px'}} + },this.ln); + }, + + submit : function(e) { + var url = this.inputs['href'].value; + if(url == "http://" || url == "") { + alert("You must enter a URL to Create a Link"); + return false; + } + this.removePane(); + + if(!this.ln) { + var tmp = 'javascript:nicTemp();'; + this.ne.nicCommand("createlink",tmp); + this.ln = this.findElm('A','href',tmp); + } + if(this.ln) { + this.ln.setAttributes({ + href : this.inputs['href'].value, + title : this.inputs['title'].value, + target : this.inputs['target'].options[this.inputs['target'].selectedIndex].value + }); + } + } +}); + +nicEditors.registerPlugin(nicPlugin,nicLinkOptions); + + + +/* START CONFIG */ +var nicColorOptions = { + buttons : { + 'forecolor' : {name : __('Change Text Color'), type : 'nicEditorColorButton', noClose : true}, + 'bgcolor' : {name : __('Change Background Color'), type : 'nicEditorBgColorButton', noClose : true} + } +}; +/* END CONFIG */ + +var nicEditorColorButton = nicEditorAdvancedButton.extend({ + addPane : function() { + var colorList = {0 : '00',1 : '33',2 : '66',3 :'99',4 : 'CC',5 : 'FF'}; + var colorItems = new bkElement('DIV').setStyle({width: '270px'}); + + for(var r in colorList) { + for(var b in colorList) { + for(var g in colorList) { + var colorCode = '#'+colorList[r]+colorList[g]+colorList[b]; + + var colorSquare = new bkElement('DIV').setStyle({'cursor' : 'pointer', 'height' : '15px', 'float' : 'left'}).appendTo(colorItems); + var colorBorder = new bkElement('DIV').setStyle({border: '2px solid '+colorCode}).appendTo(colorSquare); + var colorInner = new bkElement('DIV').setStyle({backgroundColor : colorCode, overflow : 'hidden', width : '11px', height : '11px'}).addEvent('click',this.colorSelect.closure(this,colorCode)).addEvent('mouseover',this.on.closure(this,colorBorder)).addEvent('mouseout',this.off.closure(this,colorBorder,colorCode)).appendTo(colorBorder); + + if(!window.opera) { + colorSquare.onmousedown = colorInner.onmousedown = bkLib.cancelEvent; + } + + } + } + } + this.pane.append(colorItems.noSelect()); + }, + + colorSelect : function(c) { + this.ne.nicCommand('foreColor',c); + this.removePane(); + }, + + on : function(colorBorder) { + colorBorder.setStyle({border : '2px solid #000'}); + }, + + off : function(colorBorder,colorCode) { + colorBorder.setStyle({border : '2px solid '+colorCode}); + } +}); + +var nicEditorBgColorButton = nicEditorColorButton.extend({ + colorSelect : function(c) { + this.ne.nicCommand('hiliteColor',c); + this.removePane(); + } +}); + +nicEditors.registerPlugin(nicPlugin,nicColorOptions); + + + +/* START CONFIG */ +var nicImageOptions = { + buttons : { + 'image' : {name : 'Add Image', type : 'nicImageButton', tags : ['IMG']} + } + +}; +/* END CONFIG */ + +var nicImageButton = nicEditorAdvancedButton.extend({ + addPane : function() { + this.im = this.ne.selectedInstance.selElm().parentTag('IMG'); + this.addForm({ + '' : {type : 'title', txt : 'Add/Edit Image'}, + 'src' : {type : 'text', txt : 'URL', 'value' : 'http://', style : {width: '150px'}}, + 'alt' : {type : 'text', txt : 'Alt Text', style : {width: '100px'}}, + 'align' : {type : 'select', txt : 'Align', options : {none : 'Default','left' : 'Left', 'right' : 'Right'}} + },this.im); + }, + + submit : function(e) { + var src = this.inputs['src'].value; + if(src == "" || src == "http://") { + alert("You must enter a Image URL to insert"); + return false; + } + this.removePane(); + + if(!this.im) { + var tmp = 'javascript:nicImTemp();'; + this.ne.nicCommand("insertImage",tmp); + this.im = this.findElm('IMG','src',tmp); + } + if(this.im) { + this.im.setAttributes({ + src : this.inputs['src'].value, + alt : this.inputs['alt'].value, + align : this.inputs['align'].value + }); + } + } +}); + +nicEditors.registerPlugin(nicPlugin,nicImageOptions); + + + + +/* START CONFIG */ +var nicSaveOptions = { + buttons : { + 'save' : {name : __('Save this content'), type : 'nicEditorSaveButton'} + } +}; +/* END CONFIG */ + +var nicEditorSaveButton = nicEditorButton.extend({ + init : function() { + if(!this.ne.options.onSave) { + this.margin.setStyle({'display' : 'none'}); + } + }, + mouseClick : function() { + var onSave = this.ne.options.onSave; + var selectedInstance = this.ne.selectedInstance; + onSave(selectedInstance.getContent(), selectedInstance.elm.id, selectedInstance); + } +}); + +nicEditors.registerPlugin(nicPlugin,nicSaveOptions); + + + +/* START CONFIG */ +var nicUploadOptions = { + buttons : { + 'upload' : {name : 'Upload Image', type : 'nicUploadButton'} + } + +}; +/* END CONFIG */ + +var nicUploadButton = nicEditorAdvancedButton.extend({ + nicURI : 'http://api.imgur.com/2/upload.json', + errorText : 'Failed to upload image', + + addPane : function() { + if(typeof window.FormData === "undefined") { + return this.onError("Image uploads are not supported in this browser, use Chrome, Firefox, or Safari instead."); + } + this.im = this.ne.selectedInstance.selElm().parentTag('IMG'); + + var container = new bkElement('div') + .setStyle({ padding: '10px' }) + .appendTo(this.pane.pane); + + new bkElement('div') + .setStyle({ fontSize: '14px', fontWeight : 'bold', paddingBottom: '5px' }) + .setContent('Insert an Image') + .appendTo(container); + + this.fileInput = new bkElement('input') + .setAttributes({ 'type' : 'file' }) + .appendTo(container); + + this.progress = new bkElement('progress') + .setStyle({ width : '100%', display: 'none' }) + .setAttributes('max', 100) + .appendTo(container); + + this.fileInput.onchange = this.uploadFile.closure(this); + }, + + onError : function(msg) { + this.removePane(); + alert(msg || "Failed to upload image"); + }, + + uploadFile : function() { + var file = this.fileInput.files[0]; + if (!file || !file.type.match(/image.*/)) { + this.onError("Only image files can be uploaded"); + return; + } + this.fileInput.setStyle({ display: 'none' }); + this.setProgress(0); + + var fd = new FormData(); // https://hacks.mozilla.org/2011/01/how-to-develop-a-html5-image-uploader/ + fd.append("image", file); + fd.append("key", "b7ea18a4ecbda8e92203fa4968d10660"); + var xhr = new XMLHttpRequest(); + xhr.open("POST", this.ne.options.uploadURI || this.nicURI); + + xhr.onload = function() { + try { + var res = JSON.parse(xhr.responseText); + } catch(e) { + return this.onError(); + } + this.onUploaded(res.upload); + }.closure(this); + xhr.onerror = this.onError.closure(this); + xhr.upload.onprogress = function(e) { + this.setProgress(e.loaded / e.total); + }.closure(this); + xhr.send(fd); + }, + + setProgress : function(percent) { + this.progress.setStyle({ display: 'block' }); + if(percent < .98) { + this.progress.value = percent; + } else { + this.progress.removeAttribute('value'); + } + }, + + onUploaded : function(options) { + this.removePane(); + var src = options.links.original; + if(!this.im) { + this.ne.selectedInstance.restoreRng(); + var tmp = 'javascript:nicImTemp();'; + this.ne.nicCommand("insertImage", src); + this.im = this.findElm('IMG','src', src); + } + var w = parseInt(this.ne.selectedInstance.elm.getStyle('width')); + if(this.im) { + this.im.setAttributes({ + src : src, + width : (w && options.image.width) ? Math.min(w, options.image.width) : '' + }); + } + } +}); + +nicEditors.registerPlugin(nicPlugin,nicUploadOptions); + + + +var nicXHTML = bkClass.extend({ + stripAttributes : ['_moz_dirty','_moz_resizing','_extended'], + noShort : ['style','title','script','textarea','a'], + cssReplace : {'font-weight:bold;' : 'strong', 'font-style:italic;' : 'em'}, + sizes : {1 : 'xx-small', 2 : 'x-small', 3 : 'small', 4 : 'medium', 5 : 'large', 6 : 'x-large'}, + + construct : function(nicEditor) { + this.ne = nicEditor; + if(this.ne.options.xhtml) { + nicEditor.addEvent('get',this.cleanup.closure(this)); + } + }, + + cleanup : function(ni) { + var node = ni.getElm(); + var xhtml = this.toXHTML(node); + ni.content = xhtml; + }, + + toXHTML : function(n,r,d) { + var txt = ''; + var attrTxt = ''; + var cssTxt = ''; + var nType = n.nodeType; + var nName = n.nodeName.toLowerCase(); + var nChild = n.hasChildNodes && n.hasChildNodes(); + var extraNodes = new Array(); + + switch(nType) { + case 1: + var nAttributes = n.attributes; + + switch(nName) { + case 'b': + nName = 'strong'; + break; + case 'i': + nName = 'em'; + break; + case 'font': + nName = 'span'; + break; + } + + if(r) { + for(var i=0;i'; + } + + if(attrTxt == "" && nName == "span") { + r = false; + } + if(r) { + txt += '<'+nName; + if(nName != 'br') { + txt += attrTxt; + } + } + } + + + + if(!nChild && !bkLib.inArray(this.noShort,attributeName)) { + if(r) { + txt += ' />'; + } + } else { + if(r) { + txt += '>'; + } + + for(var i=0;i'; + } + + for(var i=0;i'; + } + + break; + case 3: + //if(n.nodeValue != '\n') { + txt += n.nodeValue; + //} + break; + } + + return txt; + } +}); +nicEditors.registerPlugin(nicXHTML); + + + + +/* START CONFIG */ +var nicCodeOptions = { + buttons : { + 'xhtml' : {name : 'Edit HTML', type : 'nicCodeButton'} + } + +}; +/* END CONFIG */ + +var nicCodeButton = nicEditorAdvancedButton.extend({ + width : '350px', + + addPane : function() { + this.addForm({ + '' : {type : 'title', txt : 'Edit HTML'}, + 'code' : {type : 'content', 'value' : this.ne.selectedInstance.getContent(), style : {width: '340px', height : '200px'}} + }); + }, + + submit : function(e) { + var code = this.inputs['code'].value; + this.ne.selectedInstance.setContent(code); + this.removePane(); + } +}); + +nicEditors.registerPlugin(nicPlugin,nicCodeOptions); + + diff --git a/nicEditorIcons.gif b/nicEditorIcons.gif new file mode 100644 index 0000000000000000000000000000000000000000..cd33a5df5cb0401c714351c7a948c191feab81de GIT binary patch literal 3716 zcmd^8iCYuN_U#TyNWzv7z=%OZWHX|IaX~~)FhJNOq78!R0BQruD5wy2!`=jyfS}|J zVnEg?N)#1oXMSN38SPO}Tt;mlAS&uJFFLOCl)Ui%jo$@Dq^4zS1sk^Frbq%Fqn@@ zMF=d_i9|XPq=O)XkuYp9W~5SsRLVyfB7^}UTu8}t*V7_7r#0}ksjDT9wPL?{D7`LLP~qx_k!C>O@~QcNVpj8zR%1Xe0V%9&>H zOiN6J;E<6@97Zr>MX9kUg2PH&s>C5R4y$pg+PKicYMs=mr~yF`r4edGi6W?4iKx}a z$p{pk*~8Tch9Wp>R3(lob!tSXR_ait0Y#M!wNdh;6v8uTx}ye!JM%WcGEtNWiZJkL$@{UoP@pz5-u^)~f zytw9b(BemK(BoTY!WTR~^X6D@Se6%KSqM!taq)2Es*(`RQn;&q+1AMm>gu0+n-*W{ zSr&f3Vjao!_0Xm^ikV$8`Nc?_>-mCLG;1e;Y)qRE5?l%oPhNT16y$wly6e|1#iOjj zt;3hY-#rRvzB60m*JHzA+LQK?TZBNXsu7Z0(%g_`hjd91 ziZ(yNB)3XPPK})k%6z4%dKUGz;qJ3+=8qc)cdveY!hX}i5x)Y$s`%$ejvn?Lob^*; zCCN_W<2Y=4>Cg0E_BN}khS;TT9`xY-fToY;&T=hf9|)y0g|$uZ+3X}Ig+GrXbUk@+ z6p{k|aHFy%&8#=Ig|KU_^yR_P-YCg0d(}x2X{|o+q_E((t1ZHsm=BZ%#}3DBpB*pq zCJS>WUcVBA*0w%E$~3R0tWBFgkl88M^8J02n&kexFC()@c+(X=cX2`GmWf&HV(z4~ zu)RA-At&e<1D!v!#n1hYd&ScVVJ}}t({OQWgTQ__$B Tk|^eOv+;x?^JkGe0h%f z9O7aA-W7`Z$Gi3fI_n3`s7@=qJ$Eh)v{yb^a0dBs!*SJj5Bj#^vm9r-JK(sUy2N~< zO1QuN&CNV&qK!lSgE&_K0A@4+hpJLnz71&02?+Xqhu+SA_AZ&{xG1<*8j;nmL};uU zSy1AkbJy|(zWFYSQ|&wbKZ<|4ZS6EKmr;DRRj8${PPP!TGR_LxwfX+`iOGGuhbcC> zk_#PPA2_}pTUe&1vva~1J+bYwy%>d`3%^+A_11l4y8DIYob~t1*|+vytHJg>=X&R9 zkYCTyllZ)Vpb!71uZwk-TV}+h6!u2m+~`Yp9;&=Sq`Pu7cS`3vwKhL+P|WjRg2pGD zGW&UHqVKGW_3weA`Xsl2C3p6=3oC#X=QG<7Mu}a#`_gBEo}X^~M{wXt^2+Qs1;KxQ zmQ_*Nu*tV9#XHJ1$KOQop2=m+lJk9tOgPFpWU;BMcfHk$F=xrb_Ld9O+N4JVhVbR} zXMeV^X#LyXz7JMJBm&XNPv}nvH?3iAy8}OdUf=!nVIyZ?tni~*UC-`OTJTv@>mbN`p)PW7XqM`E77Gc5OZG1QCe$2EqfiWLO(*H=!j>L@2y&YmTN5oSsW^6NG%%KWI37*{C-Ro^O!H;Z+11NMSKav0A%s<{T zR`A3}bMCeVJMLs=RZU~UZD6TO(2~_e@Zq1)bGAlKO_rbYuyVRaFIgEqYL+6}6aCOW zyeit(yU_*!TFihGG~&AW@AJ>@T)y^AZ5U_u#6}@!BQ@cEMCcViN*MJ6-_X6!ZxOQ3 z>@c0iW#yatj5P|d()$lCEt8!8j1NE8jjX=pvj8 zSwks!*-ZI%nZs~IK#KpAd`Y$5J%3xV9lL+YBKCuSthh&<^GH>|o&+q<$lNW{hE3+Z z83X$pK-)w?>0DOjMM?_9tKV|JP<2!lX717P^!~XFzrHRrhoL`Xz+u;kh)7efQ^Mrn zuqD#7oSo0yrhVD@-AG->EjA=}?&FlWd8t54mG&=0*Q^s)(5!Kpndi!!fbDDqvp)plfpXI)YiV@H(U9AdMNwWu#0I*)iIZyB-Z3_t(9|?Tzet zPshmnRsBR_swjgtS@xi2s3x>LdVrKQpTd$wj<08ie|4i-cbhos6sdB~Rv(h(s`%+{ z?Y|1D~=wy@ZNb`=qG zr`GHD2xLE~KY}m(g1ZdvNQ)Zmur+TJka@#t|1>%D^{<6_zkezDe6mz#)qjQTI1Ccr z6O%u0Jh*aWdV)0j2C+4T96`@#c#*3G)C5TeHEvd>Ky>Rp@CWEQk`H{T+*uuvYQbWR1@IZ>(=$0AeX`~jBBl#3ZnpKMPx)x{q z_vDjbvO?1tS9ZajS29n0$r??|Iysd|1sAV5?b*C?n`%qhsaCpKEou80a48|1E-558 zl!5xP&nxr3x^mY{F~&cUe!aImw5e#UCaig?tSy8752T#Pu#+nYr(;bPaE@#g+L^@x zANYCO#PnD_sYOO<(vvob>2t@>$*`^mIM&pX0k-G8CMK`I?J1Y}ay&6jPfKqMnfM=sMr6KoR_?X!%A!22d6# z2=#QvZao;#dN5=q9nq7lK9SDE(zGY&b)Crx9jcPrrIj{iEW6hX2YveAVn&sg6hg1| zT~!^)p|Uco#eqy|N`fU&X``XUdf12>h?}EopeRzHau!Jftk9Z}ztMLK0AeiQ8pV_> is0og(*