DIRECTORY AbSets, AMBridge, Asserting, Basics, BiRels, Convert, FS, GList, Interpreter, InterpreterOps, IntHashTable, IntStuff, IO, LichenArrayStuff, LichenDataOps, LichenDataStructure, LichenNavigation, LichenPrinting, List, ProcessProps, Rope, SetBasics, StructuredStreams, SymTab, TiogaAccess, UnparserBuffer, ViewerIO;

LichenData2Impl: CEDAR PROGRAM
IMPORTS AbSets, AMBridge, Asserting, BiRels, Convert, FS, InterpreterOps, IntStuff, IO, LichenArrayStuff, LichenDataOps, LichenDataStructure, LichenNavigation, List, ProcessProps, Rope, SetBasics, StructuredStreams, SymTab, TiogaAccess, UnparserBuffer
EXPORTS LichenArrayStuff, LichenDataStructure, LichenPrinting
=

BEGIN OPEN LichenDataOps, LichenPrinting, LichenArrayStuff, LichenDataStructure, Sets:AbSets, Ints:IntStuff, SS:StructuredStreams, UB:UnparserBuffer;

DimName: ARRAY Dim OF ROPE = [Foo: "Foo", Bar: "Bar"];

step: ROPE = ".";

Describe: PUBLIC PROC [subject: REF ANY, relativeTo: REF ANY _ NIL, nameGen: NameGenerator _ NIL] RETURNS [name: ROPE] = {
name _ UnparseSteppyName[SteppyDescribe[subject, relativeTo, nameGen]];
RETURN};

SteppyDescribe: PUBLIC PROC [subject: REF ANY, relativeTo: REF ANY _ NIL, nameGen: NameGenerator _ NIL] RETURNS [name: SteppyName] = {
GetShort: PROC [oldAssns: Assertions] RETURNS [newAssns: Assertions, name: ROPE] = {
name _ NARROW[Asserting.FnVal[nameReln, newAssns _ oldAssns]];
IF name = NIL THEN {
name _ nameGen.GenerateName[nameGen.data, subject];
WITH subject SELECT FROM
v: Vertex => KnowVertexName[v, LIST[name]];
ENDCASE => newAssns _ Asserting.Assert1[nameReln, name, newAssns];
name _ name};
RETURN};
IF nameGen = NIL THEN nameGen _ defaultNameGen;
IF subject = relativeTo THEN name _ NIL ELSE WITH subject SELECT FROM
d: Design => {
short: ROPE;
[d.other, short] _ GetShort[d.other];
name _ LIST[short];
RETURN};
ct: CellType => {
short: ROPE;
[ct.otherPublic, short] _ GetShort[ct.otherPublic];
name _ LIST[short];
IF ct.designs.HasMemA[relativeTo] OR ct.designs.Empty THEN NULL ELSE name _ List.Append[SteppyDescribe[GetADesign[ct], relativeTo, nameGen], name];
RETURN};
v: Vertex => {
parent: REF ANY;
IF v.VertexNames.Empty THEN KnowVertexName[v, name _ LIST[nameGen.GenerateName[nameGen.data, subject]]] ELSE name _ NARROW[v.VertexNames.First[].MA];
WITH v SELECT FROM
ci: CellInstance => parent _ v.containingCT;
im: Intermediary => parent _ ImParent[im];
w: Wire => parent _ WireContainer[w];
ENDCASE => ERROR;
IF relativeTo#parent AND parent#NIL THEN name _ List.Append[SteppyDescribe[parent, relativeTo, nameGen], name];
RETURN};
port: Port => {
parent: REF ANY ~ port.parent;
IF port.PortNames.Empty THEN [] _ KnowPortName[port, name _ LIST[nameGen.GenerateName[nameGen.data, subject]]] ELSE name _ NARROW[port.PortNames.First[].MA];
IF relativeTo#parent AND parent#NIL THEN name _ List.Append[SteppyDescribe[parent, relativeTo, nameGen], name];
RETURN};
ENDCASE => ERROR;
};

GetADesign: PROC [ct: CellType] RETURNS [d: Design] = {
RETURN [NARROW[ct.designs.AnElt[].MDA]]};

WireContainer: PROC [w: Wire] RETURNS [container: REF ANY] = {
container _ SELECT w.containingWire FROM
NIL => w.containingCT,
ENDCASE => w.containingWire;
};

genBland: NameGenerator = NEW [NameGeneratorPrivate _ [
GenerateBlandName,
NEW [NameCountsPrivate _ []]
]];

NameCounts: TYPE = REF NameCountsPrivate;
NameCountsPrivate: TYPE = RECORD [
design, cellType, port, vertex: INT _ 0
];

GenerateBlandName: PROC [data, subject: REF ANY] RETURNS [name: ROPE] = {
nc: NameCounts = NARROW[data];
name _ GenByCount[nc, "#", subject];
};

GenByCount: PROC [nc: NameCounts, sep: ROPE, subject: REF ANY] RETURNS [name: ROPE] = {
n: INT _ 0;
WITH subject SELECT FROM
d: Design => {n _ nc.design _ nc.design + 1; name _ "D"};
ct: CellType => {n _ nc.cellType _ nc.cellType + 1; name _ "CT"};
p: Port => {n _ nc.port _ nc.port + 1; name _ "P"};
v: Vertex => {n _ nc.vertex _ nc.vertex + 1; name _ "V"};
ENDCASE => ERROR;
name _ name.Cat[sep, Convert.RopeFromInt[n]];
};

genSymbol: NameGenerator = NEW [NameGeneratorPrivate _ [
GenerateSymbolName,
NEW [TVNameGeneratorPrivate _ [
nc: NEW [NameCountsPrivate _ []],
symbols: LIST[SymTab.Create[]]
]]
]];

TVNameGenerator: TYPE = REF TVNameGeneratorPrivate;
TVNameGeneratorPrivate: TYPE = RECORD [
nc: NameCounts,
symbols: Interpreter.SymbolsList
];

GenerateSymbolName: PROC [data, subject: REF ANY] RETURNS [name: ROPE] = {
tvng: TVNameGenerator ~ NARROW[data];
evalHead: InterpreterOps.EvalHead ~ NARROW[List.Assoc[$EvalHead, ProcessProps.GetPropList[]]];
syms: Interpreter.SymbolsList ~ IF evalHead#NIL AND evalHead.specials#NIL THEN evalHead.specials ELSE tvng.symbols;
name _ Rope.Concat[IF syms=tvng.symbols THEN "&&" ELSE "&", GenByCount[tvng.nc, "", subject]];
TRUSTED {InterpreterOps.RegisterTV[
name: name,
tv: AMBridge.TVForReferent[WITH subject SELECT FROM
d: Design => NEW [Design _ d],
ct: CellType => NEW [CellType _ ct],
p: Port => NEW [Port _ p],
v: Vertex => NEW [Vertex _ v],
ENDCASE => ERROR],
symbolsList: syms]};
RETURN};

defaultNameGen: NameGenerator ~ genSymbol;

PrintObject: PROC [to: IO.STREAM, united: BOOL, PrintIt: PROC] = {
SS.Bp[to, IF united THEN united ELSE lookLeft, printStep];
SS.Begin[to];
PrintIt[!UNWIND => SS.End[to]];
SS.End[to];
};

PrintRope: PROC [to: IO.STREAM, united: BOOL, rope: ROPE] = {
SS.Bp[to, IF united THEN united ELSE lookLeft, printStep];
SS.Begin[to];
to.PutRope[rope !UNWIND => SS.End[to]];
SS.End[to];
};

printStep: INT _ 2;
printWidth: INT _ 76;

PrintDesignOnFile: PUBLIC PROC [design: Design, nameGen: NameGenerator _ NIL, fileName: ROPE _ NIL, tioga: BOOL _ FALSE, pacify: IO.STREAM _ NIL, Filter: CellTypeFilter _ NIL] = {
realFileName: ROPE = IF fileName # NIL THEN fileName ELSE Rope.Cat[Describe[design], ".design"];
ss, fs: IO.STREAM;
taw: TiogaAccess.Writer;
IF tioga
THEN {
taw _ TiogaAccess.Create[];
ss _ SS.Create[UB.NewInittedHandle[[output: [access[taw, printStep]], margin: printWidth]]];
}
ELSE {
fs _ FS.StreamOpen[fileName: realFileName, accessOptions: create, keep: 10];
ss _ SS.Create[UB.NewInittedHandle[[output: [stream[fs]], margin: printWidth]]];
};
PrintDesignSubset[ss, design, nameGen, pacify, Filter];
IF tioga THEN TiogaAccess.WriteFile[taw, realFileName] ELSE IO.Close[fs];
ss.Close[];
};

PrintDesign: PUBLIC PROC [to: IO.STREAM, design: Design, nameGen: NameGenerator _ NIL, pacify: IO.STREAM _ NIL] = {
PrintDesignSubset[to, design, nameGen, pacify, NIL];
};

PrintDesignSubset: PUBLIC PROC [to: IO.STREAM, design: Design, nameGen: NameGenerator _ NIL, pacify: IO.STREAM _ NIL, Filter: CellTypeFilter _ NIL] = {
n: NAT _ 0;
CTPrint: PROC [ra: Sets.Value] = {
ct: CellType = NARROW[ra.VA];
Inner: PROC = {
IF pacify#NIL THEN pacify.PutF["%g: %g ", [integer[n _ n+1]], [rope[Describe[ct, design, nameGen]]]];
PrintCellType[to, ct, nameGen];
IF pacify#NIL THEN pacify.PutRope[" .\n"];
};
IF Filter=NIL OR Filter[ct] THEN PrintObject[to, TRUE, Inner];
};
IF pacify#NIL AND Filter=NIL THEN pacify.PutF["Total: %g\n", [integer[design.cellTypes.Size.EN]]];
IF NOT SS.IsAnSS[to] THEN to _ SS.Create[UB.NewInittedHandle[[output: [stream[to]], margin: printWidth]]];
to.PutF["%g: Design {", [rope[Describe[design, NIL, nameGen]]]];
design.cellTypes.Enumerate[CTPrint];
to.PutF["}"];
};

PrintNameAndAliases: PROC [to: IO.STREAM, name: ROPE, names: Set--of SteppyName--] ~ {
first, second: BOOL _ TRUE;
PerName: PROC [val: Sets.Value] ~ {
name: SteppyName ~ NARROW[val.VA];
IF first THEN first _ FALSE ELSE {
IF second THEN second _ FALSE ELSE to.PutRope[","];
SS.Bp[to, width, printStep, " "];
to.PutRope[UnparseSteppyName[name]];
};
RETURN};
to.PutRope[name];
IF names.Size[Ints.two].Compare[Ints.one]>equal THEN {
to.PutRope["(a.k.a."];
names.Enumerate[PerName];
to.PutRope[")"];
};
RETURN};

PrintCellType: PUBLIC PROC [to: IO.STREAM, ct: CellType, nameGen: NameGenerator _ NIL] = {
PortPrint: PROC = {
to.PutF["port: "];
PrintPort[to, ct.port, nameGen];
};
IWPrint: PROC = {
to.PutF["internal wire: "];
PrintWire[to, ct.asUnorganized.internalWire, nameGen];
};
CIPrint: PROC = {
to.PutF["contained instances: "];
PrintInstances[to, ct.asUnorganized.containedInstances, ct.asUnorganized.mirror, nameGen];
};
AyPrint: PROC = {
to.PutRope["asArray: "];
PrintArray[to, ct, nameGen]
};
IF NOT SS.IsAnSS[to] THEN to _ SS.Create[UB.NewInittedHandle[[output: [stream[to]], margin: printWidth]]];
to.PutRope[Describe[ct, GetADesign[ct], nameGen]];
to.PutRope[": CellType["];
PrintObject[to, TRUE, PortPrint];
IF ct.asUnorganized # NIL THEN {
to.PutRope[", "]; PrintObject[to, TRUE, IWPrint];
to.PutRope[", "]; PrintObject[to, TRUE, CIPrint];
};
IF ct.asArray # NIL THEN {
to.PutRope[", "]; PrintObject[to, TRUE, AyPrint];
};
to.PutRope["]"];
};

limitPort: BOOL _ TRUE;
portLimit: NAT _ 69;

MaybePrintSeq: PROC [to: IO.STREAM, parent: REF ANY, toKids: Function--parent _ Seq of child--, toName: Function--child _ SteppyName--] RETURNS [did: BOOL] ~ {
kids: Seq--of child-- ~ BiRels.DeRef[toKids.ApplyA[parent].MA];
bounds: Ints.Interval ~ kids.GetIntDom[];
is: BOOL _ TRUE;
FOR i: INT IN [bounds.min .. bounds.max] DO
child: REF ANY ~ kids.ApplyI[i].MDA;
IF child=NIL THEN EXIT;
{name: SteppyName ~ NARROW[toName.ApplyA[child].MDA];
IF name#NIL AND name.rest=NIL THEN WITH name.first SELECT FROM
x: REF INT => IF x^ = i THEN {
grandKids: Seq ~ BiRels.DeRef[toKids.ApplyA[child].MA];
IF grandKids.Empty THEN LOOP;
};
x: ROPE => NULL;
ENDCASE => ERROR;
EXIT;
};REPEAT FINISHED => {
IF bounds.min=0
THEN to.PutF["*%g", [integer[bounds.max+1]]]
ELSE to.PutF["*%g..%g", [integer[bounds.min]], [integer[bounds.max]]];
RETURN [TRUE]};
ENDLOOP;
RETURN [FALSE]};

PrintPort: PUBLIC PROC [to: IO.STREAM, port: Port, nameGen: NameGenerator _ NIL] = {
first: BOOL _ TRUE;
i: INT _ 0;
PrintNameAndAliases[to, Describe[port, port.parent, nameGen], port.PortNames];
IF port.FirstChildPort[] = NIL THEN RETURN;
IF MaybePrintSeq[to, port, LichenNavigation.portToChildren, LichenNavigation.bestPortShortName] THEN RETURN;
to.PutRope["["];
FOR subPort: Port _ port.FirstChildPort[], subPort.NextChildPort[] WHILE subPort#NIL DO
PortPrint: PROC = {PrintPort[to, subPort, nameGen]};
PrintElipsis: PROC = {to.PutF["..%g.., ", [integer[i-portLimit]]]};
IF (NOT limitPort) OR i < portLimit OR subPort.NextChildPort[] = NIL THEN {
IF first THEN first _ FALSE ELSE to.PutRope[", "];
IF limitPort AND i > portLimit THEN PrintObject[to, FALSE, PrintElipsis];
PrintObject[to, FALSE, PortPrint]
};
i _ i + 1;
ENDLOOP;
to.PutRope["]"];
};

PrintWire: PUBLIC PROC [to: IO.STREAM, wire: Wire, nameGen: NameGenerator _ NIL] = {
first: BOOL _ TRUE;
PrintNameAndAliases[to, Describe[wire, WireContainer[wire], nameGen], wire.VertexNames];
IF wire.FirstChildWire[] = NIL THEN RETURN;
IF MaybePrintSeq[to, wire, LichenNavigation.wireToChildren, LichenNavigation.bestVertexShortName] THEN RETURN;
to.PutRope["["];
FOR subWire: Wire _ wire.FirstChildWire[], subWire.NextChildWire[] WHILE subWire # NIL DO
WirePrint: PROC = {PrintWire[to, subWire, nameGen]};
IF first THEN first _ FALSE ELSE to.PutRope[", "];
PrintObject[to, FALSE, WirePrint];
ENDLOOP;
to.PutRope["]"];
};

PrintInstances: PUBLIC PROC [to: IO.STREAM, set: Set--OF CellInstance--, mirror: CellInstance, nameGen: NameGenerator _ NIL] = {
first: BOOL _ TRUE;
PrintIt: PROC [val: REF ANY] = {
ci: CellInstance = NARROW[val];
IPrint: PROC = {PrintInstance[to, ci, nameGen]};
IF first THEN first _ FALSE ELSE to.PutRope[", "];
PrintObject[to, TRUE, IPrint];
};
to.PutRope["["];
set.EnumA[PrintIt];
IF printMirror THEN PrintIt[mirror];
to.PutRope["]"];
};
printMirror: BOOL _ TRUE;

PrintInstance: PUBLIC PROC [to: IO.STREAM, ci: CellInstance, nameGen: NameGenerator _ NIL] = {
PrintConnections: PROC [v: Vertex] = {
first: BOOL _ TRUE;
PrintConnection: PROC [port: Port, w: Vertex] = {
CPrint: PROC = {
to.PutRope[Describe[port, port.parent, nameGen]];
to.PutRope[": "];
WITH w SELECT FROM
im: Intermediary => {
subbing, first, allSame: BOOL _ TRUE;
wi, pi, num: INT _ 0;
parent, theOne: Wire _ NIL;
TestConnection: PROC [p: Port, u: Vertex] ~ {
ow: Wire ~ WITH u SELECT FROM
x: Wire => x,
x: Intermediary => NIL,
x: CellInstance => ERROR,
ENDCASE => ERROR;
IF ow=NIL THEN subbing _ FALSE;
IF allSame THEN {
IF ow=NIL THEN allSame _ FALSE
ELSE IF theOne=NIL THEN theOne _ ow
ELSE IF theOne#ow THEN allSame _ FALSE};
num _ num+1;
IF NOT subbing THEN RETURN;
{pn: SteppyName ~ NARROW[p.PortNames.First.MDA];
IF pn#NIL AND pn.rest=NIL THEN WITH pn.first SELECT FROM
x: REF INT => {
wn: SteppyName ~ NARROW[ow.VertexNames.First.MDA];
IF wn#NIL AND wn.rest=NIL THEN WITH wn.first SELECT FROM
y: REF INT => IF first
THEN {wi _ y^; pi _ x^; first _ FALSE; parent _ ow.containingWire; RETURN}
ELSE {IF y^ = (wi _ wi+1) AND x^ = (pi _ pi+1) AND parent=ow.containingWire THEN RETURN};
y: ROPE => NULL;
ENDCASE => ERROR;
};
x: ROPE => NULL;
ENDCASE => ERROR;
subbing _ FALSE;
RETURN}};
EnumerateImmediateConnections[im, TestConnection, [cellward: FALSE, wireward: TRUE]];
IF subbing THEN to.PutF["%g[%g..%g]", [rope[Describe[parent, ci.containingCT.asUnorganized.internalWire, nameGen]]], [integer[wi+1-num]], [integer[wi]]]
ELSE IF allSame AND theOne#NIL THEN to.PutF["%g*%g", [integer[num]], [rope[Describe[theOne, ci.containingCT.asUnorganized.internalWire, nameGen]]]]
ELSE PrintConnections[im];
};
wire: Wire => {
to.PutRope[Describe[wire, ci.containingCT.asUnorganized.internalWire, nameGen]];
};
ci: CellInstance => ERROR;
ENDCASE => ERROR;
};
IF first THEN first _ FALSE ELSE to.PutRope[", "];
PrintObject[to, FALSE, CPrint];
};
to.PutRope["["];
EnumerateImmediateConnections[v, PrintConnection, [cellward: FALSE, wireward: TRUE]];
to.PutRope["]"];
};
PrintNameAndAliases[to, Describe[ci, ci.containingCT, nameGen], ci.VertexNames];
to.PutF[": %g", [rope[Describe[ci.type, GetADesign[ci.type], nameGen]]] ];
PrintConnections[ci];
};

Array: TYPE ~ LichenDataStructure.Array;

printStatRep: BOOL _ TRUE;
printDumbRep: BOOL _ FALSE;

PrintArray: PUBLIC PROC [to: IO.STREAM, ct: CellType, nameGen: NameGenerator _ NIL] = {
a: Array = ct.asArray;
groupName: VarFunction = BiRels.CreateHashFn[];
nGroups: NAT _ 0;
BasePrint: PROC = {
to.PutF["base period = [%g, %g]", [integer[a.basePeriod[Foo]]], [integer[a.basePeriod[Bar]]]]};
StatPrint: PROC = {
to.PutRope["static graph = ["];
PrintStatRep[to, a, nameGen];
to.PutRope["]"];
};
to.PutF["{%g BY %g OF %g, ",
[integer[a.size2[Foo]]], [integer[a.size2[Bar]]],
[rope[Describe[a.eltType, GetADesign[ct], nameGen]]]
];
PrintObject[to, FALSE, BasePrint];
IF printStatRep THEN {
to.PutRope[", "];
PrintObject[to, TRUE, StatPrint];
};
IF printDumbRep THEN ERROR nyet;
to.PutRope["}"];
};

PrintStatRep: PROC [to: IO.STREAM, a: Array, nameGen: NameGenerator] ~ {
firstEdge: BOOL _ TRUE;
PrintEdge: PROC [val: REF ANY] ~ {
se: StatEdge ~ NARROW[val];
IF firstEdge THEN firstEdge _ FALSE ELSE to.PutRope[", "];
PrintRope[to, TRUE, FmtStatEdge[se, a, nameGen]];
RETURN};
a.statrep.edges.EnumA[PrintEdge, fwd];
RETURN};

FmtStatEdge: PUBLIC PROC [se: StatEdge, a: Array _ NIL, nameGen: NameGenerator _ NIL] RETURNS [ROPE] ~ {
Fmt: PROC [b: BOOL] RETURNS [ans: ROPE] ~ {
ep: Port ~ se.vs[b].port;
ans _ Describe[ep, PortCCT[ep].port, nameGen];
IF a=NIL OR a.basePeriod#ALL[1] THEN ans _ ans.Concat[Rope.Cat["@<", Convert.RopeFromInt[se.vs[b].phase[Foo]], ",", Convert.RopeFromInt[se.vs[b].phase[Bar]], ">"]];
RETURN};
RETURN Rope.Cat[Fmt[FALSE], " -> ", Fmt[TRUE], " by ", FmtInt2[a, se.d]]};

FmtRange2: PROC [a: Array, r: Range2] RETURNS [asRope: ROPE] = {
RETURN [SELECT TRUE FROM
a.size2[Bar]=1 => FmtRange[r[Foo]],
a.size2[Foo]=1 => FmtRange[r[Bar]],
ENDCASE => FmtRange[r[Foo]].Cat[":", FmtRange[r[Bar]]]
]};

FmtRange: PUBLIC PROC [r: Range] RETURNS [asRope: ROPE] = {
asRope _ Convert.RopeFromInt[r.min];
IF r.min+1 # r.maxPlusOne THEN asRope _ asRope.Cat["~", Convert.RopeFromInt[r.maxPlusOne-1]];
};

FmtInt2: PROC [a: Array, i2: Int2] RETURNS [ROPE] ~ {
RETURN [SELECT TRUE FROM
a=NIL => IO.PutFR["<%g, %g>", [integer[i2[Foo]]], [integer[i2[Bar]]]],
a.size2[Bar]=1 => Convert.RopeFromInt[i2[Foo]],
a.size2[Foo]=1 => Convert.RopeFromInt[i2[Bar]],
ENDCASE => IO.PutFR["<%g, %g>", [integer[i2[Foo]]], [integer[i2[Bar]]]]
]};

IsArray: PROC [ct: CellType] RETURNS [pass: BOOL] = {pass _ ct.asArray # NIL};

Is1D: PROC [ct: CellType] RETURNS [BOOL]
~ {RETURN [ct.asArray#NIL AND (ct.asArray.size2[Foo]=1 OR ct.asArray.size2[Bar]=1)]};

Is2D: PROC [ct: CellType] RETURNS [BOOL]
~ {RETURN [ct.asArray#NIL AND ct.asArray.size2[Foo]#1 AND ct.asArray.size2[Bar]#1]};

PrintArrays: PROC [to: IO.STREAM, design: Design, nameGen: NameGenerator _ NIL, pacify: IO.STREAM _ NIL] = {
PrintDesignSubset[to, design, nameGen, pacify, IsArray];
};

PrintIncompletes: PROC [to: IO.STREAM, design: Design, nameGen: NameGenerator _ NIL, pacify: IO.STREAM _ NIL] = {
PrintDesignSubset[to, design, nameGen, pacify, IsIncompleteArray];
};

END.
����^��LichenData2Impl.Mesa
Last tweaked by Mike Spreitzer on February 1, 1988 4:52:06 pm PST
�Ê$��˜�™Icode™A—J˜�KšÏk	œ7œ>œÀ˜ÂK˜�šÐbxœœ˜Kšœ/œœ¥˜ûKšœ6˜=Kšœ˜—K˜�KšœœGÏnœŸœœœ˜•K˜�KšŸœœœœ˜6K˜�Kšœœ˜K˜�šŸœœœœœœœœœœœ˜zKšœG˜GKšœ˜—K˜�šŸœœœœœœœœœœ˜†šŸœœœœ˜TKšœœ1˜>šœœœ˜K˜3šœ	œ˜Kšœœ˜+Kšœ;˜B—K˜
—Kšœ˜—Kšœœœ˜/š
œœœœœ	œ˜E˜Kšœœ˜K˜%Kšœœ˜Kšœ˜—˜Kšœœ˜Kšœ3˜3Kšœœ˜Kš
œ œœœœO˜“Kšœ˜—˜Kšœœœ˜Kšœœœ/œœœ˜•šœœ˜K˜,Kšœ*˜*Kšœ%˜%Kšœœ˜—KšœœœœG˜oKšœ˜—˜Kšœœœ˜Kšœœ œ/œœœ˜KšœœœœG˜oKšœ˜—Kšœœ˜—Kšœ˜—K˜�šŸ
œœœ˜7Kšœœœ˜)—K˜�š
Ÿ
œœœ
œœ˜>šœœ˜(Kšœ˜Kšœ˜—K˜—K˜�šœœ˜7K˜Kšœ˜K˜—K˜�Kšœœœ˜)šœœœ˜"Kšœ œ˜'K˜—K˜�šŸœœœœœœ˜IKšœœ˜K˜$K˜—K˜�šŸ
œœœœœœœ˜WKšœœ˜šœ	œ˜K˜9K˜AK˜3K˜9Kšœœ˜—K˜-K˜—K˜�šœœ˜8K˜šœ˜Kšœœ˜!Kšœ	œ˜K˜—K˜—K˜�Kšœœœ˜3šœœœ˜'K˜Kšœ ˜ K˜—K˜�šŸœœœœœœ˜JKšœœ˜%Kšœ$œ4˜^Kš
œ œ
œœœœœ˜sKšœœœœ(˜^šœ˜#K˜šœœ	œ˜3Kšœ
œ˜Kšœœ˜$Kšœœ˜Kšœ
œ˜Kšœœ˜—Kšœ˜—Kšœ˜—K˜�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šœœE˜LKšœœœ?˜PK˜——Kšœ7˜7Kšœœ*œœ˜IK˜K˜—K˜�šŸœœœœœ+œ
œœœ˜sKšœ/œ˜4Kšœ˜—K˜�šŸœœœœœ+œ
œœœŸœœ˜—Kšœœ˜šŸœœ˜"Kšœœœ˜šŸœœ˜KšœœœS˜eKšœ˜Kšœœœ˜*Kšœ˜—Kš
œœœœœ	˜>K˜—Kšœœœœœ;œ˜bKšœœœœœœ?˜jKšœ/œ˜@Kšœ$˜$K˜
K˜—K˜�šŸœœœœœÏcœ˜VKšœœœ˜šŸœœ˜#Kšœœœ˜"šœœ	œœ˜"Kšœœ
œœ˜3Kšœ˜!Kšœ$˜$K˜—Kšœ˜—Kšœ˜šœ.œ˜6K˜K˜K˜K˜—Kšœ˜—K˜�šŸ
œœœœœ)œ˜ZšŸ	œœ˜K˜K˜ K˜—šŸœœ˜K˜Kšœ6˜6K˜—šŸœœ˜K˜!KšœZ˜ZK˜—šŸœœ˜K˜Kšœ˜K˜—Kšœœœœœœ?˜jKšœ2˜2Kšœ˜Kšœœ
˜!šœœœ˜ Kšœ"œ˜1Kšœ"œ˜1K˜—šœœœ˜Kšœ"œ˜1K˜—K˜K˜—K˜�Kšœœœ˜Kšœœ˜K˜�šŸ
œœœœ
œœ 	Ðcm œ ¡ 
œœœ˜ŸKšœ	 œ&œ˜?Kšœ)˜)Kšœœœ˜šœœœ˜+Kšœœœœ˜$Kšœœœœ˜Kšœœœ˜5šœœœœœœœ˜>š	œœœœœ˜Kšœ3œ˜7Kšœœœ˜K˜—Kšœœœ˜Kšœœ˜—Kšœ˜šœœœ˜šœ
˜Kšœ(˜,KšœB˜F—Kšœœ˜—Kšœ˜—Kšœœ˜—K˜�šŸ	œœœœœ'œ˜TKšœœœ˜Kšœœ˜KšœN˜NKšœœœœ˜+Kšœ^œœ˜lK˜šœ@œ	œ˜WKšŸ	œœ%˜4KšŸœœ1˜Cšœœœœœœ˜KKšœœ	œœ˜2Kšœœœœ˜IKšœœ˜!Kšœ˜—K˜
Kšœ˜—K˜K˜—K˜�šŸ	œœœœœ'œ˜TKšœœœ˜KšœX˜XKšœœœœ˜+Kšœ`œœ˜nK˜šœ@œœ˜YKšŸ	œœ%˜4Kšœœ	œœ˜2Kšœœ
˜"Kšœ˜—K˜K˜—K˜�šŸœœœœœ
 œ1œ˜€Kšœœœ˜šŸœœœœ˜ Kšœœ˜KšŸœœ$˜0Kšœœ	œœ˜2Kšœœ
˜K˜—K˜K˜Kšœ
œ˜$K˜K˜Kšœ
œœ˜—K˜�šŸ
œœœœœ-œ˜^šŸœœ˜&Kšœœœ˜šŸœœ˜1šŸœœ˜K˜1K˜šœœ˜˜Kšœœœ˜%Kšœ
œ˜Kšœœ˜šŸœœ˜-šœœœ˜K˜
Kšœœ˜Kšœœ˜Kšœœ˜—Kšœœœœ˜šœ	œ˜Kšœœœ˜Kšœœœœ˜#Kšœœœœ˜(—K˜Kšœœ	œœ˜Kšœœœ˜0šœœœ	œœœ
œ˜8šœœœ˜Kšœœœ˜2šœœœ	œœœ
œ˜8šœœœœ˜Kšœœœ˜JKšœœœœœœ˜Y—Kšœœœ˜Kšœœ˜—K˜—Kšœœœ˜Kšœœ˜—Kšœ
œ˜Kšœ˜	—Kšœ=œœ˜UKšœ	œ‰˜˜Kš
œœ	œœœp˜“Kšœ˜K˜—˜KšœP˜PK˜—Kšœœ˜Kšœœ˜—K˜—Kšœœ	œœ˜2Kšœœ
˜K˜—K˜Kšœ=œœ˜UK˜K˜—KšœP˜PKšœJ˜JK˜K˜—K˜�Kšœœ˜(K˜�Kšœœœ˜Kšœœœ˜K˜�šŸ
œœœœœ)œ˜WKšœ˜Kšœ/˜/Kšœ	œ˜šŸ	œœ˜Kšœ_˜_—šŸ	œœ˜K˜K˜K˜K˜—˜K˜1Kšœ4˜4K˜—Kšœœ
˜"šœœ˜K˜Kšœœ
˜!K˜—Kšœœœ˜ K˜K˜—K˜�šŸœœœœ'˜HKšœœœ˜šŸ	œœœœ˜"Kšœœ˜Kšœœ
œœ˜:Kšœœ˜1Kšœ˜—Kšœ&˜&Kšœ˜—K˜�šŸœœœœœœœ˜hš
Ÿœœœœœ˜+K˜K˜.Kš
œœœœœ€˜¤Kšœ˜—KšœœœÏgœ˜J—K˜�šŸ	œœœ
œ˜@šœœœ˜Kšœ#˜#Kšœ#˜#Kšœ/˜6K˜——K˜�š
Ÿœœœœ
œ˜;K˜$Kšœœ?˜]K˜—K˜�šŸœœœœ˜5šœœœ˜Kšœœœ;˜FK˜/K˜/Kšœœ:˜GK˜——K˜�Kš
Ÿœœœœœ˜NK˜�šŸœœœœ˜(Kš	œœ
œœœ˜U—K˜�šŸœœœœ˜(Kš	œœ
œœœ˜T—K˜�šŸœœœœ+œ
œœœ˜lKšœ8˜8Kšœ˜—K˜�šŸœœœœ+œ
œœœ˜qKšœB˜BKšœ˜—K˜�Kšœ˜—�…—����A¬��W.��