DIRECTORY Clip3d, Draw2d, Draw3d, Imager, ImagerBackdoor, IO, Matrix3d, Polygons3d, Real, Rope, Spline3d, Vector2, Vector3d;

Draw3dImpl: CEDAR PROGRAM
IMPORTS Clip3d, Draw2d, Imager, ImagerBackdoor, IO, Matrix3d, Real, Polygons3d, Spline3d, Vector2, Vector3d
EXPORTS Draw3d

~ BEGIN

OPEN Draw3d;
PairClip: TYPE ~ RECORD [pair: Pair, clipped: BOOL];

TransformAndClip: PROC [point: Triple, matrix: Matrix] RETURNS [PairClip] ~ {
IF matrix[2][3] # 0.0
THEN {
q: Quad _ Matrix3d.TransformH[point, matrix];
IF q.z+q.w < 0.0 THEN RETURN[[[0.0, 0.0], TRUE]];
RETURN[[[q.x/q.w, q.y/q.w], FALSE]];
}
ELSE RETURN[[Matrix3d.TransformD[point, matrix], FALSE]];
};

Mark: PUBLIC PROC [
context: Context,
point: Triple,
matrix: Matrix,
label: ROPE _ NIL,
markType: MarkType _ cross]
~ {
IF markType # none OR label # NIL THEN {
pairClip: PairClip ~ TransformAndClip[point, matrix];
IF pairClip.clipped THEN RETURN;
IF markType # none THEN Draw2d.Mark[context, pairClip.pair, markType];
IF label # NIL THEN Draw2d.Label[context, [pairClip.pair.x+6, pairClip.pair.y], label];
};
};

DoWithPoint: PUBLIC PROC [
context: Context, point: Triple, matrix: Matrix, pointProc: PointProc] ~ {
pairClip: PairClip ~ TransformAndClip[point, matrix];
IF NOT pairClip.clipped THEN pointProc[context, pairClip.pair];
};
Segment: PUBLIC PROC [
context: Context,
point0, point1: Triple,
matrix: Matrix,
drawType: DrawType _ solid]
~ {
c0, c1: Pair;
IF Matrix3d.HasPerspective[matrix] THEN {
off: BOOL;
[c0, c1, off] _ 
Clip3d.NearH[Matrix3d.TransformH[point0, matrix], Matrix3d.TransformH[point1, matrix]];
IF NOT off THEN Draw2d.Line[context, c0, c1, drawType];
}
ELSE {
c0 _ Matrix3d.TransformD[point0, matrix];
c1 _ Matrix3d.TransformD[point1, matrix];
Draw2d.Line[context, c0, c1, drawType];
};
};

Vector: PUBLIC PROC [
context: Context,
base, vector: Triple,
matrix: Matrix,
label: ROPE _ NIL,
scale: REAL _ 0.2,
markType: MarkType _ none,
drawType: DrawType _ solid]
~ {
c0, c1, d: Pair;
end: Triple _ Vector3d.Add[base, vector];
IF Matrix3d.HasPerspective[matrix] THEN {
off: BOOL;
[c0, c1, off] _ 
Clip3d.NearH[Matrix3d.TransformH[base, matrix], Matrix3d.TransformH[end, matrix]];
IF off THEN RETURN;
IF markType # none THEN Mark[context, base, matrix, , markType];
}
ELSE {
c0 _ Matrix3d.TransformD[base, matrix];
c1 _ Matrix3d.TransformD[end, matrix];
IF markType # none THEN Draw2d.Mark[context, c0, markType];
};
d _ [scale*(c1.x-c0.x), scale*(c1.y-c0.y)];
c1 _ [c0.x+d.x, c0.y+d.y];
Draw2d.Arrow[context, c0, c1, drawType];
IF label # NIL THEN {
Draw2d.Label[
context,
IF d = [0, 0] THEN c1 ELSE Vector2.Add[[c1.x, c1.y-4], Vector2.Mul[Vector2.Unit[d], 6]],
label];
};
};

Axes: PUBLIC PROC [context: Context, matrix: Matrix] ~ {
Vector[context, [0.0, 0.0, 0.0], [1.0, 0.0, 0.0], matrix, "X"];
Vector[context, [0.0, 0.0, 0.0], [0.0, 1.0, 0.0], matrix, "Y"];
Vector[context, [0.0, 0.0, 0.0], [0.0, 0.0, 1.0], matrix, "Z"];
};
Curve: PUBLIC PROC [context: Context, coeffs: Coeffs, matrix: Matrix _ NIL] ~ {
IF coeffs # NIL THEN {
persp: BOOL _ Matrix3d.HasPerspective[matrix];
xc: Coeffs _ IF matrix = NIL THEN coeffs ELSE Matrix3d.Mul[coeffs, matrix];
nSegs: INTEGER _ Spline3d.Resolution[xc, 1.0];
dif: Coeffs _ Spline3d.FwdDif[xc, nSegs];
nCoords: NAT _ IF persp THEN 3 ELSE 1;
p0, p1: Pair _ [dif[0][0], dif[0][1]];
q0, q1: Quad _ [dif[0][0], dif[0][1], dif[0][2], dif[0][3]];

FOR i: INTEGER IN[0..nSegs) DO
IF persp
THEN q1 _ [q0.x+dif[1][0], q0.y+dif[1][1], q0.z+dif[1][2], q0.w+dif[1][3]]
ELSE p1 _ [p0.x+dif[1][0], p0.y+dif[1][1]];
FOR j: INTEGER IN[0..nCoords] DO
dif[1][j] _ dif[1][j]+dif[2][j];
dif[2][j] _ dif[2][j]+dif[3][j];
ENDLOOP;
IF persp THEN {
c0, c1: Pair;
offScreen: BOOL;
[c0, c1, offScreen] _ Clip3d.NearH[q0, q1];
IF NOT offScreen THEN Draw2d.Line[context, c0, c1];
q0 _ q1;
}
ELSE {
Draw2d.Line[context, p0, p1];
p0 _ p1;
};
ENDLOOP;
};
};

DotCurve: PUBLIC PROC [context: Context, coeffs: Coeffs, matrix: Matrix _ NIL] ~ {
IF coeffs # NIL THEN {
persp: BOOL _ Matrix3d.HasPerspective[matrix];
xc: Coeffs _ IF matrix = NIL THEN coeffs ELSE Matrix3d.Mul[coeffs, matrix];
nSegs: INTEGER _ 4*Spline3d.Resolution[xc, 1.0];
dif: Coeffs _ Spline3d.FwdDif[xc, nSegs];
nCoords: NAT _ IF persp THEN 3 ELSE 1;
p: Pair _ [dif[0][0], dif[0][1]];
q: Quad _ [dif[0][0], dif[0][1], dif[0][2], dif[0][3]];

FOR i: INTEGER IN[0..nSegs) DO
IF persp
THEN {IF q.w+q.z >= 0.0 THEN Imager.MaskRectangle[context, [q.x/q.w, q.y/q.w,1,1]]}
ELSE Imager.MaskRectangle[context, [p.x, p.y, 1, 1]];
IF persp
THEN q _ [q.x+dif[1][0], q.y+dif[1][1], q.z+dif[1][2], q.w+dif[1][3]]
ELSE p _ [p.x+dif[1][0], p.y+dif[1][1]];
FOR j: INTEGER IN[0..nCoords] DO
dif[1][j] _ dif[1][j]+dif[2][j];
dif[2][j] _ dif[2][j]+dif[3][j];
ENDLOOP;
ENDLOOP;
};
};

BezierPolygon: PUBLIC PROC [
context: Context,
bezier: Bezier,
matrix: Matrix _ NIL,
drawType: Draw2d.DrawType _ solid,
close: BOOL _ FALSE]
~ {
Segment[context, bezier.b0, bezier.b1, matrix, drawType];
Segment[context, bezier.b1, bezier.b2, matrix, drawType];
Segment[context, bezier.b2, bezier.b3, matrix, drawType];
IF close THEN Segment[context, bezier.b0, bezier.b3, matrix, drawType];
};
Triangle: PUBLIC PROC [
context: Context,
p0, p1, p2: Triple,
view: Matrix]
~ {
pp0: Pair _ Matrix3d.TransformD[p0, view];
pp1: Pair _ Matrix3d.TransformD[p1, view];
pp2: Pair _ Matrix3d.TransformD[p2, view];
Draw2d.Line[context, pp0, pp1];
Draw2d.Line[context, pp1, pp2];
Draw2d.Line[context, pp2, pp0];
};
FrontFacingTriangle: PUBLIC PROC [
context: Context,
p0, p1, p2: Triple,
view: Matrix,
normal: Triple _ origin]
~ {
IF normal = origin THEN normal _ Polygons3d.TriangleNormal[p0, p1, p2];
IF normal.x*view[0][2]+normal.y*view[1][2]+normal.z*view[2][2] >= 0.0
THEN Triangle[context, p0, p1, p2, view];
};
PolygonPairs: PUBLIC PROC [
triples: TripleSequence,
view: Matrix,
pairs: PairSequence _ NIL]
RETURNS [PairSequence]
~ {
IF triples # NIL AND view # NIL THEN {
IF pairs = NIL OR pairs.length < triples.length
THEN pairs _ NEW[PairSequenceRep[triples.length]];
pairs.length _ triples.length;

FOR n: NAT IN[0..triples.length) DO
pairs[n] _ Matrix3d.TransformD[triples[n], view];
ENDLOOP;
};
RETURN[pairs];
};
Polygon: PUBLIC PROC [
context: Context,
poly: REF NatSequence,
pairs: PairSequence _ NIL,
triples: TripleSequence _ NIL,
view: Matrix _ NIL]
~ {
stop: CARDINAL ~ poly.length-1;
IF pairs = NIL AND view # NIL AND triples # NIL THEN {
pairs _ NEW[PairSequenceRep[triples.length]];
FOR n: NAT IN [0..poly.length) DO
i: NAT ~ poly[n];
pairs[i] _ Matrix3d.TransformD[triples[i], view];
ENDLOOP;
};
IF pairs # NIL AND poly # NIL AND poly.length > 0 THEN {
FOR i: NAT IN[0..stop) DO
Draw2d.Line[context, pairs[poly[i]], pairs[poly[i+1]]];
ENDLOOP;
Draw2d.Line[context, pairs[poly[stop]], pairs[poly[0]]];
};
};
FrontFacingPolygon: PUBLIC PROC [
context: Context,
poly: REF NatSequence,
view: Matrix,
normal: Triple _ origin,
pairs: PairSequence _ NIL,
triples: TripleSequence _ NIL]
~ {
IF normal = origin AND triples = NIL THEN RETURN;
IF normal = origin THEN {
vertices: TripleSequence _ NEW[TripleSequenceRep[poly.length]];
FOR n: NAT IN [0..poly.length) DO vertices[n] _ triples[poly[n]]; ENDLOOP;
normal _ Polygons3d.PolygonNormal[vertices];
};
IF normal.x*view[0][2]+normal.y*view[1][2]+normal.z*view[2][2] >= 0.0
THEN Polygon[context, poly, pairs, triples, view];
};
Polygons: PUBLIC PROC [
context: Context,
polygons: REF NatTable,
pairs: PairSequence _ NIL,
triples: TripleSequence _ NIL,
view: Matrix _ NIL]
~ {
IF pairs = NIL AND view # NIL AND triples # NIL THEN {
pairs _ NEW[PairSequenceRep[triples.length]];
FOR n: NAT IN [0..triples.length) DO
pairs[n] _ Matrix3d.TransformD[triples[n], view];
ENDLOOP;
};
IF polygons # NIL AND pairs # NIL THEN FOR n: NAT IN[0..polygons.length) DO
poly: REF NatSequence ~ polygons[n];
stop: CARDINAL ~ poly.length-1; 
IF poly = NIL OR poly.length < 1 THEN LOOP;
FOR i: NAT IN[0..stop) DO
Draw2d.Line[context, pairs[poly[i]], pairs[poly[i+1]]];
ENDLOOP;
Draw2d.Line[context, pairs[poly[stop]], pairs[poly[0]]];
ENDLOOP;
};
FrontFacingPolygons: PUBLIC PROC [
context: Context,
polygons: REF NatTable,
view: Matrix,
normals: TripleSequence,
pairs: PairSequence _ NIL,
triples: TripleSequence _ NIL]
~ {
IF polygons = NIL OR view = NIL OR normals = NIL OR (pairs = NIL AND triples = NIL)
THEN RETURN;
IF pairs = NIL THEN {
pairs _ NEW[PairSequenceRep[triples.length]];
FOR n: NAT IN [0..triples.length) DO
pairs[n] _ Matrix3d.TransformD[triples[n], view];
ENDLOOP;
};
FOR n: NAT IN[0..polygons.length) DO
poly: REF NatSequence _ polygons[n];
IF poly = NIL OR poly.length < 1 THEN LOOP;
IF normals[n].x*view[0][2]+normals[n].y*view[1][2]+normals[n].z*view[2][2] < 0.0
THEN LOOP;
FOR i: NAT IN[0..poly.length-1) DO
Draw2d.Line[context, pairs[poly[i]], pairs[poly[i+1]]];
ENDLOOP;
Draw2d.Line[context, pairs[poly[poly.length-1]], pairs[poly[0]]];
ENDLOOP;
};
Pendant: PUBLIC PROC [
context: Context,
view: Matrix,
size: REAL _ .07,
wPos, hPos: REAL _ .7,
names: ARRAY [0..6) OF ROPE _ ALL[NIL]]
~ {
mx: REAL _ 0.0;
v: ARRAY [0..6) OF V;
V: TYPE ~ RECORD[rope: ROPE, vec: Triple];
axes: ARRAY [0..6) OF Triple ~ [[1, 0, 0], [0, 1, 0], [0, 0, 1], [-1, 0, 0], [0, -1, 0], [0, 0, -1]];
c: Pair;
rect: Imager.Rectangle _ [0.0, 0.0, 600.0, 400.0];
rect _ ImagerBackdoor.GetBounds[context ! Imager.Error => CONTINUE];
c _ [rect.w*(1+wPos)/2, rect.h*(1+hPos)/2];
FOR n: NAT IN [0..6) DO
v[n] _ [names[n], Matrix3d.TransformVec[axes[n], view]];
ENDLOOP;
FOR n: NAT IN [0..6) DO mx _ MAX[mx, Vector2.Square[[v[n].vec.x, v[n].vec.y]]]; ENDLOOP;
mx _ MAX[rect.w, rect.h]*size/Real.SqRt[mx];
FOR n: NAT IN [0..6) DO v[n].vec _ Vector3d.Mul[v[n].vec, mx]; ENDLOOP;
DO		-- order v by increasing z:
d: BOOL _ FALSE;
FOR n: NAT IN [0..5) DO 
IF v[n].vec.z<v[n+1].vec.z THEN {t: V _ v[n]; v[n] _ v[n+1]; v[n+1] _ t; d _ TRUE};
ENDLOOP;
IF NOT d THEN EXIT;
ENDLOOP;
FOR n: NAT IN [0..6) DO
IF v[n].rope = NIL THEN LOOP;
Imager.SetColor[context, Imager.white];
Imager.MaskRectangle[context, [c.x+v[n].vec.x, c.y+v[n].vec.y-4, 8, 8]];
Imager.SetColor[context, Imager.black];
Draw2d.Label[context, [c.x+v[n].vec.x, c.y+v[n].vec.y-4], v[n].rope];
ENDLOOP;
FOR n: NAT IN [0..6) DO
IF v[n].rope # NIL THEN {
a: Pair _ IF v[n].vec.x = 0 AND v[n].vec.y = 0
THEN [0, 0] ELSE Vector2.Mul[Vector2.Unit[[v[n].vec.x, v[n].vec.y]], 6.0];
Draw2d.Arrow[context, c, [c.x+v[n].vec.x-a.x, c.y+v[n].vec.y-a.y]];
};
ENDLOOP;
};

LabelPairs: PUBLIC PROC [context: Context, pairs: PairSequence] ~ {
IF pairs # NIL THEN FOR n: NAT IN[0..pairs.length) DO
Draw2d.Label[context, pairs[n], IO.PutFR["%g", IO.int[n]]];
ENDLOOP;
};

END.
..


���†��Draw3dImpl.mesa
Copyright c 1985 by Xerox Corporation.  All rights reserved.
Bloomenthal, February 26, 1987 7:28:41 pm PST
Point Marking
Straight Line Drawing
Curve Drawing
Triangle Drawing

Polygon Drawing
 



Labelling
To be used sometime after Cedar7.0:
TransformPointToDisplay: PUBLIC PROC [context3d: Context3d, point: Triple]
RETURNS [displayPoint: Triple] ~ {
xpoint: Triple;
[xpoint, ] _ ThreeDScenes.XfmPtToEyeSpace[context3d, point];
displayPoint _ ThreeDScenes.XfmPtToDisplay[context3d, NIL, xpoint];
};

PerspPP: PUBLIC PROC [p0, p1: Triple, context: Context, focalLength, tanHalfFov: REAL] ~ {
Draw segment p0p1 with perspective determined by focalLength and the tangent of 1/2 the field of view.

ClipZ: PROC [p0, p1: Triple, zLim: REAL] RETURNS [c0, c1: Triple, off: BOOL] ~ {
dx, dy, dz: REAL;
a0: REAL _ 0.0;
a1: REAL _ 1.0;

IF p0.z < zLim THEN {
IF p1.z < zLim THEN RETURN[c0, c1, TRUE];
a0 _ p0.z/(p0.z-p1.z);
}
ELSE IF p1.z < zLim THEN a1 _ p0.z/(p0.z-p1.z);
IF a0 > a1 THEN RETURN[c0, c1, TRUE];

dx _ p1.x-p0.x;
dy _ p1.y-p0.y;
dz _ p1.z-p0.z;
RETURN[[p0.x+a0*dx,p0.y+a0*dy,p0.z+a0*dz], [p0.x+a1*dx,p0.y+a1*dy,p0.z+a1*dz], FALSE];
};
off: BOOL _ FALSE;
c0, c1: Triple;
[c0, c1, off] _ ClipZ[p0, p1, -focalLength+0.01];
IF NOT off THEN {
f0: REAL _ 1.0/(1.0+c0.z*tanHalfFov);
f1: REAL _ 1.0/(1.0+c1.z*tanHalfFov);
Draw2d.Solid[context, [f0*c0.x, f0*c0.y], [f1*c1.x, f1*c1.y]];
};
};

�Ê��˜�šœ™Jšœ
Ïmœ1™<J™-J˜�JšÏk	œ1žœ@˜|J˜�—šÐbl
œžœž˜Jšžœ)žœ9˜kJšžœ˜J˜�—Jšœž˜˜�Jšžœ˜—headšÏl
™
Jšœ
žœžœžœ˜4J˜�šÏnœžœ žœ˜Mšžœ˜šžœ˜Jšœ-˜-Jšžœžœžœžœ˜1Jšžœžœ˜$J˜—Jšžœžœ&žœ˜9—J˜J˜�—š¡œžœ˜Jšœ˜Jšœ˜Jšœ˜Jšœžœžœ˜Jšœ˜Jšœ˜šžœžœ	žœžœ˜(Jšœ5˜5Jšžœžœžœ˜ Jšžœžœ/˜FJšžœ	žœžœD˜WJ˜—J˜J˜�—š¡œžœžœ˜JšœJ˜JJšœ5˜5Jšžœžœžœ#˜?J˜——š ™š¡œžœžœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ
˜
šžœ!žœ˜)Jšœžœ˜
šœ˜JšœW˜W—Jšžœžœžœ(˜7J˜—šžœ˜Jšœ)˜)Jšœ)˜)Jšœ'˜'J˜—J˜J˜�—š¡œžœ˜Jšœ˜Jšœ˜Jšœ˜Jšœžœžœ˜Jšœžœ˜Jšœ˜Jšœ˜J˜Jšœ˜Jšœ)˜)šžœ!žœ˜)Jšœžœ˜
šœ˜JšœR˜R—Jšžœžœžœ˜Jšžœžœ)˜@J˜—šžœ˜Jšœ'˜'Jšœ&˜&Jšžœžœ$˜;J˜—Jšœ+˜+Jšœ˜J˜(šžœ	žœžœ˜šœ
˜
Jšœ˜Jšžœžœžœ>˜XJšœ˜—J˜—J˜—J˜�š¡œžœžœ'˜8Jšœ?˜?Jšœ?˜?Jšœ?˜?J˜——š 
™
š¡œžœžœ5žœ˜Ošžœ
žœžœ˜Jšœžœ#˜.Jš	œ
žœ
žœžœžœ˜KJšœžœ ˜.Jšœ)˜)Jš	œ	žœžœžœžœ˜&Icodešœ&˜&Lšœ<˜<L˜�šžœžœžœž˜šžœ˜LšžœF˜JLšžœ'˜+—šžœžœžœ
ž˜ L˜ L˜ Lšžœ˜—šžœžœ˜Lšœ
˜
Lšœžœ˜Lšœ+˜+Lšžœžœžœ˜3L˜L˜—šžœ˜Jšœ˜Lšœ˜L˜—Lšžœ˜—L˜—L˜L˜�—š¡œžœžœ5žœ˜Ršžœ
žœžœ˜Jšœžœ#˜.Jš	œ
žœ
žœžœžœ˜KJšœžœ"˜0Jšœ)˜)Jš	œ	žœžœžœžœ˜&Lšœ!˜!Lšœ7˜7L˜�šžœžœžœž˜šžœ˜Lšžœžœžœ7˜SJšžœ1˜5—šžœ˜LšžœA˜ELšžœ$˜(—šžœžœžœ
ž˜ L˜ L˜ Lšžœ˜—Lšžœ˜—L˜—L˜—L˜�š¡
œžœžœ˜Jšœ˜Jšœ˜Jšœžœ˜Jšœ"˜"Jšœžœžœ˜Jšœ˜Jšœ9˜9Jšœ9˜9Jšœ9˜9Jšžœžœ:˜GJ˜——š ™š¡œžœ˜Jšœ˜J˜Jšœ
˜
Jšœ˜Jšœ*˜*Jšœ*˜*Jšœ*˜*Jšœ˜Jšœ˜Jšœ˜˜J™�——š¡œžœ˜"Jšœ˜J˜Jšœ
˜
Jšœ˜J˜Jšžœžœ0˜GšžœC˜EJšžœ%˜)—J˜——š ™šÏbœžœžœ˜Jšœ˜Jšœ
˜
Jšœžœ˜Jšžœ˜Jšœ˜š
žœžœžœžœžœ˜&šžœ	žœžœ˜/Jšžœ	žœ"˜2—Jšœ˜J˜�šžœžœžœž˜#Jšœ1˜1Jšžœ˜—J˜—Jšžœ˜J˜J™—š¡œžœ˜Jšœ˜Jšœžœ
˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœ˜Jšœžœ˜šžœ	žœžœžœžœžœžœ˜6Jšœžœ"˜-šžœžœžœž˜!Jšœžœ˜Jšœ1˜1Jšžœ˜—J˜—šžœ	žœžœžœžœžœ˜8šžœžœžœ
ž˜Jšœ7˜7Jšžœ˜—Jšœ8˜8J˜—˜J™�——š¡œžœ˜!Jšœ˜Jšœžœ
˜Jšœ
˜
Jšœ˜Jšœžœ˜Jšœžœ˜J˜Jš
žœžœžœžœžœ˜1šžœžœ˜Jšœžœ!˜?Jš
žœžœžœžœ žœ˜JJ˜,J˜—šžœC˜EJšžœ.˜2—J˜J™�—š¡œžœ˜Jšœ˜Jšœ
žœ
˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœ˜šžœ	žœžœžœžœžœžœ˜6Jšœžœ"˜-šžœžœžœž˜$Jšœ1˜1Jšžœ˜—J˜—šžœžœžœ	žœžœžœžœž˜KJšœžœ˜$Jšœžœ˜ Jš
žœžœžœžœžœ˜+šžœžœžœ
ž˜Jšœ7˜7Jšžœ˜—Jšœ8˜8Jšžœ˜—˜J™�——š¡œžœ˜"Jšœ˜Jšœ
žœ
˜Jšœ
˜
Jšœ˜Jšœžœ˜Jšœžœ˜Jšœ˜šžœžœžœžœžœžœžœ
žœžœžœ˜SJšžœžœ˜—šžœ	žœžœ˜Jšœžœ"˜-šžœžœžœž˜$Jšœ1˜1Jšžœ˜—J˜—šžœžœžœž˜$Jšœžœ˜$Jš
žœžœžœžœžœ˜+šžœN˜PJšžœžœ˜
—šžœžœžœž˜"Jšœ7˜7Jšžœ˜—JšœA˜AJšžœ˜—J˜——š 	™	š¡œžœžœ˜Lšœ˜Lšœ
˜
Lšœžœ˜Lšœžœ˜Lšœžœžœžœžœžœ˜'Lšœ˜Lšœžœ˜Lšœžœžœ˜Lšœžœžœžœ˜*LšœžœžœP˜eLšœ˜Lšœ2˜2Lšœ:žœ˜DLšœ+˜+šžœžœžœž˜Lšœ8˜8Lšžœ˜—Lšžœžœžœžœžœ/žœ˜XLšœžœ$˜,Lš
žœžœžœžœ'žœ˜GšžœÏc˜Jšœžœžœ˜šžœžœžœžœ˜Jšžœžœ.žœ˜SJšžœ˜—Jšžœžœžœžœ˜Jšžœ˜—šžœžœžœž˜Jšžœ
žœžœžœ˜Jšœ'˜'JšœH˜HJšœ'˜'LšœE˜EJšžœ˜—šžœžœžœž˜šžœ
žœžœ˜šœ
žœžœ˜.Jšžœžœ:˜J—L˜CL˜—Jšžœ˜—L˜L˜�—š¡
œžœžœ,˜Cš
žœ	žœžœžœžœžœž˜5Jšœ žœ
žœ
˜;Jšžœ˜—J˜—L˜�—Jšžœ˜J˜˜�J™#š¡œžœžœ&™JJšžœ™"Jšœ™J™<Jšœ6žœ
™CJ™J™�—š¡œžœ=žœ™ZJ™fJ™�—š
¡œžœžœžœžœ™PJšœžœ™Jšœžœ™Jšœžœ™J™�šžœ
žœ™Jšžœ
žœžœ	žœ™)Jšœ™J™—Jšžœžœ
žœ™/Jšžœ	žœžœ	žœ™%J™�Jšœ™Jšœ™Jšœ™JšžœIžœ™VJ™Lšœžœ™Lšœ™Lšœ1™1šžœžœžœ™Lšœžœ™%Lšœžœ™%Lšœ>™>L™—J™J™�——J˜�—�…—����)H��>ì��