DIRECTORY Contours, Cubic2, Matrix3d, Real, RealFns, Spline3d, TubeContour, Vector3d, TubeDefs, TubeFrame, TubeMisc;

TubeFrameImpl: CEDAR PROGRAM
IMPORTS Contours, Cubic2, Matrix3d, Real, RealFns, Spline3d, TubeContour, TubeMisc, Vector3d
EXPORTS TubeFrame

~ BEGIN

OPEN TubeDefs;

ReScale: PUBLIC PROC [tube: Tube, scale: REAL _ 1.0, taper: REAL _ 0.0] ~ {
DoScale: PROC [tube: Tube, scale0, scale1: REAL] ~ {
sc0: REAL _ tube.r0*scale0;
sc1: REAL _ tube.r1*scale1;
FOR n: NAT IN [0..NFrames[tube]) DO
f: Frame _ tube.frames[n];
f.scale _ MAX[0.000001, sc0+f.t*(sc1-sc0)];
f.matrix _ RefMatrix[f.position, f.triad, f.scale, f.twist, f.matrix];
ENDLOOP;
};
InnerReScale: PROC [tube: Tube, length, scale0: REAL] ~ {
IF tube # NIL THEN {
scale1: REAL _ scale0;
IF taper # 0.0 THEN {
length _ length+Spline3d.Length[tube.coeffs];
scale1 _ scale*(1.0-taper*length);
};
DoScale[tube, scale0, scale1];
InnerReScale[tube.next, length, scale1];
FOR n: NAT IN [0..TubeMisc.NBranches[tube]) DO
InnerReScale[tube.branches[n], length, scale1];
ENDLOOP;
};
};
InnerReScale[tube, 0.0, scale];
};

Make: PUBLIC PROC [
tube: Tube,
epsilon: REAL _ 0.03,
scale: REAL _ 1.0,
taper: REAL _ 0.0,
skin: BOOL _ FALSE,
view: Matrix _ NIL,
frameProc: FrameProc _ NIL]
~ {
InnerMake: TubeProc ~ {
tube.coeffs _ Spline3d.CoeffsFromHermite[[tube.p0, tube.p1, tube.v0, tube.v1]];
};
TubeMisc.ApplyToTube[tube, InnerMake];
MakeFrames[tube, epsilon, scale, taper, skin, view, frameProc];
};

MakeFrames: PUBLIC PROC [
tube: Tube,
epsilon: REAL _ 0.03,
scale: REAL _ 1.0,
taper: REAL _ 0.0,
skin: BOOL _ FALSE,
view: Matrix _ NIL,
frameProc: FrameProc _ NIL]
~ {
InnerMakeFrames: PROC [tube: Tube, length, scale0: REAL] ~ {
IF tube # NIL THEN {
scale1: REAL _ scale0;
IF taper # 0.0 THEN {
length _ length+Spline3d.Length[tube.coeffs];
scale1 _ scale*(1.0-taper*length);
};
MakeSectionFrames[tube, epsilon, scale0, scale1, skin, view, frameProc];
InnerMakeFrames[tube.next, length, scale1];
FOR n: NAT IN [0..TubeMisc.NBranches[tube]) DO
InnerMakeFrames[tube.branches[n], length, scale1];
ENDLOOP;
};
};
InnerMakeFrames[tube, 0.0, scale];
};

MakeSectionFrames: PUBLIC PROC [
tube: Tube,
epsilon: REAL _ 0.03, 
scale0, scale1: REAL _ 1.0,
skin: BOOL _ FALSE,
view: Matrix _ NIL,
frameProc: FrameProc _ NIL]
~ {
bez: Bezier _ Spline3d.BezierFromCoeffs[tube.coeffs];
maxLen: REAL _ IF view = NIL THEN 0.01*Spline3d.ConvexHullLength[bez] ELSE 0.0;
vv: Triple _ IF Vector3d.Equal[bez.b1, bez.b0, 0.0001]
THEN Vector3d.Sub[bez.b2, bez.b1]
ELSE Vector3d.Sub[bez.b1, bez.b0];
sc0: REAL _ tube.r0*scale0;
sc1: REAL _ tube.r1*scale1;
circle: Contour _ Contours.Circle[tube.circleRes];
c0: Contour _ TubeContour.TContour[tube.contours, circle, 0.0];
c1: Contour _ TubeContour.TContour[tube.contours, circle, 1.0];

MakeFrame: PROC [position, velocity: Triple, t: REAL, c: Contour] ~ {
tube.frames _ TestFrameSequence[tube.frames];
IF frameProc # NIL
THEN tube.frames[tube.frames.length] _ frameProc[position, velocity, t]
ELSE {
f: Frame _ tube.frames[tube.frames.length];
f.t _ t;
f.position _ position;
f.triad _ Basis[velocity, vv, tube.refVec];
f.scale _ MAX[0.000001, sc0+t*(sc1-sc0)];
f.twist _ tube.tw0+t*(tube.tw1-tube.tw0);
f.matrix _ RefMatrix[f.position, f.triad, f.scale, f.twist, f.matrix];
IF skin THEN {
f.contour _ c;
f.normals _ SELECT TRUE FROM
c.circle => c.pairs,
c.normals # NIL => c.normals,
ENDCASE => Contours.Normals[c];
};
};
tube.frames.length _ tube.frames.length+1;
vv _ velocity;
tube.refVec _ tube.frames[tube.frames.length-1].triad.n;
};

Walker: PROC [bez: Bezier, t0, t1: REAL, c0, c1: Contour] ~ {
IF DividedEnough[bez, t0, t1, c0, c1]
THEN MakeFrame[
bez.b0,
IF Vector3d.Equal[bez.b1, bez.b0, 0.0001]		-- degenerate end tangent check
THEN Vector3d.Sub[bez.b2, bez.b1]
ELSE Vector3d.Sub[bez.b1, bez.b0],
t0,
c0]
ELSE {
left, rite: Bezier;
t: REAL _ 0.5*(t0+t1);
c: Contour _ IF skin THEN TubeContour.TContour[tube.contours, circle, t] ELSE NIL;
[left, rite] _ Spline3d.SplitBezier[bez];
Walker[left, t0, t, c0, c];
Walker[rite, t, t1, c, c1];
};
};

DividedEnough: PROC [bez: Bezier, t0, t1: REAL, c0, c1: Contour] RETURNS [BOOL] ~ {
BezSmallEnough: PROC [bez: Bezier] RETURNS[BOOL] ~ { 
RETURN[IF view = NIL
THEN Spline3d.ConvexHullLength[bez] < maxLen OR Spline3d.FlatBezier[bez, epsilon]
ELSE Cubic2.Flat[
[Matrix3d.TransformD[bez.b0, view], Matrix3d.TransformD[bez.b1, view],
 Matrix3d.TransformD[bez.b2, view], Matrix3d.TransformD[bez.b3, view]],
100.0*epsilon]];
};
TwistSmallEnough: PROC [t0, t1: REAL] RETURNS[BOOL] ~ {
RETURN[ABS[(t1-t0)*(tube.tw1-tube.tw0)] < 20.0];
};
ContoursCloseEnough: PROC [c0, c1: Contour] RETURNS [BOOL] ~ {
AllCircles: PROC [contours: ContourSequence] RETURNS [BOOL] ~ {
FOR n: NAT IN [0..contours.length) DO
IF NOT contours[n].circle THEN RETURN [FALSE];
ENDLOOP;
RETURN[TRUE];
};
IF tube.contours = NIL OR AllCircles[tube.contours]
THEN RETURN[TRUE]
ELSE {
similar: REAL _ Contours.Similar[c0, c1];
RETURN[similar > 1.0-10.0*epsilon];
};
};

IF t1-t0 < 0.01 THEN RETURN[TRUE];
RETURN[
BezSmallEnough[bez] AND
TwistSmallEnough[t0, t1] AND
(IF NOT skin THEN TRUE ELSE ContoursCloseEnough[c0, c1])
];
};

IF tube # NIL AND tube.frames # NIL THEN tube.frames.length _ 0;
tube.refVec _ IF tube.prev # NIL
THEN tube.prev.refVec
ELSE Spline3d.RefVec[tube.coeffs, 0.0];
Walker[bez, 0.0, 1.0, c0, c1];
MakeFrame[
bez.b3,
IF Vector3d.Equal[bez.b3, bez.b2, 0.0001]	-- test for degenerate end tangent
THEN Vector3d.Sub[bez.b2, bez.b1]
ELSE Vector3d.Sub[bez.b3, bez.b2],
1.0,
c1];
IF view # NIL THEN tube.circleRes _
Real.RoundI[TubeContour.ScreenCircleRes[tube, view]/MAX[0.01, 100*epsilon]];
};

NFrames: PUBLIC PROC [tube: Tube] RETURNS [INTEGER] ~ {
RETURN[IF tube.frames # NIL THEN tube.frames.length ELSE 0];
};

TestFrameSequence: PROC [frames: FrameSequence] RETURNS [FrameSequence] ~ {
IF frames = NIL OR frames.length >= frames.maxLength
THEN frames _ LengthenFrameSequence[frames];
RETURN[frames];
};

LengthenFrameSequence: PROC [frames: FrameSequence] RETURNS [FrameSequence] ~ {
nFrames: INTEGER _ IF frames = NIL THEN 0 ELSE frames.length;
temp: FrameSequence _ NEW[FrameSequenceRec[MAX[5, Real.RoundI[1.3*nFrames]]]];
FOR i: NAT IN[0..nFrames) DO temp[i] _ frames[i]; ENDLOOP;
FOR i: NAT IN[nFrames..temp.maxLength) DO temp[i] _ NEW[FrameRec]; ENDLOOP;
temp.length _ nFrames;
RETURN[temp];
};

GetFrame: PUBLIC PROC [tube: Tube, t: REAL] RETURNS [Frame] ~ {
nFrames: INTEGER _ NFrames[tube];
frames: FrameSequence _ tube.frames;

SELECT TRUE FROM
nFrames = 0 =>
RETURN[NIL];
t < frames[0].t =>
RETURN[tube.frames[0]];
t > tube.frames[nFrames-1].t =>
RETURN[tube.frames[nFrames-1]];
ENDCASE => {
n: NAT _ 0;
WHILE frames[n].t < t DO tube.frames[n] _ frames[n]; n _ n+1; ENDLOOP;
IF tube.frames[n].t = t
THEN RETURN[tube.frames[n]]
ELSE {
frame: Frame _ NEW[FrameRec];
frame0: Frame _ tube.frames[n-1];
frame1: Frame _ tube.frames[n];
alpha: REAL _ (frame.t-frame0.t)/(frame1.t-frame0.t);

frame.t _ t;
frame.position _ Spline3d.Position[tube.coeffs, t];
frame.triad _ Basis[Spline3d.Velocity[tube.coeffs, t], frame0.triad.v, frame0.triad.n];
frame.scale _ frame0.scale+alpha*(frame1.scale-frame0.scale);
frame.twist _ frame0.twist+alpha*(frame1.twist-frame0.twist);
frame.matrix _ RefMatrix[frame.position, frame.triad, frame.scale, frame.twist];
frame.contour _ Contours.Interpolate[frame0.contour, frame1.contour, alpha];
frame.normals _ Contours.Normals[frame.contour];
RETURN[frame];
};
};
};

PutFrame: PUBLIC PROC [tube: Tube, frame: Frame] ~ {
InsertFrame: PROC [frame: Frame, frames: FrameSequence, n: NAT] ~ {
FOR i: NAT DECREASING IN [n..frames.length) DO frames[n+1] _ frames[n]; ENDLOOP;
frames[n] _ frame;
};
tube.frames _ TestFrameSequence[tube.frames];
SELECT TRUE FROM
tube.frames.length = 0 =>
tube.frames[0] _ frame;
frame.t < tube.frames[0].t =>
InsertFrame[frame, tube.frames, 0];
frame.t > tube.frames[tube.frames.length-1].t =>
tube.frames[tube.frames.length] _ frame;
ENDCASE => {
n: NAT _ 0;
WHILE tube.frames[n].t < frame.t DO n _ n+1; ENDLOOP;
IF tube.frames[n].t = frame.t THEN {
tube.frames[n] _ frame;
RETURN;
};
InsertFrame[frame, tube.frames, n];
};
tube.frames.length _ tube.frames.length+1;
};

CopyFrame: PUBLIC PROC [frame: Frame] RETURNS [Frame] ~ {
copy: Frame _ NIL;
IF frame # NIL THEN {
copy _ NEW[FrameRec];
copy.t _ frame.t;
copy.position _ frame.position;
copy.triad _ frame.triad;
copy.scale _ frame.scale;
copy.matrix _ Matrix3d.CopyMatrix[frame.matrix];
copy.contour _ Contours.Copy[frame.contour];
};
RETURN[copy];
};

CopyFrames: PUBLIC PROC [frames: FrameSequence] RETURNS [FrameSequence] ~ {
copy: FrameSequence _ NIL;
IF frames # NIL THEN {
copy _ NEW[FrameSequenceRec[frames.length]];
copy.length _ frames.length;
FOR n: NAT IN [0..copy.length) DO copy[n] _ CopyFrame[frames[n]]; ENDLOOP;
};
RETURN[copy];
};

Basis: PUBLIC PROC [v, vv, rv: Triple] RETURNS [Triad] ~ {
dot: REAL;
b, n: Triple;
vv _ Vector3d.Normalize[vv];
v _ Vector3d.Normalize[v];
rv _ Vector3d.Normalize[rv];
dot _ Vector3d.Dot[v, vv];

IF ABS[dot] > 0.9999 THEN {               							-- tangents v, vv colinear
n _ IF dot > 0.0 THEN rv ELSE [-rv.x, -rv.y, -rv.z];
n _ Vector3d.V90[v, n];                      						-- ensure orthogonality
}
ELSE {
a: REAL _ RealFns.ArcTanDeg[RealFns.SqRt[1.0-dot*dot], dot];	-- == Acos[]
axis: Triple _ Vector3d.Cross[v, vv];
n _ Vector3d.Normalize[Vector3d.RotateAbout[rv, axis, a]];	-- incremental kludge
};
b _ Vector3d.Normalize[Vector3d.Cross[v, n]];
RETURN[[v, n, b]];
};

RefMatrix: PUBLIC PROC [position: Triple, triad: Triad, scale, twist: REAL, out: Matrix _ NIL]
RETURNS [Matrix] ~ {
IF ABS[twist] > 0.001 THEN {
out _ Matrix3d.MakePureRotate[triad.v, twist, , out];
triad.n _ Matrix3d.TransformVec[triad.n, out];
triad.b _ Matrix3d.TransformVec[triad.b, out];
};
RETURN[
Matrix3d.LocalScale[Matrix3d.MakeFromTriad[triad.n, triad.b, triad.v, position], scale, out]];
};

END.
..


���	"��TubeFrameImpl.mesa
Copyright c 1985 by Xerox Corporation.  All rights reserved.
Bloomenthal, September 30, 1986 12:39:39 pm PDT
Keep scale non-zero (avoid subsequent surface normal computation problems):
MakeMatrices: PUBLIC PROC [s: SplineData, scale: REAL] ~ {
sc0: REAL _ s.rad0*scale;
sc1: REAL _ s.rad1*scale;
tw0: REAL _ s.twist0;
tw1: REAL _ s.twist1;
vv: Triple _ s.v0;
mats: MatrixSeq _ s.mats;
s.refVec _ IF s.prev # NIL THEN s.prev.refVec ELSE Spline3d.RefVec[s.c, 0.0];
mats[0] _Misc3d.RefMatrix[s.p0, s.refVec, Vector3d.Cross[vv, s.refVec], vv, sc0, tw0, mats[0]];
FOR i: NAT IN[1..s.axialRes) DO
n, b: Triple;
t: REAL _ i/REAL[s.axialRes-1.0];
p: Triple _ Spline3d.Position[s.c, t];
v: Triple _ Spline3d.Tangent[s.c, t];
[n, b] _ Misc3d.Basis[v, vv, s.refVec];
mats[i] _ Misc3d.RefMatrix[p, n, b, v, (1.0-t)*sc0+t*sc1, (1.0-t)*tw0+t*tw1, mats[i]];
vv _ v;
s.refVec _ n;
ENDLOOP;
};

GetFrame: PUBLIC PROC [tube: Tube, t: REAL] RETURNS [Frame] ~ {
frames: FrameSequence _ tube.frames;
numFrames: INT _ IF frames # NIL THEN frames.maxLength ELSE 0;

SELECT TRUE FROM
numFrames = 0 =>
RETURN[NIL];
frame.t < frames[0].t =>
RETURN[tube.frames[0]];
frame.t > tube.frames[numFrames-1].t =>
RETURN[tube.frames[numFrames-1];
ENDCASE => {
n: NAT _ 0;
WHILE frames[n].t < frame.t DO tube.frames[n] _ frames[n]; n _ n+1; ENDLOOP;
IF tube.frames[n].t = t
THEN RETURN[tube.frames[n]]
ELSE {				-- the following is sloppy:
frame0: Frame _ tube.frames[n-1];
frame1: Frame _ tube.frames[n];
m0: Matrix _ frame0.m;
m1: Matrix _ frame1.m;
alpha: REAL _ (frame.t-frame0.t)/(frame1.t-frame0.t);
beta: REAL _ 1.0-alpha;
x: Triple _ Vector3d.Combine[
[m0[0][0], m0[0][1], m0[0][2]], alpha, [m1[0][0], m1[0][1], m1[0][2]], beta];
y: Triple _ Vector3d.Combine[
[m0[1][0], m0[1][1], m0[1][2]], alpha, [m1[1][0], m1[1][1], m1[1][2]], beta];
z: Triple _ Vector3d.Combine[
[m0[2][0], m0[2][1], m0[2][2]], alpha, [m1[2][0], m1[2][1], m1[2][2]], beta];
v: Triple _ Vector3d.SameMag[z, Spline3d.Velocity[tube.coeffs, t]];
n: Triple _ Vector3d.SameMag[x, Vector3d.Cross[v, y]];
b: Triple _ Vector3d.SameMag[y, Vector3d.Cross[v, n]];
p: Triple _ Spline3d.Position[tube.coeffs, t];
frame: Frame _ NEW[FrameRec];
frame.t _ t;
frame.c _ Contour.Interpolate[frame0.c, frame1.c, alpha];
frame.m _ RefMatrix[p, n, b, v, 1.0, 0.0];
RETURN[frame];
};
};
};

�Ê��˜�šœ™Jšœ
Ïmœ1™<J™/J˜�JšÏk	œk˜tJ˜�—šÐbl
œžœž˜JšžœU˜\Jšžœ
˜J˜�—šœž˜J˜�Jšžœ
˜J˜�codeš
Ïnœžœžœžœžœ˜Kš œžœžœ˜4Jšœžœ˜Jšœžœ˜šžœžœžœž˜#J˜Jšœ
žœ˜+JšœF˜FJšžœ˜—J˜—š œžœžœ˜9šžœžœžœ˜Kšœžœ
˜šžœ
žœ˜Kšœ-˜-K˜"K˜—Kšœ˜Kšœ(˜(šžœžœžœž˜.Kšœ/˜/Kšžœ˜—J˜—J˜—J˜J˜J˜�—š œžœžœ˜Kšœ˜Kšœ	žœ˜Kšœžœ˜Kšœžœ˜Jšœžœžœ˜Kšœžœ˜Kšœžœ˜Kšœ˜š 	œ˜KšœO˜OK˜—Kšœ&˜&Kšœ?˜?Jšœ˜J˜�—š 
œžœ˜Jšœ˜Jšœ	žœ˜Jšœžœ˜Jšœžœ˜Jšœžœžœ˜Jšœžœ˜Jšœžœ˜Jšœ˜š œžœžœ˜<šžœžœžœ˜Kšœžœ
˜šžœ
žœ˜Kšœ-˜-K˜"K˜—JšœH˜HKšœ+˜+šžœžœžœž˜.Kšœ2˜2Kšžœ˜—J˜—J˜—J˜"J˜J˜�—š œžœ˜ Jšœ˜Jšœ	žœ	˜Jšœžœ˜Jšœžœžœ˜Jšœžœ˜Jšœžœ˜Jšœ˜J˜5Jšœžœžœžœžœ%žœ˜Ošœ
žœ'˜6Jšžœ˜!Jšžœ˜"—Jšœžœ˜Jšœžœ˜J˜2J˜?J˜?K˜�š 	œžœ!žœ˜EJ˜-šžœ
ž˜JšžœC˜Gšžœ˜Jšœ+˜+J˜Jšœ˜Jšœ+˜+J™KJšœ
žœ˜)Jšœ)˜)JšœF˜Fšžœžœ˜J˜šœžœžœž˜Jšœ˜Jšœžœ˜Jšžœ˜—J˜—J˜——J˜*Jšœ˜Jšœ8˜8J˜J˜�—š œžœžœ˜=šžœ#˜%šžœ˜Jšœ˜šžœ'Ïc!˜JJšžœ˜!Jšžœ˜"—Jšœ˜Jšœ˜—šžœ˜J˜Jšœžœ˜Jš	œ
žœžœ/žœžœ˜RJ˜)J˜J˜J˜——J˜J˜�—š
 
œžœžœžœžœ˜Sš œžœžœžœ˜5šžœžœž˜Kšžœ)žœ"˜Qšžœ
˜KšœF˜FKšœG˜GKšœ˜——K˜—š
 œžœ
žœžœžœ˜7Jšžœžœ&˜0K˜—š œžœžœžœ˜>š 
œžœžœžœ˜?šžœžœžœž˜%Kš
žœžœžœžœžœ˜.Kšžœ˜—Kšžœžœ˜
K˜—šžœžœžœ˜3Kšžœžœžœ˜šžœ˜Kšœ	žœ˜)Kšžœ˜#K˜——K˜—J˜�Jšžœžœžœ˜"šžœ˜Jšœž˜Jšœž˜Jšœžœžœžœžœžœ˜8Jšœ˜—J˜—J˜�Jš
žœžœžœžœžœ˜@šœžœ
ž˜ Jšžœ˜Jšžœ#˜'—K˜šœ
˜
Kšœ˜šžœ'¡#˜LKšžœ˜!Kšžœ˜"—Kšœ˜Kšœ˜—šžœžœ˜#Kšœ4žœ˜L—J˜J˜�—š
 œžœžœžœžœ˜7Kš
žœžœžœžœžœ˜<K˜K˜�—š œžœžœ˜Kšžœ
žœžœ"˜4Jšžœ(˜,—Jšžœ	˜J˜J˜�—š œžœžœ˜OJšœ	žœžœ
žœžœžœ˜=Jšœžœžœ ˜NJš
žœžœžœ
žœžœ˜:Jšžœžœžœžœžœžœ˜KJ˜Jšžœ˜
J˜J˜�—š
 œžœžœžœžœ˜?Kšœ	žœ˜!K˜$K˜�šžœžœž˜šœ˜Kšžœžœ˜—˜Kšžœ˜—šœ˜Kšžœ˜—šžœ˜Kšœžœ˜Kšžœžœ&žœ˜Fšžœ˜Kšžœžœ˜šžœ˜Kšœžœ˜K˜!K˜Kšœžœ*˜5K˜�K˜K˜3K˜WK˜=K˜=K˜PK˜LK˜0Kšžœ˜K˜——K˜——Kšœ˜J˜�—š œžœžœ˜4š œžœ*žœ˜CKšžœžœž
œžœžœžœ˜PKšœ˜K˜—K˜-šžœžœž˜šœ˜Kšœ˜—˜K˜#—šœ0˜0Kšœ(˜(—šžœ˜Kšœžœ˜Kšžœžœ
žœ˜5šžœžœ˜$Kšœ˜Kšžœ˜K˜—K˜#K˜—K˜*—Kšœ˜J˜�—š 	œžœžœžœ˜9Jšœžœ˜šžœ	žœžœ˜Jšœžœ˜J˜J˜J˜J˜J˜0J˜,J˜—Jšžœ˜
˜J˜�——š 
œžœžœžœ˜KJšœžœ˜šžœ
žœžœ˜Jšœžœ"˜,J˜Kš
žœžœžœžœ žœ˜JK˜—Kšžœ˜
˜J˜�——š œžœžœžœ˜:Jšœžœ˜
J˜
J˜J˜J˜Jšœ˜šžœžœžœ¡˜KJšœžœžœžœ˜4Jšœ3¡˜JJšœ˜—šžœ˜Jšœžœ6¡˜IJšœ%˜%Jšœ;¡˜PJšœ˜—Jšœ-˜-Jšžœ˜J˜J˜�—š
 	œžœžœ0žœžœ˜^Jšžœ
˜šžœžœžœ˜Jšœ5˜5J˜.J˜.J˜—šžœ˜Jšœ^˜^—J˜J˜�——šžœ˜J˜J˜�š œžœžœžœ™:Jšœžœ™Jšœžœ™Jšœžœ™Jšœžœ™Jšœ™Jšœ™Jš	œžœ
žœžœžœ™MJšœ_™_šžœžœžœž™J™
Jšœžœžœ™!J™&J™%Jšœ'™'JšœV™VJ™Jšœ
™
Jšžœ™—J™J™�—š
 œžœžœžœžœ™?K™$Kšœžœžœ
žœžœžœ™>K™�šžœžœž™šœ™Kšžœžœ™—™Kšžœ™—šœ'™'Kšžœ™ —šžœ™Kšœžœ™Kšžœžœ&žœ™Lšžœ™Kšžœžœ™šžœ¡™%K™!K™K™K™Kšœžœ*™5Kšœžœ
™™K™M—™K™M—™K™M—K™CK™6K™6K™.Kšœžœ™K™K™9K™*Kšžœ™K™——K™——Kšœ™J™�—J˜�——�…—����& ��=Ý��