DIRECTORY Basics, Vector2, ImagerPixelMap, PrincOps, PrincOpsUtils, Real, ImagerTransformation, Scaled, ImagerPixelSeq, GreenBay; ImagerPixelSeqImpl: CEDAR MONITOR IMPORTS Basics, ImagerPixelMap, PrincOpsUtils, Real, ImagerTransformation, Scaled, GreenBay EXPORTS ImagerPixelSeq ~ BEGIN OPEN ImagerPixelSeq; DeviceRectangle: TYPE ~ ImagerPixelMap.DeviceRectangle; IntRectangle: TYPE ~ RECORD [x, y, w, h: INT]; TransformIntRectangle: PROC [in: IntRectangle, m: ImagerTransformation.Transformation] RETURNS [IntRectangle] ~ { r: ImagerTransformation.Rectangle ~ ImagerTransformation.TransformRectangle[m: m, r: [in.x, in.y, in.w, in.h]]; RETURN [[Real.Round[r.x], Real.Round[r.y], Real.Round[r.w], Real.Round[r.h]]] }; Pair: TYPE ~ Vector2.VEC; bitsPerWord: NAT ~ Basics.bitsPerWord; pixelSeqElementSize: NAT ~ SIZE[PixelSeqRep[1]]-SIZE[PixelSeqRep[0]]; Create: PUBLIC PROC [maxSize: NAT] RETURNS [new: PixelSeq] ~ { new _ NEW[PixelSeqRep[maxSize]]; }; nScratchSlots: NAT ~ 2; nScratchAvail: NAT _ 0; scratch: ARRAY [0..nScratchSlots) OF PixelSeq; rover: NAT _ 0; ObtainScratch: PUBLIC ENTRY PROC [maxSize: NAT] RETURNS [new: PixelSeq] ~ { ENABLE UNWIND => NULL; FOR i: NAT DECREASING IN [0..nScratchAvail) DO IF scratch[i].maxSize >= maxSize THEN { new _ scratch[i]; IF i # nScratchAvail-1 THEN scratch[i] _ scratch[nScratchAvail-1]; nScratchAvail _ nScratchAvail - 1; scratch[nScratchAvail] _ NIL; EXIT; }; ENDLOOP; IF new = NIL THEN new _ NEW[PixelSeqRep[maxSize]]; }; ReleaseScratch: PUBLIC ENTRY PROC [pixelSeq: PixelSeq] ~ { IF nScratchAvail < nScratchSlots THEN { scratch[nScratchAvail] _ pixelSeq; nScratchAvail _ nScratchAvail + 1; } ELSE { scratch[rover] _ pixelSeq; rover _ (rover + 1) MOD nScratchSlots; }; }; Clear: PUBLIC PROC [pixelSeq: PixelSeq, size: NAT] ~ TRUSTED { size _ MIN[size, pixelSeq.maxSize]; IF size > 0 THEN PrincOpsUtils.LongZero[@(pixelSeq[0]), size*pixelSeqElementSize]; }; Copy: PUBLIC PROC [pixelSeq: PixelSeq, size: NAT, scratch: PixelSeq _ NIL] RETURNS [new: PixelSeq] ~ { size _ MIN[size, pixelSeq.maxSize]; new _ IF scratch = NIL OR scratch.maxSize < size THEN NEW[PixelSeqRep[size]] ELSE scratch; IF size > 0 THEN TRUSTED { PrincOpsUtils.LongCopy[from: @(pixelSeq[0]), nwords: size*pixelSeqElementSize, to: @(new[0])]; }; }; Add: PUBLIC PROC [dest, source: PixelSeq, size: NAT] ~ { fMin: INTEGER _ 0; fMax: INTEGER _ size; IF fMin < fMax THEN TRUSTED { destArr: LONG POINTER TO RECORD[SEQUENCE COMPUTED CARDINAL OF Pixel] _ LOOPHOLE[@(dest[fMin])]; sourceArr: LONG POINTER TO RECORD[SEQUENCE COMPUTED CARDINAL OF Pixel] _ LOOPHOLE[@(source[fMin])]; lengthMinusOne: NAT _ fMax-fMin-1; dest[fMax-1] _ destArr[lengthMinusOne] + source[fMax-1]; FOR j: NAT IN [0..lengthMinusOne) DO destArr[j] _ destArr[j] + sourceArr[j]; ENDLOOP; }; }; Subtract: PUBLIC PROC [dest, source: PixelSeq, size: NAT] ~ { fMin: INTEGER _ 0; fMax: INTEGER _ size; IF fMin < fMax THEN TRUSTED { destArr: LONG POINTER TO RECORD[SEQUENCE COMPUTED CARDINAL OF Pixel] _ LOOPHOLE[@(dest[fMin])]; sourceArr: LONG POINTER TO RECORD[SEQUENCE COMPUTED CARDINAL OF Pixel] _ LOOPHOLE[@(source[fMin])]; lengthMinusOne: NAT _ fMax-fMin-1; dest[fMax-1] _ destArr[lengthMinusOne] - source[fMax-1]; FOR j: NAT IN [0..lengthMinusOne) DO destArr[j] _ destArr[j] - sourceArr[j]; ENDLOOP; }; }; Apply: PUBLIC PROC [dest, source: PixelSeq, size: NAT, table: PixelSeq] ~ { IF size > 0 THEN TRUSTED { destArr: LONG POINTER TO RECORD[SEQUENCE COMPUTED CARDINAL OF Pixel] _ LOOPHOLE[@(dest[0])]; sourceArr: LONG POINTER TO RECORD[SEQUENCE COMPUTED CARDINAL OF Pixel] _ LOOPHOLE[@(source[0])]; lengthMinusOne: NAT _ size-1; dest[lengthMinusOne] _ table[source[lengthMinusOne]]; FOR j: NAT IN [0..lengthMinusOne) DO destArr[j] _ table[sourceArr[j]]; ENDLOOP; }; }; ApplyAndAdd: PUBLIC PROC [dest, source: PixelSeq, size: NAT, table: PixelSeq] ~ { IF size > 0 THEN TRUSTED { destArr: LONG POINTER TO RECORD[SEQUENCE COMPUTED CARDINAL OF Pixel] _ LOOPHOLE[@(dest[0])]; sourceArr: LONG POINTER TO RECORD[SEQUENCE COMPUTED CARDINAL OF Pixel] _ LOOPHOLE[@(source[0])]; lengthMinusOne: NAT _ size-1; dest[lengthMinusOne] _ destArr[lengthMinusOne] + table[source[lengthMinusOne]]; FOR j: NAT IN [0..lengthMinusOne) DO destArr[j] _ destArr[j] + table[sourceArr[j]]; ENDLOOP; }; }; LoadF: PUBLIC PROC [pixelSeq: PixelSeq, s, f: INTEGER, size: NAT, source: PixelMap] ~ TRUSTED { fOriginMap: INTEGER _ source.fOrigin; fOriginRow: INTEGER _ f; fSizeRow: INTEGER _ MIN[size, pixelSeq.maxSize]; mapBB: DeviceRectangle _ source.BoundedWindow; fMin: INTEGER _ MAX[fOriginRow, mapBB.fMin]; fMax: INTEGER _ MIN[fOriginRow+fSizeRow, mapBB.fMin+mapBB.fSize]; IF fMin >= fMax OR s NOT IN [mapBB.sMin..mapBB.sMin+mapBB.sSize) THEN {Clear[pixelSeq, size]; RETURN}; IF fMin-fOriginRow > 0 THEN PrincOpsUtils.LongZero[@(pixelSeq[0]), (fMin-fOriginRow)*pixelSeqElementSize]; IF fMax-fOriginRow < fSizeRow THEN PrincOpsUtils.LongZero[@(pixelSeq[fMax-fOriginRow]), (fSizeRow-fMax+fOriginRow)*pixelSeqElementSize]; GreenBay.UnPack[ wordPointer: @(pixelSeq[fMin-fOriginRow]), bitsPerElement: Basics.BITSHIFT[1, source.refRep.lgBitsPerPixel], base: source.refRep.pointer + Basics.LongMult[(s - source.sOrigin), source.refRep.rast], start: fMin-fOriginMap, count: fMax-fMin ]; }; LoadS: PUBLIC PROC [pixelSeq: PixelSeq, s, f: INTEGER, size: NAT, source: PixelMap] ~ TRUSTED { sOriginMap: INTEGER _ source.sOrigin; seqOrigin: INTEGER _ s; seqSize: INTEGER _ MIN[size, pixelSeq.maxSize]; mapBB: DeviceRectangle _ source.BoundedWindow; sMin: INTEGER _ MAX[seqOrigin, mapBB.sMin]; sMax: INTEGER _ MIN[seqOrigin+seqSize, mapBB.sMin+mapBB.sSize]; bbTableSpace: PrincOps.BBTableSpace; bb: PrincOps.BBptr ~ PrincOpsUtils.AlignedBBTable[@bbTableSpace]; bitsPerElement: CARDINAL ~ Basics.BITSHIFT[1, source.refRep.lgBitsPerPixel]; bit: CARDINAL ~ Basics.BITSHIFT[NAT[f-source.fOrigin], source.refRep.lgBitsPerPixel]; Clear[pixelSeq, size]; IF sMin >= sMax OR f NOT IN [mapBB.fMin..mapBB.fMin+mapBB.fSize) THEN RETURN; bb^ _ [ dst: [word: @(pixelSeq[sMin-seqOrigin]), bit: bitsPerWord-bitsPerElement], dstBpl: bitsPerWord, src: [word: source.refRep.pointer + Basics.LongMult[(sMin - source.sOrigin), source.refRep.rast] + bit/bitsPerWord, bit: bit MOD bitsPerWord], srcDesc: [srcBpl[source.refRep.rast*bitsPerWord]], width: bitsPerElement, height: sMax-sMin, flags: [] ]; PrincOpsUtils.BITBLT[bb]; }; StoreF: PUBLIC PROC [pixelSeq: PixelSeq, s, f: INTEGER, size: NAT, dest: PixelMap] ~ TRUSTED { fOriginMap: INTEGER _ dest.fOrigin; fOriginRow: INTEGER _ f; fSizeRow: INTEGER _ MIN[size, pixelSeq.maxSize]; mapBB: DeviceRectangle _ dest.BoundedWindow; fMin: INTEGER _ MAX[fOriginRow, mapBB.fMin]; fMax: INTEGER _ MIN[fOriginRow+fSizeRow, mapBB.fMin+mapBB.fSize]; IF fMin >= fMax OR s NOT IN [mapBB.sMin..mapBB.sMin+mapBB.sSize) THEN RETURN; GreenBay.Pack[ wordPointer: @(pixelSeq[fMin-fOriginRow]), bitsPerElement: Basics.BITSHIFT[1, dest.refRep.lgBitsPerPixel], base: dest.refRep.pointer + Basics.LongMult[(s - dest.sOrigin), dest.refRep.rast], start: fMin-fOriginMap, count: fMax-fMin ]; }; StoreS: PUBLIC PROC [pixelSeq: PixelSeq, s, f: INTEGER, size: NAT, dest: PixelMap] ~ TRUSTED { sOriginMap: INTEGER _ dest.sOrigin; seqOrigin: INTEGER _ s; seqSize: INTEGER _ MIN[size, pixelSeq.maxSize]; mapBB: DeviceRectangle _ dest.BoundedWindow; sMin: INTEGER _ MAX[seqOrigin, mapBB.sMin]; sMax: INTEGER _ MIN[seqOrigin+seqSize, mapBB.sMin+mapBB.sSize]; bbTableSpace: PrincOps.BBTableSpace; bb: PrincOps.BBptr ~ PrincOpsUtils.AlignedBBTable[@bbTableSpace]; bitsPerElement: CARDINAL ~ Basics.BITSHIFT[1, dest.refRep.lgBitsPerPixel]; bit: CARDINAL ~ Basics.BITSHIFT[NAT[f-dest.fOrigin], dest.refRep.lgBitsPerPixel]; IF sMin >= sMax OR f NOT IN [mapBB.fMin..mapBB.fMin+mapBB.fSize) THEN RETURN; bb^ _ [ dst: [word: dest.refRep.pointer + Basics.LongMult[(sMin - dest.sOrigin), dest.refRep.rast] + bit/bitsPerWord, bit: bit MOD bitsPerWord], dstBpl: dest.refRep.rast*bitsPerWord, src: [word: @(pixelSeq[sMin-seqOrigin]), bit: bitsPerWord-bitsPerElement], srcDesc: [srcBpl[bitsPerWord]], width: bitsPerElement, height: sMax-sMin, flags: [] ]; PrincOpsUtils.BITBLT[bb]; }; TransferSamples: PUBLIC PROC [dest, source: PixelMap, transformation: Transformation, tile: BOOLEAN _ FALSE, multiplier: CARDINAL _ 1, lgScale: INTEGER _ 0] ~ { sr: DeviceRectangle _ source.Window; sb: DeviceRectangle _ source.BoundedWindow; db: IntRectangle _ TransformIntRectangle[[sr.sMin, sr.fMin, sr.sSize, sr.fSize], transformation]; destRect: DeviceRectangle _ dest.BoundedWindow; dr: DeviceRectangle _ IF tile THEN destRect ELSE ImagerPixelMap.Intersect[destRect, [db.x, db.y, db.w, db.h]]; pixelSeq: PixelSeq _ ObtainScratch[dr.fSize]; deltaPixel: Pair ~ ImagerTransformation.InverseTransformVec[transformation, [0, 1]]; sDelta: Scaled.Value ~ Scaled.FromReal[deltaPixel.x]; fDelta: Scaled.Value ~ Scaled.FromReal[deltaPixel.y]; deltaLine: Pair ~ ImagerTransformation.InverseTransformVec[transformation, [1, 0]]; sDeltaLine: Scaled.Value ~ Scaled.FromReal[deltaLine.x]; fDeltaLine: Scaled.Value ~ Scaled.FromReal[deltaLine.y]; sourceOrigin: Pair ~ ImagerTransformation.InverseTransform[transformation, [dr.sMin+0.5, dr.fMin+0.5]]; sSource: Scaled.Value _ Scaled.FromReal[sourceOrigin.x]; fSource: Scaled.Value _ Scaled.FromReal[sourceOrigin.y]; GetSamples: PROC ~ { sMax: INTEGER _ sb.sMin+sb.sSize; fMax: INTEGER _ sb.fMin+sb.fSize; s: Scaled.Value _ sSource; f: Scaled.Value _ fSource; FOR j: NAT IN [0..dr.fSize) DO IF tile THEN { WHILE s.Floor < sr.sMin DO s _ s.PLUS[Scaled.FromInt[sr.sSize]] ENDLOOP; WHILE s.Floor >= sr.sMin+sr.sSize DO s _ s.MINUS[Scaled.FromInt[sr.sSize]] ENDLOOP; WHILE f.Floor < sr.fMin DO f _ f.PLUS[Scaled.FromInt[sr.fSize]] ENDLOOP; WHILE f.Floor >= sr.fMin+sr.fSize DO f _ f.MINUS[Scaled.FromInt[sr.fSize]] ENDLOOP; }; IF s.Floor IN [sb.sMin..sMax) AND f.Floor IN [sb.fMin..fMax) THEN { pixelSeq[j] _ Basics.BITSHIFT[source.GetPixel[s.Floor, f.Floor]*multiplier, lgScale]; }; s _ s.PLUS[sDelta]; f _ f.PLUS[fDelta]; ENDLOOP; }; FOR s: INTEGER IN [dr.sMin..dr.sMin+dr.sSize) DO LoadF[pixelSeq, s, dr.fMin, dr.fSize, dest]; GetSamples[]; StoreF[pixelSeq, s, dr.fMin, dr.fSize, dest]; sSource _ sSource.PLUS[sDeltaLine]; fSource _ fSource.PLUS[fDeltaLine]; ENDLOOP; ReleaseScratch[pixelSeq]; }; UnderSample: PUBLIC PROC [pixelMap: PixelMap, transformation: Transformation, tile: BOOLEAN _ FALSE, background: CARDINAL _ 0, scratch: REF ImagerPixelMap.PixelMapRep _ NIL] RETURNS [PixelMap] ~ { sr: DeviceRectangle _ pixelMap.Window; db: IntRectangle _ TransformIntRectangle[[sr.sMin, sr.fMin, sr.sSize, sr.fSize], transformation]; dr: DeviceRectangle _ [db.x, db.y, db.w, db.h]; new: PixelMap _ ImagerPixelMap.Reshape[scratch, pixelMap.refRep.lgBitsPerPixel, dr]; new.Fill[dr, background]; TransferSamples[new, pixelMap, transformation, tile]; RETURN [new] }; BoxTooBig: PUBLIC ERROR ~ CODE; BoxFilter: PUBLIC PROC [pixelMap: PixelMap, sSizeBox, fSizeBox: NAT] ~ { IF LONG[sSizeBox]*fSizeBox*255 > CARDINAL.LAST THEN { BoxFilter[pixelMap, sSizeBox, 1]; BoxFilter[pixelMap, 1, fSizeBox]; } ELSE { sHalf: NAT ~ sSizeBox/2; fHalf: NAT ~ (fSizeBox+1)/2; sStart: INTEGER ~ pixelMap.sOrigin+pixelMap.sMin; sEnd: INTEGER ~ sStart + pixelMap.sSize; fStart: INTEGER ~ pixelMap.fOrigin+pixelMap.fMin; fEnd: INTEGER ~ fStart+pixelMap.fSize; sum: ARRAY [0..256) OF PixelSeq; nPixels: CARDINAL _ sSizeBox*fSizeBox; sOrigin: INTEGER _ sStart-2*sSizeBox+sHalf; fOrigin: INTEGER ~ fStart-fSizeBox; result: PixelSeq _ ObtainScratch[pixelMap.fSize]; paddedSize: NAT _ pixelMap.fSize+2*fSizeBox; MoveToNextRow: PROC ~ { t: PixelSeq _ sum[0]; p: Pixel; FOR i: NAT IN [0..sSizeBox) DO sum[i] _ sum[i+1]; ENDLOOP; sum[sSizeBox] _ t; sOrigin _ sOrigin + 1; LoadF[ pixelSeq: t, s: MAX[MIN[sOrigin + sSizeBox, sEnd-1], sStart], f: fOrigin, size: paddedSize, source: pixelMap ]; p _ t[fSizeBox]; FOR i: NAT IN [0..fSizeBox) DO t[i] _ p; ENDLOOP; p _ t[paddedSize-fSizeBox-1]; FOR i: NAT IN [paddedSize-fSizeBox..paddedSize) DO t[i] _ p; ENDLOOP; FOR i: NAT IN [1..paddedSize) DO t[i] _ t[i] + t[i-1] ENDLOOP; Add[t, sum[sSizeBox-1], paddedSize]; }; FOR i: NAT IN [0..sSizeBox] DO sum[i] _ Create[paddedSize]; ENDLOOP; FOR s: INTEGER IN [sStart..sEnd) DO WHILE sOrigin+sHalf+1 # s DO MoveToNextRow[] ENDLOOP; FOR f: INTEGER IN [fStart..fEnd) DO boxSum: Pixel _ sum[sSizeBox][f-fHalf+fSizeBox-fOrigin] - sum[sSizeBox][f-fHalf-fOrigin] - sum[0][f-fHalf+fSizeBox-fOrigin] + sum[0][f-fHalf-fOrigin]; result[f-fStart] _ boxSum/nPixels; ENDLOOP; StoreF[result, s, fStart, pixelMap.fSize, pixelMap]; ENDLOOP; ReleaseScratch[result]; }; }; ChangeBitsPerPixel: PUBLIC PROC [pixelMap: PixelMap, newLgBitsPerPixel: [0..4], scratch: REF ImagerPixelMap.PixelMapRep _ NIL] RETURNS [PixelMap] ~ { bounds: DeviceRectangle _ pixelMap.Window; new: PixelMap _ ImagerPixelMap.Reshape[scratch, newLgBitsPerPixel, bounds]; pixelSeq: PixelSeq _ ObtainScratch[bounds.fSize]; FOR s: INTEGER IN [bounds.sMin..bounds.sMin+bounds.sSize) DO LoadF[pixelSeq, s, bounds.fMin, bounds.fSize, pixelMap]; StoreF[pixelSeq, s, bounds.fMin, bounds.fSize, new]; ENDLOOP; ReleaseScratch[pixelSeq]; RETURN [new] }; Renormalize: PUBLIC PROC [pixelMap: PixelMap, oldmin, oldmax, newmin, newmax: REAL] ~ { bounds: DeviceRectangle _ pixelMap.Window; pixelSeq: PixelSeq _ ObtainScratch[bounds.fSize]; m: REAL _ (newmax-newmin)/(oldmax-oldmin); FOR s: INTEGER IN [bounds.sMin..bounds.sMin+bounds.sSize) DO LoadF[pixelSeq, s, bounds.fMin, bounds.fSize, pixelMap]; FOR j: NAT IN [0..bounds.fSize) DO pix: REAL _ pixelSeq[j]; out: REAL _ (pix-oldmin)*m+newmin; pixelSeq[j] _ MAX[MIN[Real.RoundLI[out], CARDINAL.LAST], 0]; ENDLOOP; StoreF[pixelSeq, s, bounds.fMin, bounds.fSize, pixelMap]; ENDLOOP; ReleaseScratch[pixelSeq]; }; END. `ImagerPixelSeqImpl.mesa Copyright (C) 1984, Xerox Corporation. All rights reserved. Michael Plass, October 18, 1985 12:07:55 pm PDT Do last element the hard way to get bounds checking. Do last element the hard way to get bounds checking. Do last element the hard way to get bounds checking. Do last element the hard way to get bounds checking. ΚΉ˜šœ™J™Jšœœ˜ Jšœ˜J˜—Jšœœ˜Jšœœ˜Jšœ œœ ˜.šœœ˜J˜—š ž œœœœ œœ˜KJšœœœ˜š œœ œœ˜.šœœ˜'Jšœ˜Jšœœ'˜BJšœ"˜"Jšœœ˜Jšœ˜Jšœ˜—Jšœ˜—Jšœœœœ˜2šœ˜J˜——šžœœœœ˜:šœœ˜'Jšœ"˜"Jšœ"˜"Jšœ˜—šœ˜Jšœ˜Jšœœ˜&Jšœ˜—Jšœ˜J˜—š žœœœœœ˜>Jšœœ˜#Jšœ œB˜RJšœ˜J˜—š žœœœœœœ˜fJšœœ˜#Jš œœ œœœœœ ˜Zšœ œœ˜Jšœ^˜^Jšœ˜—Jšœ˜J˜—šžœœœ œ˜8Jšœœ˜Jšœœ˜šœ œœ˜Jšœ œœœœœœœœ œ˜_Jšœ œœœœœœœœ œ˜cJšœœ˜"šœ8˜8J™4—šœœœ˜$Jšœ'˜'Jš˜—Jšœ˜—Jšœ˜J˜—šžœœœ œ˜=Jšœœ˜Jšœœ˜šœ œœ˜Jšœ œœœœœœœœ œ˜_Jšœ œœœœœœœœ œ˜cJšœœ˜"šœ8˜8J™4—šœœœ˜$Jšœ'˜'Jš˜—Jšœ˜—Jšœ˜J˜—šžœœœ œ˜Kšœ œœ˜Jšœ œœœœœœœœ œ ˜\Jšœ œœœœœœœœ œ˜`Jšœœ ˜šœ5˜5J™4—šœœœ˜$Jšœ!˜!Jš˜—Jšœ˜—Jšœ˜J˜—šž œœœ œ˜Qšœ œœ˜Jšœ œœœœœœœœ œ ˜\Jšœ œœœœœœœœ œ˜`Jšœœ ˜šœO˜OJ™4—šœœœ˜$Jšœ.˜.Jš˜—Jšœ˜—Jšœ˜J˜—š žœœœœœœ˜_Jšœ œ˜%Jšœ œ˜Jšœ œœ˜0Jšœ.˜.Jšœœœ˜,Jšœœœ.˜AJšœœœœ%˜@Jšœœ˜%JšœœO˜jJšœœf˜ˆšœ˜Jšœ*˜*Jšœœ"˜AJšœX˜XJšœ˜Jšœ˜Jšœ˜—Jšœ˜J˜—š žœœœœœœ˜_Jšœ œ˜%Jšœ œ˜Jšœ œœ˜/Jšœ.˜.Jšœœœ˜+Jšœœœ,˜?J˜$JšœA˜AJšœœ œ"˜LJšœœ œœ2˜UJšœ˜Jš œœœœ&œœ˜Mšœ˜JšœJ˜JJšœ˜Jšœ}œ˜ŽJšœ2˜2Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜—Jšœœ˜Jšœ˜J˜—š žœœœœœœ˜^Jšœ œ˜#Jšœ œ˜Jšœ œœ˜0Jšœ,˜,Jšœœœ˜,Jšœœœ.˜AJš œœœœ&œœ˜Mšœ˜Jšœ*˜*Jšœœ ˜?JšœR˜RJšœ˜Jšœ˜Jšœ˜—Jšœ˜J˜—š žœœœœœœ˜^Jšœ œ˜#Jšœ œ˜Jšœ œœ˜/Jšœ,˜,Jšœœœ˜+Jšœœœ,˜?J˜$JšœA˜AJšœœ œ ˜JJšœœ œœ.˜QJš œœœœ&œœ˜Mšœ˜Jšœwœ˜ˆJšœ%˜%JšœJ˜JJšœ˜Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜—Jšœœ˜Jšœ˜J˜—šžœœœ@œœœœ ˜ Jšœ$˜$Jšœ+˜+Jšœa˜aJšœ/˜/Jšœœœ œ>˜nJšœ-˜-JšœT˜TJšœ5˜5Jšœ5˜5JšœS˜SJšœ8˜8Jšœ8˜8Jšœg˜gJšœ8˜8Jšœ8˜8šž œœ˜Jšœœ˜!Jšœœ˜!Jšœ˜Jšœ˜šœœœ˜šœœ˜Jšœœœœ˜HJšœœœœ˜SJšœœœœ˜HJšœœœœ˜SJšœ˜—š œ œœ œœ˜CJšœœ8˜UJšœ˜—Jšœœ ˜Jšœœ ˜Jšœ˜—Jšœ˜—šœœœ˜0Jšœ,˜,Jšœ ˜ Jšœ-˜-Jšœœ ˜#Jšœœ ˜#Jš˜—Jšœ˜Jšœ˜J˜—šž œœœ<œœœœœœ˜ΔJšœ&˜&Jšœa˜aJšœ/˜/JšœT˜TJšœ˜Jšœ5˜5Jšœ˜ Jšœ˜J˜—Jšœ œœœ˜šž œœœ*œ˜Hš œœœœœ˜5Jšœ!˜!Jšœ!˜!Jšœ˜—šœ˜Jšœœ˜Jšœœ˜Jšœœ"˜1Jšœœ˜(Jšœœ"˜1Jšœœ˜&Jšœœ œ ˜ Jšœ œ˜&Jšœ œ˜+Jšœ œ˜#Jšœ1˜1Jšœ œ˜,šž œœ˜Jšœ˜J˜ šœœœ˜Jšœ˜Jšœ˜—Jšœ˜Jšœ˜šœ˜Jšœ ˜ Jšœœœ&˜0Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜—Jšœ˜šœœœ˜J˜ Jšœ˜—Jšœ˜šœœœ#˜2J˜ Jšœ˜—Jš œœœœœ˜>Jšœ$˜$Jšœ˜—šœœœ˜Jšœ˜Jšœ˜—šœœœ˜#Jšœœœ˜5šœœœ˜#šœ˜Jšœ'˜'Jšœ ˜ Jšœ"˜"Jšœ˜—Jšœ"˜"Jšœ˜—Jšœ4˜4Jšœ˜—Jšœ˜Jšœ˜—Jšœ˜J˜—š žœœœ:œœœ˜•Jšœ*˜*JšœK˜KJšœ1˜1šœœœ)˜