DIRECTORY Alloc: TYPE USING [AddNotify, DropNotify, Handle, Notifier, Top, Words], BcdDefs: TYPE USING [ControlItem, CTIndex, CTRecord, cttype, cxtype, EVIndex, EVNull, EVRecord, evtype, EXPIndex, EXPRecord, exptype, FPIndex, FPRecord, fptype, FTIndex, FTNull, FTRecord, FTSelf, fttype, IMPIndex, IMPNull, IMPRecord, imptype, LFIndex, LFNull, lftype, Link, LinkFrag, ModuleIndex, MTIndex, MTRecord, mttype, Namee, NameRecord, NTIndex, NTRecord, nttype, NullLink, NullName, NullVersion, RFIndex, RFNull, rftype, RefLitFrag, SGIndex, SGRecord, sgtype, SpaceID, SPIndex, SPRecord, sptype, sttype, TFIndex, TFNull, tftype, TMIndex, TMRecord, tmtype, TypeFrag, TYPIndex, TYPNull, TYPRecord, typtype, VersionStamp], BcdErrorDefs: TYPE USING [Error2Versions], BcdUtilDefs: TYPE USING [BcdBasePtr], ConvertUnsafe: TYPE USING [EqualSubStrings, SubString], HashOps: TYPE USING [EnterString, FindEquivalentString, FindString, SubStringForHash], PrincOpsUtils: TYPE USING [LongCopy], Symbols: TYPE USING [CXIndex, CXRecord, HTIndex, htNull, STIndex, stNull, STRecord], Table: TYPE USING [Base], Tree: TYPE USING [Link]; BcdUtilities: PROGRAM IMPORTS Alloc, BcdErrorDefs, ConvertUnsafe, HashOps, PrincOpsUtils EXPORTS BcdUtilDefs = { OPEN BcdUtilDefs, BcdDefs; Copy: PROC[from: LONG POINTER, nwords: CARDINAL, to: LONG POINTER] ~ PrincOpsUtils.LongCopy; STIndex: TYPE ~ Symbols.STIndex; stNull: STIndex ~ Symbols.stNull; HTIndex: TYPE ~ Symbols.HTIndex; htNull: HTIndex ~ Symbols.htNull; SubString: TYPE ~ ConvertUnsafe.SubString; table: Alloc.Handle; ctb, mtb, lfb, rfb, tfb: Table.Base; sgb, ftb, itb, etb, ntb, stb, cxb, evb, tyb, tmb, spb, fpb: Table.Base; Notifier: Alloc.Notifier ~ { ctb _ base[cttype]; mtb _ base[mttype]; lfb _ base[lftype]; rfb _ base[rftype]; tfb _ base[tftype]; sgb _ base[sgtype]; ftb _ base[fttype]; itb _ base[imptype]; etb _ base[exptype]; ntb _ base[nttype]; stb _ base[sttype]; cxb _ base[cxtype]; evb _ base[evtype]; tyb _ base[typtype]; tmb _ base[tmtype]; spb _ base[sptype]; fpb _ base[fptype]}; EnterName: PUBLIC PROC[ss: SubString] RETURNS[NameRecord] ~ { hti: HTIndex ~ HashOps.EnterString[ss]; lss: SubString ~ HashOps.SubStringForHash[hti]; RETURN[[lss.offset]]}; MapName: PUBLIC PROC[bcd: BcdBasePtr, n: NameRecord] RETURNS[NameRecord] ~ { ss: SubString ~ [base~@bcd.ssb.string, offset~n, length~bcd.ssb.size[n]]; RETURN[EnterName[ss]]}; MapEquivalentName: PROC[bcd: BcdBasePtr, n: NameRecord] RETURNS[NameRecord] ~ { ss: SubString ~ [base~@bcd.ssb.string, offset~n, length~bcd.ssb.size[n]]; hti: HTIndex _ HashOps.FindString[ss]; IF hti = htNull THEN hti _ HashOps.FindEquivalentString[ss]; RETURN[[IF hti # htNull THEN NameForHti[hti] ELSE EnterName[ss]]]}; HtiForName: PUBLIC PROC[bcd: BcdBasePtr, n: NameRecord] RETURNS[HTIndex] ~ { ss: SubString ~ [base~@bcd.ssb.string, offset~n, length~bcd.ssb.size[n]]; RETURN[HashOps.EnterString[ss]]}; NameForHti: PUBLIC PROC[hti: HTIndex] RETURNS[NameRecord] ~ { ss: SubString ~ HashOps.SubStringForHash[hti]; RETURN[[ss.offset]]}; NameForSti: PUBLIC PROC[sti: STIndex] RETURNS[NameRecord] ~ { RETURN[NameForHti[stb[sti].hti]]}; ContextForTree: PUBLIC PROC[t: Tree.Link] RETURNS[Symbols.CXIndex] ~ { RETURN[WITH t SELECT FROM symbol => WITH stb[index] SELECT FROM local => context, ENDCASE => ERROR, ENDCASE => ERROR] }; EqVersions: PUBLIC PROC[fti1, fti2: FTIndex] RETURNS[BOOL] ~ { RETURN[fti1 = fti2 OR ftb[fti1].version = ftb[fti2].version]}; EquivalentVersions: PUBLIC PROC[v1, v2: VersionStamp] RETURNS[BOOL] ~ { RETURN[v1 = v2]}; InsertFile: PROC[ fn: NameRecord, version: VersionStamp] RETURNS[fti: FTIndex] ~ { ftLimit: FTIndex ~ table.Top[fttype]; mismatched: BOOL _ FALSE; otherVersion: VersionStamp; FOR fti _ FTIndex.FIRST, fti+FTRecord.SIZE UNTIL fti = ftLimit DO IF ftb[fti].name = fn THEN SELECT TRUE FROM (ftb[fti].version = NullVersion) => {ftb[fti].version _ version; EXIT}; EquivalentVersions[ftb[fti].version, version], (version = NullVersion) => EXIT; ENDCASE => {mismatched _ TRUE; otherVersion _ ftb[fti].version}; REPEAT FINISHED => { fti _ table.Words[fttype, FTRecord.SIZE]; ftb[fti] _ [name~fn, version~version]; IF mismatched THEN BcdErrorDefs.Error2Versions[ class~$warning, fileName~fn, v1~version, v2~otherVersion]}; ENDLOOP; RETURN}; MergeFile: PUBLIC PROC[bcd: BcdBasePtr, oldFti: FTIndex] RETURNS[FTIndex] ~ { fn: NameRecord; IF oldFti = FTSelf OR oldFti = FTNull THEN RETURN[oldFti]; fn _ MapEquivalentName[bcd, bcd.ftb[oldFti].name]; RETURN[InsertFile[fn, bcd.ftb[oldFti].version]]}; EnterFile: PUBLIC PROC[name: LONG STRING] RETURNS[FTIndex] ~ { ss: SubString _ [base~name, offset~0, length~name.length]; fn: NameRecord; hti: HTIndex; nullV: VersionStamp _ NullVersion; IF ss.base[ss.offset+ss.length-1] = '. THEN ss.length _ ss.length-1; IF ss.length > 4 THEN { ext: SubString ~ [base~".bcd"L, offset~0, length~4]; st: SubString ~ [base~ss.base, offset~ss.offset+ss.length-4, length~4]; IF st.EqualSubStrings[ext, FALSE] THEN ss.length _ ss.length-4}; hti _ HashOps.FindString[ss]; IF hti = htNull THEN hti _ HashOps.FindEquivalentString[ss]; fn _ IF hti # htNull THEN NameForHti[hti] ELSE EnterName[ss]; RETURN[InsertFile[fn, nullV]]}; SetFileVersion: PUBLIC PROC[fti: FTIndex, v: VersionStamp] ~ { OPEN file~~ftb[fti]; SELECT TRUE FROM (file.version = NullVersion) => file.version _ v; EquivalentVersions[file.version, v] => NULL; ENDCASE => BcdErrorDefs.Error2Versions[ class~$warning, fileName~file.name, v1~v, v2~file.version] }; FileForVersion: PUBLIC PROC[v: VersionStamp] RETURNS[fti: FTIndex] ~ { ftLimit: FTIndex ~ table.Top[fttype]; FOR fti _ FTIndex.FIRST, fti+FTRecord.SIZE UNTIL fti = ftLimit DO IF ftb[fti].version = v THEN EXIT; REPEAT FINISHED => fti _ FTNull; ENDLOOP; RETURN}; nextGfi: CARDINAL; nextDummyGfi: CARDINAL; GftOverflow: PUBLIC SIGNAL ~ CODE; GetGfi: PUBLIC PROC[n: CARDINAL] RETURNS[gfi: ModuleIndex] ~ { gfi _ nextGfi; nextGfi _ nextGfi + n; IF nextGfi > ModuleIndex.LAST THEN ERROR GftOverflow; RETURN}; GetDummyGfi: PUBLIC PROC[n: CARDINAL] RETURNS[gfi: CARDINAL] ~ { gfi _ nextDummyGfi; nextDummyGfi _ nextDummyGfi + n; RETURN}; NewContext: PUBLIC PROC RETURNS[ctx: Symbols.CXIndex] ~ { ctx _ table.Words[cxtype, Symbols.CXRecord.SIZE]; cxb[ctx] _ [link~stNull]; RETURN}; NewSemanticEntry: PUBLIC PROC[hti: HTIndex] RETURNS[sti: STIndex] ~ { sti _ table.Words[sttype, Symbols.STRecord.SIZE]; stb[sti] _ [ filename~FALSE, assigned~FALSE, imported~FALSE, exported~FALSE, hti~htNull, link~stNull, impi~IMPNull, impgfi~0, body~unknown[]]; stb[sti].hti _ hti; RETURN}; EnterConfig: PUBLIC PROC[bcd: BcdBasePtr, oldCti: CTIndex, name: HTIndex] RETURNS[cti: CTIndex] ~ { OPEN old~~bcd.ctb[oldCti]; size: CARDINAL ~ CTRecord.SIZE + old.nControls*ControlItem.SIZE; cti _ table.Words[cttype, size]; Copy[from~@old, to~@ctb[cti], nwords~size]; ctb[cti].name _ MapName[bcd, old.name]; IF name # htNull THEN { ctb[cti].namedInstance _ TRUE; CreateInstanceName[name, [config[cti]]]} ELSE IF old.namedInstance THEN CopyInstanceName[bcd, [config[oldCti]], [config[cti]]]; RETURN}; EnterModule: PUBLIC PROC[bcd: BcdBasePtr, oldMti: MTIndex, name: HTIndex] RETURNS[mti: MTIndex] ~ { OPEN old~~bcd.mtb[oldMti]; size: CARDINAL ~ (WITH o~~old SELECT FROM direct => MTRecord.direct.SIZE + o.length*Link.SIZE, indirect => MTRecord.indirect.SIZE, multiple => MTRecord.multiple.SIZE, ENDCASE => ERROR); mti _ table.Words[mttype, size]; Copy[to~@mtb[mti], from~@old, nwords~size]; mtb[mti].name _ MapName[bcd, old.name]; IF name # htNull THEN { mtb[mti].namedInstance _ TRUE; CreateInstanceName[name, [module[mti]]]} ELSE IF old.namedInstance THEN CopyInstanceName[bcd, [module[oldMti]], [module[mti]]]; IF old.variables # EVNull THEN mtb[mti].variables _ EnterVariables[bcd, old.variables]; WITH m~~mtb[mti] SELECT FROM indirect => WITH o~~old SELECT FROM indirect => m.links _ EnterLinks[bcd, o.links]; ENDCASE => ERROR; multiple => WITH o~~old SELECT FROM multiple => { m.links _ EnterLinks[bcd, o.links]; m.refLiterals _ EnterLits[bcd, o.refLiterals]; m.types _ EnterTypes[bcd, o.types]}; ENDCASE => ERROR; ENDCASE; RETURN}; EnterLinks: PROC[bcd: BcdBasePtr, oldLfi: LFIndex] RETURNS[lfi: LFIndex] ~ { IF oldLfi = LFNull THEN lfi _ LFNull ELSE { OPEN old~~bcd.lfb[oldLfi]; size: CARDINAL ~ LinkFrag[old.length].SIZE; lfi _ table.Words[lftype, size]; Copy[to~@lfb[lfi], from~@old, nwords~size]}; RETURN}; EnterLits: PROC[bcd: BcdBasePtr, oldRfi: RFIndex] RETURNS[rfi: RFIndex] ~ { IF oldRfi = RFNull THEN rfi _ RFNull ELSE { OPEN old~~bcd.rfb[oldRfi]; size: CARDINAL ~ RefLitFrag[old.length].SIZE; rfi _ table.Words[rftype, size]; Copy[to~@rfb[rfi], from~@old, nwords~size]}; RETURN}; EnterTypes: PROC[bcd: BcdBasePtr, oldTfi: TFIndex] RETURNS[tfi: TFIndex] ~ { IF oldTfi = TFNull THEN tfi _ TFNull ELSE { OPEN old~~bcd.tfb[oldTfi]; size: CARDINAL ~ TypeFrag[old.length].SIZE; tfi _ table.Words[tftype, size]; Copy[to~@tfb[tfi], from~@old, nwords~size]}; RETURN}; EnterVariables: PROC[bcd: BcdBasePtr, oldEvi: EVIndex] RETURNS[evi: EVIndex] ~ { OPEN old~~bcd.evb[oldEvi]; evLimit: EVIndex ~ table.Top[evtype]; oldLength: CARDINAL ~ old.length; FOR evi _ EVIndex.FIRST, evi+EVRecord.SIZE+evb[evi].length UNTIL evi = evLimit DO IF evb[evi].length >= oldLength THEN FOR i: CARDINAL DECREASING IN [1..oldLength] DO IF evb[evi].offsets[i] # old.offsets[i] THEN EXIT; REPEAT FINISHED => RETURN; ENDLOOP; ENDLOOP; evi _ table.Words[evtype, EVRecord.SIZE+oldLength]; Copy[to~@evb[evi], from~@old, nwords~EVRecord.SIZE+oldLength]; RETURN}; EnterSegment: PUBLIC PROC[seg: SGRecord] RETURNS[sgi: SGIndex] ~ { sgLimit: SGIndex ~ table.Top[sgtype]; FOR sgi _ SGIndex.FIRST, sgi+SGRecord.SIZE UNTIL sgi = sgLimit DO IF sgb[sgi] = seg THEN RETURN ENDLOOP; sgi _ table.Words[sgtype, SGRecord.SIZE]; sgb[sgi] _ seg; RETURN}; EnterImport: PUBLIC PROC[bcd: BcdBasePtr, oldIti: IMPIndex, copyName: BOOL] RETURNS[iti: IMPIndex] ~ { OPEN old~~bcd.itb[oldIti]; iti _ table.Words[imptype, IMPRecord.SIZE]; itb[iti] _ old; itb[iti].name _ MapName[bcd, old.name]; IF copyName AND old.namedInstance THEN CopyInstanceName[bcd, [import[oldIti]], [import[iti]]] ELSE itb[iti].namedInstance _ FALSE; RETURN}; EnterExport: PUBLIC PROC[bcd: BcdBasePtr, oldEti: EXPIndex, copyName: BOOL] RETURNS[eti: EXPIndex] ~ { OPEN old~~bcd.etb[oldEti]; size: CARDINAL ~ old.size + EXPRecord.SIZE; eti _ table.Words[exptype, size]; etb[eti] _ old; FOR i: CARDINAL IN [0..etb[eti].size) DO etb[eti].links[i] _ NullLink ENDLOOP; etb[eti].name _ MapName[bcd, old.name]; IF copyName AND old.namedInstance THEN CopyInstanceName[bcd, [export[oldEti]], [export[eti]]] ELSE etb[eti].namedInstance _ FALSE; RETURN}; EnterType: PUBLIC PROC[bcd: BcdBasePtr, oldTypi: TYPIndex] RETURNS[typi: TYPIndex] ~ { OPEN old~~bcd.tyb[oldTypi]; typLimit: TYPIndex ~ table.Top[typtype]; FOR typi _ TYPIndex.FIRST, typi +TYPRecord.SIZE UNTIL typi = typLimit DO IF tyb[typi] = old THEN EXIT; REPEAT FINISHED => { typi _ table.Words[typtype, TYPRecord.SIZE]; tyb[typi] _ old}; ENDLOOP; RETURN}; EnterTypeMap: PUBLIC PROC[bcd: BcdBasePtr, oldTmi: TMIndex] RETURNS[tmi: TMIndex] ~ { OPEN old~~bcd.tmb[oldTmi]; tmLimit: TMIndex ~ table.Top[tmtype]; FOR tmi _ TMIndex.FIRST, tmi + TMRecord.SIZE UNTIL tmi = tmLimit DO IF tmb[tmi].offset = old.offset AND tmb[tmi].version = old.version THEN EXIT; REPEAT FINISHED => { tmi _ table.Words[tmtype, TMRecord.SIZE]; tmb[tmi] _ [version~old.version, offset~old.offset, map~TYPNull]}; ENDLOOP; RETURN}; EnterSpace: PUBLIC PROC[bcd: BcdBasePtr, oldSpi: SPIndex] RETURNS[spi: SPIndex] ~ { OPEN old~~bcd.spb[oldSpi]; size: CARDINAL ~ SPRecord.SIZE + old.length*SpaceID.SIZE; spi _ table.Words[sptype, size]; Copy[from~@old, to~@spb[spi], nwords~size]; FOR i: CARDINAL IN [0 .. spb[spi].length) DO spb[spi].spaces[i].name _ MapName[bcd, old.spaces[i].name]; ENDLOOP; RETURN}; EnterFramePack: PUBLIC PROC[bcd: BcdBasePtr, oldFpi: FPIndex] RETURNS[fpi: FPIndex] ~ { OPEN old~~bcd.fpb[oldFpi]; size: CARDINAL ~ FPRecord.SIZE + old.length*MTIndex.SIZE; fpi _ table.Words[fptype, size]; Copy[from~@old, to~@fpb[fpi], nwords~size]; fpb[fpi].name _ MapName[bcd, old.name]; RETURN}; CreateInstanceName: PUBLIC PROC[hti: HTIndex, item: Namee] ~ { nti: NTIndex ~ table.Words[nttype, NTRecord.SIZE]; ntb[nti] _ [item~item, name~NameForHti[hti]]}; InstanceName: PUBLIC PROC[item: Namee] RETURNS[NameRecord] ~ { ntLimit: NTIndex ~ table.Top[nttype]; FOR nti: NTIndex _ NTIndex.FIRST, nti + NTRecord.SIZE UNTIL nti = ntLimit DO IF ntb[nti].item = item THEN RETURN[ntb[nti].name] ENDLOOP; RETURN[NullName]}; CopyInstanceName: PROC[bcd: BcdBasePtr, old, new: Namee] ~ { nti: NTIndex = table.Words[nttype, NTRecord.SIZE]; FOR oldNti: NTIndex _ NTIndex.FIRST, oldNti + NTRecord.SIZE DO IF (bcd.ntb[oldNti]).item = old THEN { ntb[nti] _ [item~new, name~MapName[bcd, bcd.ntb[oldNti].name]]; RETURN}; ENDLOOP }; Init: PUBLIC PROC[ownTable: Alloc.Handle] ~ { table _ ownTable; table.AddNotify[Notifier]; nextGfi _ nextDummyGfi _ 1}; Reset: PUBLIC PROC ~ {table.DropNotify[Notifier]; table _ NIL}; }. BcdUtilities.Mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Satterthwaite on April 17, 1986 12:43:25 pm PST Lewis on 16-Dec-80 10:47:39 Maxwell, August 4, 1983 11:54 am Russ Atkinson (RRA) March 7, 1985 0:11:27 am PST Administrative Procedures Κ˜codešœ™Kšœ Οmœ1™Kšžœ žœ)˜>K˜—š Ÿœžœžœžœžœ˜HKšžœ ˜K˜—šŸ œžœ˜Kšœ'žœ˜@K˜%Kšœ žœžœ˜K˜š žœžœžœžœž˜Ašžœž˜šžœžœž˜KšœAžœ˜G˜.Kšœžœ˜ —Kšžœžœ$˜A——šž˜šžœ˜ Kšœ#žœ˜)K˜&šžœ žœ˜/K˜;———Kšžœ˜—Kšžœ˜K˜—šŸ œžœžœ#žœ ˜MK˜Kšžœžœžœžœ ˜:K˜2Kšžœ+˜1K˜—š Ÿ œžœžœžœžœžœ ˜>K˜:K˜K˜ K˜"Kšžœ%žœ˜Dšžœžœ˜K˜4K˜GKšžœžœžœ˜@—K˜Kšžœžœ(˜Kšžœ˜šžœžœž˜K˜1Kšœ'žœ˜,šžœ˜ ˜K˜:———˜K˜——šŸœžœžœžœ˜FK˜%š žœžœžœžœž˜AKšžœžœžœ˜"šž˜Kšžœ˜—Kšžœ˜—Kšžœ˜K˜—Kšœ žœ˜Kšœžœ˜K˜Kšœ žœžœžœ˜"K˜š Ÿœžœžœžœžœ˜>K˜K˜Kšžœžœžœžœ ˜5Kšžœ˜K˜—š Ÿ œžœžœžœžœžœ˜@K˜K˜ Kšžœ˜K˜—šŸ œžœžœžœ˜9Kšœ+žœ˜1K˜Kšžœ˜K˜—šŸœžœžœžœ˜EKšœ+žœ˜1˜ Kšœ žœ žœ˜Kšœ žœ žœ˜K˜ K˜ K˜K˜—K˜Kšžœ˜K˜—šŸ œžœžœ1˜IKšžœ˜Kšžœ˜Kšœžœ žœžœ˜@K˜ K˜+K˜'šžœžœ˜Kšœžœ*˜G—Kšžœžœžœ8˜VKšžœ˜K˜—šŸ œžœžœ1˜IKšžœ˜Kšžœ˜šœžœžœžœž˜)Kšœžœžœ˜4Kšœžœ˜#Kšœžœ˜#Kšžœžœ˜—K˜ K˜+K˜'šžœžœ˜Kšœžœ*˜G—Kšžœžœžœ8˜VKšžœžœ9˜Wšžœ žœž˜˜ šžœžœž˜K˜/Kšžœžœ˜——˜ šžœžœž˜˜ K˜#K˜.K˜$—Kšžœžœ˜——Kšžœ˜—Kšžœ˜K˜—šŸ œžœ#žœ˜LKšžœžœ ˜$šžœ˜Kšžœ˜Kšœžœžœ˜+K˜ K˜,—Kšžœ˜K˜—šŸ œžœ#žœ˜KKšžœžœ ˜$šžœ˜Kšžœ˜Kšœžœžœ˜-K˜ K˜,—Kšžœ˜K˜—šŸ œžœ#žœ˜LKšžœžœ ˜$šžœ˜Kšžœ˜Kšœžœžœ˜+K˜ K˜,—Kšžœ˜K˜—šŸœžœ"˜6Kšžœ˜Kšžœ˜K˜%Kšœ žœ˜!š žœžœžœžœž˜Qšžœž˜$š žœžœž œžœž˜/Kšžœ&žœžœ˜2šž˜Kšžœžœ˜—Kšžœ˜——Kšžœ˜—Kšœ#žœ ˜3Kšœ.žœ ˜>Kšžœ˜K˜—šŸ œžœžœžœ˜BK˜%š žœžœžœžœž˜AKšžœžœžœžœ˜&—Kšœ#žœ˜)K˜Kšžœ˜K˜—šŸ œžœžœ.žœ˜KKšžœ˜Kšžœ˜Kšœ%žœ˜+K˜K˜'šžœ žœž˜&K˜6—Kšžœžœ˜$Kšžœ˜K˜—šŸ œžœžœ.žœ˜KKšžœ˜Kšžœ˜Kšœžœžœ˜+K˜!K˜Kš žœžœžœžœžœ˜NK˜'šžœ žœž˜&K˜6—Kšžœžœ˜$Kšžœ˜K˜—šŸ œžœžœ%žœ˜VKšžœ˜K˜(š žœžœžœžœž˜HKšžœžœžœ˜šžœžœ˜Kšœ&žœ˜>—Kšžœ˜—Kšžœ˜K˜—šŸ œžœžœ#žœ˜UKšžœ˜K˜%š žœžœžœžœž˜CKšžœžœ žœžœ˜Mšž˜šžœ˜ Kšœ#žœ˜)K˜B——Kšžœ˜—Kšžœ˜K˜—šŸ œžœžœ#žœ˜SKšžœ˜Kšœžœ žœžœ˜9K˜ K˜+šžœžœžœž˜,K˜;Kšžœ˜—Kšžœ˜K˜—šŸœžœžœ#žœ˜WKšžœ˜Kšœžœ žœžœ˜9K˜ K˜+K˜'Kšžœ˜K˜—šŸœžœžœ˜>Kšœ,žœ˜2K˜.K˜—šŸ œžœžœžœ˜>K˜%š žœžœžœžœž˜LKšžœžœžœžœ˜;—Kšžœ ˜K˜K˜—šŸœžœ&˜šžœžœ˜&Kšœ@žœ˜H—Kšž˜—šœ˜K˜———šœ™K˜šŸœžœžœ˜-K˜K˜7K˜—KšŸœžœžœ(žœ˜?K˜K˜K˜——…—2κB