DIRECTORY PrintColorXForms, PrintColor USING [ColorCorrection, CorrectionProc, ColorCorrectionRep], ImagerSample USING [PointerToSamples], ImagerPixel USING [PixelBuffer], CalibratedColor USING [RGBCalibration, XYZ, XYZFromRGB], CalibratedColorFns USING [LStarFromLuminance], Real, RealFns, Basics, FS USING [StreamOpen], IO USING [STREAM, GetCard, GetLineRope, Close, GetID], Rope USING [ROPE]; PrintColorXFormsImpl: CEDAR PROGRAM IMPORTS Real, RealFns, ImagerSample, FS, IO, CalibratedColor, CalibratedColorFns EXPORTS PrintColorXForms ~ BEGIN OPEN PrintColorXForms; ROPE: TYPE ~ Rope.ROPE; ColorCorrection: TYPE ~ PrintColor.ColorCorrection; XYZ: TYPE ~ CalibratedColor.XYZ; SWOPData: TYPE = REF SWOPDataRec; SWOPDataRec: TYPE = RECORD[gcTable, cyanTable, magentaTable, yellowTable, blackTable: TRCTable _ NIL, rgbToCMY: RGBToCMYProc, rgbToCMYData: REF _ NIL]; SWOPLinearDotArea: PUBLIC PROC RETURNS[ColorCorrection] = { maxSampleOut: NAT = 255; cc: ColorCorrection _ NEW[PrintColor.ColorCorrectionRep _ [ type: $SWOP, correctionProc: SWOPColorCorrectionProc, maxSampleIn: [255, 255, 255], samplesPerPixelOut: maxSampleOut, data: NEW[SWOPDataRec _ [ cyanTable: cyanTable, magentaTable: magentaTable, yellowTable: yellowTable, blackTable: blackTable, gcTable: IdentityTRC[], rgbToCMY: FlipRGB, rgbToCMYData: NIL ]] ]]; RETURN[cc]; }; SWOPWithGCLinearLStar: PUBLIC PROC RETURNS[ColorCorrection] = { maxSampleOut: NAT = 255; cc: ColorCorrection _ NEW[PrintColor.ColorCorrectionRep _ [ type: $SWOPLinearLStar, correctionProc: SWOPColorCorrectionProc, maxSampleIn: [255, 255, 255], samplesPerPixelOut: maxSampleOut, data: NEW[SWOPDataRec _ [ cyanTable: cyanTable, magentaTable: magentaTable, yellowTable: yellowTable, blackTable: blackTable, gcTable: convertToLStar, rgbToCMY: FlipRGB, rgbToCMYData: NIL ]] ]]; RETURN[cc]; }; SWOPWithMatrix: PUBLIC PROC[matrixTables: MatrixTables] RETURNS[ColorCorrection] = { maxSampleOut: NAT = 255; cc: ColorCorrection _ NEW[PrintColor.ColorCorrectionRep _ [ type: $SWOPWithMatrix, correctionProc: SWOPColorCorrectionProc, maxSampleIn: [255, 255, 255], samplesPerPixelOut: maxSampleOut, data: NEW[SWOPDataRec _ [ cyanTable: cyanTable, magentaTable: magentaTable, yellowTable: yellowTable, blackTable: blackTable, gcTable: convertToLStar, rgbToCMY: MatrixTransform, rgbToCMYData: matrixTables ]] ]]; RETURN[cc]; }; SWOPColorCorrectionProc: PrintColor.CorrectionProc = { c,m,y,k, gc: NAT; data: SWOPData _ NARROW[self.data]; data.rgbToCMY[maxSampleIn: self.maxSampleIn, rgbIn: rgbIn, cmyOut: pixelsOut, data: data.rgbToCMYData]; FOR i: NAT IN [0..pixelsOut.length) DO c _ pixelsOut[0][i]; m _ pixelsOut[1][i]; y _ pixelsOut[2][i]; gc _ data.gcTable[MIN[c,m,y]]; c _ MAX[0, MIN[255, c-gc+data.cyanTable[gc]]]; m _ MAX[0, MIN[255, m-gc+data.magentaTable[gc]]]; y _ MAX[0, MIN[255, y-gc+data.yellowTable[gc]]]; k _ data.blackTable[gc]; pixelsOut[0][i] _ c; pixelsOut[1][i] _ m; pixelsOut[2][i] _ y; pixelsOut[3][i] _ k; ENDLOOP; }; Largest24bitNumber: INT ~ 77777777B; BYTE: TYPE ~ [0..377B]; InitMatrixTables: PUBLIC PROC[rgbToLStar, densityToDotArea: TRCTable, printerDMax, saturation, contrast: REAL, matrix: MatrixN _ NIL] RETURNS[MatrixTables] ~ { LToDTable: PROC [matrixEl:REAL, trc:TRCTable _ NIL] RETURNS [table: MatrixEltTable] ~ { Dens24FromLStarRel : PROC [pixel:NAT] RETURNS [tableValue: INT] ~ { dens: REAL _ LStarToDens[printerLStarMin + (printerRange * (pixel / 255.0))] * matrixEl; tableValue _ Real.InlineRound[ (dens / printerDMax) * Largest24bitNumber]; }; table _ NEW[MatrixEltTableRec]; FOR i: NAT IN [0..255] DO table[i] _ Dens24FromLStarRel[trc[i]]; ENDLOOP }; blackValue:NAT = 255; printerLStarMin, printerRange: REAL; tables: MatrixTables _ NEW[MatrixTablesRec]; IF matrix=NIL THEN matrix _ IdentityMatrix[]; FOR i:NAT IN [0..2] DO -- add required saturation boost FOR j:NAT IN [0..2] DO IF i=j THEN matrix[i][j] _ matrix[i][j] + saturation*2 ELSE matrix[i][j] _ matrix[i][j] - saturation ENDLOOP; ENDLOOP; FOR i:NAT IN [0..2] DO -- add required contrast boost matrix[i][i] _ matrix[i][i] + contrast; ENDLOOP; printerLStarMin _ DensToLStar[printerDMax]; printerRange _ 100.0 - printerLStarMin; tables.m00 _ LToDTable[matrix[0][0], rgbToLStar]; tables.m10 _ LToDTable[matrix[1][0], rgbToLStar]; tables.m20 _ LToDTable[matrix[2][0], rgbToLStar]; tables.m01 _ LToDTable[matrix[0][1], rgbToLStar]; tables.m11 _ LToDTable[matrix[1][1], rgbToLStar]; tables.m21 _ LToDTable[matrix[2][1], rgbToLStar]; tables.m02 _ LToDTable[matrix[0][2], rgbToLStar]; tables.m12 _ LToDTable[matrix[1][2], rgbToLStar]; tables.m22 _ LToDTable[matrix[2][2], rgbToLStar]; tables.cyan _ densityToDotArea; tables.magenta _ densityToDotArea; tables.yellow _ densityToDotArea; RETURN [tables] }; LStarToRef: PROC [lstar: REAL] RETURNS [ref: REAL] ~ { IF lstar<8.9 THEN ref _ lstar / 903.29 ELSE { t: REAL _ (lstar+16) / 116.0; ref _ t * t * t; } }; RefToLstar: PROC [ref: REAL] RETURNS [lstar: REAL] ~ { IF ref<0.01 THEN lstar _ ref * 903.29 ELSE { lstar _ 116.0 * RealFns.Root[3, ref] - 16; } }; RefToDens: PROC [ref: REAL] RETURNS [dens: REAL] ~ { IF ref=0 THEN RETURN [Real.LargestNumber]; dens _ -RealFns.Log[10, ref] }; LStarToDens: PROC [lstar: REAL] RETURNS [dens: REAL] ~ { dens _ RefToDens[LStarToRef[lstar]]; }; DensToLStar: PROC [dens: REAL] RETURNS [lstar: REAL] ~ { lstar _ RefToLstar[DensToRef[dens]]; }; DensToRef: PROC [dens: REAL] RETURNS [ref: REAL] ~ { ref _ RealFns.Power[10, -dens]; }; FlipRGB: PUBLIC RGBToCMYProc = { --CMY _ [255,255, 255] -RGB maxRed: CARDINAL _ maxSampleIn[0]; maxGreen: CARDINAL _ maxSampleIn[1]; maxBlue: CARDINAL _ maxSampleIn[2]; FOR i: NAT IN [0..rgbIn.length) DO cmyOut[0][i] _ maxRed-rgbIn[0][i]; cmyOut[1][i] _ maxGreen-rgbIn[1][i]; cmyOut[2][i] _ maxBlue-rgbIn[2][i]; ENDLOOP; }; MatrixTransform: PUBLIC RGBToCMYProc = { tables: MatrixTables _ NARROW[data]; rPtr: LONG POINTER TO WORD _ LOOPHOLE[ImagerSample.PointerToSamples[rgbIn[0], 0, rgbIn.length]]; gPtr: LONG POINTER TO WORD _ LOOPHOLE[ImagerSample.PointerToSamples[rgbIn[1], 0, rgbIn.length]]; bPtr: LONG POINTER TO WORD _ LOOPHOLE[ImagerSample.PointerToSamples[rgbIn[2], 0, rgbIn.length]]; yPtr: LONG POINTER TO WORD _ LOOPHOLE[ImagerSample.PointerToSamples[cmyOut[2], 0, cmyOut.length]]; mPtr: LONG POINTER TO WORD _ LOOPHOLE[ImagerSample.PointerToSamples[cmyOut[1], 0, cmyOut.length]]; cPtr: LONG POINTER TO WORD _ LOOPHOLE[ImagerSample.PointerToSamples[cmyOut[0], 0, cmyOut.length]]; m00: MatrixEltTable _ tables.m00; m01: MatrixEltTable _ tables.m01; m02: MatrixEltTable _ tables.m02; m10: MatrixEltTable _ tables.m10; m11: MatrixEltTable _ tables.m11; m12: MatrixEltTable _ tables.m12; m20: MatrixEltTable _ tables.m20; m21: MatrixEltTable _ tables.m21; m22: MatrixEltTable _ tables.m22; yellow: TRCTable _ tables.yellow; magenta: TRCTable _ tables.magenta; cyan: TRCTable _ tables.cyan; FOR j: NAT IN [0..cmyOut.length) DO TRUSTED { r: CARDINAL _ rPtr^; g: CARDINAL _ gPtr^; b: CARDINAL _ bPtr^; cyan24: INT ~ MAX[ MIN[m00[r] + m01[g] + m02[b], Largest24bitNumber], 0]; mag24: INT ~ MAX[ MIN[m10[r] + m11[g] + m12[b], Largest24bitNumber], 0]; yel24: INT ~ MAX[ MIN[m20[r] + m21[g] + m22[b], Largest24bitNumber], 0]; yPtr^ _ 255-yellow[LOOPHOLE[yel24, Basics.LongNumber].hl]; mPtr^ _ 255-magenta[LOOPHOLE[mag24, Basics.LongNumber].hl]; cPtr^ _ 255-cyan[LOOPHOLE[cyan24, Basics.LongNumber].hl]; rPtr _ rPtr + 1; gPtr _ gPtr + 1; bPtr _ bPtr + 1; yPtr _ yPtr + 1; mPtr _ mPtr + 1; cPtr _ cPtr + 1; } ENDLOOP; }; ReadTRC: PUBLIC PROC [trcFn: ROPE] RETURNS [trc: TRCTable] ~ { in: IO.STREAM; in _ FS.StreamOpen[trcFn]; trc _ NEW[TRCTableRec _ ALL[0]]; [] _ in.GetID[]; FOR i:CARDINAL IN [0..255] DO index:CARDINAL; prev:CARDINAL _ index; index _ in.GetCard[]; IF index>0 AND prev+1#index THEN ERROR; prev _ index; trc[index] _ IO.GetCard[in]; [] _ in.GetLineRope[]; ENDLOOP; in.Close[]; }; IdentityTRC: PUBLIC PROC [] RETURNS [initTrc:TRCTable] ~ { initTrc _ NEW[TRCTableRec _ ALL[0]]; FOR i: NAT IN [0..255] DO initTrc[i] _ i; ENDLOOP }; RGBToLStar: PUBLIC PROC [cal: CalibratedColor.RGBCalibration] RETURNS [convertRGB:TRCTable] = { white: XYZ _ CalibratedColor.XYZFromRGB[[1,1,1], cal]; getLStar: PROC [val: REAL] RETURNS[lStar: REAL] = { --val in [0..1] xyz: XYZ _ CalibratedColor.XYZFromRGB[[val, val, val], cal]; lStar _ CalibratedColorFns.LStarFromLuminance[Y: xyz.Y, whiteY: white.Y]; }; step: REAL _ 1.0/255.0; convertRGB _ NEW[TRCTableRec]; FOR val: INT IN [0..256) DO convertRGB[val] _ Real.Round[2.55*getLStar[val*step]]; ENDLOOP; }; DensityToLStar: PUBLIC PROC [dMax: REAL] RETURNS [trc:TRCTable] ~ { minLStar: REAL _ DensToLStar[dMax]; scale: REAL _ 2.55*100.0/(100-minLStar); trc _ NEW[TRCTableRec _ ALL[0]]; FOR i: NAT IN [0..255] DO trc[i] _ Real.Round[scale*(DensToLStar[dMax*(i/255.0)]-minLStar)]; ENDLOOP }; MatrixFromValues: PUBLIC PROC[c0,m0,y0,c1,m1,y1,c2,m2,y2: REAL] RETURNS[MatrixN] = { matrix: MatrixN _ NEW[MatrixSeq[3]]; matrix[0] _ NEW[VecSeq[3]]; matrix[0][0] _ c0; matrix[0][1] _ m0; matrix[0][2] _ y0; matrix[1] _ NEW[VecSeq[3]]; matrix[1][0] _ c1; matrix[1][1] _ m1; matrix[1][2] _ y1; matrix[2] _ NEW[VecSeq[3]]; matrix[2][0] _ c2; matrix[2][1] _ m2; matrix[2][2] _ y2; RETURN[matrix]; }; IdentityMatrix: PUBLIC PROC RETURNS[MatrixN] = { RETURN[MatrixFromValues[1,0,0,0,1,0,0,0,1]]; }; BuildTables: PROC = { --use of this is odd. Run it to read the TRC's, print result and copy it into the code below. Prefer to keep result pickled in code. Data comes from measuring and processing a gray wedge produced by Kedie-Orent. cyanTable _ ReadTRC["/ivy/stone/coloroffset/SWOP-cyan.trc"]; magentaTable _ ReadTRC["/ivy/stone/coloroffset/SWOP-magenta.trc"]; yellowTable _ ReadTRC["/ivy/stone/coloroffset/SWOP-yellow.trc"]; blackTable _ ReadTRC["/ivy/stone/coloroffset/SWOP-black.trc"]; }; cyanTable: TRCTable _ NEW[TRCTableRec _ [0, 1, 3, 4, 6, 7, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 36, 37, 38, 39, 40, 42, 43, 44, 46, 47, 48, 50, 51, 52, 54, 55, 57, 58, 59, 61, 62, 63, 65, 66, 67, 69, 70, 72, 73, 75, 76, 77, 79, 80, 82, 83, 85, 86, 87, 89, 90, 92, 93, 95, 96, 97, 98, 99, 100, 101, 102, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 172, 173, 174, 175, 175, 176, 177, 178, 178, 179, 180, 181, 181, 182, 183, 184, 184, 185, 186, 187, 187, 188, 189, 190, 190, 191, 192, 193, 193, 194, 195, 196, 196, 197, 198, 199, 199, 200, 201, 202, 202, 203, 204, 204, 205, 205, 206, 206, 207, 207, 208, 208, 209, 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216, 216, 217, 217, 218, 218, 219, 219, 219, 220, 220, 221, 221, 221, 222, 222, 223, 223, 223, 224, 224, 225, 225, 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 234, 235]]; magentaTable: TRCTable _ NEW[TRCTableRec _ [0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 52, 53, 54, 55, 56, 58, 59, 60, 61, 62, 63, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 79, 80, 81, 82, 83, 84, 84, 85, 86, 87, 88, 88, 89, 90, 91, 92, 92, 93, 94, 95, 96, 97, 97, 98, 99, 100, 101, 102, 102, 103, 104, 105, 106, 107, 108, 108, 109, 110, 111, 112, 113, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 138, 139, 140, 141, 141, 142, 143, 144, 144, 145, 146, 147, 147, 148, 149, 150, 150, 151, 152, 153, 153, 154, 155, 155, 156, 157, 157, 158, 159, 159, 160, 160, 161, 162, 162, 163, 164, 164, 165, 166, 166, 167, 168, 168, 169, 169, 170, 170, 171, 171, 172, 172, 173, 173, 174, 174, 175, 175, 176, 176, 177, 177, 178, 178, 179, 179, 180, 180, 181, 182, 182, 183, 183, 184, 184, 185, 185, 186, 186, 187, 187, 188, 188, 189, 189, 190, 190, 191, 191, 192, 192, 193, 193, 194, 195, 195, 196, 196, 197, 197, 198, 198, 199, 199, 200, 200, 201]]; yellowTable: TRCTable _ NEW[TRCTableRec _ [0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 62, 63, 64, 65, 66, 67, 69, 70, 71, 72, 73, 75, 76, 77, 78, 79, 80, 81, 82, 83, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98, 99, 100, 101, 102, 103, 103, 104, 105, 106, 107, 107, 108, 109, 110, 111, 112, 112, 113, 114, 115, 116, 116, 117, 118, 119, 120, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 143, 144, 145, 145, 146, 147, 147, 148, 149, 149, 150, 151, 151, 152, 153, 153, 154, 155, 155, 156, 157, 157, 158, 158, 159, 160, 160, 161, 161, 162, 163, 163, 164, 165, 165, 166, 166, 167, 168, 168, 169, 169, 170, 170, 171, 171, 172, 172, 172, 173, 173, 174, 174, 174, 175, 175, 176, 176, 177, 177, 177, 178, 178, 179, 179, 179, 180, 180, 181, 181, 181, 182, 182, 183, 183, 183, 184, 184, 185, 185, 185, 186, 186, 187, 187, 187, 188, 188, 189, 189, 189, 190, 190, 191, 191, 192, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 198, 199]]; blackTable: TRCTable _ NEW[TRCTableRec _ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17, 17, 18, 18, 19, 20, 20, 21, 22, 22, 23, 24, 24, 25, 26, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 134, 135, 136, 137, 138, 139, 140, 142, 144, 146, 147, 149, 151, 153, 155, 157, 158, 160, 162, 164]]; convertToLStar: TRCTable _ NEW[TRCTableRec _ [0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 43, 44, 45, 46, 47, 48, 49, 49, 50, 51, 52, 53, 53, 54, 55, 56, 56, 57, 58, 59, 59, 60, 61, 61, 62, 63, 63, 64, 65, 65, 66, 67, 67, 68, 68, 69, 70, 70, 71, 71, 72, 72, 73, 74, 75, 76, 77, 79, 80, 81, 82, 83, 84, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 116, 117, 118, 119, 120, 121, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 137, 138, 139, 140, 141, 141, 142, 143, 144, 144, 145, 146, 147, 148, 150, 151, 152, 154, 155, 156, 158, 159, 160, 162, 163, 164, 165, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 214, 216, 218, 221, 224, 228, 231, 234, 236, 239, 241, 243, 245, 247, 248, 250, 251, 253, 254, 255]]; END. ÜPrintColorXFormsImpl.mesa Copyright Ó 1987 by Xerox Corporation. All rights reserved. Maureen Stone, July 27, 1989 12:59:11 pm PDT Color Transformation routines for printing monitor images SWOP Transformation SWOP Standard GCR and black RGB Transformations -- table values range from -LAST[INT]...LAST[INT] -- representation for printerDMax = Largest24bitNumber -- trc=NIL means that no mapping is to be performed. i.e. inputs are density coded Utility Procedures Ê ç˜code•Mark outsideHeaderšœ™Kšœ<™šœœœ˜Kšœ/˜2Kšœ˜—šœœœ˜Kšœ/˜2K˜—šœœœ˜Kšœ/˜2K˜—Kšœœ˜:Kšœœ˜;Kšœœ ˜9Kšœ2˜2Kšœ3˜3Kšœœ˜ —K˜—K˜—™š œ œ œœ˜>Jšœœ˜Kšœœ˜Jšœœœ˜ J˜šœœœ ˜Jšœœ˜Jšœœ ˜Jšœ˜Jšœ œœœ˜'J˜ Jšœ œ ˜Jšœ˜Jšœ˜—J˜ J˜J˜—šŸ¡œ œœ˜:Jšœ œœ˜$šœœœ ˜Jšœ˜Jš˜—J˜—š¡ œœœ'œ˜_Kšœœ,˜6š œ œœœœ£˜CKšœœ5˜=KšœJ˜JK˜—Kšœœ ˜Kšœ œ˜šœœœ œ˜Kšœ6˜6Kšœ˜—J˜—š ¡œœœœœ˜CJšœ œ˜#Jšœœ˜(Jšœœœ˜ šœœœ ˜JšœC˜CJš˜—J˜—š œ œœœ ˜TJšœœ˜$Jšœ œ ˜Jšœ˜Jšœ˜Jšœ˜Jšœ œ ˜Jšœ˜Jšœ˜Jšœ˜Jšœ œ ˜Jšœ˜Jšœ˜Jšœ˜Jšœ ˜J˜—š œ œœ ˜0Jšœ&˜,J˜—J˜š  œœ£Ö˜ìKšœ<˜˜>J˜——˜šœœ˜'Jšœ® ˜® —šœœ˜*Jšœ‹ ˜‹ —šœœ˜)Jšœ“ ˜“ —šœœ˜(JšœÕ˜Õ—šœœ˜,Jšœä˜ä——Kšœ˜—…—=&Ké