DIRECTORY AdobeCommon USING [AddToOtherQLList, AddToSet, ButtonSeqObject, EnumeratedTypesRec, GetNextAR, GrowSet, Handle, InitialSetStatus, PostMessage, SetStatus, StringArray], AdobeCommonInternal USING [InstanceDataHandle, InstanceData], AdobeOps USING [ARNumber, ARSystemHandle, QLHandle, QueryList, QueryListBody, SetOfARs, SetOfARsObject], AdobeTool, AccessCH USING [NSNameFromRope], Buttons USING [ButtonProc], Convert USING [CardFromRope, RopeFromCard, RopeFromChar], IO USING [Close, EndOfStream, GetChar, PutChar, PutRope, STREAM], PFS USING [Error, PathFromRope, StreamOpen], Rope USING [Concat, Equal, Fetch, Length, ROPE], XNSAdobeClientOps USING [ReadLastARNumber]; AdobeToolImplC: CEDAR MONITOR IMPORTS AdobeCommon, AccessCH, Convert, IO, PFS, Rope, XNSAdobeClientOps EXPORTS AdobeTool = { unionPos: CARDINAL = 0; intsctnPos: CARDINAL = 1; compPos: CARDINAL = 2; diffPos: CARDINAL = 3; xorPos: CARDINAL = 4; copyToListPos: CARDINAL = 5; copyToFilePos: CARDINAL =6; op1Pos: CARDINAL = 7; op2Pos: CARDINAL = 8; resultPos: <> CARDINAL = 9;--used in QLNameHints in AdobeCommonImplE nQLParams: CARDINAL = 10; backStr: Rope.ROPE ¬ NIL; SetUpQueryListTool: PUBLIC PROCEDURE [handle: AdobeCommon.Handle] = { handle.fieldViewer.buttons ¬ NEW[AdobeCommon.ButtonSeqObject[1]]; handle.fieldViewer.buttons[0] ¬ NEW[AdobeCommon.EnumeratedTypesRec]; handle.fieldViewer.buttons[0].button ¬ handle.makeButton[ x: 3, y: 5, name: "List: ", scrollable: FALSE, parent: handle.fieldViewer.outer, --border: FALSE-- proc: $ListAction, data: handle, cData: handle, paint: TRUE]; handle.editors[4] ¬ handle.newFieldBox[ parent: handle.fieldViewer.outer, x: 3 + handle.getBoxGeometry[handle.fieldViewer.buttons[0].button].w, y: 6, w: 400, h: 800, scrollable: FALSE, border: FALSE]; }; QLNameHintsForQueryList: PUBLIC Buttons.ButtonProc = { arSH: AdobeOps.ARSystemHandle; data: AdobeCommon.Handle ¬ NARROW[clientData]; --AdobeCommon.GetDataSW[sw]; hintsLength, hintsIndex: CARDINAL ¬ 0; hintSeq: REF AdobeCommon.StringArray; list: AdobeOps.QLHandle; CountOtherQLs: PROCEDURE RETURNS [count: CARDINAL ¬ 0] = BEGIN list: AdobeOps.QLHandle ¬ arSH.otherQLs; WHILE list # NIL DO count ¬ count + 1; list ¬ list.next; ENDLOOP; END; arSH ¬ data.systemHandle; hintsLength ¬ CountOtherQLs[]; hintsLength ¬ hintsLength + 3; hintsIndex ¬ 3; hintSeq ¬ NEW[AdobeCommon.StringArray[hintsLength]]; hintSeq[0] ¬ "SysQL"; hintSeq[1] ¬ "List"; hintSeq[2] ¬ "filename"; list ¬ arSH.otherQLs; WHILE list # NIL DO hintSeq[hintsIndex] ¬ list.qL.name; hintsIndex ¬ hintsIndex + 1; list ¬ list.next; ENDLOOP; }; ChooseQLCmd: PUBLIC PROCEDURE [windowData: AdobeCommon.Handle, index: CARD] = { { ENABLE UNWIND => windowData.isBusy ¬ FALSE; windowData.isBusy ¬ TRUE; SELECT index FROM unionPos => ORSets[windowData]; intsctnPos => ANDSets[windowData]; copyToListPos => CopySet[windowData, FALSE]; copyToFilePos => CopySet[windowData, TRUE]; compPos => ComplementSet[windowData]; diffPos => DifferenceOfSets[windowData]; xorPos => XORSets[windowData]; ENDCASE => ERROR; windowData.isBusy ¬ FALSE; AdobeCommon.PostMessage[windowData, TRUE, "Done. "] }; }; NotDoneYet: PROCEDURE [windowData: AdobeCommon.Handle] = BEGIN AdobeCommon.PostMessage[windowData, TRUE, "Not Done Yet. "]; END; ORSets: PROCEDURE[data: AdobeCommon.Handle] = BEGIN set1, set2, resultSet: AdobeOps.SetOfARs ¬ NIL; AdobeCommon.PostMessage[data, FALSE, "Taking Union ... "]; set1 ¬ GetSetOne[data]; set2 ¬ GetSetTwo[data]; resultSet ¬ OrSetsImplB[set1, set2]; StoreQLinQueryList[data, resultSet]; END; --of ORSets ANDSets: PROCEDURE[data:AdobeCommon.Handle] = BEGIN set1, set2, resultSet: AdobeOps.SetOfARs ¬ NIL; AdobeCommon.PostMessage[data, FALSE, "Taking Intersection ... "]; set1 ¬ GetSetOne[data]; set2 ¬ GetSetTwo[data]; resultSet ¬ AndSetsImplB[set1, set2]; StoreQLinQueryList[data, resultSet]; END; --of ANDSets CopySet: PROCEDURE [data: AdobeCommon.Handle, toFile: BOOLEAN] = { sH: IO.STREAM; set: AdobeOps.SetOfARs ¬ NIL; instanceData:AdobeCommonInternal.InstanceDataHandle ¬ NARROW[data.instanceData]; AdobeCommon.PostMessage[data, FALSE, "Copying ... "]; set ¬ GetSetOne[data]; WITH instanceData SELECT FROM queryListData: REF AdobeCommonInternal.InstanceData.queryList => { queryListData.result ¬ data.getContents[data.editors[3]]; IF Rope.Equal[queryListData.result, "list", FALSE] THEN { StoreQLinFileOrList[set, NIL, data]; data.setContents[data.editors[4], queryListData.list]; AdobeCommon.PostMessage[data, TRUE, "copying to List. "]; } ELSE IF Rope.Equal[queryListData.result, "sysql", FALSE] THEN { AdobeCommon.PostMessage[data, TRUE, "copying to SysQL. "]; IF data.systemHandle.sysQL = NIL THEN data.systemHandle.sysQL ¬ NEW[AdobeOps.QueryListBody]; data.systemHandle.sysQL.list ¬ set} ELSE { IF ~toFile THEN StoreQLinQueryList[data, set] ELSE { sH ¬ PFS.StreamOpen[PFS.PathFromRope[queryListData.result], write ! PFS.Error => { AdobeCommon.PostMessage[data, FALSE, " ERROR--"]; IF queryListData.result =NIL OR queryListData.result.Length = 0 THEN AdobeCommon.PostMessage[data, FALSE, "no file specified in result field"] ELSE { AdobeCommon.PostMessage[data, FALSE, queryListData.result]; AdobeCommon.PostMessage[data, FALSE, " in result field"]}; AdobeCommon.PostMessage[data, TRUE, " cannot be obtained."]; ERROR ABORTED}]; StoreQLinFileOrList[set, sH, data]; sH ¬ CleanUpStream[sH]}}}; ENDCASE => ERROR; --shouldn't happen }; --of CopySet ComplementSet: PROCEDURE [data: AdobeCommon.Handle] = BEGIN setIndex, tempIndex: CARDINAL ¬ 0; ARNumber, lastAR: AdobeOps.ARNumber ¬ 0; set, tempSet, resultSet: AdobeOps.SetOfARs ¬ NIL; system: Rope.ROPE ¬ data.systemHandle.name; AdobeCommon.PostMessage[data, FALSE, "Complementing sets ..."]; lastAR ¬ XNSAdobeClientOps.ReadLastARNumber[data.systemHandle.service, AccessCH.NSNameFromRope[system].local]; set ¬ GetSetOne[data]; IF set = NIL THEN { tempSet ¬ NEW[AdobeOps.SetOfARsObject[1]]; tempSet[0] ¬ [1, lastAR]; StoreQLinQueryList[data, tempSet]; RETURN} ELSE { tempSet ¬ NEW[AdobeOps.SetOfARsObject[set.len + 1]]; FOR i: CARDINAL IN [0..tempSet.len) DO tempSet[i] ¬ [0,0]; ENDLOOP}; IF set[setIndex].startValue # 1 THEN { tempSet[tempIndex].startValue ¬ 1; IF set[setIndex].startValue <= lastAR THEN tempSet[tempIndex].runLength ¬ set[setIndex].startValue - 1 ELSE tempSet[tempIndex].runLength ¬ lastAR; tempIndex ¬ tempIndex + 1}; WHILE setIndex < set.len DO ARNumber ¬ set[setIndex].startValue + set[setIndex].runLength; IF ARNumber >= lastAR + 1 THEN EXIT; tempSet[tempIndex].startValue ¬ ARNumber; setIndex ¬ setIndex + 1; IF setIndex < set.len THEN IF set[setIndex].startValue = lastAR THEN tempSet[tempIndex].runLength ¬ lastAR - tempSet[tempIndex].startValue ELSE IF set[setIndex].startValue > lastAR THEN tempSet[tempIndex].runLength ¬ lastAR - tempSet[tempIndex].startValue + 1 ELSE tempSet[tempIndex].runLength ¬ set[setIndex].startValue - ARNumber ELSE tempSet[tempIndex].runLength ¬ lastAR - ARNumber + 1; tempIndex ¬ tempIndex + 1; ENDLOOP; resultSet ¬ PruneQL[tempSet, tempIndex - 1]; StoreQLinQueryList[data, resultSet]; END;--of ComplementSet DifferenceOfSets: PROCEDURE [data:AdobeCommon.Handle] = BEGIN ar1, ar2: AdobeOps.ARNumber ¬ 0; set1, set2: AdobeOps.SetOfARs ¬ NIL; set1Status, set2Status: AdobeCommon.SetStatus ¬ AdobeCommon.InitialSetStatus; resultState: CARDINAL ¬ 0; resultSet, tempSet: AdobeOps.SetOfARs ¬ NIL; AdobeCommon.PostMessage[data, FALSE, "Taking difference ... "]; set1 ¬ GetSetOne[data]; set2 ¬ GetSetTwo[data]; IF set1 = NIL THEN {StoreQLinQueryList[data, NIL]; RETURN}; IF set2 = NIL THEN {StoreQLinQueryList[data, set1]; RETURN}; tempSet ¬ NEW[AdobeOps.SetOfARsObject[set1.len]]; [ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status]; [ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status]; FOR i: CARDINAL IN [0..tempSet.len) DO tempSet[i] ¬ [0,0]; ENDLOOP; WHILE set1Status.setIndex < set1.len AND set2Status.setIndex < set2.len DO SELECT TRUE FROM ar1 = ar2 => { [ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status]; [ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status]}; ar1 > ar2 => [ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status]; ar1 < ar2 => { resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState]; [ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status]}; ENDCASE; ENDLOOP; WHILE set1Status.setIndex < set1.len DO resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState]; [ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status]; ENDLOOP; resultSet ¬ PruneQL[tempSet, resultState]; StoreQLinQueryList[data, resultSet]; END; -- of DifferenceOfSets XORSets: PROCEDURE[data: AdobeCommon.Handle] = BEGIN ar1, ar2: AdobeOps.ARNumber ¬ 0; set1,set2: AdobeOps.SetOfARs ¬ NIL; set1Status, set2Status: AdobeCommon.SetStatus ¬ AdobeCommon.InitialSetStatus; resultState: CARDINAL ¬ 0; resultSet, tempSet: AdobeOps.SetOfARs ¬ NIL; AdobeCommon.PostMessage[data, FALSE, "XORing sets ..."]; set1 ¬ GetSetOne[data]; set2 ¬ GetSetTwo[data]; IF set1 = NIL THEN {StoreQLinQueryList[data, set2]; RETURN}; IF set2 = NIL THEN {StoreQLinQueryList[data, set1]; RETURN}; tempSet ¬ NEW[AdobeOps.SetOfARsObject[set1.len + set2.len]]; FOR i: CARDINAL IN [0..tempSet.len) DO tempSet[i] ¬ [0,0]; ENDLOOP; [ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status]; [ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status]; WHILE set1Status.setIndex < set1.len AND set2Status.setIndex < set2.len DO SELECT TRUE FROM ar1 = ar2 => { [ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status]; [ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status]}; ar1 > ar2 => { resultState ¬ AdobeCommon.AddToSet[ar2, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState]; [ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status]}; ar1 < ar2 => { resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState]; [ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status]}; ENDCASE; ENDLOOP; WHILE set1Status.setIndex < set1.len DO resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState]; [ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status]; ENDLOOP; WHILE set2Status.setIndex < set2.len DO resultState ¬ AdobeCommon.AddToSet[ar2, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState]; [ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status]; ENDLOOP; resultSet ¬ PruneQL[tempSet, resultState]; StoreQLinQueryList[data, resultSet]; END; --of XORSets GetSetOne: PROCEDURE[data:AdobeCommon.Handle] RETURNS[set1: AdobeOps.SetOfARs ¬ NIL] = BEGIN qlH: AdobeOps.QLHandle ¬ NIL; instanceData: AdobeCommonInternal.InstanceDataHandle ¬ NARROW[data.instanceData]; WITH instanceData SELECT FROM queryListData: REF AdobeCommonInternal.InstanceData.queryList => { queryListData.operand1 ¬ data.getContents[data.editors[1]]; SELECT TRUE FROM queryListData.operand1 = NIL OR queryListData.operand1.Length = 0 => { AdobeCommon.PostMessage[data, TRUE, "sysQL will be used for operand1. "]; IF data.systemHandle.sysQL = NIL THEN RETURN[NIL] ELSE RETURN[data.systemHandle.sysQL.list]}; Rope.Equal[queryListData.operand1, "list", FALSE] => { set1 ¬ GetList[data]; RETURN[set1]}; Rope.Equal[queryListData.operand1, "sysQL", FALSE] => { IF data.systemHandle.sysQL = NIL THEN RETURN[NIL] ELSE RETURN[data.systemHandle.sysQL.list]}; ENDCASE => { qlH ¬ data.systemHandle.otherQLs; WHILE qlH # NIL DO IF Rope.Equal[queryListData.operand1, qlH.qL.name, FALSE] THEN RETURN[qlH.qL.list]; qlH ¬ qlH.next; ENDLOOP; RETURN[RetrieveQL[queryListData.operand1, data]]}; }; ENDCASE; --shouldn't happen; END; --of GetSetOne GetSetTwo: PROCEDURE [data: AdobeCommon.Handle] RETURNS[set2: AdobeOps.SetOfARs] = BEGIN qlH:AdobeOps.QLHandle ¬ NIL; instanceData: AdobeCommonInternal.InstanceDataHandle ¬ NARROW[data.instanceData]; WITH instanceData SELECT FROM queryListData: REF AdobeCommonInternal.InstanceData.queryList => { queryListData.operand2 ¬ data.getContents[data.editors[2]]; SELECT TRUE FROM queryListData.operand2 = NIL OR queryListData.operand2.Length = 0 => { AdobeCommon.PostMessage[ data, TRUE, "sysQL will be used for operand2. "]; IF data.systemHandle.sysQL = NIL THEN RETURN[NIL] ELSE RETURN[data.systemHandle.sysQL.list]}; Rope.Equal[queryListData.operand2, "list", FALSE] => { set2 ¬ GetList[data]; RETURN[set2]}; Rope.Equal[queryListData.operand2, "sysQL", FALSE] => { <> IF data.systemHandle.sysQL = NIL THEN RETURN[NIL] ELSE RETURN[data.systemHandle.sysQL.list]}; ENDCASE => { qlH ¬ data.systemHandle.otherQLs; WHILE qlH # NIL DO IF Rope.Equal[queryListData.operand2, qlH.qL.name, FALSE] THEN RETURN[qlH.qL.list]; qlH ¬ qlH.next; ENDLOOP; RETURN[RetrieveQL[queryListData.operand2, data]]}; }; ENDCASE; --shouldn't happen; END; --of GetSetTwo GetList: PROCEDURE [data:AdobeCommon.Handle] RETURNS [resultSet: AdobeOps.SetOfARs ¬ NIL] = BEGIN qlH:AdobeOps.QLHandle ¬ NIL; setIndex: CARDINAL ¬ 0; listIndex: INTEGER ¬ 0; arNumberString: Rope.ROPE ¬ NIL; arNumber, prevarNumber: AdobeOps.ARNumber ¬ 0; set: AdobeOps.SetOfARs ¬ NIL; instanceData: AdobeCommonInternal.InstanceDataHandle ¬ NARROW[data.instanceData]; BEGIN ENABLE { UNWIND => { IF arNumberString # NIL THEN arNumberString ¬ NIL; IF set # NIL THEN set ¬ NIL } }; GetAR: PROCEDURE[list: Rope.ROPE] = BEGIN arNumber ¬ 0; WHILE listIndex < list.Length AND list.Fetch[listIndex] = ' DO listIndex ¬ listIndex + 1; ENDLOOP; IF listIndex < list.Length AND list.Fetch[listIndex] NOT IN ['0..'9] AND list.Fetch[listIndex] # '- THEN { AdobeCommon.PostMessage[data, TRUE, "Invalid character entered in List."]; ERROR ABORTED}; WHILE listIndex < list.Length AND list.Fetch[listIndex] IN ['0..'9] DO arNumberString ¬ arNumberString.Concat[Convert.RopeFromChar[list.Fetch[listIndex], FALSE]]; listIndex ¬ listIndex + 1; ENDLOOP; IF listIndex < list.Length AND list.Fetch[listIndex] # ' AND list.Fetch[listIndex] # '- THEN { AdobeCommon.PostMessage[data, TRUE, "Invalid character entered in List."]; ERROR ABORTED}; IF arNumberString.Length #0 THEN { arNumber ¬ Convert.CardFromRope[arNumberString]; IF arNumber = 0 THEN { AdobeCommon.PostMessage[data, TRUE, "AR number 0 is invalid"]; ERROR ABORTED}}; arNumberString ¬ ClearString[arNumberString]; WHILE listIndex < list.Length AND list.Fetch[listIndex] = ' DO listIndex ¬ listIndex + 1; ENDLOOP; IF listIndex < list.Length AND list.Fetch[listIndex] NOT IN ['0..'9] AND list.Fetch[listIndex] # '- THEN { AdobeCommon.PostMessage[data, TRUE, "Invalid character entered in List."]; ERROR ABORTED}; END;--of GetAR WITH instanceData SELECT FROM queryListData: REF AdobeCommonInternal.InstanceData.queryList => { queryListData.list ¬ data.getContents[data.editors[4]]; IF queryListData.list = NIL OR queryListData.list.Length = 0 THEN RETURN[NIL]; set ¬ NEW[AdobeOps.SetOfARsObject[10]]; FOR i: CARDINAL IN [0..set.len) DO set[i] ¬ [0,0]; ENDLOOP; WHILE listIndex < queryListData.list.Length DO GetAR[queryListData.list]; SELECT TRUE FROM prevarNumber = 0 AND arNumber = 0 => AdobeCommon.PostMessage[data, TRUE, "List is empty or invalid list format. An empty query list has been created"]; prevarNumber > arNumber AND arNumber # 0 => { AdobeCommon.PostMessage[data, TRUE, "The numbers entered in list should be in ascending order."]; ERROR ABORTED}; prevarNumber = arNumber => { AdobeCommon.PostMessage[data, TRUE, "Duplicate numbers."]; ERROR ABORTED}; ENDCASE; prevarNumber ¬ arNumber; IF set[setIndex].startValue + set[setIndex].runLength = arNumber THEN set[setIndex].runLength ¬ set[setIndex].runLength + 1 ELSE { IF set[setIndex].startValue # 0 THEN { setIndex ¬ setIndex + 1; IF setIndex = set.len THEN AdobeCommon.GrowSet[NEW[AdobeOps.SetOfARs ¬ set]]}; set[setIndex].startValue ¬ arNumber; set[setIndex].runLength ¬ 1}; IF listIndex < queryListData.list.Length AND queryListData.list.Fetch[listIndex] = '- THEN { listIndex ¬ listIndex + 1; GetAR[queryListData.list]; IF prevarNumber > arNumber AND arNumber # 0 THEN { AdobeCommon.PostMessage[data, TRUE, "The numbers entered in list should be in ascending order."]; ERROR ABORTED}; set[setIndex].runLength ¬ arNumber - set[setIndex].startValue + 1}; ENDLOOP}; ENDCASE; resultSet ¬ PruneQL[set, setIndex]; END; --enable END;--of GetList OrSetsImplB: PROCEDURE [set1, set2: AdobeOps.SetOfARs] RETURNS [resultSet: AdobeOps.SetOfARs] = BEGIN ar1, ar2: AdobeOps.ARNumber; set1Status, set2Status: AdobeCommon.SetStatus ¬ [0, 0]; resultState: CARDINAL ¬ 0; tempSet: AdobeOps.SetOfARs; IF set1 = NIL THEN RETURN[set2]; IF set2 = NIL THEN RETURN[set1]; tempSet ¬ NEW[ AdobeOps .SetOfARsObject[set1.len + set2.len]]; ar1 ¬ set1[0].startValue; ar2 ¬ set2[0].startValue; FOR i: CARDINAL IN [0..tempSet.len) DO tempSet[i] ¬ [0, 0]; ENDLOOP; WHILE set1Status.setIndex < set1.len AND set2Status.setIndex < set2.len DO SELECT TRUE FROM ar1 = ar2 => { --add only once resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState]; [ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status]; [ar1, set1Status] ¬ AdobeCommon.GetNextAR[ set1, set1Status]}; ar1 > ar2 => { resultState ¬ AdobeCommon.AddToSet[ar2, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState]; [ar2, set2Status] ¬ AdobeCommon.GetNextAR[ set2, set2Status]}; ar1 < ar2 => { resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState]; [ar1, set1Status] ¬ AdobeCommon.GetNextAR[ set1, set1Status]}; ENDCASE; ENDLOOP; IF set1Status.setIndex < set1.len THEN --add rest of set1 WHILE set1Status.setIndex < set1.len DO resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState]; [ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status]; ENDLOOP ELSE --add rest of set2 WHILE set2Status.setIndex < set2.len DO resultState ¬ AdobeCommon.AddToSet[ar2, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState]; [ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status]; ENDLOOP; IF resultState + 1 = (set1.len + set2.len) THEN { RETURN[tempSet]} ELSE { resultSet ¬ NEW[ AdobeOps .SetOfARsObject[resultState + 1]]; FOR i: CARDINAL IN [0..resultSet.len) DO resultSet[i] ¬ tempSet[i]; ENDLOOP; }; END; AndSetsImplB: PROCEDURE [set1, set2: AdobeOps.SetOfARs] RETURNS [resultSet: AdobeOps.SetOfARs] = BEGIN ar1, ar2: AdobeOps.ARNumber; set1Status, set2Status: AdobeCommon.SetStatus ¬ AdobeCommon.InitialSetStatus; resultState: CARDINAL ¬ 0; tempSet: AdobeOps.SetOfARs; IF set1 = NIL THEN { IF set2 # NIL THEN set2 ¬ NIL; RETURN[NIL]} ELSE IF set2 = NIL THEN { set1 ¬ NIL; RETURN[NIL]}; tempSet ¬ NEW[ AdobeOps .SetOfARsObject[MAX[set1.len, set2.len]]]; [ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status]; [ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status]; FOR i: CARDINAL IN [0..tempSet.len) DO tempSet[i] ¬ [0, 0]; ENDLOOP; WHILE set1Status.setIndex < set1.len AND set2Status.setIndex < set2.len DO SELECT TRUE FROM ar1 = ar2 => { resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState]; [ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status]; [ar1, set1Status] ¬ AdobeCommon.GetNextAR[ set1, set1Status]}; ar1 > ar2 => [ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status]; ar1 < ar2 => [ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status]; ENDCASE; ENDLOOP; IF resultState = 0 AND tempSet[0].startValue = 0 THEN { --empty set RETURN[NIL]}; IF resultState + 1 = MAX[set1.len, set2.len] THEN { RETURN[tempSet]} ELSE { resultSet ¬ NEW[ AdobeOps .SetOfARsObject[resultState + 1]]; FOR i: CARDINAL IN [0..resultSet.len) DO resultSet[i] ¬ tempSet[i]; ENDLOOP; }; END; RetrieveQL: PROCEDURE[fileName: Rope.ROPE, data:AdobeCommon.Handle] RETURNS [resultSet: AdobeOps.SetOfARs ¬ NIL] = BEGIN fH: IO.STREAM ¬ NIL; char: CHARACTER ¬ ' ; prevARNumber, arNumber: AdobeOps.ARNumber ¬ 0; arNumberString: Rope.ROPE ¬ NIL; tempSet: AdobeOps.SetOfARs ¬ NIL; tempIndex: CARDINAL ¬ 0; endOfFile: BOOLEAN ¬ FALSE; BEGIN ENABLE { UNWIND => { IF fH # NIL THEN IO.Close[fH]; IF arNumberString # NIL THEN arNumberString ¬ NIL; IF tempSet # NIL THEN tempSet ¬ NIL}}; GetNextARNumber: PROCEDURE = BEGIN WHILE char = ' DO char ¬ IO.GetChar[fH !IO.EndOfStream => GOTO EOF]; ENDLOOP; WHILE char IN ['0..'9] AND NOT endOfFile DO arNumberString ¬ arNumberString.Concat[Convert.RopeFromChar[char, FALSE]]; char ¬ IO.GetChar[fH !IO.EndOfStream => GOTO EOF]; ENDLOOP; WHILE char = ' DO char ¬ IO.GetChar[fH !IO.EndOfStream => GOTO EOF]; ENDLOOP; IF char NOT IN ['0..'9] AND char # '- THEN { AdobeCommon.PostMessage[data, TRUE, "Invalid character in file! ."]; ERROR ABORTED}; prevARNumber ¬ arNumber; IF arNumberString.Length = 0 THEN { AdobeCommon.PostMessage[data, TRUE, "Invalid syntax! ."]; ERROR ABORTED}; arNumber ¬ Convert.CardFromRope[arNumberString]; arNumberString ¬ ClearString[arNumberString]; IF arNumber <= prevARNumber THEN { AdobeCommon.PostMessage[data, TRUE, "AR numbers must be in ascending order! ."]; ERROR ABORTED} EXITS EOF => { IF arNumberString.Length # 0 THEN { prevARNumber ¬ arNumber; arNumber ¬ Convert.CardFromRope[arNumberString]; IF arNumber <= prevARNumber THEN { AdobeCommon.PostMessage[ data, TRUE, "AR numbers must be in ascending order! ."]; ERROR ABORTED}; arNumberString ¬ ClearString[arNumberString]}; endOfFile ¬ TRUE;} END; --of GetNextARNumber fH ¬ PFS.StreamOpen[PFS.PathFromRope[fileName] ! PFS.Error => {AdobeCommon.PostMessage[data, FALSE, fileName]; AdobeCommon.PostMessage[data, TRUE, " does not exist as a querylist or file."]; ERROR ABORTED}]; tempSet ¬ NEW[AdobeOps.SetOfARsObject[100]]; FOR i: CARDINAL IN [0..tempSet.len) DO tempSet[i] ¬ [0,0]; ENDLOOP; GetNextARNumber[]; tempSet[0].startValue ¬ arNumber; IF endOfFile OR char IN ['0..'9] THEN tempSet[0].runLength ¬ 1 ELSE IF NOT endOfFile AND char = '- THEN { char ¬ IO.GetChar[fH !IO.EndOfStream => { AdobeCommon.PostMessage[data, TRUE, "Invalid Syntax! ."]; ERROR ABORTED}]; GetNextARNumber[]; tempSet[0].runLength ¬ arNumber - tempSet[0].startValue + 1}; WHILE NOT endOfFile DO GetNextARNumber[]; IF arNumber # tempSet[tempIndex].startValue + tempSet[tempIndex].runLength THEN{ tempIndex ¬ tempIndex + 1; IF tempIndex = tempSet.len THEN AdobeCommon.GrowSet[NEW[AdobeOps.SetOfARs ¬ tempSet]]; tempSet[tempIndex].startValue ¬ arNumber; IF endOfFile OR char IN ['0..'9] THEN tempSet[tempIndex].runLength ¬ 1 ELSE IF NOT endOfFile AND char = '- THEN { char ¬ IO.GetChar[fH !IO.EndOfStream => { AdobeCommon.PostMessage[data, TRUE, "Invalid Syntax! ."]; ERROR ABORTED}]; GetNextARNumber[]; tempSet[tempIndex].runLength ¬ arNumber - tempSet[tempIndex].startValue + 1}} ELSE { IF endOfFile OR char IN ['0..'9] THEN tempSet[tempIndex].runLength ¬ tempSet[tempIndex].runLength + 1 ELSE IF NOT endOfFile AND char = '- THEN { char ¬ IO.GetChar[fH !IO.EndOfStream => { AdobeCommon.PostMessage[data, TRUE, "Invalid Syntax! ."]; ERROR ABORTED}]; GetNextARNumber[]; tempSet[tempIndex].runLength ¬ arNumber - tempSet[tempIndex].startValue + 1;}} ENDLOOP; fH ¬ CleanUpStream[fH]; arNumberString ¬ NIL; resultSet ¬ PruneQL[tempSet, tempIndex] END; END; --of RetrieveQL StoreQLinQueryList: PROCEDURE[data: AdobeCommon.Handle, set: AdobeOps.SetOfARs] = { found: BOOLEAN ¬ FALSE; qlH: AdobeOps.QLHandle ¬ NIL; ql: AdobeOps.QueryList ¬ NIL; instanceData: AdobeCommonInternal.InstanceDataHandle ¬ NARROW[data.instanceData]; WITH instanceData SELECT FROM queryListData: REF AdobeCommonInternal.InstanceData.queryList => { queryListData.result ¬ data.getContents[data.editors[3]]; IF queryListData.result = NIL OR queryListData.result.Length = 0 THEN AdobeCommon.PostMessage[ data, TRUE, "ERROR--result field not specified."] ELSE IF Rope.Equal[queryListData.result, "SysQL", FALSE] THEN { IF data.systemHandle.sysQL = NIL THEN data.systemHandle.sysQL ¬ NEW[AdobeOps.QueryListBody]; data.systemHandle.sysQL.list ¬ set} ELSE IF Rope.Equal[queryListData.result, "List", FALSE] THEN { StoreQLinFileOrList[set, NIL, data]; } ELSE { qlH ¬ data.systemHandle.otherQLs; WHILE qlH # NIL AND found = FALSE DO IF Rope.Equal[queryListData.result, qlH.qL.name, FALSE] THEN found ¬ TRUE ELSE qlH ¬ qlH.next; ENDLOOP; IF found THEN qlH.qL.list ¬ set ELSE { ql ¬ NEW[AdobeOps.QueryListBody]; ql­.name ¬ queryListData.result; ql­.list ¬ set; AdobeCommon.AddToOtherQLList[data.systemHandle, ql]}}}; ENDCASE; --shoud not happen };--of StoreQLinQueryList StoreQLinFileOrList: PROCEDURE[set: AdobeOps.SetOfARs, fH: IO.STREAM, data: AdobeCommon.Handle] = BEGIN beginValue, runValue, endValue: AdobeOps.ARNumber ¬ 0; stringValue: Rope.ROPE ¬NIL; hyphen: CHARACTER ¬ '-; space: CHARACTER ¬ ' ; copyToList: BOOLEAN ¬ FALSE; instanceData: AdobeCommonInternal.InstanceDataHandle ¬ NARROW[data.instanceData]; WITH instanceData SELECT FROM queryListData: REF AdobeCommonInternal.InstanceData.queryList => { IF fH = NIL THEN { copyToList ¬ TRUE; IF queryListData.list # NIL THEN queryListData.list ¬ NIL; }; IF set # NIL THEN BEGIN FOR index:CARDINAL IN [0..set.len) DO beginValue ¬ set[index].startValue; stringValue ¬ ClearString[stringValue]; stringValue ¬ stringValue.Concat[Convert.RopeFromCard[beginValue, 10, FALSE]]; IF copyToList THEN queryListData.list ¬ queryListData.list.Concat[stringValue] ELSE IO.PutRope[fH, stringValue]; runValue ¬ set[index].runLength; IF runValue = 1 AND index # set.len - 1 THEN IF copyToList THEN queryListData.list ¬ queryListData.list.Concat[Convert.RopeFromChar[space, FALSE]] ELSE IO.PutChar[fH, space] ELSE IF runValue # 1 THEN { IF copyToList THEN queryListData.list ¬ queryListData.list.Concat[Convert.RopeFromChar[hyphen, FALSE]] ELSE IO.PutChar[fH, hyphen]; endValue ¬ beginValue + runValue -1; stringValue ¬ ClearString[stringValue]; stringValue ¬ stringValue.Concat[Convert.RopeFromCard[endValue, 10, FALSE]]; IF copyToList THEN queryListData.list ¬ queryListData.list.Concat[stringValue] ELSE IO.PutRope[fH, stringValue]; IF index # set.len - 1 THEN IF copyToList THEN queryListData.list ¬ queryListData.list.Concat[Convert.RopeFromChar[space, FALSE]] ELSE IO.PutChar[fH,space]}; ENDLOOP; stringValue ¬ NIL; END ELSE IF ~copyToList THEN IO.PutChar[fH,space]}; ENDCASE; END; CleanUpStream: PROCEDURE[streamHandle: IO.STREAM--MStream.Handle--] RETURNS [--MStream.Handle-- IO.STREAM] = { streamHandle.Close; streamHandle ¬ NIL; RETURN [streamHandle]; }; --of CleanUpStream ClearString: PROCEDURE[inString: Rope.ROPE] RETURNS [Rope.ROPE ¬ NIL] = { RETURN [NIL]; }; --of ClearString PruneQL: PROCEDURE[set:AdobeOps.SetOfARs, index:CARDINAL] RETURNS [AdobeOps.SetOfARs] = BEGIN newSet: AdobeOps.SetOfARs ¬ NIL; IF set[0].startValue = 0 THEN { RETURN[NIL]}; IF index + 1 = set.len THEN RETURN[set] ELSE { newSet ¬ NEW[AdobeOps.SetOfARsObject[index + 1]]; FOR i: CARDINAL IN [0..newSet.len) DO newSet[i] ¬ set[i]; ENDLOOP; RETURN[newSet]}; END; --of PruneQL }. . . %Ό File: AdobeToolsC.mesa - created by JCS. Last edit: Copyright Σ 1992 by Xerox Corporation. All rights reserved. JCS 2-Mar-86 14:58:34 RSF 17-Apr-85 13:06:40 Philip James, March 9, 1992 1:12 pm PST Christian Jacobi, April 7, 1992 5:37 pm PDT Copyright (C) 1985, 1986 by Xerox Corporation. All rights reserved. QueryList globals for queryList NilFormProc: FormSW.ClientItemsProcType = { freeDesc _ TRUE; items _ FormSW.AllocateItemDescriptor[1]; items[0] _ FormSW.StringItem[invisible: TRUE, string: @backStr]}; CreateQuerylistSW: PUBLIC PROCEDURE[ w: AdobeCommon.Handle, makeCmdSW: BOOLEAN _ TRUE] RETURNS[initialMsg: Rope.ROPE _ NIL] = BEGIN data: AdobeCommon.Handle _ AdobeCommon.GetData[w]; instanceData: AdobeCommonInternal.InstanceDataHandle _ NARROW[data.instanceData]; IF makeCmdSW THEN { instanceData _ AdobeCommonInternal.AllocateInstanceData[data]; instanceData.cmdSW _ Tool.MakeFormSW[ window: w, formProc: QueryListCmdSW, zone: data.heap]}; instanceData.formSW _ Tool.MakeFormSW[ window: w, formProc: QueryListFormSW, zone: data.heap]; AdobeCommon.DisableAdobeAborts[w]; AdobeCommonInternal.SetWindowName[ w, IF data.knownSystems # NIL AND data.context # NIL AND data.system # LAST[CARDINAL] THEN data.knownSystems[data.system] ELSE NIL, AdobeCommonInternal.queryListHeraldName]; END; QueryListCmdSW: FormSW.ClientItemsProcType = { OPEN FormSW; windowData: AdobeCommon.Handle _ AdobeCommon.GetDataSW[sw]; instanceData: AdobeCommonInternal.InstanceDataHandle _ windowData.instanceData; WITH qLToolData: instanceData SELECT FROM queryList => { items _ AllocateItemDescriptor[nQLParams, windowData.heap]; freeDesc _ TRUE; items[unionPos] _ CommandItem[ tag: "Union", place: [0, line0], proc: QLCommandProc--, --z: windowData.heap--]; items[intsctnPos] _ CommandItem[ tag: "Intersection", place: [72, line0], proc: QLCommandProc--, z: windowData.heap--]; items[compPos] _ CommandItem[ tag: "Complement", place: [195, line0], proc: QLCommandProc--, z: windowData.heap--]; items[diffPos] _ CommandItem[ tag: "Difference", place: [306, line0], proc: QLCommandProc--, z: windowData.heap--]; items[xorPos] _ CommandItem[ tag: "XOR", place: [408, line0], proc: QLCommandProc--, z: windowData.heap--]; items[copyToListPos] _ CommandItem[ tag: "CopyToQueryList", place: [0, line1], proc: QLCommandProc--, z: windowData.heap--]; items[copyToFilePos] _ CommandItem[ tag: "CopyToFile", place: [119, line1], proc: QLCommandProc--, z: windowData.heap--]; items[op1Pos] _ StringItem[ tag: "Operand1", string: @qLToolData.operand1, place: [0, line2], menuProc: QLNameHintsForQueryList--, --z: windowData.heap, inHeap: TRUE--]; items[op2Pos] _ StringItem[ tag: "Operand2", string: @qLToolData.operand2, place: [171,line2], menuProc: QLNameHintsForQueryList--, --z: windowData.heap, inHeap: TRUE--]; items[resultPos] _ StringItem[ tag: "Result", place: [348,line2], string: @qLToolData.result, menuProc: QLNameHintsForQueryList--, --z: windowData.heap, inHeap: TRUE--]; }; ENDCASE => ERROR; --shouldn't happen }; FormSW.MenuProcType = BEGIN IF data.context = NIL THEN { hints _ NIL; RETURN}; freeHintsProc _ AdobeCommon.FreeHintStrings; replace _ TRUE; hints _ DESCRIPTOR[hintSeq]; QueryListFormSW: FormSW.ClientItemsProcType = BEGIN OPEN FormSW; windowData: AdobeCommon.Handle _ AdobeCommon.GetDataSW[sw]; instanceData: AdobeCommonInternal.InstanceDataHandle _ NARROW[windowData.instanceData]; WITH qLToolData: instanceData SELECT FROM queryList => { items _ AllocateItemDescriptor[1, windowData.heap]; freeDesc _ TRUE; items[0] _ StringItem[ tag: "List", string: @qLToolData.list, place: [0, line0]--, z: windowData.heap, inHeap: TRUE--]}; ENDCASE => ERROR; --shouldn't happen END; QLCommandProc: PUBLIC Buttons.ButtonProc = { FormSW.ProcType = { windowData: AdobeCommon.Handle _ NARROW[clientData]; --AdobeCommon.GetDataSW[sw]; instanceData: AdobeCommonInternal.InstanceDataHandle _ NARROW[windowData.instanceData]; MsgSW.Clear[windowData.msgSW]; IF windowData.system = LAST[CARDINAL] --OR windowData.context = NIL --OR windowData.knownSystems = NIL OR windowData.knownSystems.next = 0 THEN { AdobeCommon.PostMessage[windowData, TRUE, "No available systems"]; RETURN}; IF windowData.isBusy THEN AdobeCommon.PostMessage[windowData, TRUE, "Adobe system is Busy. Please try again later. "] ELSE { windowData.isBusy _ TRUE; IF instanceData.background AND ~TajoMisc.toolDriverRunning THEN Process.Detach[ windowData.processID _ FORK AdobeCommon.CatchErrors[ sw, item, index, windowData, ChooseQLCmd]] ELSE { windowData.processID _ Process.GetCurrent[]; AdobeCommon.CatchErrors[ --sw, item, index, --windowData, ChooseQLCmd]}--}; }; FormSW.ProcType = { windowData: AdobeCommon.Handle _ AdobeCommon.GetDataSW[sw]; IF windowData.context # NIL THEN { windowData.processID _ NIL; } ELSE AdobeCommon.PostMessage[windowData, TRUE, "Adobe is not set to an Adobe system. "]; cannot use AdobeCommon.OrSets because it will free set1 and set2 resultSet _ AdobeCommon.OrSets[set1, set2]; cannnot use AdobeCommon.AndSets because it will free set1 and set2 resultSet _ AdobeCommon.AndSets[set1, set2]; copies a querylist into a file or to list the querylist is gotten from operand1 if the result field is not equal to "list" then, the filename is gotten from the result field sH: MStream.Handle; mfRD: MStream.ReleaseData _ [NIL, NIL]; formItem: FormSW.ItemHandle; code formItem _ FormSW.FindItem[instanceData.formSW, 0]; formItem.flags.invisible _ TRUE; formItem.flags.invisible _ FALSE; FormSW.DisplayItem[queryListData.formSW, 0] sH _ MStream.WriteOnly[queryListData.result, mfRD, text ! MStream.Error => { AdobeCommon.PostMessage[data, FALSE, " ERROR--"]; IF queryListData.result =NIL OR queryListData.result.Length = 0 THEN AdobeCommon.PostMessage[data, FALSE, "no file specified in result field"] ELSE { AdobeCommon.PostMessage[data, FALSE, queryListData.result]; AdobeCommon.PostMessage[data, FALSE, " in result field"]}; AdobeCommon.PostMessage[data, TRUE, " cannot be obtained."]; ERROR ABORTED}]; AdobeServer.ReadLastARNumber returns the total number of AR in the given system initialize tempSet prune tempSet assume that ARs given are in numeric order initialize temp For the difference of two sets, set1-set2, if set1 is exhausted first, we are done or if set2 is exhausted first, append what remains on set1 to the resultset. if set2 is exhausted first then append what remains on set1 to resultset. prune tempSet assume that ARs given are in numeric order initialize tempSet prune tempSet if this code is executed then operand1 is not in otherqls. before returning sysQL, check if operand1 is a filename if this code is executed then operand2 is not in otherqls. before returning sysQL, check if operand2 is a filename AdobeOps.z.FREE[@set]}}; String.AppendChar[arNumberString, list.Fetch[listIndex]]; arNumberString _ String.MakeString[data.heap, 16]; initialize temp taken from AdobeToolsB, I thought it would be faster to do this rather that to allocate and deallocate two sets assume that ARs given are in numeric order initialize temp For OR, when one set is exhausted, we've got to append what remains of the unexhausted set to the result. AdobeOps.z.FREE[@set1]; we don't want to free this AdobeOps.z.FREE[@set2]; we don't want to free this AdobeOps.z.FREE[@tempSet] AdobeOps.z.FREE[@set1]; we don't want to free this AdobeOps.z.FREE[@set2]; we don't want to free this taken from AdobeToolsB, thought it would be faster to do this rather than allocating and deallocating space for the two sets next time we change AdobeCommon interface add boolean parameter to see if set should be freed assume that ARs given are in numeric order AdobeOps.z.FREE[@set2]; AdobeOps.z.FREE[@set1]; initialize temp For AND, when one set is exhausted, we've got all that are common to both so can just exit knowing we're done AdobeOps.z.FREE[@tempSet]; AdobeOps.z.FREE[@set1]; we don't want to free this AdobeOps.z.FREE[@set2]; we don't want to free this prune to just fit AdobeOps.z.FREE[@set1]; we don't want to free this AdobeOps.z.FREE[@set2]; we don't want to free this AdobeOps.z.FREE[@tempSet] AdobeOps.z.FREE[@set1]; we don't want to free this AdobeOps.z.FREE[@set2]; we don't want to free this reads a file containing ar numbers variables fH: MStream.Handle _ NIL; mfRD: MStream.ReleaseData _ [NIL, NIL]; Stream.Delete[fH]; AdobeOps.z.FREE[@tempSet]}}; String.AppendChar[arNumberString, char]; code fH _ MStream.ReadOnly[fileName, mfRD !MStream.Error => {AdobeCommon.PostMessage[data, FALSE, fileName]; AdobeCommon.PostMessage[data, TRUE, " does not exist as a querylist or file."]; ERROR ABORTED}]; arNumberString _ String.MakeString[data.heap, 16]; initialize temp String.FreeString[data.heap, arNumberString]; prune tempSet if necessary formItem: FormSW.ItemHandle; formItem _ FormSW.FindItem[instanceData.formSW, 0]; formItem.flags.invisible _ TRUE; formItem.flags.invisible _ FALSE; FormSW.DisplayItem[queryListData.formSW, 0] queryListData.list _ String.MakeString[data.heap,50]; queryListData.list.Length _ 0 stringValue _ String.MakeString[data.heap,16]; String.AppendLongNumber[stringValue, beginValue]; String.AppendChar[queryListData.list, space] String.AppendChar[queryListData.list, hyphen] String.AppendLongNumber[stringValue, endValue]; String.AppendChar[queryListData.list, space] String.FreeString[data.heap, stringValue]; Stream.Delete[streamHandle]; index: CARDINAL _ 0; FOR index IN [0..16) DO inString.text[index] _ ' ; FOR index IN [0..inString.Length) DO inString.text[index] _ ' ; ENDLOOP; inString.Length _ 0; RETURN [inString]; AdobeOps.z.FREE[@set]; AdobeOps.z.FREE[@set]; Κ${•NewlineDelimiter –(cedarcode) style™šœ3™3Jšœ Οeœ1™™%J™;——™&J™7—J™"™"Jš œžœžœžœžœž™8Jšœžœžœž™!Jšœžœžœ™(J™)—Jšžœ™—K˜K˜šŸœžœž œ!˜EKšœžœ!˜AKšœ žœ!˜D˜9Kšœ(žœ$ ˜bKšœ7žœ˜=—˜'KšœŠžœ žœ˜ —K˜K˜—šŸœ!™/Jšžœ™ Jšœ;™;™6J™—Jšžœžœž™)™J™;Jšœ žœ™™J™7J™™ J™)J™-—™J™(J™-—™J™(J™-—™J™!J™-—™#J™+J™-—™#J™(J™-—™J™.J™7Jšœžœ™&—™J™.J™8Jšœžœ™&—™J™"J™@Jšœžœ™&——J™—Jšžœžœ ™$Jšœ™J™—šŸœžœ˜6Jšœž™K˜Kšœžœ ˜KKšœžœ˜&Kšœ žœ˜%K˜K˜šŸ œž œžœ žœ˜8Kšž˜K˜(šžœžœž˜K˜K˜Kšžœ˜—Kšžœ˜K˜—šžœžœžœ™Jšœžœžœ™—K˜J™,Jšœ žœ™K˜K˜K˜Kšœ žœ'˜4K˜K˜K˜K˜šžœžœž˜K˜#K˜K˜Kšžœ˜—Jšœž œ ™Kšœ˜——˜K˜šŸœ™-šžœžœ™Jšœ;™;™7Jšžœ™ —Jšžœžœž™)™J™3Jšœ žœ™™J™&Jšœ &œ™:——Jšžœžœ ™$—Jšžœ™—K˜šŸ œžœ™,Jšœ™Jšœ!žœ ™Q™7Jšžœ™ —J™šžœžœžœ  žœžœžœ"žœ™‘Jšœ$žœ™BJšžœ™—šžœž™Jšœ$žœ5™]—šžœ™Jšœžœ™šžœžœž™?™šœžœ™4J™*———šžœ™J™,™Jš œ ™2———Jšœ™—K˜šŸ œžœž œ)žœ˜OJšœ™J™;šœ˜Kšžœžœžœ˜+Kšœžœ˜šžœžœžœ™"šžœž˜K˜K˜"Kšœ%žœ˜,Kšœ%žœ˜+K˜%K˜(K˜Kšžœžœ˜—Kšœžœ˜Jšœžœ™Kšœ$žœ ˜3Jšœ™—Jšžœ%žœ+™XKšœ˜—Kšœ˜K˜—šŸ œž œ#˜8Kšž˜Kšœ$žœ˜Kšžœžœžœ˜)K˜)K˜šžœžœ˜šžœ#žœ˜*K˜E—šžœžœ#žœ˜/K˜I—KšžœC˜G—Kšžœ7˜;K˜—Kšžœ˜Jšœ ™ K˜,K˜$K˜Kšžœ ˜K˜—šŸœž œ˜8Kšž˜Jšœ*™*K˜ Kšœ žœ˜$K˜MKšœ žœ˜Kšœ(žœ˜,K˜Kšœžœ˜?K˜K˜K˜Kš žœžœžœžœžœ˜Kšžœ˜—K˜—Kšžœ˜Jšœ:™:Jšœ7™7Kšžœ-˜3—Kšœ˜—Kšžœ ˜—Kšžœ ˜K˜šŸ œž œžœ˜VKšž˜Kšœžœ˜Kšœ7žœ˜Q—šžœžœž˜šœžœ0˜BK˜;Kšžœžœž˜šœžœžœ'˜F˜Kšœžœ'˜1—Kš žœžœžœžœžœ˜1Kšžœžœ ˜+—šœ+žœ˜6K˜Kšžœ˜—šœ,žœ˜7˜)Kšœžœ˜6Kšœžœ˜%—Kš žœžœžœžœžœ˜1Kšžœžœ ˜+—šžœ˜ K˜!šžœžœž˜šžœ1žœž˜>Kšžœ˜—K˜—Kšžœ˜Jšœ:™:Jšœ7™7Kšžœ.˜4—K˜—Kšžœ ˜—Kšžœ ˜—˜šŸœž œžœ!žœ˜\Kšž˜Kšœžœ˜Kšœ žœ˜Kšœ žœ˜Kšœžœžœ˜ K˜.Kšœžœ˜Kšœ7žœ˜QK˜šžœžœ˜Kšžœ˜ Kšžœžœžœžœ˜2šžœžœžœžœ˜ Jšœ žœ ™——K˜šŸœž œ žœ˜#Kšž˜K˜ šžœžœž˜?K˜—Kšžœ˜š žœžœžœžœ žœžœ˜jKšœžœ(˜JKšžœžœ˜—šžœžœžœ ž˜FšœSžœ˜[J™9—K˜—Kšžœ˜šžœžœžœžœ˜_Kšœžœ(˜JKšžœžœ˜—šžœžœ˜"K˜0šžœžœ˜Kšœžœ˜>Kšžœžœ˜——K˜-šžœžœž˜?K˜—Kšžœ˜ š žœžœžœžœ žœžœ˜jKšœžœ(˜JKšžœžœ˜—Kšžœ  ˜—˜K˜—šžœžœž˜šœžœ0˜CK˜7Kš žœžœžœžœžœžœ˜NJ™2Kšœžœ˜'Jšœ™šžœžœžœž˜"K˜—Kšžœ˜ šžœ'ž˜.K˜—šžœžœž˜Kšœžœ0žœQ˜™šœžœLžœ?˜ͺKšžœžœ˜—˜Kšœžœ˜:Kšžœžœ˜—Kšžœ˜K˜šžœ?ž˜EK˜5—šžœ˜šžœžœ˜&K˜Kšžœžœ4˜N—K˜$K˜K˜—šžœ'žœ*žœ˜\K˜K˜šžœžœžœBžœ?˜΅Kšžœžœ˜—K˜C——Kšžœ˜ —Kšžœ˜K˜#—Kšžœ ˜ Kšžœ  ˜K˜—šŸ œž œ ˜6Kšžœ!˜(Kšž˜Jšœo™oJšœ*™*K˜K˜7Kšœ žœ˜K˜Kšžœžœžœžœ˜ Kšžœžœžœžœ˜ šœ žœ˜K˜/—K˜K˜Jšœ™šžœžœžœž˜&Kšœžœ˜—Jšœ<™J™3Jšœžœ™ Kšœžœ˜$Jšœžœ™!J™+K˜—šžœ˜K˜!š žœžœžœ žœž˜$šžœ/žœž˜