DIRECTORY Commander USING [CommandProc, Register, Handle], CommanderOps USING [CreateFromStreams, ParseToList], Convert USING [CardFromRope], Basics USING [LowHalf], FS USING [StreamOpen, Error, NameProc, EnumerateForNames, ComponentPositions, ExpandName], IO USING [STREAM, rope, int, PutF, PutF1, EndOfStream, Close, PutChar, PutRope, GetLineRope], List USING [DReverse], RegularExpression USING [CreateFromRope, SearchRope, MalformedPattern, Finder, NameLoc], Rope USING [ROPE, Size, Fetch, Concat, Find, Translate, Substr, Replace, FromChar], RopeFile USING [FromStream], Ascii USING [Upper, Lower] ; TransImpl: CEDAR PROGRAM IMPORTS Commander, CommanderOps, FS, IO, List, RegularExpression, Ascii, Rope, RopeFile, Convert, Basics = { ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; ReplacementRec: TYPE = RECORD [kind: {field, fieldLower, fieldUpper, text} ¬ text, text: ROPE]; Replacement: TYPE = LIST OF REF ReplacementRec; TransOp: TYPE = {delete, select, replace}; TransProgramContent: TYPE = RECORD [ pattern: RegularExpression.Finder, replacement: Replacement, patternText: ROPE, replacementText: ROPE, literal: BOOL, word: BOOL, ignoreCase: BOOL, transOp: TransOp ]; TransProgram: TYPE = REF TransProgramContent; Trans: Commander.CommandProc -- [cmd: Commander.Handle] -- = { stdout: STREAM ¬ cmd.out; stdin: STREAM ¬ cmd.in; stderr: STREAM ¬ cmd.err; cmdLine: LIST OF ROPE; whoCares: LIST OF ROPE; transPrograms: LIST OF TransProgram ¬ NIL; verbose: BOOL ¬ TRUE; outFile: STREAM ¬ NIL; UsageMessage: PROC [] = { IO.PutRope[stderr, "Usage: trans [switches] [ ] \n"]; }; TransFile: FS.NameProc = { inFile: STREAM; cnt: INT; newR: ROPE; x: FS.ComponentPositions ¬ FS.ExpandName[fullFName].cp; continue ¬ TRUE; inFile ¬ FS.StreamOpen[fullFName, read ! FS.Error => { IO.PutF[stderr, "Could not open \"%g\" -- %g\n", IO.rope[fullFName], IO.rope[error.explanation]]; GOTO openFailed; }]; IF verbose THEN IO.PutF1[stderr, "Transforming \"%g\"...", IO.rope[fullFName]]; [newR, cnt] ¬ TransStream[inFile]; IF cnt > 0 OR appendFile # NIL THEN { IF appendFile = NIL THEN outFile ¬ FS.StreamOpen[fileName: fullFName, accessOptions: create, keep: 2 ! FS.Error => { IO.PutF[stderr, "Could not open \"%g\" for write -- %g\n", IO.rope[fullFName], IO.rope[error.explanation]]; GOTO openFailed; }]; outFile.PutRope[newR]; IF appendFile = NIL THEN outFile.Close[]; stderr.PutF1["%g changes\n", IO.int[cnt]]; } ELSE { IF verbose THEN IO.PutRope[stderr, "no changes, file not rewritten.\n"]; }; inFile.Close[]; EXITS openFailed => NULL; }; TransStream: PROC [inFile: STREAM] RETURNS [newR: ROPE, cnt: INT] = { r: ROPE ¬ RopeFile.FromStream[inFile]; [newR, cnt] ¬ TransRope[r, transPrograms]; }; TransRope: PROC [r: ROPE, p: LIST OF TransProgram] RETURNS [newR: ROPE, cnt: INT ¬ 0] = { found: BOOL; ReplacementRope: PROC [r: ROPE, p: TransProgram] RETURNS [rep: ROPE ¬ NIL] = { FOR l: Replacement ¬ p.replacement, l.rest UNTIL l = NIL DO IF l.first.kind # text THEN { at, atEnd: INT; t: ROPE; [at, atEnd] ¬ RegularExpression.NameLoc[p.pattern, l.first.text]; t ¬ r.Substr[at, atEnd-at]; SELECT l.first.kind FROM fieldUpper => t ¬ Upper[t]; fieldLower => t ¬ Lower[t]; ENDCASE; rep ¬ rep.Concat[t]; } ELSE rep ¬ rep.Concat[l.first.text]; ENDLOOP; }; newR ¬ r; FOR l: LIST OF TransProgram ¬ p, l.rest UNTIL l = NIL DO lastLoc, start, atEnd, before, after: INT ¬ 0; DO replRope: ROPE; [found, start, atEnd, before, after] ¬ RegularExpression.SearchRope[l.first.pattern, newR, start]; IF ~found THEN EXIT; IF atEnd=start THEN ERROR; replRope ¬ ReplacementRope[newR, l.first]; newR ¬ newR.Replace[start, atEnd-start, replRope]; IF l.first.transOp = select THEN { IF lastLoc < start THEN newR ¬ newR.Replace[lastLoc, start-lastLoc]; start ¬ start + Rope.Size[replRope]-(start-lastLoc); lastLoc ¬ start; } ELSE start ¬ start + Rope.Size[replRope]; cnt ¬ cnt + 1; ENDLOOP; IF l.first.transOp = select THEN newR ¬ newR.Replace[lastLoc, newR.Size[]-lastLoc]; IF verbose THEN stderr.PutChar['.]; ENDLOOP; }; MakeTransProgram: PROC [p, r: ROPE, literal, word, ignoreCase: BOOL, transOp: TransOp] RETURNS [ok: BOOL ¬ TRUE, t: TransProgram ¬ NEW[TransProgramContent]] = { t.patternText ¬ p; t.replacementText ¬ r; t.literal ¬ literal; t.word ¬ word; t.ignoreCase ¬ ignoreCase; t.transOp ¬ transOp; t.pattern ¬ RegularExpression.CreateFromRope[pattern: p, literal: literal, word: word, ignoreCase: ignoreCase ! RegularExpression.MalformedPattern => { stderr.PutF1["Syntax error in pattern \"%g\"\n", IO.rope[p]]; GOTO prematureExit;}]; [ok, t.replacement] ¬ MakeReplacement[r, literal]; EXITS prematureExit => ok ¬ FALSE; }; MakeReplacement: PROC [r: ROPE, literal: BOOL] RETURNS [ok: BOOL ¬ TRUE, x: Replacement ¬ NIL] = { startPoint, endPoint: INT ¬ 0; len: INT ¬ r.Size[]; IF literal THEN { IF len > 0 THEN x ¬ CONS[NEW[ReplacementRec ¬ [text, r]], NIL]; RETURN; }; WHILE startPoint < len DO frag: REF ReplacementRec ¬ NEW[ReplacementRec]; endPoint ¬ startPoint; SELECT r.Fetch[startPoint] FROM '< => { colonPoint: INT ¬ startPoint; endPoint ¬ startPoint + 1; DO IF endPoint >= len THEN GOTO SyntaxError; SELECT r.Fetch[endPoint] FROM '' => { r ¬ r.Replace[endPoint, 1]; len ¬ len - 1; }; '> => { endPoint ¬ endPoint + 1; EXIT; }; ': => colonPoint ¬ endPoint; ENDCASE => NULL; endPoint ¬ endPoint + 1; ENDLOOP; IF colonPoint > startPoint THEN { frag.text ¬ r.Substr[startPoint+1, colonPoint-startPoint-1]; SELECT Ascii.Lower[r.Fetch[colonPoint+1]] FROM 'u => frag.kind ¬ fieldUpper; 'l => frag.kind ¬ fieldLower; ENDCASE => GOTO SyntaxError; } ELSE { frag.kind ¬ field; frag.text ¬ r.Substr[startPoint+1, endPoint-startPoint-2]; }; }; ENDCASE => { endPoint ¬ startPoint; DO IF endPoint > len THEN GOTO SyntaxError; IF endPoint = len THEN EXIT; SELECT r.Fetch[endPoint] FROM '' => { IF r.Fetch[endPoint+1] = '0 THEN { r ¬ r.Replace[endPoint, 5, Rope.FromChar[VAL[Basics.LowHalf[Convert.CardFromRope[r.Substr[endPoint+1, 4], 8]]]]]; len ¬ len - 4; } ELSE { r ¬ r.Replace[endPoint, 1]; len ¬ len - 1; }; }; '\\ => { SELECT Ascii.Lower[r.Fetch[endPoint+1]] FROM 'n => { r ¬ r.Replace[endPoint, 2, "\n"]; len ¬ len - 1; }; 't => { r ¬ r.Replace[endPoint, 2, "\t"]; len ¬ len - 1; }; 's => { r ¬ r.Replace[endPoint, 2, " "]; len ¬ len - 1; }; '\\ => { r ¬ r.Replace[endPoint, 2, "\\"]; len ¬ len - 1; }; ENDCASE => ERROR; }; '< => EXIT; ENDCASE => NULL; endPoint ¬ endPoint + 1; ENDLOOP; frag.kind ¬ text; frag.text ¬ r.Substr[startPoint, endPoint-startPoint]; }; x ¬ CONS[frag, x]; startPoint ¬ endPoint; ENDLOOP; TRUSTED {x ¬ LOOPHOLE[List.DReverse[LOOPHOLE[x]]];}; EXITS SyntaxError => { stderr.PutF1["Syntax error in replacement expression: \"%g\"\n", IO.rope[r]]; ok ¬ FALSE; }; }; ParseCmdSwitches: PROC [handle: Commander.Handle, literal, ignoreCase, word: BOOL, transOp: TransOp, fileNamesOK: BOOL] RETURNS [ok: BOOL ¬ TRUE, cmdLine: LIST OF ROPE, appendFile: ROPE ¬ NIL] = { filePatternName: ROPE; present: BOOL; cmdLine ¬ CommanderOps.ParseToList[handle].list; [present, cmdLine, whoCares] ¬ GetSwitch["-pattern", cmdLine]; IF present THEN literal ¬ FALSE; [present, cmdLine, whoCares] ¬ GetSwitch["-literal", cmdLine]; IF present THEN literal ¬ TRUE; [present, cmdLine, whoCares] ¬ GetSwitch["-caseSensitive", cmdLine]; IF present THEN ignoreCase ¬ FALSE; [present, cmdLine, whoCares] ¬ GetSwitch["-ignoreCase", cmdLine]; IF present THEN ignoreCase ¬ TRUE; [present, cmdLine, whoCares] ¬ GetSwitch["-wordMatch", cmdLine]; IF present THEN word ¬ FALSE; [present, cmdLine, whoCares] ¬ GetSwitch["-matchAnywhere", cmdLine]; IF present THEN word ¬ TRUE; [present, cmdLine, whoCares] ¬ GetSwitch["-deleteMatched", cmdLine]; IF present THEN transOp ¬ delete; [present, cmdLine, whoCares] ¬ GetSwitch["-selectMatched", cmdLine]; IF present THEN transOp ¬ select; [present, cmdLine, whoCares] ¬ GetSwitch["-replaceMatched", cmdLine]; IF present THEN transOp ¬ replace; [present, appendFile, cmdLine, whoCares] ¬ GetSwitchWithArg["-appendFile", cmdLine]; [present, filePatternName, cmdLine, whoCares] ¬ GetSwitchWithArg["-filePatterns", cmdLine]; IF SwitchesLeft[cmdLine, stderr] THEN GOTO SyntaxError; IF present THEN { h: Commander.Handle ¬ CommanderOps.CreateFromStreams[parentCommander: handle]; -- Hacque. in: STREAM ¬ FS.StreamOpen[filePatternName ! FS.Error => { stderr.PutF1["Could not open \"%g\"\n", IO.rope[filePatternName]]; GOTO SyntaxError}]; DO nc: LIST OF ROPE; h.commandLine ¬ in.GetLineRope[ ! IO.EndOfStream => EXIT]; IF h.commandLine.Size[] > 0 THEN [ok, nc, appendFile] ¬ ParseCmdSwitches[h, literal, ignoreCase, word, transOp, FALSE]; IF ~ok THEN GOTO SyntaxError; ENDLOOP; in.Close[]; } ELSE IF cmdLine = NIL THEN { stderr.PutF1["Missing pattern and replacement in \"%g\"\n", IO.rope[handle.commandLine]]; GOTO SyntaxError; } ELSE IF transOp # delete AND cmdLine.rest = NIL THEN { stderr.PutF1["Missing replacement expression in \"%g\"\n", IO.rope[handle.commandLine]]; GOTO SyntaxError; } ELSE IF transOp = delete AND cmdLine.rest # NIL THEN { stderr.PutF1["Delete mode should not have replacement expression in \"%g\"\n", IO.rope[handle.commandLine]]; GOTO SyntaxError; } ELSE IF transOp = delete THEN { ok: BOOL; program: TransProgram; [ok, program] ¬ MakeTransProgram[cmdLine.first, "", literal, word, ignoreCase, transOp]; IF ~ok THEN GOTO SyntaxError; transPrograms ¬ CONS[program, transPrograms]; cmdLine ¬ cmdLine.rest; } ELSE { ok: BOOL; program: TransProgram; IF cmdLine.rest = NIL THEN GOTO SyntaxError; [ok, program] ¬ MakeTransProgram[cmdLine.first, cmdLine.rest.first, literal, word, ignoreCase, transOp]; IF ~ok THEN GOTO SyntaxError; transPrograms ¬ CONS[program, transPrograms]; cmdLine ¬ cmdLine.rest.rest; }; IF cmdLine # NIL AND ~fileNamesOK THEN { stderr.PutF1["File names are not allowed in pattern files: \"%g\"\n", IO.rope[handle.commandLine]]; GOTO SyntaxError; }; EXITS SyntaxError => ok ¬ FALSE; }; ok: BOOL; appendFile: ROPE ¬ NIL; [ok, cmdLine, appendFile] ¬ ParseCmdSwitches[cmd, FALSE, TRUE, FALSE, replace, TRUE]; IF appendFile # NIL THEN outFile ¬ FS.StreamOpen[fileName: appendFile, accessOptions: create, keep: 2 ! FS.Error => { IO.PutF[stderr, "Could not open \"%g\" for write -- %g\n", IO.rope[appendFile], IO.rope[error.explanation]]; GOTO openFailed; }]; IF ~ok THEN RETURN [result: $Failure]; TRUSTED {transPrograms ¬ LOOPHOLE[List.DReverse[LOOPHOLE[transPrograms]]]}; IF cmdLine = NIL THEN { stdout.PutRope[TransStream[stdin].newR]; } ELSE FOR l: LIST OF ROPE ¬ cmdLine, l.rest UNTIL l = NIL DO FS.EnumerateForNames[DefaultToHighestGeneration[l.first], TransFile]; ENDLOOP; IF appendFile # NIL THEN outFile.Close[]; EXITS openFailed => NULL; }; GetSwitch: PROC [switch: ROPE, cmdLine: LIST OF ROPE, prefixLen: INT ¬ 2] RETURNS [present: BOOL ¬ FALSE, newCmdLine: LIST OF ROPE, previous: LIST OF ROPE ¬ NIL] = { IF cmdLine = NIL THEN RETURN; IF Prefix[switch, cmdLine.first, prefixLen] THEN { present ¬ TRUE; newCmdLine ¬ cmdLine.rest; } ELSE { newCmdLine ¬ cmdLine; FOR l: LIST OF ROPE ¬ cmdLine, l.rest UNTIL l.rest = NIL DO IF Prefix[switch, l.rest.first, prefixLen] THEN { l.rest ¬ l.rest.rest; present ¬ TRUE; previous ¬ l; RETURN; }; ENDLOOP; }; }; GetSwitchWithArg: PROC [switch: ROPE, cmdLine: LIST OF ROPE, prefixLen: INT ¬ 2] RETURNS [present: BOOL ¬ FALSE, arg: ROPE, newCmdLine: LIST OF ROPE, previous: LIST OF ROPE ¬ NIL] = { IF cmdLine = NIL THEN RETURN; IF Prefix[switch, cmdLine.first, prefixLen] THEN { present ¬ TRUE; arg ¬ cmdLine.rest.first; newCmdLine ¬ cmdLine.rest.rest; } ELSE { newCmdLine ¬ cmdLine; FOR l: LIST OF ROPE ¬ cmdLine, l.rest UNTIL l.rest = NIL DO IF Prefix[switch, l.rest.first, prefixLen] THEN { arg ¬ l.rest.rest.first; l.rest ¬ l.rest.rest.rest; present ¬ TRUE; previous ¬ l; RETURN; }; ENDLOOP; }; }; SwitchesLeft: PROC [cmdLine: LIST OF ROPE, stderr: STREAM, switchChar: CHAR ¬ '-] RETURNS [switchesLeft: BOOL ¬ FALSE] = { FOR l: LIST OF ROPE ¬ cmdLine, l.rest UNTIL l = NIL DO IF Rope.Size[l.first] >= 1 THEN IF Rope.Fetch[l.first] = switchChar THEN { IO.PutF1[stderr, "Invalid switch: \"%g\"\n", IO.rope[l.first]]; switchesLeft ¬ TRUE; }; ENDLOOP; }; Prefix: PROC [r1, r2: ROPE, length: INT, ignoreCase: BOOL ¬ TRUE] RETURNS [BOOL] = { r2Len: INT ¬ r2.Size[]; r1Len: INT ¬ r1.Size[]; IF r1Len < length THEN ERROR; IF r2Len > r1Len OR r2Len < length THEN RETURN[FALSE]; IF ~ignoreCase THEN FOR i: INT IN [0..r2Len) DO IF r1.Fetch[i] # r2.Fetch[i] THEN RETURN[FALSE]; ENDLOOP ELSE FOR i: INT IN [0..r2Len) DO IF Ascii.Upper[r1.Fetch[i]] # Ascii.Upper[r2.Fetch[i]] THEN RETURN[FALSE]; ENDLOOP; RETURN[TRUE]; }; Upper: PROC [r: ROPE] RETURNS [ROPE] = { UpIt: PROC[c: CHAR] RETURNS [CHAR] = { RETURN[Ascii.Upper[c]]; }; RETURN[Rope.Translate[base: r, translator: UpIt]]; }; Lower: PROC [r: ROPE] RETURNS [ROPE] = { LowerIt: PROC[c: CHAR] RETURNS [CHAR] = { RETURN[Ascii.Lower[c]]; }; RETURN[Rope.Translate[base: r, translator: LowerIt]]; }; DefaultToHighestGeneration: PROC [filePattern: ROPE] RETURNS [ROPE] = { IF Rope.Find[filePattern, "!"] = -1 THEN RETURN[Rope.Concat[filePattern,"!H"]] ELSE RETURN[filePattern]; }; GetArg: Commander.CommandProc~{ msg ¬ CommanderOps.ParseToList[cmd].list.first; }; Commander.Register[ key: "Trans", proc: Trans, doc: "Transforms files using regular expressions."]; Commander.Register[ key: "GetArg", proc: GetArg, doc: "Tests complicated rope arguments."]; }.  TransImpl.mesa Copyright Σ 1987, 1993 by Xerox Corporation. All rights reserved. Nix, April 5, 1984 4:40:03 pm PST Eric Nickell, June 23, 1986 1:54:59 pm PDT Swinehart, March 18, 1991 11:48 pm PST Bertrand Serlet April 2, 1987 10:20:13 pm PST Willie-s, January 18, 1993 1:16 pm PST Callable from the command interpreter. Expects a list of file names as arguments, and counts the number of words in the indicated files. fullFName _ Rope.Substr[fullFName, 0, x.ver.start-1]; System now only works with UX views. Κθ•NewlineDelimiter –"cedarcode" style™šœ™Icodešœ Οeœ7™BJšœΟk™!Kšœ'ž™*Kšœ&™&K™-K™&—K˜šž ˜ Kšœ žœ!˜0Kšœ žœ"˜4Kšœžœ˜Kšœžœ ˜KšžœžœR˜ZKšžœžœžœM˜]Kšœžœ ˜KšœžœA˜XKšœžœžœC˜SKšœ žœ˜Kšœžœ˜K˜K˜—KšΠbn œžœž˜KšžœžœžœE˜lKšžœžœžœ˜Kšžœžœžœžœ˜K˜K˜Kšœžœžœ<žœ˜_Kš œ žœžœžœžœ˜/Kšœ žœ˜*šœžœžœ˜$Kšœ"˜"Kšœ˜Kšœ žœ˜Kšœžœ˜Kšœ žœ˜Kšœžœ˜ Kšœ žœ˜K˜Kšœ˜—Kšœžœžœ˜-unit•StartOfExpansion -- [cmd: Commander.Handle] -- šŸœΟcœ˜?Kšœ‰™‰Kšœžœ ˜Kšœžœ ˜Kšœžœ ˜Kšœ žœžœžœ˜Kšœ žœžœžœ˜Kšœžœžœžœ˜*Kšœ žœžœ˜Kšœ žœžœ˜šΟn œžœ˜KšžœT˜VK˜—šŸ œžœ ˜Kšœžœ˜Kšœžœ˜ Kšœžœ˜ Kšœžœžœ˜7Kšœ žœ˜šœ5™5J™$—šœ žœžœ ˜6Kšžœ/žœžœ˜aKšžœ ˜K˜—šžœ ž˜Kšžœ)žœ˜?—K˜"šžœ žœžœžœ˜%šžœžœž˜šœ žœCžœ ˜\Kšžœ9žœžœ˜kKšžœ ˜K˜——K˜šžœžœž˜K˜—Kšœžœ ˜*K˜—šžœ˜šžœ ž˜Kšžœ6˜8—K˜—Kšœ˜šž˜Kšœžœ˜—K˜—š ‘ œžœ žœžœžœžœ˜EKšœžœ˜&K˜*K˜—šŸ œžœžœžœžœžœžœžœ ˜YKšœžœ˜ š ‘œžœžœžœžœžœ˜Nšžœ(žœžœž˜;šžœžœ˜Kšœ žœ˜Kšœžœ˜K˜AK˜šžœž˜K˜K˜Kšžœ˜—K˜K˜—šž˜K˜—Kšžœ˜—K˜—K˜ š žœžœžœžœžœž˜8Kšœ&žœ˜.šž˜Kšœ žœ˜˜'Kšœ;˜;—Kšžœžœžœ˜Kšžœ žœžœ˜K˜*K˜2šžœžœ˜"šžœž˜K˜-—K˜4K˜K˜—šž˜K˜$—K˜Kšžœ˜—šžœž˜ K˜2—Kšžœ žœ˜#Kšžœ˜—K˜—š‘œžœžœžœžœžœžœžœ˜ K˜K˜K˜K˜K˜K˜˜—Kšœ1žœ ˜=Kšžœ˜—K˜2šž˜Kšœžœ˜—K˜—š‘œžœžœ žœžœžœžœžœ˜bKšœžœ˜Kšœžœ ˜šžœ žœ˜šžœ ž˜Kšœžœžœžœ˜/—Kšžœ˜K˜—šžœž˜Kšœžœžœ˜/K˜šžœž˜šœ˜Kšœ žœ˜K˜šž˜Kšžœžœžœ ˜)šžœž˜˜K˜K˜K˜—šœ˜K˜Kšžœ˜K˜—K˜Kšžœžœ˜—K˜Kšžœ˜—šžœžœ˜!K˜<šžœ$ž˜.K˜K˜Kšžœžœ ˜—K˜—šžœ˜K˜K˜:K˜—K˜——šžœ˜ K˜šž˜šžœž˜Kšžœ ˜—Kšžœžœžœ˜šžœž˜˜šžœžœ˜"Kšœ)žœE˜qK˜K˜—šžœ˜K˜K˜K˜—K˜—˜šžœ"ž˜,˜K˜!K˜K˜—˜K˜!K˜K˜—˜K˜ K˜K˜—˜K˜!K˜K˜—Kšžœžœ˜—K˜—Kšœžœ˜ Kšžœžœ˜—K˜Kšžœ˜—K˜K˜6K˜—K–[]šœžœ ˜K˜Kšžœ˜—Kšžœžœžœ˜4šž˜šœ˜KšœAžœ ˜MKšœžœ˜ K˜——K˜—š‘œžœ7žœ!žœžœžœžœ žœžœžœžœžœ˜ΔKšœžœ˜Kšœ žœ˜K˜0K˜>Kšžœ žœ žœ˜ K˜>Kšžœ žœ žœ˜K˜DKšžœ žœžœ˜#K˜AKšžœ žœžœ˜"K˜@Kšžœ žœžœ˜K˜DKšžœ žœžœ˜K˜DKšžœ žœ˜!K˜DKšžœ žœ˜!K˜EKšžœ žœ˜"K˜TK˜[Kšžœžœžœ ˜7šžœ žœ˜˜Kšœ9  ˜C—šœžœžœžœ ˜:Kšœ(žœ˜BKšžœ˜—šž˜Kšœžœžœžœ˜Kšœ"žœžœ˜:šžœž˜ KšœOžœ˜V—Kšžœžœžœ ˜Kšžœ˜—K˜ K˜—šžœžœ žœžœ˜Kšœ<žœ˜ZKšžœ ˜K˜—š žœžœžœžœžœ˜6Kšœ;žœ˜XKšžœ ˜K˜—š žœžœžœžœžœ˜6KšœOžœ˜lKšžœ ˜K˜—šžœžœžœ˜Kšœžœ˜ K˜K˜Xšžœž˜ Kšžœ ˜—Kšœžœ˜-K˜K˜—šžœ˜Kšœžœ˜ K˜Kšžœžœžœžœ ˜,K˜hšžœž˜ Kšžœ ˜—Kšœžœ˜-K˜K˜—šžœ žœžœžœ˜(KšœFžœ˜cKšžœ ˜K˜—šž˜Kšœžœ˜—Kšœ˜—Kšœžœ˜ Kšœ žœžœ˜Kš œ2žœžœžœ žœ˜Ušžœžœž˜šœ žœDžœ ˜]Kšžœ9žœžœ˜lKšžœ ˜K˜——Kšžœžœžœ˜&Kšžœžœžœ˜Kšžœ žœžœ˜K˜(K˜—šž˜š žœžœžœžœžœžœž˜6KšžœC˜EKšžœ˜——Kšžœžœžœ˜)Kšžœžœ˜K˜K˜—š"‘ œžœ žœ žœžœžœ žœžœ žœžœžœžœžœ žœžœžœžœ˜₯Kšžœ žœžœžœ˜šžœ*žœ˜2Kšœ žœ˜K˜Kšœ˜—šžœ˜K˜š žœžœžœžœžœ žœž˜;šžœ)žœ˜1K˜Kšœ žœ˜K˜ Kšžœ˜K˜—Kšžœ˜—K˜—K˜K˜K˜—š$‘œžœ žœ žœžœžœ žœžœ žœžœžœžœžœžœ žœžœžœžœ˜·Kšžœ žœžœžœ˜šžœ*žœ˜2Kšœ žœ˜K˜K˜Kšœ˜—šžœ˜K˜š žœžœžœžœžœ žœž˜;šžœ)žœ˜1K˜K˜Kšœ žœ˜K˜ Kšžœ˜K˜—Kšžœ˜—K˜—K˜K˜K˜—š‘ œžœ žœžœžœ žœžœžœžœžœ˜zš žœžœžœžœžœžœž˜6šžœž˜šžœ"žœ˜*Kšžœ+žœ˜?Kšœžœ˜K˜——Kšžœ˜—K˜K˜K˜—š‘œžœ žœ žœžœžœžœžœ˜TKšœžœ ˜Kšœžœ ˜Kšžœžœžœ˜Kš žœžœžœžœžœ˜6šžœ žœ˜šžœžœžœ ž˜Kšžœžœžœžœ˜0Kšž˜——šž˜šžœžœžœ ž˜Kšžœ5žœžœžœ˜JKšžœ˜——Kšžœžœ˜ K˜K˜—š ‘œžœžœžœžœ˜(š ‘œžœžœžœžœ˜&Kšžœ˜K˜—Kšžœ,˜2K˜K˜—š ‘œžœžœžœžœ˜(š ‘œžœžœžœžœ˜)Kšžœ˜K˜—Kšžœ/˜5K˜—K˜š ‘œžœžœžœžœ˜Gšžœ"žœ˜)Kšžœ˜%—šžœ˜Kšžœ˜—K˜K˜—˜K˜/K˜—K˜K˜šœd˜d˜K˜——šœ\˜\˜K˜——˜K˜—K˜K˜—…—4&H