From 7e795e28910d5e58ffd798ba2283c5e3ef289b37 Mon Sep 17 00:00:00 2001 From: Benjamin Cizdziel Date: Wed, 8 Apr 2015 19:45:39 -0700 Subject: [PATCH] TvSpectrumTransmitter classes to create television transmitter(s) that transmit PSD spectrums customized by attributes such as modulation type, power, antenna type, channel frequency, etc. --- doc/models/Makefile | 3 + .../doc/spectrum-tv-rand-geo-points.eps | 5740 +++++++++++++++++ src/spectrum/doc/spectrum.rst | 165 + src/spectrum/examples/tv-trans-example.cc | 110 + .../examples/tv-trans-regional-example.cc | 111 + src/spectrum/examples/wscript | 6 + .../helper/tv-spectrum-transmitter-helper.cc | 448 ++ .../helper/tv-spectrum-transmitter-helper.h | 328 + src/spectrum/model/tv-spectrum-transmitter.cc | 591 ++ src/spectrum/model/tv-spectrum-transmitter.h | 153 + .../test/tv-helper-distribution-test.cc | 142 + .../test/tv-spectrum-transmitter-test.cc | 205 + src/spectrum/wscript | 6 + 13 files changed, 8008 insertions(+) create mode 100644 src/spectrum/doc/spectrum-tv-rand-geo-points.eps create mode 100644 src/spectrum/examples/tv-trans-example.cc create mode 100644 src/spectrum/examples/tv-trans-regional-example.cc create mode 100644 src/spectrum/helper/tv-spectrum-transmitter-helper.cc create mode 100644 src/spectrum/helper/tv-spectrum-transmitter-helper.h create mode 100644 src/spectrum/model/tv-spectrum-transmitter.cc create mode 100644 src/spectrum/model/tv-spectrum-transmitter.h create mode 100644 src/spectrum/test/tv-helper-distribution-test.cc create mode 100644 src/spectrum/test/tv-spectrum-transmitter-test.cc diff --git a/doc/models/Makefile b/doc/models/Makefile index 5049368af..17405857b 100644 --- a/doc/models/Makefile +++ b/doc/models/Makefile @@ -250,6 +250,9 @@ SOURCEFIGS = \ $(SRC)/spectrum/doc/spectrum-channel-phy-interface.png \ $(SRC)/spectrum/doc/spectrum-channel-phy-interface.pdf \ $(SRC)/spectrum/doc/spectrum-analyzer-example.eps \ + $(SRC)/spectrum/doc/spectrum-tv-rand-geo-points.eps \ + $(SRC)/spectrum/doc/spectrum-tv-8vsb.png \ + $(SRC)/spectrum/doc/spectrum-tv-cofdm.png \ $(SRC)/lr-wpan/doc/lr-wpan-arch.dia \ $(SRC)/lr-wpan/doc/lr-wpan-data-example.dia \ $(SRC)/lr-wpan/doc/lr-wpan-primitives.dia \ diff --git a/src/spectrum/doc/spectrum-tv-rand-geo-points.eps b/src/spectrum/doc/spectrum-tv-rand-geo-points.eps new file mode 100644 index 000000000..933161066 --- /dev/null +++ b/src/spectrum/doc/spectrum-tv-rand-geo-points.eps @@ -0,0 +1,5740 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: MATLAB, The MathWorks, Inc. Version 8.3.0.532 (R2014a). Operating System: Microsoft Windows 8.1 Pro. +%%Title: C:\Users\Ben\Dropbox\FUNLAB\ns-3 TV Transmitter\randGeoPoints_35lat_260long_100pts_2000kmRad.eps +%%CreationDate: 12/06/2014 19:20:57 +%%DocumentNeededFonts: Helvetica +%%DocumentProcessColors: Cyan Magenta Yellow Black +%%LanguageLevel: 2 +%%Pages: 1 +%%BoundingBox: 96 238 515 553 +%%EndComments + +%%BeginProlog +% MathWorks dictionary +/MathWorks 160 dict begin +% definition operators +/bdef {bind def} bind def +/ldef {load def} bind def +/xdef {exch def} bdef +/xstore {exch store} bdef +% operator abbreviations +/c /clip ldef +/cc /concat ldef +/cp /closepath ldef +/gr /grestore ldef +/gs /gsave ldef +/mt /moveto ldef +/np /newpath ldef +/cm /currentmatrix ldef +/sm /setmatrix ldef +/rm /rmoveto ldef +/rl /rlineto ldef +/s {show newpath} bdef +/sc {setcmykcolor} bdef +/sr /setrgbcolor ldef +/sg /setgray ldef +/w /setlinewidth ldef +/j /setlinejoin ldef +/cap /setlinecap ldef +/rc {rectclip} bdef +/rf {rectfill} bdef +% page state control +/pgsv () def +/bpage {/pgsv save def} bdef +/epage {pgsv restore} bdef +/bplot /gsave ldef +/eplot {stroke grestore} bdef +% orientation switch +/portraitMode 0 def /landscapeMode 1 def /rotateMode 2 def +% coordinate system mappings +/dpi2point 0 def +% font control +/FontSize 0 def +/FMS {/FontSize xstore findfont [FontSize 0 0 FontSize neg 0 0] + makefont setfont} bdef +/ISOLatin1Encoding where {pop /WindowsLatin1Encoding 256 array bdef +ISOLatin1Encoding WindowsLatin1Encoding copy pop +/.notdef/.notdef/quotesinglbase/florin/quotedblbase/ellipsis/dagger +/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE/.notdef/.notdef +/.notdef/.notdef/quoteleft/quoteright/quotedblleft/quotedblright/bullet +/endash/emdash/tilde/trademark/scaron/guilsinglright/oe/.notdef/.notdef +/Ydieresis WindowsLatin1Encoding 128 32 getinterval astore pop} +{/WindowsLatin1Encoding StandardEncoding bdef} ifelse +/reencode {exch dup where {pop load} {pop StandardEncoding} ifelse + exch dup 3 1 roll findfont dup length dict begin + { 1 index /FID ne {def}{pop pop} ifelse } forall + /Encoding exch def currentdict end definefont pop} bdef +/isroman {findfont /CharStrings get /Agrave known} bdef +/FMSR {3 1 roll 1 index dup isroman {reencode} {pop pop} ifelse + exch FMS} bdef +/csm {1 dpi2point div -1 dpi2point div scale neg translate + dup landscapeMode eq {pop -90 rotate} + {rotateMode eq {90 rotate} if} ifelse} bdef +% line types: solid, dotted, dashed, dotdash +/SO { [] 0 setdash } bdef +/DO { [.5 dpi2point mul 4 dpi2point mul] 0 setdash } bdef +/DA { [6 dpi2point mul] 0 setdash } bdef +/DD { [.5 dpi2point mul 4 dpi2point mul 6 dpi2point mul 4 + dpi2point mul] 0 setdash } bdef +% macros for lines and objects +/L {lineto stroke} bdef +/MP {3 1 roll moveto 1 sub {rlineto} repeat} bdef +/AP {{rlineto} repeat} bdef +/PDlw -1 def +/W {/PDlw currentlinewidth def setlinewidth} def +/PP {closepath eofill} bdef +/DP {closepath stroke} bdef +/MR {4 -2 roll moveto dup 0 exch rlineto exch 0 rlineto + neg 0 exch rlineto closepath} bdef +/FR {MR stroke} bdef +/PR {MR fill} bdef +/L1i {{currentfile picstr readhexstring pop} image} bdef +/tMatrix matrix def +/MakeOval {newpath tMatrix currentmatrix pop translate scale +0 0 1 0 360 arc tMatrix setmatrix} bdef +/FO {MakeOval stroke} bdef +/PO {MakeOval fill} bdef +/PD {currentlinewidth 2 div 0 360 arc fill + PDlw -1 eq not {PDlw w /PDlw -1 def} if} def +/FA {newpath tMatrix currentmatrix pop translate scale + 0 0 1 5 -2 roll arc tMatrix setmatrix stroke} bdef +/PA {newpath tMatrix currentmatrix pop translate 0 0 moveto scale + 0 0 1 5 -2 roll arc closepath tMatrix setmatrix fill} bdef +/FAn {newpath tMatrix currentmatrix pop translate scale + 0 0 1 5 -2 roll arcn tMatrix setmatrix stroke} bdef +/PAn {newpath tMatrix currentmatrix pop translate 0 0 moveto scale + 0 0 1 5 -2 roll arcn closepath tMatrix setmatrix fill} bdef +/vradius 0 def /hradius 0 def /lry 0 def +/lrx 0 def /uly 0 def /ulx 0 def /rad 0 def +/MRR {/vradius xdef /hradius xdef /lry xdef /lrx xdef /uly xdef + /ulx xdef newpath tMatrix currentmatrix pop ulx hradius add uly + vradius add translate hradius vradius scale 0 0 1 180 270 arc + tMatrix setmatrix lrx hradius sub uly vradius add translate + hradius vradius scale 0 0 1 270 360 arc tMatrix setmatrix + lrx hradius sub lry vradius sub translate hradius vradius scale + 0 0 1 0 90 arc tMatrix setmatrix ulx hradius add lry vradius sub + translate hradius vradius scale 0 0 1 90 180 arc tMatrix setmatrix + closepath} bdef +/FRR {MRR stroke } bdef +/PRR {MRR fill } bdef +/MlrRR {/lry xdef /lrx xdef /uly xdef /ulx xdef /rad lry uly sub 2 div def + newpath tMatrix currentmatrix pop ulx rad add uly rad add translate + rad rad scale 0 0 1 90 270 arc tMatrix setmatrix lrx rad sub lry rad + sub translate rad rad scale 0 0 1 270 90 arc tMatrix setmatrix + closepath} bdef +/FlrRR {MlrRR stroke } bdef +/PlrRR {MlrRR fill } bdef +/MtbRR {/lry xdef /lrx xdef /uly xdef /ulx xdef /rad lrx ulx sub 2 div def + newpath tMatrix currentmatrix pop ulx rad add uly rad add translate + rad rad scale 0 0 1 180 360 arc tMatrix setmatrix lrx rad sub lry rad + sub translate rad rad scale 0 0 1 0 180 arc tMatrix setmatrix + closepath} bdef +/FtbRR {MtbRR stroke } bdef +/PtbRR {MtbRR fill } bdef +/stri 6 array def /dtri 6 array def +/smat 6 array def /dmat 6 array def +/tmat1 6 array def /tmat2 6 array def /dif 3 array def +/asub {/ind2 exch def /ind1 exch def dup dup + ind1 get exch ind2 get sub exch } bdef +/tri_to_matrix { + 2 0 asub 3 1 asub 4 0 asub 5 1 asub + dup 0 get exch 1 get 7 -1 roll astore } bdef +/compute_transform { + dmat dtri tri_to_matrix tmat1 invertmatrix + smat stri tri_to_matrix tmat2 concatmatrix } bdef +/ds {stri astore pop} bdef +/dt {dtri astore pop} bdef +/db {2 copy /cols xdef /rows xdef mul dup 3 mul string + currentfile + 3 index 0 eq {/ASCIIHexDecode filter} + {/ASCII85Decode filter 3 index 2 eq {/RunLengthDecode filter} if } + ifelse exch readstring pop + dup 0 3 index getinterval /rbmap xdef + dup 2 index dup getinterval /gbmap xdef + 1 index dup 2 mul exch getinterval /bbmap xdef pop pop}bdef +/it {gs np dtri aload pop moveto lineto lineto cp c + cols rows 8 compute_transform + rbmap gbmap bbmap true 3 colorimage gr}bdef +/il {newpath moveto lineto stroke}bdef +currentdict end def +%%EndProlog + +%%BeginSetup +MathWorks begin + +0 cap + +end +%%EndSetup + +%%Page: 1 1 +%%BeginPageSetup +%%PageBoundingBox: 96 238 515 553 +MathWorks begin +bpage +%%EndPageSetup + +%%BeginObject: obj1 +bplot + +/dpi2point 12 def +portraitMode 1152 6636 csm + + 0 0 5039 3780 rc +85 dict begin %Colortable dictionary +/c0 { 0.000000 0.000000 0.000000 sr} bdef +/c1 { 1.000000 1.000000 1.000000 sr} bdef +/c2 { 0.900000 0.000000 0.000000 sr} bdef +/c3 { 0.000000 0.820000 0.000000 sr} bdef +/c4 { 0.000000 0.000000 0.800000 sr} bdef +/c5 { 0.910000 0.820000 0.320000 sr} bdef +/c6 { 1.000000 0.260000 0.820000 sr} bdef +/c7 { 0.000000 0.820000 0.820000 sr} bdef +c0 +1 j +1 sg + 0 0 5040 3781 rf +6 w +-818 350 3052 94 817 -350 655 3211 4 MP +PP +-3051 -94 -818 350 3052 94 817 -350 655 3211 5 MP stroke +0 2578 817 -349 0 -2579 655 3211 4 MP +PP +-817 350 0 2578 817 -349 0 -2579 655 3211 5 MP stroke +0 2579 3052 93 0 -2578 1472 2861 4 MP +PP +-3052 -94 0 2579 3052 93 0 -2578 1472 2861 5 MP stroke +4 w +DO +SO +6 w +0 sg + 655 3211 mt 3706 3305 L +3706 3305 mt 4524 2955 L + 655 3211 mt 655 632 L + 655 3211 mt 584 3241 L +%%IncludeResource: font Helvetica +/Helvetica /WindowsLatin1Encoding 120 FMSR + + 417 3365 mt +(-8) s +1036 3222 mt 966 3252 L + 798 3377 mt +(-6) s +1417 3234 mt 1347 3264 L +1179 3389 mt +(-4) s +1799 3246 mt 1729 3276 L +1561 3401 mt +(-2) s +2180 3258 mt 2110 3288 L +2012 3412 mt +(0) s +2562 3269 mt 2491 3299 L +2394 3424 mt +(2) s +2943 3281 mt 2873 3311 L +2775 3436 mt +(4) s +3324 3293 mt 3254 3323 L +3156 3447 mt +(6) s +3706 3305 mt 3636 3335 L +3538 3459 mt +(8) s + 935 3748 mt +(x 10) s +%%IncludeResource: font Helvetica +/Helvetica /WindowsLatin1Encoding 80 FMSR + +1161 3674 mt +(6) s +3706 3305 mt 3782 3307 L +%%IncludeResource: font Helvetica +/Helvetica /WindowsLatin1Encoding 120 FMSR + +3817 3419 mt +(-1) s +4115 3130 mt 4191 3132 L +4226 3244 mt +(0) s +4524 2955 mt 4600 2957 L +4634 3069 mt +(1) s +4764 3447 mt +(x 10) s +%%IncludeResource: font Helvetica +/Helvetica /WindowsLatin1Encoding 80 FMSR + +4990 3373 mt +(7) s + 655 3211 mt 578 3208 L +%%IncludeResource: font Helvetica +/Helvetica /WindowsLatin1Encoding 120 FMSR + + 408 3251 mt +(-8) s + 655 2888 mt 578 2886 L + 408 2929 mt +(-6) s + 655 2566 mt 578 2564 L + 408 2607 mt +(-4) s + 655 2244 mt 578 2242 L + 408 2284 mt +(-2) s + 655 1922 mt 578 1919 L + 478 1962 mt +(0) s + 655 1599 mt 578 1597 L + 478 1640 mt +(2) s + 655 1277 mt 578 1275 L + 478 1318 mt +(4) s + 655 955 mt 578 952 L + 478 995 mt +(6) s + 655 632 mt 578 630 L + 478 673 mt +(8) s + 655 362 mt +(x 10) s +%%IncludeResource: font Helvetica +/Helvetica /WindowsLatin1Encoding 80 FMSR + + 881 288 mt +(6) s +gs 655 283 3870 3023 rc +/c8 { 0.562500 1.000000 0.437500 sr} bdef +c8 +-14 -160 -100 -37 3825 1795 3 MP +PP +0 sg +3825 1795 mt 3725 1758 L +3725 1758 mt 3711 1598 L +/c9 { 0.187500 1.000000 0.812500 sr} bdef +c9 +-100 -37 15 -160 3810 1955 3 MP +PP +0 sg +3810 1955 mt 3825 1795 L +3825 1795 mt 3725 1758 L +c8 +-99 -36 -15 -161 3825 1795 3 MP +PP +0 sg +3825 1795 mt 3810 1634 L +3810 1634 mt 3711 1598 L +c8 +-15 -161 21 -36 3804 1831 3 MP +PP +0 sg +3804 1831 mt 3825 1795 L +3825 1795 mt 3810 1634 L +c9 +14 -161 -99 -36 3810 1955 3 MP +PP +0 sg +3810 1955 mt 3711 1919 L +3711 1919 mt 3725 1758 L +/c10 { 0.000000 0.937500 1.000000 sr} bdef +c10 +-99 -36 45 -157 3765 2112 3 MP +PP +0 sg +3765 2112 mt 3810 1955 L +3810 1955 mt 3711 1919 L +c9 +15 -160 21 -36 3789 1991 3 MP +PP +0 sg +3789 1991 mt 3810 1955 L +3810 1955 mt 3825 1795 L +c9 +21 -36 15 -160 3789 1991 3 MP +PP +0 sg +3789 1991 mt 3804 1831 L +3804 1831 mt 3825 1795 L +/c11 { 0.000000 0.625000 1.000000 sr} bdef +c11 +-96 -35 75 -149 3690 2261 3 MP +PP +0 sg +3690 2261 mt 3765 2112 L +3765 2112 mt 3669 2077 L +c10 +42 -158 -96 -35 3765 2112 3 MP +PP +0 sg +3765 2112 mt 3669 2077 L +3669 2077 mt 3711 1919 L +c10 +45 -157 20 -34 3745 2146 3 MP +PP +0 sg +3745 2146 mt 3765 2112 L +3765 2112 mt 3810 1955 L +/c12 { 0.875000 1.000000 0.125000 sr} bdef +c12 +-42 -155 -99 -36 3810 1634 3 MP +PP +0 sg +3810 1634 mt 3711 1598 L +3711 1598 mt 3669 1443 L +c10 +21 -36 44 -155 3745 2146 3 MP +PP +0 sg +3745 2146 mt 3789 1991 L +3789 1991 mt 3810 1955 L +c8 +21 -36 -15 -161 3804 1831 3 MP +PP +0 sg +3804 1831 mt 3789 1670 L +3789 1670 mt 3810 1634 L +c12 +-96 -34 -45 -157 3810 1634 3 MP +PP +0 sg +3810 1634 mt 3765 1477 L +3765 1477 mt 3669 1443 L +c12 +-45 -157 21 -36 3789 1670 3 MP +PP +0 sg +3789 1670 mt 3810 1634 L +3810 1634 mt 3765 1477 L +c10 +-209 -32 42 -158 3669 2077 3 MP +PP +0 sg +3669 2077 mt 3711 1919 L +3711 1919 mt 3502 1887 L +c9 +15 -160 138 -32 3651 2023 3 MP +PP +0 sg +3651 2023 mt 3789 1991 L +3789 1991 mt 3804 1831 L +c9 +12 -162 -209 -32 3711 1919 3 MP +PP +0 sg +3711 1919 mt 3502 1887 L +3502 1887 mt 3514 1725 L +c9 +-211 -33 14 -161 3711 1919 3 MP +PP +0 sg +3711 1919 mt 3725 1758 L +3725 1758 mt 3514 1725 L +c9 +140 -32 13 -160 3651 2023 3 MP +PP +0 sg +3651 2023 mt 3664 1863 L +3664 1863 mt 3804 1831 L +c8 +-15 -161 140 -32 3664 1863 3 MP +PP +0 sg +3664 1863 mt 3804 1831 L +3804 1831 mt 3789 1670 L +c8 +-209 -33 -14 -160 3725 1758 3 MP +PP +0 sg +3725 1758 mt 3711 1598 L +3711 1598 mt 3502 1565 L +c8 +-12 -160 -211 -33 3725 1758 3 MP +PP +0 sg +3725 1758 mt 3514 1725 L +3514 1725 mt 3502 1565 L +c8 +138 -32 -13 -161 3664 1863 3 MP +PP +0 sg +3664 1863 mt 3651 1702 L +3651 1702 mt 3789 1670 L +c10 +33 -159 -200 -31 3669 2077 3 MP +PP +0 sg +3669 2077 mt 3469 2046 L +3469 2046 mt 3502 1887 L +c11 +-200 -31 68 -151 3601 2228 3 MP +PP +0 sg +3601 2228 mt 3669 2077 L +3669 2077 mt 3469 2046 L +c11 +68 -151 -89 -33 3690 2261 3 MP +PP +0 sg +3690 2261 mt 3601 2228 L +3601 2228 mt 3669 2077 L +c10 +138 -32 40 -154 3611 2177 3 MP +PP +0 sg +3611 2177 mt 3651 2023 L +3651 2023 mt 3789 1991 L +c10 +44 -155 134 -31 3611 2177 3 MP +PP +0 sg +3611 2177 mt 3745 2146 L +3745 2146 mt 3789 1991 L +c12 +20 -35 -44 -158 3789 1670 3 MP +PP +0 sg +3789 1670 mt 3745 1512 L +3745 1512 mt 3765 1477 L +c12 +-200 -32 -42 -155 3711 1598 3 MP +PP +0 sg +3711 1598 mt 3669 1443 L +3669 1443 mt 3469 1411 L +c12 +-33 -154 -209 -33 3711 1598 3 MP +PP +0 sg +3711 1598 mt 3502 1565 L +3502 1565 mt 3469 1411 L +c12 +-44 -158 138 -32 3651 1702 3 MP +PP +0 sg +3651 1702 mt 3789 1670 L +3789 1670 mt 3745 1512 L +/c13 { 1.000000 0.875000 0.000000 sr} bdef +c13 +-68 -147 -96 -34 3765 1477 3 MP +PP +0 sg +3765 1477 mt 3669 1443 L +3669 1443 mt 3601 1296 L +c13 +-89 -32 -75 -149 3765 1477 3 MP +PP +0 sg +3765 1477 mt 3690 1328 L +3690 1328 mt 3601 1296 L +/c14 { 0.000000 0.375000 1.000000 sr} bdef +c14 +-89 -33 101 -137 3589 2398 3 MP +PP +0 sg +3589 2398 mt 3690 2261 L +3690 2261 mt 3601 2228 L +c14 +18 -32 100 -134 3572 2427 3 MP +PP +0 sg +3572 2427 mt 3672 2293 L +3672 2293 mt 3690 2261 L +c14 +101 -137 17 -29 3572 2427 3 MP +PP +0 sg +3572 2427 mt 3589 2398 L +3589 2398 mt 3690 2261 L +c11 +20 -34 73 -147 3672 2293 3 MP +PP +0 sg +3672 2293 mt 3745 2146 L +3745 2146 mt 3765 2112 L +c11 +75 -149 18 -32 3672 2293 3 MP +PP +0 sg +3672 2293 mt 3690 2261 L +3690 2261 mt 3765 2112 L +c13 +-75 -149 20 -35 3745 1512 3 MP +PP +0 sg +3745 1512 mt 3765 1477 L +3765 1477 mt 3690 1328 L +c14 +93 -140 -81 -30 3589 2398 3 MP +PP +0 sg +3589 2398 mt 3508 2368 L +3508 2368 mt 3601 2228 L +c11 +73 -147 125 -29 3547 2322 3 MP +PP +0 sg +3547 2322 mt 3672 2293 L +3672 2293 mt 3745 2146 L +c13 +18 -33 -73 -151 3745 1512 3 MP +PP +0 sg +3745 1512 mt 3672 1361 L +3672 1361 mt 3690 1328 L +c14 +-188 -29 93 -140 3508 2368 3 MP +PP +0 sg +3508 2368 mt 3601 2228 L +3601 2228 mt 3413 2199 L +c11 +56 -153 -188 -29 3601 2228 3 MP +PP +0 sg +3601 2228 mt 3413 2199 L +3413 2199 mt 3469 2046 L +c11 +134 -31 64 -145 3547 2322 3 MP +PP +0 sg +3547 2322 mt 3611 2177 L +3611 2177 mt 3745 2146 L +c12 +134 -31 -40 -159 3651 1702 3 MP +PP +0 sg +3651 1702 mt 3611 1543 L +3611 1543 mt 3745 1512 L +c13 +-56 -144 -200 -32 3669 1443 3 MP +PP +0 sg +3669 1443 mt 3469 1411 L +3469 1411 mt 3413 1267 L +c13 +-188 -29 -68 -147 3669 1443 3 MP +PP +0 sg +3669 1443 mt 3601 1296 L +3601 1296 mt 3413 1267 L +c13 +-73 -151 134 -31 3611 1543 3 MP +PP +0 sg +3611 1543 mt 3745 1512 L +3745 1512 mt 3672 1361 L +/c15 { 1.000000 0.562500 0.000000 sr} bdef +c15 +-81 -30 -101 -137 3690 1328 3 MP +PP +0 sg +3690 1328 mt 3589 1191 L +3589 1191 mt 3508 1161 L +c15 +-93 -135 -89 -32 3690 1328 3 MP +PP +0 sg +3690 1328 mt 3601 1296 L +3601 1296 mt 3508 1161 L +c15 +-101 -137 18 -33 3672 1361 3 MP +PP +0 sg +3672 1361 mt 3690 1328 L +3690 1328 mt 3589 1191 L +/c16 { 0.000000 0.125000 1.000000 sr} bdef +c16 +116 -126 -71 -26 3463 2520 3 MP +PP +0 sg +3463 2520 mt 3392 2494 L +3392 2494 mt 3508 2368 L +c16 +-81 -30 126 -122 3463 2520 3 MP +PP +0 sg +3463 2520 mt 3589 2398 L +3589 2398 mt 3508 2368 L +c14 +125 -29 88 -132 3459 2454 3 MP +PP +0 sg +3459 2454 mt 3547 2322 L +3547 2322 mt 3672 2293 L +c13 +125 -29 -64 -153 3611 1543 3 MP +PP +0 sg +3611 1543 mt 3547 1390 L +3547 1390 mt 3672 1361 L +c15 +-76 -132 -188 -29 3601 1296 3 MP +PP +0 sg +3601 1296 mt 3413 1267 L +3413 1267 mt 3337 1135 L +c15 +-171 -26 -93 -135 3601 1296 3 MP +PP +0 sg +3601 1296 mt 3508 1161 L +3508 1161 mt 3337 1135 L +c15 +-100 -141 125 -29 3547 1390 3 MP +PP +0 sg +3547 1390 mt 3672 1361 L +3672 1361 mt 3572 1220 L +c15 +17 -29 -100 -141 3672 1361 3 MP +PP +0 sg +3672 1361 mt 3572 1220 L +3572 1220 mt 3589 1191 L +c16 +126 -122 15 -26 3448 2546 3 MP +PP +0 sg +3448 2546 mt 3463 2520 L +3463 2520 mt 3589 2398 L +c16 +17 -29 124 -119 3448 2546 3 MP +PP +0 sg +3448 2546 mt 3572 2427 L +3572 2427 mt 3589 2398 L +c14 +100 -134 113 -27 3459 2454 3 MP +PP +0 sg +3459 2454 mt 3572 2427 L +3572 2427 mt 3672 2293 L +c11 +-287 -25 56 -153 3413 2199 3 MP +PP +0 sg +3413 2199 mt 3469 2046 L +3469 2046 mt 3182 2021 L +c10 +22 -160 -287 -25 3469 2046 3 MP +PP +0 sg +3469 2046 mt 3182 2021 L +3182 2021 mt 3204 1861 L +c10 +-298 -26 33 -159 3469 2046 3 MP +PP +0 sg +3469 2046 mt 3502 1887 L +3502 1887 mt 3204 1861 L +c9 +13 -160 242 -26 3409 2049 3 MP +PP +0 sg +3409 2049 mt 3651 2023 L +3651 2023 mt 3664 1863 L +c9 +8 -162 -298 -26 3502 1887 3 MP +PP +0 sg +3502 1887 mt 3204 1861 L +3204 1861 mt 3212 1699 L +c9 +-302 -26 12 -162 3502 1887 3 MP +PP +0 sg +3502 1887 mt 3514 1725 L +3514 1725 mt 3212 1699 L +c9 +245 -26 10 -160 3409 2049 3 MP +PP +0 sg +3409 2049 mt 3419 1889 L +3419 1889 mt 3664 1863 L +c8 +-13 -161 245 -26 3419 1889 3 MP +PP +0 sg +3419 1889 mt 3664 1863 L +3664 1863 mt 3651 1702 L +c14 +-269 -24 76 -143 3337 2342 3 MP +PP +0 sg +3337 2342 mt 3413 2199 L +3413 2199 mt 3144 2175 L +c11 +38 -154 -269 -24 3413 2199 3 MP +PP +0 sg +3413 2199 mt 3144 2175 L +3144 2175 mt 3182 2021 L +c10 +242 -26 31 -153 3378 2202 3 MP +PP +0 sg +3378 2202 mt 3409 2049 L +3409 2049 mt 3651 2023 L +c8 +-298 -25 -12 -160 3514 1725 3 MP +PP +0 sg +3514 1725 mt 3502 1565 L +3502 1565 mt 3204 1540 L +c8 +-8 -159 -302 -26 3514 1725 3 MP +PP +0 sg +3514 1725 mt 3212 1699 L +3212 1699 mt 3204 1540 L +c8 +242 -25 -10 -162 3419 1889 3 MP +PP +0 sg +3419 1889 mt 3409 1727 L +3409 1727 mt 3651 1702 L +c12 +-40 -159 242 -25 3409 1727 3 MP +PP +0 sg +3409 1727 mt 3651 1702 L +3651 1702 mt 3611 1543 L +c10 +40 -154 233 -25 3378 2202 3 MP +PP +0 sg +3378 2202 mt 3611 2177 L +3611 2177 mt 3651 2023 L +c14 +51 -145 -244 -22 3337 2342 3 MP +PP +0 sg +3337 2342 mt 3093 2320 L +3093 2320 mt 3144 2175 L +c16 +-244 -22 94 -129 3243 2471 3 MP +PP +0 sg +3243 2471 mt 3337 2342 L +3337 2342 mt 3093 2320 L +c14 +76 -143 -171 -26 3508 2368 3 MP +PP +0 sg +3508 2368 mt 3337 2342 L +3337 2342 mt 3413 2199 L +c11 +233 -25 50 -143 3328 2345 3 MP +PP +0 sg +3328 2345 mt 3378 2202 L +3378 2202 mt 3611 2177 L +c16 +94 -129 -149 -23 3392 2494 3 MP +PP +0 sg +3392 2494 mt 3243 2471 L +3243 2471 mt 3337 2342 L +c16 +-171 -26 116 -126 3392 2494 3 MP +PP +0 sg +3392 2494 mt 3508 2368 L +3508 2368 mt 3337 2342 L +c11 +64 -145 219 -23 3328 2345 3 MP +PP +0 sg +3328 2345 mt 3547 2322 L +3547 2322 mt 3611 2177 L +c12 +-287 -25 -33 -154 3502 1565 3 MP +PP +0 sg +3502 1565 mt 3469 1411 L +3469 1411 mt 3182 1386 L +c12 +-22 -154 -298 -25 3502 1565 3 MP +PP +0 sg +3502 1565 mt 3204 1540 L +3204 1540 mt 3182 1386 L +c13 +-64 -153 233 -24 3378 1567 3 MP +PP +0 sg +3378 1567 mt 3611 1543 L +3611 1543 mt 3547 1390 L +c12 +233 -24 -31 -160 3409 1727 3 MP +PP +0 sg +3409 1727 mt 3378 1567 L +3378 1567 mt 3611 1543 L +/c17 { 1.000000 0.312500 0.000000 sr} bdef +c17 +-116 -118 -81 -30 3589 1191 3 MP +PP +0 sg +3589 1191 mt 3508 1161 L +3508 1161 mt 3392 1043 L +c17 +-71 -25 -126 -123 3589 1191 3 MP +PP +0 sg +3589 1191 mt 3463 1068 L +3463 1068 mt 3392 1043 L +c17 +-126 -123 17 -29 3572 1220 3 MP +PP +0 sg +3572 1220 mt 3589 1191 L +3589 1191 mt 3463 1068 L +c17 +-94 -116 -171 -26 3508 1161 3 MP +PP +0 sg +3508 1161 mt 3337 1135 L +3337 1135 mt 3243 1019 L +c17 +-149 -24 -116 -118 3508 1161 3 MP +PP +0 sg +3508 1161 mt 3392 1043 L +3392 1043 mt 3243 1019 L +c17 +-124 -126 113 -27 3459 1247 3 MP +PP +0 sg +3459 1247 mt 3572 1220 L +3572 1220 mt 3448 1094 L +c17 +15 -26 -124 -126 3572 1220 3 MP +PP +0 sg +3572 1220 mt 3448 1094 L +3448 1094 mt 3463 1068 L +/c18 { 0.000000 0.000000 0.937500 sr} bdef +c18 +15 -26 145 -100 3303 2646 3 MP +PP +0 sg +3303 2646 mt 3448 2546 L +3448 2546 mt 3463 2520 L +c18 +-71 -26 147 -105 3316 2625 3 MP +PP +0 sg +3316 2625 mt 3463 2520 L +3463 2520 mt 3392 2494 L +c18 +147 -105 13 -21 3303 2646 3 MP +PP +0 sg +3303 2646 mt 3316 2625 L +3316 2625 mt 3463 2520 L +c16 +124 -119 99 -23 3349 2569 3 MP +PP +0 sg +3349 2569 mt 3448 2546 L +3448 2546 mt 3572 2427 L +c15 +113 -27 -88 -143 3547 1390 3 MP +PP +0 sg +3547 1390 mt 3459 1247 L +3459 1247 mt 3572 1220 L +c16 +113 -27 110 -115 3349 2569 3 MP +PP +0 sg +3349 2569 mt 3459 2454 L +3459 2454 mt 3572 2427 L +c18 +-149 -23 135 -109 3257 2603 3 MP +PP +0 sg +3257 2603 mt 3392 2494 L +3392 2494 mt 3243 2471 L +c14 +88 -132 199 -20 3260 2474 3 MP +PP +0 sg +3260 2474 mt 3459 2454 L +3459 2454 mt 3547 2322 L +c14 +219 -23 68 -129 3260 2474 3 MP +PP +0 sg +3260 2474 mt 3328 2345 L +3328 2345 mt 3547 2322 L +c13 +-269 -24 -56 -144 3469 1411 3 MP +PP +0 sg +3469 1411 mt 3413 1267 L +3413 1267 mt 3144 1243 L +c13 +-38 -143 -287 -25 3469 1411 3 MP +PP +0 sg +3469 1411 mt 3182 1386 L +3182 1386 mt 3144 1243 L +c15 +-88 -143 219 -23 3328 1413 3 MP +PP +0 sg +3328 1413 mt 3547 1390 L +3547 1390 mt 3459 1247 L +c13 +219 -23 -50 -154 3378 1567 3 MP +PP +0 sg +3378 1567 mt 3328 1413 L +3328 1413 mt 3547 1390 L +/c19 { 1.000000 0.062500 0.000000 sr} bdef +c19 +-135 -101 -71 -25 3463 1068 3 MP +PP +0 sg +3463 1068 mt 3392 1043 L +3392 1043 mt 3257 942 L +c19 +-59 -22 -147 -104 3463 1068 3 MP +PP +0 sg +3463 1068 mt 3316 964 L +3316 964 mt 3257 942 L +c19 +-147 -104 15 -26 3448 1094 3 MP +PP +0 sg +3448 1094 mt 3463 1068 L +3463 1068 mt 3316 964 L +c18 +110 -113 -124 -19 3257 2603 3 MP +PP +0 sg +3257 2603 mt 3133 2584 L +3133 2584 mt 3243 2471 L +c18 +135 -109 -59 -22 3316 2625 3 MP +PP +0 sg +3316 2625 mt 3257 2603 L +3257 2603 mt 3392 2494 L +c16 +110 -115 173 -18 3176 2587 3 MP +PP +0 sg +3176 2587 mt 3349 2569 L +3349 2569 mt 3459 2454 L +c15 +-244 -21 -76 -132 3413 1267 3 MP +PP +0 sg +3413 1267 mt 3337 1135 L +3337 1135 mt 3093 1114 L +c15 +-51 -129 -269 -24 3413 1267 3 MP +PP +0 sg +3413 1267 mt 3144 1243 L +3144 1243 mt 3093 1114 L +c15 +199 -21 -68 -145 3328 1413 3 MP +PP +0 sg +3328 1413 mt 3260 1268 L +3260 1268 mt 3459 1247 L +c16 +199 -20 84 -113 3176 2587 3 MP +PP +0 sg +3176 2587 mt 3260 2474 L +3260 2474 mt 3459 2454 L +c17 +99 -23 -110 -130 3459 1247 3 MP +PP +0 sg +3459 1247 mt 3349 1117 L +3349 1117 mt 3448 1094 L +c17 +-110 -130 199 -21 3260 1268 3 MP +PP +0 sg +3260 1268 mt 3459 1247 L +3459 1247 mt 3349 1117 L +c19 +-124 -19 -135 -101 3392 1043 3 MP +PP +0 sg +3392 1043 mt 3257 942 L +3257 942 mt 3133 923 L +c19 +-110 -96 -149 -24 3392 1043 3 MP +PP +0 sg +3392 1043 mt 3243 1019 L +3243 1019 mt 3133 923 L +c19 +-145 -109 99 -23 3349 1117 3 MP +PP +0 sg +3349 1117 mt 3448 1094 L +3448 1094 mt 3303 985 L +c19 +13 -21 -145 -109 3448 1094 3 MP +PP +0 sg +3448 1094 mt 3303 985 L +3303 985 mt 3316 964 L +/c20 { 0.000000 0.000000 0.750000 sr} bdef +c20 +-59 -22 166 -84 3150 2709 3 MP +PP +0 sg +3150 2709 mt 3316 2625 L +3316 2625 mt 3257 2603 L +c20 +13 -21 162 -79 3141 2725 3 MP +PP +0 sg +3141 2725 mt 3303 2646 L +3303 2646 mt 3316 2625 L +c20 +166 -84 9 -16 3141 2725 3 MP +PP +0 sg +3141 2725 mt 3150 2709 L +3150 2709 mt 3316 2625 L +c18 +145 -100 82 -19 3221 2665 3 MP +PP +0 sg +3221 2665 mt 3303 2646 L +3303 2646 mt 3448 2546 L +c18 +99 -23 128 -96 3221 2665 3 MP +PP +0 sg +3221 2665 mt 3349 2569 L +3349 2569 mt 3448 2546 L +c10 +9 -161 -345 -16 3182 2021 3 MP +PP +0 sg +3182 2021 mt 2837 2005 L +2837 2005 mt 2846 1844 L +c11 +-345 -16 38 -154 3144 2175 3 MP +PP +0 sg +3144 2175 mt 3182 2021 L +3182 2021 mt 2837 2005 L +c10 +-358 -17 22 -160 3182 2021 3 MP +PP +0 sg +3182 2021 mt 3204 1861 L +3204 1861 mt 2846 1844 L +c9 +10 -160 323 -16 3086 2065 3 MP +PP +0 sg +3086 2065 mt 3409 2049 L +3409 2049 mt 3419 1889 L +c9 +3 -162 -358 -17 3204 1861 3 MP +PP +0 sg +3204 1861 mt 2846 1844 L +2846 1844 mt 2849 1682 L +c9 +-363 -17 8 -162 3204 1861 3 MP +PP +0 sg +3204 1861 mt 3212 1699 L +3212 1699 mt 2849 1682 L +c8 +-10 -162 327 -17 3092 1906 3 MP +PP +0 sg +3092 1906 mt 3419 1889 L +3419 1889 mt 3409 1727 L +c9 +327 -17 6 -159 3086 2065 3 MP +PP +0 sg +3086 2065 mt 3092 1906 L +3092 1906 mt 3419 1889 L +c11 +16 -155 -323 -15 3144 2175 3 MP +PP +0 sg +3144 2175 mt 2821 2160 L +2821 2160 mt 2837 2005 L +c14 +-323 -15 51 -145 3093 2320 3 MP +PP +0 sg +3093 2320 mt 3144 2175 L +3144 2175 mt 2821 2160 L +c10 +323 -16 18 -152 3068 2217 3 MP +PP +0 sg +3068 2217 mt 3086 2065 L +3086 2065 mt 3409 2049 L +c10 +31 -153 310 -15 3068 2217 3 MP +PP +0 sg +3068 2217 mt 3378 2202 L +3378 2202 mt 3409 2049 L +c8 +323 -17 -6 -162 3092 1906 3 MP +PP +0 sg +3092 1906 mt 3086 1744 L +3086 1744 mt 3409 1727 L +c8 +-358 -17 -8 -159 3212 1699 3 MP +PP +0 sg +3212 1699 mt 3204 1540 L +3204 1540 mt 2846 1523 L +c8 +-3 -159 -363 -17 3212 1699 3 MP +PP +0 sg +3212 1699 mt 2849 1682 L +2849 1682 mt 2846 1523 L +c12 +-31 -160 323 -17 3086 1744 3 MP +PP +0 sg +3086 1744 mt 3409 1727 L +3409 1727 mt 3378 1567 L +c14 +21 -147 -293 -13 3093 2320 3 MP +PP +0 sg +3093 2320 mt 2800 2307 L +2800 2307 mt 2821 2160 L +c16 +-293 -13 63 -133 3030 2453 3 MP +PP +0 sg +3030 2453 mt 3093 2320 L +3093 2320 mt 2800 2307 L +c16 +63 -133 -213 -18 3243 2471 3 MP +PP +0 sg +3243 2471 mt 3030 2453 L +3030 2453 mt 3093 2320 L +c11 +310 -15 30 -142 3038 2359 3 MP +PP +0 sg +3038 2359 mt 3068 2217 L +3068 2217 mt 3378 2202 L +c12 +-345 -16 -22 -154 3204 1540 3 MP +PP +0 sg +3204 1540 mt 3182 1386 L +3182 1386 mt 2837 1370 L +c12 +-9 -153 -358 -17 3204 1540 3 MP +PP +0 sg +3204 1540 mt 2846 1523 L +2846 1523 mt 2837 1370 L +c13 +-50 -154 310 -16 3068 1583 3 MP +PP +0 sg +3068 1583 mt 3378 1567 L +3378 1567 mt 3328 1413 L +c12 +310 -16 -18 -161 3086 1744 3 MP +PP +0 sg +3086 1744 mt 3068 1583 L +3068 1583 mt 3378 1567 L +c11 +50 -143 290 -14 3038 2359 3 MP +PP +0 sg +3038 2359 mt 3328 2345 L +3328 2345 mt 3378 2202 L +c20 +124 -93 -96 -15 3105 2692 3 MP +PP +0 sg +3105 2692 mt 3009 2677 L +3009 2677 mt 3133 2584 L +c20 +152 -89 -45 -17 3150 2709 3 MP +PP +0 sg +3150 2709 mt 3105 2692 L +3105 2692 mt 3257 2603 L +c20 +-124 -19 152 -89 3105 2692 3 MP +PP +0 sg +3105 2692 mt 3257 2603 L +3257 2603 mt 3133 2584 L +c18 +173 -18 99 -93 3077 2680 3 MP +PP +0 sg +3077 2680 mt 3176 2587 L +3176 2587 mt 3349 2569 L +c18 +128 -96 144 -15 3077 2680 3 MP +PP +0 sg +3077 2680 mt 3221 2665 L +3221 2665 mt 3349 2569 L +c17 +-63 -113 -244 -21 3337 1135 3 MP +PP +0 sg +3337 1135 mt 3093 1114 L +3093 1114 mt 3030 1001 L +c17 +-213 -18 -94 -116 3337 1135 3 MP +PP +0 sg +3337 1135 mt 3243 1019 L +3243 1019 mt 3030 1001 L +c17 +173 -18 -84 -133 3260 1268 3 MP +PP +0 sg +3260 1268 mt 3176 1135 L +3176 1135 mt 3349 1117 L +c19 +-75 -94 -213 -18 3243 1019 3 MP +PP +0 sg +3243 1019 mt 3030 1001 L +3030 1001 mt 2955 907 L +c19 +-178 -16 -110 -96 3243 1019 3 MP +PP +0 sg +3243 1019 mt 3133 923 L +3133 923 mt 2955 907 L +c19 +-128 -113 173 -18 3176 1135 3 MP +PP +0 sg +3176 1135 mt 3349 1117 L +3349 1117 mt 3221 1004 L +c19 +82 -19 -128 -113 3349 1117 3 MP +PP +0 sg +3349 1117 mt 3221 1004 L +3221 1004 mt 3303 985 L +c18 +-257 -12 75 -116 2955 2569 3 MP +PP +0 sg +2955 2569 mt 3030 2453 L +3030 2453 mt 2773 2441 L +c18 +75 -116 -178 -15 3133 2584 3 MP +PP +0 sg +3133 2584 mt 2955 2569 L +2955 2569 mt 3030 2453 L +c18 +-213 -18 110 -113 3133 2584 3 MP +PP +0 sg +3133 2584 mt 3243 2471 L +3243 2471 mt 3030 2453 L +c14 +68 -129 264 -14 2996 2488 3 MP +PP +0 sg +2996 2488 mt 3260 2474 L +3260 2474 mt 3328 2345 L +c13 +-16 -142 -345 -16 3182 1386 3 MP +PP +0 sg +3182 1386 mt 2837 1370 L +2837 1370 mt 2821 1228 L +c13 +-323 -15 -38 -143 3182 1386 3 MP +PP +0 sg +3182 1386 mt 3144 1243 L +3144 1243 mt 2821 1228 L +c15 +-68 -145 290 -14 3038 1427 3 MP +PP +0 sg +3038 1427 mt 3328 1413 L +3328 1413 mt 3260 1268 L +c16 +27 -134 -257 -12 3030 2453 3 MP +PP +0 sg +3030 2453 mt 2773 2441 L +2773 2441 mt 2800 2307 L +c14 +290 -14 42 -129 2996 2488 3 MP +PP +0 sg +2996 2488 mt 3038 2359 L +3038 2359 mt 3328 2345 L +c13 +290 -14 -30 -156 3068 1583 3 MP +PP +0 sg +3068 1583 mt 3038 1427 L +3038 1427 mt 3328 1413 L +/c21 { 0.875000 0.000000 0.000000 sr} bdef +c21 +-124 -75 -124 -19 3257 942 3 MP +PP +0 sg +3257 942 mt 3133 923 L +3133 923 mt 3009 848 L +c21 +-96 -15 -152 -79 3257 942 3 MP +PP +0 sg +3257 942 mt 3105 863 L +3105 863 mt 3009 848 L +c21 +-45 -16 -166 -85 3316 964 3 MP +PP +0 sg +3316 964 mt 3150 879 L +3150 879 mt 3105 863 L +c21 +-152 -79 -59 -22 3316 964 3 MP +PP +0 sg +3316 964 mt 3257 942 L +3257 942 mt 3105 863 L +c21 +-166 -85 13 -21 3303 985 3 MP +PP +0 sg +3303 985 mt 3316 964 L +3316 964 mt 3150 879 L +c21 +9 -17 -162 -89 3303 985 3 MP +PP +0 sg +3303 985 mt 3141 896 L +3141 896 mt 3150 879 L +c21 +-162 -89 82 -19 3221 1004 3 MP +PP +0 sg +3221 1004 mt 3303 985 L +3303 985 mt 3141 896 L +/c22 { 0.000000 0.000000 0.625000 sr} bdef +c22 +9 -16 177 -56 2964 2781 3 MP +PP +0 sg +2964 2781 mt 3141 2725 L +3141 2725 mt 3150 2709 L +c22 +179 -61 7 -11 2964 2781 3 MP +PP +0 sg +2964 2781 mt 2971 2770 L +2971 2770 mt 3150 2709 L +c22 +-45 -17 179 -61 2971 2770 3 MP +PP +0 sg +2971 2770 mt 3150 2709 L +3150 2709 mt 3105 2692 L +c20 +82 -19 144 -75 3077 2740 3 MP +PP +0 sg +3077 2740 mt 3221 2665 L +3221 2665 mt 3303 2646 L +c20 +162 -79 64 -15 3077 2740 3 MP +PP +0 sg +3077 2740 mt 3141 2725 L +3141 2725 mt 3303 2646 L +c20 +83 -96 -137 -12 3009 2677 3 MP +PP +0 sg +3009 2677 mt 2872 2665 L +2872 2665 mt 2955 2569 L +c20 +-178 -15 124 -93 3009 2677 3 MP +PP +0 sg +3009 2677 mt 3133 2584 L +3133 2584 mt 2955 2569 L +c16 +84 -113 231 -12 2945 2599 3 MP +PP +0 sg +2945 2599 mt 3176 2587 L +3176 2587 mt 3260 2474 L +c15 +-21 -128 -323 -15 3144 1243 3 MP +PP +0 sg +3144 1243 mt 2821 1228 L +2821 1228 mt 2800 1100 L +c15 +-293 -14 -51 -129 3144 1243 3 MP +PP +0 sg +3144 1243 mt 3093 1114 L +3093 1114 mt 2800 1100 L +c17 +-84 -133 264 -13 2996 1281 3 MP +PP +0 sg +2996 1281 mt 3260 1268 L +3260 1268 mt 3176 1135 L +c15 +264 -13 -42 -146 3038 1427 3 MP +PP +0 sg +3038 1427 mt 2996 1281 L +2996 1281 mt 3260 1268 L +c16 +264 -14 51 -111 2945 2599 3 MP +PP +0 sg +2945 2599 mt 2996 2488 L +2996 2488 mt 3260 2474 L +c21 +-137 -12 -124 -75 3133 923 3 MP +PP +0 sg +3133 923 mt 3009 848 L +3009 848 mt 2872 836 L +c21 +-83 -71 -178 -16 3133 923 3 MP +PP +0 sg +3133 923 mt 2955 907 L +2955 907 mt 2872 836 L +c21 +64 -15 -144 -93 3221 1004 3 MP +PP +0 sg +3221 1004 mt 3077 911 L +3077 911 mt 3141 896 L +c21 +-144 -93 144 -15 3077 1019 3 MP +PP +0 sg +3077 1019 mt 3221 1004 L +3221 1004 mt 3077 911 L +c19 +144 -15 -99 -116 3176 1135 3 MP +PP +0 sg +3176 1135 mt 3077 1019 L +3077 1019 mt 3221 1004 L +c22 +165 -67 -31 -11 2971 2770 3 MP +PP +0 sg +2971 2770 mt 2940 2759 L +2940 2759 mt 3105 2692 L +c20 +144 -75 111 -12 2966 2752 3 MP +PP +0 sg +2966 2752 mt 3077 2740 L +3077 2740 mt 3221 2665 L +c22 +-96 -15 165 -67 2940 2759 3 MP +PP +0 sg +2940 2759 mt 3105 2692 L +3105 2692 mt 3009 2677 L +c20 +144 -15 111 -72 2966 2752 3 MP +PP +0 sg +2966 2752 mt 3077 2680 L +3077 2680 mt 3221 2665 L +c17 +231 -12 -51 -134 2996 1281 3 MP +PP +0 sg +2996 1281 mt 2945 1147 L +2945 1147 mt 3176 1135 L +c17 +-257 -12 -63 -113 3093 1114 3 MP +PP +0 sg +3093 1114 mt 3030 1001 L +3030 1001 mt 2773 989 L +c17 +-27 -111 -293 -14 3093 1114 3 MP +PP +0 sg +3093 1114 mt 2800 1100 L +2800 1100 mt 2773 989 L +c19 +-99 -116 231 -12 2945 1147 3 MP +PP +0 sg +2945 1147 mt 3176 1135 L +3176 1135 mt 3077 1019 L +c22 +-137 -12 134 -72 2875 2749 3 MP +PP +0 sg +2875 2749 mt 3009 2677 L +3009 2677 mt 2872 2665 L +c18 +231 -12 60 -91 2885 2690 3 MP +PP +0 sg +2885 2690 mt 2945 2599 L +2945 2599 mt 3176 2587 L +c22 +134 -72 -65 -10 2940 2759 3 MP +PP +0 sg +2940 2759 mt 2875 2749 L +2875 2749 mt 3009 2677 L +c18 +99 -93 192 -10 2885 2690 3 MP +PP +0 sg +2885 2690 mt 3077 2680 L +3077 2680 mt 3176 2587 L +/c23 { 0.687500 0.000000 0.000000 sr} bdef +c23 +-134 -52 -96 -15 3105 863 3 MP +PP +0 sg +3105 863 mt 3009 848 L +3009 848 mt 2875 796 L +c23 +-65 -10 -165 -57 3105 863 3 MP +PP +0 sg +3105 863 mt 2940 806 L +2940 806 mt 2875 796 L +c23 +-165 -57 -45 -16 3150 879 3 MP +PP +0 sg +3150 879 mt 3105 863 L +3105 863 mt 2940 806 L +c23 +-179 -62 9 -17 3141 896 3 MP +PP +0 sg +3141 896 mt 3150 879 L +3150 879 mt 2971 817 L +c23 +-31 -11 -179 -62 3150 879 3 MP +PP +0 sg +3150 879 mt 2971 817 L +2971 817 mt 2940 806 L +c23 +7 -12 -177 -67 3141 896 3 MP +PP +0 sg +3141 896 mt 2964 829 L +2964 829 mt 2971 817 L +/c24 { 0.000000 0.000000 0.562500 sr} bdef +c24 +185 -32 22 -5 2757 2818 3 MP +PP +0 sg +2757 2818 mt 2779 2813 L +2779 2813 mt 2964 2781 L +c24 +43 -10 164 -27 2757 2818 3 MP +PP +0 sg +2757 2818 mt 2921 2791 L +2921 2791 mt 2964 2781 L +c24 +7 -11 185 -32 2779 2813 3 MP +PP +0 sg +2779 2813 mt 2964 2781 L +2964 2781 mt 2971 2770 L +c22 +64 -15 156 -51 2921 2791 3 MP +PP +0 sg +2921 2791 mt 3077 2740 L +3077 2740 mt 3141 2725 L +c22 +177 -56 43 -10 2921 2791 3 MP +PP +0 sg +2921 2791 mt 2964 2781 L +2964 2781 mt 3141 2725 L +c23 +-93 -8 -134 -52 3009 848 3 MP +PP +0 sg +3009 848 mt 2875 796 L +2875 796 mt 2782 788 L +c23 +-90 -48 -137 -12 3009 848 3 MP +PP +0 sg +3009 848 mt 2872 836 L +2872 836 mt 2782 788 L +c23 +-177 -67 64 -15 3077 911 3 MP +PP +0 sg +3077 911 mt 3141 896 L +3141 896 mt 2964 829 L +c10 +-383 -6 9 -161 2837 2005 3 MP +PP +0 sg +2837 2005 mt 2846 1844 L +2846 1844 mt 2463 1838 L +c8 +-6 -162 375 -5 2717 1911 3 MP +PP +0 sg +2717 1911 mt 3092 1906 L +3092 1906 mt 3086 1744 L +c11 +-370 -6 16 -155 2821 2160 3 MP +PP +0 sg +2821 2160 mt 2837 2005 L +2837 2005 mt 2467 1999 L +c9 +6 -159 371 -5 2715 2070 3 MP +PP +0 sg +2715 2070 mt 3086 2065 L +3086 2065 mt 3092 1906 L +c10 +-4 -161 -370 -6 2837 2005 3 MP +PP +0 sg +2837 2005 mt 2467 1999 L +2467 1999 mt 2463 1838 L +c9 +375 -5 2 -159 2715 2070 3 MP +PP +0 sg +2715 2070 mt 2717 1911 L +2717 1911 mt 3092 1906 L +c9 +-388 -6 3 -162 2846 1844 3 MP +PP +0 sg +2846 1844 mt 2849 1682 L +2849 1682 mt 2461 1676 L +c12 +-18 -161 371 -5 2715 1749 3 MP +PP +0 sg +2715 1749 mt 3086 1744 L +3086 1744 mt 3068 1583 L +c14 +-346 -5 21 -147 2800 2307 3 MP +PP +0 sg +2800 2307 mt 2821 2160 L +2821 2160 mt 2475 2155 L +c10 +18 -152 357 -6 2711 2223 3 MP +PP +0 sg +2711 2223 mt 3068 2217 L +3068 2217 mt 3086 2065 L +c11 +-8 -156 -346 -5 2821 2160 3 MP +PP +0 sg +2821 2160 mt 2475 2155 L +2475 2155 mt 2467 1999 L +c10 +371 -5 4 -153 2711 2223 3 MP +PP +0 sg +2711 2223 mt 2715 2070 L +2715 2070 mt 3086 2065 L +c9 +-2 -162 -383 -6 2846 1844 3 MP +PP +0 sg +2846 1844 mt 2463 1838 L +2463 1838 mt 2461 1676 L +c8 +371 -5 -2 -162 2717 1911 3 MP +PP +0 sg +2717 1911 mt 2715 1749 L +2715 1749 mt 3086 1744 L +c19 +-213 -10 -75 -94 3030 1001 3 MP +PP +0 sg +3030 1001 mt 2955 907 L +2955 907 mt 2742 897 L +c21 +111 -11 -111 -97 3077 1019 3 MP +PP +0 sg +3077 1019 mt 2966 922 L +2966 922 mt 3077 911 L +c24 +-31 -11 189 -38 2782 2808 3 MP +PP +0 sg +2782 2808 mt 2971 2770 L +2971 2770 mt 2940 2759 L +c24 +189 -38 3 -5 2779 2813 3 MP +PP +0 sg +2779 2813 mt 2782 2808 L +2782 2808 mt 2971 2770 L +c22 +156 -51 76 -8 2845 2799 3 MP +PP +0 sg +2845 2799 mt 2921 2791 L +2921 2791 mt 3077 2740 L +c23 +43 -10 -156 -72 3077 911 3 MP +PP +0 sg +3077 911 mt 2921 839 L +2921 839 mt 2964 829 L +c22 +111 -12 121 -47 2845 2799 3 MP +PP +0 sg +2845 2799 mt 2966 2752 L +2966 2752 mt 3077 2740 L +c23 +-156 -72 111 -11 2966 922 3 MP +PP +0 sg +2966 922 mt 3077 911 L +3077 911 mt 2921 839 L +c19 +192 -10 -60 -118 2945 1147 3 MP +PP +0 sg +2945 1147 mt 2885 1029 L +2885 1029 mt 3077 1019 L +c19 +-31 -92 -257 -12 3030 1001 3 MP +PP +0 sg +3030 1001 mt 2773 989 L +2773 989 mt 2742 897 L +c21 +-111 -97 192 -10 2885 1029 3 MP +PP +0 sg +2885 1029 mt 3077 1019 L +3077 1019 mt 2966 922 L +c22 +90 -76 -93 -8 2875 2749 3 MP +PP +0 sg +2875 2749 mt 2782 2741 L +2782 2741 mt 2872 2665 L +c24 +141 -48 -33 -5 2767 2802 3 MP +PP +0 sg +2767 2802 mt 2734 2797 L +2734 2797 mt 2875 2749 L +c24 +-93 -8 141 -48 2734 2797 3 MP +PP +0 sg +2734 2797 mt 2875 2749 L +2875 2749 mt 2782 2741 L +c24 +-65 -10 173 -43 2767 2802 3 MP +PP +0 sg +2767 2802 mt 2940 2759 L +2940 2759 mt 2875 2749 L +c20 +111 -72 148 -7 2818 2759 3 MP +PP +0 sg +2818 2759 mt 2966 2752 L +2966 2752 mt 3077 2680 L +c20 +192 -10 67 -69 2818 2759 3 MP +PP +0 sg +2818 2759 mt 2885 2690 L +2885 2690 mt 3077 2680 L +c8 +-383 -6 -3 -159 2849 1682 3 MP +PP +0 sg +2849 1682 mt 2846 1523 L +2846 1523 mt 2463 1517 L +c8 +2 -159 -388 -6 2849 1682 3 MP +PP +0 sg +2849 1682 mt 2461 1676 L +2461 1676 mt 2463 1517 L +c12 +357 -5 -4 -161 2715 1749 3 MP +PP +0 sg +2715 1749 mt 2711 1588 L +2711 1588 mt 3068 1583 L +c12 +4 -153 -383 -6 2846 1523 3 MP +PP +0 sg +2846 1523 mt 2463 1517 L +2463 1517 mt 2467 1364 L +c12 +-370 -6 -9 -153 2846 1523 3 MP +PP +0 sg +2846 1523 mt 2837 1370 L +2837 1370 mt 2467 1364 L +c13 +-30 -156 357 -5 2711 1588 3 MP +PP +0 sg +2711 1588 mt 3068 1583 L +3068 1583 mt 3038 1427 L +c14 +-11 -147 -314 -5 2800 2307 3 MP +PP +0 sg +2800 2307 mt 2486 2302 L +2486 2302 mt 2475 2155 L +c16 +-314 -5 27 -134 2773 2441 3 MP +PP +0 sg +2773 2441 mt 2800 2307 L +2800 2307 mt 2486 2302 L +c11 +357 -6 8 -141 2703 2364 3 MP +PP +0 sg +2703 2364 mt 2711 2223 L +2711 2223 mt 3068 2217 L +c11 +30 -142 335 -5 2703 2364 3 MP +PP +0 sg +2703 2364 mt 3038 2359 L +3038 2359 mt 3068 2217 L +c13 +335 -5 -8 -156 2711 1588 3 MP +PP +0 sg +2711 1588 mt 2703 1432 L +2703 1432 mt 3038 1427 L +c16 +-13 -134 -274 -5 2773 2441 3 MP +PP +0 sg +2773 2441 mt 2499 2436 L +2499 2436 mt 2486 2302 L +c18 +-274 -5 31 -118 2742 2559 3 MP +PP +0 sg +2742 2559 mt 2773 2441 L +2773 2441 mt 2499 2436 L +c18 +31 -118 -213 -10 2955 2569 3 MP +PP +0 sg +2955 2569 mt 2742 2559 L +2742 2559 mt 2773 2441 L +c14 +335 -5 11 -128 2692 2492 3 MP +PP +0 sg +2692 2492 mt 2703 2364 L +2703 2364 mt 3038 2359 L +c14 +42 -129 304 -4 2692 2492 3 MP +PP +0 sg +2692 2492 mt 2996 2488 L +2996 2488 mt 3038 2359 L +c13 +8 -141 -370 -6 2837 1370 3 MP +PP +0 sg +2837 1370 mt 2467 1364 L +2467 1364 mt 2475 1223 L +c13 +-346 -5 -16 -142 2837 1370 3 MP +PP +0 sg +2837 1370 mt 2821 1228 L +2821 1228 mt 2475 1223 L +c15 +-42 -146 335 -5 2703 1432 3 MP +PP +0 sg +2703 1432 mt 3038 1427 L +3038 1427 mt 2996 1281 L +c20 +-228 -4 35 -99 2707 2658 3 MP +PP +0 sg +2707 2658 mt 2742 2559 L +2742 2559 mt 2514 2555 L +c20 +35 -99 -165 -7 2872 2665 3 MP +PP +0 sg +2872 2665 mt 2707 2658 L +2707 2658 mt 2742 2559 L +c20 +-213 -10 83 -96 2872 2665 3 MP +PP +0 sg +2872 2665 mt 2955 2569 L +2955 2569 mt 2742 2559 L +c16 +51 -111 266 -4 2679 2603 3 MP +PP +0 sg +2679 2603 mt 2945 2599 L +2945 2599 mt 2996 2488 L +c15 +-314 -5 -21 -128 2821 1228 3 MP +PP +0 sg +2821 1228 mt 2800 1100 L +2800 1100 mt 2486 1095 L +c15 +11 -128 -346 -5 2821 1228 3 MP +PP +0 sg +2821 1228 mt 2475 1223 L +2475 1223 mt 2486 1095 L +c17 +-51 -134 304 -4 2692 1285 3 MP +PP +0 sg +2692 1285 mt 2996 1281 L +2996 1281 mt 2945 1147 L +c15 +304 -4 -11 -147 2703 1432 3 MP +PP +0 sg +2703 1432 mt 2692 1285 L +2692 1285 mt 2996 1281 L +c18 +-15 -119 -228 -4 2742 2559 3 MP +PP +0 sg +2742 2559 mt 2514 2555 L +2514 2555 mt 2499 2436 L +c16 +304 -4 13 -111 2679 2603 3 MP +PP +0 sg +2679 2603 mt 2692 2492 L +2692 2492 mt 2996 2488 L +/c25 { 0.562500 0.000000 0.000000 sr} bdef +c25 +-48 -4 -141 -27 2875 796 3 MP +PP +0 sg +2875 796 mt 2734 769 L +2734 769 mt 2686 765 L +c25 +-96 -23 -93 -8 2875 796 3 MP +PP +0 sg +2875 796 mt 2782 788 L +2782 788 mt 2686 765 L +c25 +-141 -27 -65 -10 2940 806 3 MP +PP +0 sg +2940 806 mt 2875 796 L +2875 796 mt 2734 769 L +c25 +-33 -5 -173 -32 2940 806 3 MP +PP +0 sg +2940 806 mt 2767 774 L +2767 774 mt 2734 769 L +c25 +-15 -6 -189 -37 2971 817 3 MP +PP +0 sg +2971 817 mt 2782 780 L +2782 780 mt 2767 774 L +c25 +-173 -32 -31 -11 2971 817 3 MP +PP +0 sg +2971 817 mt 2940 806 L +2940 806 mt 2767 774 L +c25 +-189 -37 7 -12 2964 829 3 MP +PP +0 sg +2964 829 mt 2971 817 L +2971 817 mt 2782 780 L +c21 +-165 -8 -83 -71 2955 907 3 MP +PP +0 sg +2955 907 mt 2872 836 L +2872 836 mt 2707 828 L +c21 +-35 -69 -213 -10 2955 907 3 MP +PP +0 sg +2955 907 mt 2742 897 L +2742 897 mt 2707 828 L +c23 +76 -8 -121 -75 2966 922 3 MP +PP +0 sg +2966 922 mt 2845 847 L +2845 847 mt 2921 839 L +c21 +148 -8 -67 -99 2885 1029 3 MP +PP +0 sg +2885 1029 mt 2818 930 L +2818 930 mt 2966 922 L +c23 +-121 -75 148 -8 2818 930 3 MP +PP +0 sg +2818 930 mt 2966 922 L +2966 922 mt 2845 847 L +c24 +178 -18 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2767 2802 L +c24 +-33 -5 178 -18 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2767 2802 L +2767 2802 mt 2734 2797 L +2734 2797 mt 2589 2820 L +c24 +-15 -6 193 -12 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2782 2808 L +2782 2808 mt 2767 2802 L +2767 2802 mt 2589 2820 L +c24 +173 -43 -15 -6 2782 2808 3 MP +PP +0 sg +2782 2808 mt 2767 2802 L +2767 2802 mt 2940 2759 L +c22 +121 -47 100 -6 2745 2805 3 MP +PP +0 sg +2745 2805 mt 2845 2799 L +2845 2799 mt 2966 2752 L +c22 +148 -7 73 -46 2745 2805 3 MP +PP +0 sg +2745 2805 mt 2818 2759 L +2818 2759 mt 2966 2752 L +c25 +-185 -44 43 -10 2921 839 3 MP +PP +0 sg +2921 839 mt 2964 829 L +2964 829 mt 2779 785 L +c25 +3 -5 -185 -44 2964 829 3 MP +PP +0 sg +2964 829 mt 2779 785 L +2779 785 mt 2782 780 L +c17 +13 -111 -314 -5 2800 1100 3 MP +PP +0 sg +2800 1100 mt 2486 1095 L +2486 1095 mt 2499 984 L +c17 +-274 -5 -27 -111 2800 1100 3 MP +PP +0 sg +2800 1100 mt 2773 989 L +2773 989 mt 2499 984 L +c19 +-60 -118 266 -4 2679 1151 3 MP +PP +0 sg +2679 1151 mt 2945 1147 L +2945 1147 mt 2885 1029 L +c20 +-17 -100 -176 -3 2707 2658 3 MP +PP +0 sg +2707 2658 mt 2531 2655 L +2531 2655 mt 2514 2555 L +c22 +-176 -3 38 -77 2669 2735 3 MP +PP +0 sg +2669 2735 mt 2707 2658 L +2707 2658 mt 2531 2655 L +c22 +38 -77 -113 -6 2782 2741 3 MP +PP +0 sg +2782 2741 mt 2669 2735 L +2669 2735 mt 2707 2658 L +c22 +-165 -7 90 -76 2782 2741 3 MP +PP +0 sg +2782 2741 mt 2872 2665 L +2872 2665 mt 2707 2658 L +c18 +266 -4 15 -90 2664 2693 3 MP +PP +0 sg +2664 2693 mt 2679 2603 L +2679 2603 mt 2945 2599 L +c17 +266 -4 -13 -134 2692 1285 3 MP +PP +0 sg +2692 1285 mt 2679 1151 L +2679 1151 mt 2945 1147 L +c18 +60 -91 221 -3 2664 2693 3 MP +PP +0 sg +2664 2693 mt 2885 2690 L +2885 2690 mt 2945 2599 L +c24 +168 -2 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2757 2818 L +c24 +38 -4 130 2 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2719 2822 L +2719 2822 mt 2757 2818 L +2757 2818 mt 2589 2820 L +c24 +22 -5 168 -2 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2757 2818 L +2757 2818 mt 2779 2813 L +2779 2813 mt 2589 2820 L +c24 +190 -7 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2779 2813 L +c24 +3 -5 190 -7 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2779 2813 L +2779 2813 mt 2782 2808 L +2782 2808 mt 2589 2820 L +c24 +164 -27 38 -4 2719 2822 3 MP +PP +0 sg +2719 2822 mt 2757 2818 L +2757 2818 mt 2921 2791 L +c25 +-39 -21 -113 -5 2782 788 3 MP +PP +0 sg +2782 788 mt 2669 783 L +2669 783 mt 2630 762 L +c25 +-56 -3 -96 -23 2782 788 3 MP +PP +0 sg +2782 788 mt 2686 765 L +2686 765 mt 2630 762 L +c23 +-113 -5 -90 -48 2872 836 3 MP +PP +0 sg +2872 836 mt 2782 788 L +2782 788 mt 2669 783 L +c25 +22 -5 -164 -49 2921 839 3 MP +PP +0 sg +2921 839 mt 2757 790 L +2757 790 mt 2779 785 L +c24 +76 -8 126 -23 2719 2822 3 MP +PP +0 sg +2719 2822 mt 2845 2799 L +2845 2799 mt 2921 2791 L +c23 +-38 -45 -165 -8 2872 836 3 MP +PP +0 sg +2872 836 mt 2707 828 L +2707 828 mt 2669 783 L +c25 +-164 -49 76 -8 2845 847 3 MP +PP +0 sg +2845 847 mt 2921 839 L +2921 839 mt 2757 790 L +c24 +-119 -1 39 -55 2630 2790 3 MP +PP +0 sg +2630 2790 mt 2669 2735 L +2669 2735 mt 2550 2734 L +c22 +-19 -79 -119 -1 2669 2735 3 MP +PP +0 sg +2669 2735 mt 2550 2734 L +2550 2734 mt 2531 2655 L +c24 +39 -55 -56 -3 2686 2793 3 MP +PP +0 sg +2686 2793 mt 2630 2790 L +2630 2790 mt 2669 2735 L +c24 +-113 -6 96 -52 2686 2793 3 MP +PP +0 sg +2686 2793 mt 2782 2741 L +2782 2741 mt 2669 2735 L +c20 +221 -3 17 -69 2647 2762 3 MP +PP +0 sg +2647 2762 mt 2664 2693 L +2664 2693 mt 2885 2690 L +c19 +221 -3 -15 -119 2679 1151 3 MP +PP +0 sg +2679 1151 mt 2664 1032 L +2664 1032 mt 2885 1029 L +c24 +96 -52 -48 -4 2734 2797 3 MP +PP +0 sg +2734 2797 mt 2686 2793 L +2686 2793 mt 2782 2741 L +c20 +67 -69 171 -3 2647 2762 3 MP +PP +0 sg +2647 2762 mt 2818 2759 L +2818 2759 mt 2885 2690 L +c19 +15 -90 -274 -5 2773 989 3 MP +PP +0 sg +2773 989 mt 2499 984 L +2499 984 mt 2514 894 L +c19 +-228 -3 -31 -92 2773 989 3 MP +PP +0 sg +2773 989 mt 2742 897 L +2742 897 mt 2514 894 L +c21 +-67 -99 221 -3 2664 1032 3 MP +PP +0 sg +2664 1032 mt 2885 1029 L +2885 1029 mt 2818 930 L +c25 +38 -5 -126 -52 2845 847 3 MP +PP +0 sg +2845 847 mt 2719 795 L +2719 795 mt 2757 790 L +c24 +130 2 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2719 2822 L +c24 +51 -3 79 5 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2668 2825 L +2668 2825 mt 2719 2822 L +2719 2822 mt 2589 2820 L +c24 +126 -23 51 -3 2668 2825 3 MP +PP +0 sg +2668 2825 mt 2719 2822 L +2719 2822 mt 2845 2799 L +c25 +-126 -52 100 -5 2745 852 3 MP +PP +0 sg +2745 852 mt 2845 847 L +2845 847 mt 2719 795 L +c23 +100 -5 -73 -78 2818 930 3 MP +PP +0 sg +2818 930 mt 2745 852 L +2745 852 mt 2845 847 L +c24 +193 -12 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2782 2808 L +c24 +100 -6 77 -20 2668 2825 3 MP +PP +0 sg +2668 2825 mt 2745 2805 L +2745 2805 mt 2845 2799 L +c24 +-56 -3 97 -27 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2686 2793 L +2686 2793 mt 2630 2790 L +2630 2790 mt 2589 2820 L +c24 +97 -27 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2686 2793 L +c24 +145 -23 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2734 2797 L +c24 +-48 -4 145 -23 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2734 2797 L +2734 2797 mt 2686 2793 L +2686 2793 mt 2589 2820 L +c22 +73 -46 117 -1 2628 2806 3 MP +PP +0 sg +2628 2806 mt 2745 2805 L +2745 2805 mt 2818 2759 L +c21 +171 -2 -17 -100 2664 1032 3 MP +PP +0 sg +2664 1032 mt 2647 932 L +2647 932 mt 2818 930 L +c21 +17 -69 -228 -3 2742 897 3 MP +PP +0 sg +2742 897 mt 2514 894 L +2514 894 mt 2531 825 L +c21 +-176 -3 -35 -69 2742 897 3 MP +PP +0 sg +2742 897 mt 2707 828 L +2707 828 mt 2531 825 L +c23 +-73 -78 171 -2 2647 932 3 MP +PP +0 sg +2647 932 mt 2818 930 L +2818 930 mt 2745 852 L +c22 +171 -3 19 -44 2628 2806 3 MP +PP +0 sg +2628 2806 mt 2647 2762 L +2647 2762 mt 2818 2759 L +c25 +19 -20 -119 -2 2669 783 3 MP +PP +0 sg +2669 783 mt 2550 781 L +2550 781 mt 2569 761 L +c25 +-61 -1 -39 -21 2669 783 3 MP +PP +0 sg +2669 783 mt 2630 762 L +2630 762 mt 2569 761 L +/c26 { 0.500000 0.000000 0.000000 sr} bdef +c26 +0 0 -193 -13 2782 780 3 MP +PP +0 sg +2782 780 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +-193 -13 3 -5 2779 785 3 MP +PP +0 sg +2779 785 mt 2782 780 L +2782 780 mt 2589 767 L +2589 767 mt 2779 785 L +c26 +-178 -7 -15 -6 2782 780 3 MP +PP +0 sg +2782 780 mt 2767 774 L +2767 774 mt 2589 767 L +2589 767 mt 2782 780 L +c26 +0 0 -190 -18 2779 785 3 MP +PP +0 sg +2779 785 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +-190 -18 22 -5 2757 790 3 MP +PP +0 sg +2757 790 mt 2779 785 L +2779 785 mt 2589 767 L +2589 767 mt 2757 790 L +c26 +-145 -2 -33 -5 2767 774 3 MP +PP +0 sg +2767 774 mt 2734 769 L +2734 769 mt 2589 767 L +2589 767 mt 2767 774 L +c26 +0 0 -178 -7 2767 774 3 MP +PP +0 sg +2767 774 mt 2589 767 L +2589 767 mt 2589 767 L +c23 +-119 -2 -38 -45 2707 828 3 MP +PP +0 sg +2707 828 mt 2669 783 L +2669 783 mt 2550 781 L +c26 +-168 -23 38 -5 2719 795 3 MP +PP +0 sg +2719 795 mt 2757 790 L +2757 790 mt 2589 767 L +2589 767 mt 2719 795 L +c26 +0 0 -168 -23 2757 790 3 MP +PP +0 sg +2757 790 mt 2589 767 L +2589 767 mt 2589 767 L +c23 +19 -44 -176 -3 2707 828 3 MP +PP +0 sg +2707 828 mt 2531 825 L +2531 825 mt 2550 781 L +c25 +-77 -55 117 -1 2628 853 3 MP +PP +0 sg +2628 853 mt 2745 852 L +2745 852 mt 2668 797 L +c23 +117 -1 -19 -79 2647 932 3 MP +PP +0 sg +2647 932 mt 2628 853 L +2628 853 mt 2745 852 L +c25 +51 -2 -77 -55 2745 852 3 MP +PP +0 sg +2745 852 mt 2668 797 L +2668 797 mt 2719 795 L +c24 +59 -1 20 6 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2609 2826 L +2609 2826 mt 2668 2825 L +2668 2825 mt 2589 2820 L +c24 +79 5 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2668 2825 L +c24 +117 -1 19 -20 2609 2826 3 MP +PP +0 sg +2609 2826 mt 2628 2806 L +2628 2806 mt 2745 2805 L +c24 +77 -20 59 -1 2609 2826 3 MP +PP +0 sg +2609 2826 mt 2668 2825 L +2668 2825 mt 2745 2805 L +c26 +0 0 -145 -2 2734 769 3 MP +PP +0 sg +2734 769 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +-97 2 -48 -4 2734 769 3 MP +PP +0 sg +2734 769 mt 2686 765 L +2686 765 mt 2589 767 L +2589 767 mt 2734 769 L +c26 +0 0 -130 -28 2719 795 3 MP +PP +0 sg +2719 795 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +-130 -28 51 -2 2668 797 3 MP +PP +0 sg +2668 797 mt 2719 795 L +2719 795 mt 2589 767 L +2589 767 mt 2668 797 L +c11 +-357 5 -8 -156 2475 2155 3 MP +PP +0 sg +2475 2155 mt 2467 1999 L +2467 1999 mt 2110 2004 L +c9 +2 -159 383 6 2332 2064 3 MP +PP +0 sg +2332 2064 mt 2715 2070 L +2715 2070 mt 2717 1911 L +c10 +-18 -161 -357 5 2467 1999 3 MP +PP +0 sg +2467 1999 mt 2110 2004 L +2110 2004 mt 2092 1843 L +c10 +-371 5 -4 -161 2467 1999 3 MP +PP +0 sg +2467 1999 mt 2463 1838 L +2463 1838 mt 2092 1843 L +c9 +388 6 -3 -159 2332 2064 3 MP +PP +0 sg +2332 2064 mt 2329 1905 L +2329 1905 mt 2717 1911 L +c8 +-2 -162 388 6 2329 1905 3 MP +PP +0 sg +2329 1905 mt 2717 1911 L +2717 1911 mt 2715 1749 L +c11 +-30 -156 -335 5 2475 2155 3 MP +PP +0 sg +2475 2155 mt 2140 2160 L +2140 2160 mt 2110 2004 L +c14 +-335 5 -11 -147 2486 2302 3 MP +PP +0 sg +2486 2302 mt 2475 2155 L +2475 2155 mt 2140 2160 L +c10 +383 6 -9 -153 2341 2217 3 MP +PP +0 sg +2341 2217 mt 2332 2064 L +2332 2064 mt 2715 2070 L +c10 +4 -153 370 6 2341 2217 3 MP +PP +0 sg +2341 2217 mt 2711 2223 L +2711 2223 mt 2715 2070 L +c9 +-375 5 -2 -162 2463 1838 3 MP +PP +0 sg +2463 1838 mt 2461 1676 L +2461 1676 mt 2086 1681 L +c12 +-4 -161 383 6 2332 1743 3 MP +PP +0 sg +2332 1743 mt 2715 1749 L +2715 1749 mt 2711 1588 L +c9 +-6 -162 -371 5 2463 1838 3 MP +PP +0 sg +2463 1838 mt 2092 1843 L +2092 1843 mt 2086 1681 L +c8 +383 6 3 -162 2329 1905 3 MP +PP +0 sg +2329 1905 mt 2332 1743 L +2332 1743 mt 2715 1749 L +c16 +-304 4 -13 -134 2499 2436 3 MP +PP +0 sg +2499 2436 mt 2486 2302 L +2486 2302 mt 2182 2306 L +c11 +8 -141 346 5 2357 2359 3 MP +PP +0 sg +2357 2359 mt 2703 2364 L +2703 2364 mt 2711 2223 L +c8 +-371 5 2 -159 2461 1676 3 MP +PP +0 sg +2461 1676 mt 2463 1517 L +2463 1517 mt 2092 1522 L +c13 +-8 -156 370 6 2341 1582 3 MP +PP +0 sg +2341 1582 mt 2711 1588 L +2711 1588 mt 2703 1432 L +c8 +6 -159 -375 5 2461 1676 3 MP +PP +0 sg +2461 1676 mt 2086 1681 L +2086 1681 mt 2092 1522 L +c12 +370 6 9 -161 2332 1743 3 MP +PP +0 sg +2332 1743 mt 2341 1582 L +2341 1582 mt 2711 1588 L +c14 +-42 -146 -304 4 2486 2302 3 MP +PP +0 sg +2486 2302 mt 2182 2306 L +2182 2306 mt 2140 2160 L +c11 +370 6 -16 -142 2357 2359 3 MP +PP +0 sg +2357 2359 mt 2341 2217 L +2341 2217 mt 2711 2223 L +c12 +-357 6 4 -153 2463 1517 3 MP +PP +0 sg +2463 1517 mt 2467 1364 L +2467 1364 mt 2110 1370 L +c15 +-11 -147 346 5 2357 1427 3 MP +PP +0 sg +2357 1427 mt 2703 1432 L +2703 1432 mt 2692 1285 L +c16 +-51 -134 -266 4 2499 2436 3 MP +PP +0 sg +2499 2436 mt 2233 2440 L +2233 2440 mt 2182 2306 L +c18 +-266 4 -15 -119 2514 2555 3 MP +PP +0 sg +2514 2555 mt 2499 2436 L +2499 2436 mt 2233 2440 L +c14 +346 5 -21 -128 2378 2487 3 MP +PP +0 sg +2378 2487 mt 2357 2359 L +2357 2359 mt 2703 2364 L +c14 +11 -128 314 5 2378 2487 3 MP +PP +0 sg +2378 2487 mt 2692 2492 L +2692 2492 mt 2703 2364 L +c12 +18 -152 -371 5 2463 1517 3 MP +PP +0 sg +2463 1517 mt 2092 1522 L +2092 1522 mt 2110 1370 L +c13 +346 5 16 -155 2341 1582 3 MP +PP +0 sg +2341 1582 mt 2357 1427 L +2357 1427 mt 2703 1432 L +c18 +-60 -118 -221 3 2514 2555 3 MP +PP +0 sg +2514 2555 mt 2293 2558 L +2293 2558 mt 2233 2440 L +c20 +-221 3 -17 -100 2531 2655 3 MP +PP +0 sg +2531 2655 mt 2514 2555 L +2514 2555 mt 2293 2558 L +c16 +314 5 -27 -111 2405 2598 3 MP +PP +0 sg +2405 2598 mt 2378 2487 L +2378 2487 mt 2692 2492 L +c13 +30 -142 -357 6 2467 1364 3 MP +PP +0 sg +2467 1364 mt 2110 1370 L +2110 1370 mt 2140 1228 L +c13 +-335 5 8 -141 2467 1364 3 MP +PP +0 sg +2467 1364 mt 2475 1223 L +2475 1223 mt 2140 1228 L +c15 +314 5 21 -147 2357 1427 3 MP +PP +0 sg +2357 1427 mt 2378 1280 L +2378 1280 mt 2692 1285 L +c17 +-13 -134 314 5 2378 1280 3 MP +PP +0 sg +2378 1280 mt 2692 1285 L +2692 1285 mt 2679 1151 L +c16 +13 -111 274 5 2405 2598 3 MP +PP +0 sg +2405 2598 mt 2679 2603 L +2679 2603 mt 2692 2492 L +c26 +0 0 -97 2 2686 765 3 MP +PP +0 sg +2686 765 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +-41 5 -56 -3 2686 765 3 MP +PP +0 sg +2686 765 mt 2630 762 L +2630 762 mt 2589 767 L +2589 767 mt 2686 765 L +c22 +-73 -78 -117 1 2550 2734 3 MP +PP +0 sg +2550 2734 mt 2433 2735 L +2433 2735 mt 2360 2657 L +c22 +-171 2 -19 -79 2550 2734 3 MP +PP +0 sg +2550 2734 mt 2531 2655 L +2531 2655 mt 2360 2657 L +c18 +15 -90 228 3 2436 2690 3 MP +PP +0 sg +2436 2690 mt 2664 2693 L +2664 2693 mt 2679 2603 L +c20 +-67 -99 -171 2 2531 2655 3 MP +PP +0 sg +2531 2655 mt 2360 2657 L +2360 2657 mt 2293 2558 L +c18 +274 5 -31 -92 2436 2690 3 MP +PP +0 sg +2436 2690 mt 2405 2598 L +2405 2598 mt 2679 2603 L +c15 +42 -129 -335 5 2475 1223 3 MP +PP +0 sg +2475 1223 mt 2140 1228 L +2140 1228 mt 2182 1099 L +c15 +-304 4 11 -128 2475 1223 3 MP +PP +0 sg +2475 1223 mt 2486 1095 L +2486 1095 mt 2182 1099 L +c17 +274 5 27 -134 2378 1280 3 MP +PP +0 sg +2378 1280 mt 2405 1146 L +2405 1146 mt 2679 1151 L +c19 +-15 -119 274 5 2405 1146 3 MP +PP +0 sg +2405 1146 mt 2679 1151 L +2679 1151 mt 2664 1032 L +c26 +0 0 -79 -30 2668 797 3 MP +PP +0 sg +2668 797 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +-79 -30 59 -1 2609 798 3 MP +PP +0 sg +2609 798 mt 2668 797 L +2668 797 mt 2589 767 L +2589 767 mt 2609 798 L +c25 +59 -1 -19 -55 2628 853 3 MP +PP +0 sg +2628 853 mt 2609 798 L +2609 798 mt 2668 797 L +c17 +-266 4 13 -111 2486 1095 3 MP +PP +0 sg +2486 1095 mt 2499 984 L +2499 984 mt 2233 988 L +c21 +-17 -100 228 4 2436 1028 3 MP +PP +0 sg +2436 1028 mt 2664 1032 L +2664 1032 mt 2647 932 L +c17 +51 -111 -304 4 2486 1095 3 MP +PP +0 sg +2486 1095 mt 2182 1099 L +2182 1099 mt 2233 988 L +c19 +228 4 31 -118 2405 1146 3 MP +PP +0 sg +2405 1146 mt 2436 1028 L +2436 1028 mt 2664 1032 L +c24 +-77 -55 -59 1 2569 2789 3 MP +PP +0 sg +2569 2789 mt 2510 2790 L +2510 2790 mt 2433 2735 L +c24 +-117 1 -19 -55 2569 2789 3 MP +PP +0 sg +2569 2789 mt 2550 2734 L +2550 2734 mt 2433 2735 L +c20 +228 3 -35 -69 2471 2759 3 MP +PP +0 sg +2471 2759 mt 2436 2690 L +2436 2690 mt 2664 2693 L +c24 +-19 -55 -61 -1 2630 2790 3 MP +PP +0 sg +2630 2790 mt 2569 2789 L +2569 2789 mt 2550 2734 L +c20 +17 -69 176 3 2471 2759 3 MP +PP +0 sg +2471 2759 mt 2647 2762 L +2647 2762 mt 2664 2693 L +c24 +-100 5 -77 -55 2510 2790 3 MP +PP +0 sg +2510 2790 mt 2433 2735 L +2433 2735 mt 2333 2740 L +c24 +-126 -52 -51 2 2510 2790 3 MP +PP +0 sg +2510 2790 mt 2459 2792 L +2459 2792 mt 2333 2740 L +c24 +-38 5 -130 -28 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2459 2792 L +2459 2792 mt 2421 2797 L +2421 2797 mt 2589 2820 L +c24 +-51 2 -79 -30 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2510 2790 L +2510 2790 mt 2459 2792 L +2459 2792 mt 2589 2820 L +c24 +-130 -28 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2459 2792 L +c24 +-59 1 -20 -31 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2569 2789 L +2569 2789 mt 2510 2790 L +2510 2790 mt 2589 2820 L +c24 +-79 -30 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2510 2790 L +c22 +176 3 -38 -45 2509 2804 3 MP +PP +0 sg +2509 2804 mt 2471 2759 L +2471 2759 mt 2647 2762 L +c19 +60 -91 -266 4 2499 984 3 MP +PP +0 sg +2499 984 mt 2233 988 L +2233 988 mt 2293 897 L +c19 +-221 3 15 -90 2499 984 3 MP +PP +0 sg +2499 984 mt 2514 894 L +2514 894 mt 2293 897 L +c21 +176 3 35 -99 2436 1028 3 MP +PP +0 sg +2436 1028 mt 2471 929 L +2471 929 mt 2647 932 L +c24 +-20 -31 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2569 2789 L +c24 +-61 -1 41 -30 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2630 2790 L +2630 2790 mt 2569 2789 L +2569 2789 mt 2589 2820 L +c24 +41 -30 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2630 2790 L +c22 +19 -44 119 2 2509 2804 3 MP +PP +0 sg +2509 2804 mt 2628 2806 L +2628 2806 mt 2647 2762 L +c23 +-19 -79 176 3 2471 929 3 MP +PP +0 sg +2471 929 mt 2647 932 L +2647 932 mt 2628 853 L +c26 +0 0 -41 5 2630 762 3 MP +PP +0 sg +2630 762 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +20 6 -61 -1 2630 762 3 MP +PP +0 sg +2630 762 mt 2569 761 L +2569 761 mt 2589 767 L +2589 767 mt 2630 762 L +c21 +-171 3 17 -69 2514 894 3 MP +PP +0 sg +2514 894 mt 2531 825 L +2531 825 mt 2360 828 L +c25 +-19 -55 119 1 2509 852 3 MP +PP +0 sg +2509 852 mt 2628 853 L +2628 853 mt 2609 798 L +c24 +-3 5 -190 -18 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2399 2802 L +2399 2802 mt 2396 2807 L +2396 2807 mt 2589 2820 L +c24 +-22 5 -168 -23 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2421 2797 L +2421 2797 mt 2399 2802 L +2399 2802 mt 2589 2820 L +c24 +-190 -18 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2399 2802 L +c24 +-168 -23 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2421 2797 L +c24 +56 3 -97 2 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2492 2822 L +2492 2822 mt 2548 2825 L +2548 2825 mt 2589 2820 L +c24 +-41 5 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2548 2825 L +c24 +-193 -13 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2396 2807 L +c24 +48 4 -145 -2 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2444 2818 L +2444 2818 mt 2492 2822 L +2492 2822 mt 2589 2820 L +c24 +-97 2 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2492 2822 L +c24 +33 5 -178 -7 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2411 2813 L +2411 2813 mt 2444 2818 L +2444 2818 mt 2589 2820 L +c24 +-145 -2 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2444 2818 L +c24 +15 6 -193 -13 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2396 2807 L +2396 2807 mt 2411 2813 L +2411 2813 mt 2589 2820 L +c24 +-178 -7 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2411 2813 L +c24 +61 1 -41 5 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2548 2825 L +2548 2825 mt 2609 2826 L +2609 2826 mt 2589 2820 L +c24 +20 6 0 0 2589 2820 3 MP +PP +0 sg +2589 2820 mt 2589 2820 L +2589 2820 mt 2609 2826 L +c24 +19 -20 61 1 2548 2825 3 MP +PP +0 sg +2548 2825 mt 2609 2826 L +2609 2826 mt 2628 2806 L +c24 +119 2 -39 -21 2548 2825 3 MP +PP +0 sg +2548 2825 mt 2509 2804 L +2509 2804 mt 2628 2806 L +c21 +67 -69 -221 3 2514 894 3 MP +PP +0 sg +2514 894 mt 2293 897 L +2293 897 mt 2360 828 L +c23 +119 1 38 -77 2471 929 3 MP +PP +0 sg +2471 929 mt 2509 852 L +2509 852 mt 2628 853 L +c26 +-20 -31 61 1 2548 797 3 MP +PP +0 sg +2548 797 mt 2609 798 L +2609 798 mt 2589 767 L +2589 767 mt 2548 797 L +c26 +0 0 -20 -31 2609 798 3 MP +PP +0 sg +2609 798 mt 2589 767 L +2589 767 mt 2589 767 L +c23 +73 -46 -171 3 2531 825 3 MP +PP +0 sg +2531 825 mt 2360 828 L +2360 828 mt 2433 782 L +c23 +-117 1 19 -44 2531 825 3 MP +PP +0 sg +2531 825 mt 2550 781 L +2550 781 mt 2433 782 L +c25 +61 1 39 -55 2509 852 3 MP +PP +0 sg +2509 852 mt 2548 797 L +2548 797 mt 2609 798 L +c25 +-38 4 126 -23 2333 788 3 MP +PP +0 sg +2333 788 mt 2459 765 L +2459 765 mt 2421 769 L +c25 +126 -23 -100 6 2433 782 3 MP +PP +0 sg +2433 782 mt 2333 788 L +2333 788 mt 2459 765 L +c25 +-51 3 77 -20 2433 782 3 MP +PP +0 sg +2433 782 mt 2510 762 L +2510 762 mt 2459 765 L +c25 +77 -20 -117 1 2550 781 3 MP +PP +0 sg +2550 781 mt 2433 782 L +2433 782 mt 2510 762 L +c25 +-59 1 19 -20 2550 781 3 MP +PP +0 sg +2550 781 mt 2569 761 L +2569 761 mt 2510 762 L +c26 +193 -12 -3 5 2399 774 3 MP +PP +0 sg +2399 774 mt 2396 779 L +2396 779 mt 2589 767 L +2589 767 mt 2399 774 L +c26 +0 0 190 -7 2399 774 3 MP +PP +0 sg +2399 774 mt 2589 767 L +2589 767 mt 2589 767 L +c23 +-100 6 73 -46 2360 828 3 MP +PP +0 sg +2360 828 mt 2433 782 L +2433 782 mt 2333 788 L +c26 +178 -18 15 6 2396 779 3 MP +PP +0 sg +2396 779 mt 2411 785 L +2411 785 mt 2589 767 L +2589 767 mt 2396 779 L +c26 +0 0 193 -12 2396 779 3 MP +PP +0 sg +2396 779 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +0 0 178 -18 2411 785 3 MP +PP +0 sg +2411 785 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +97 -27 48 4 2444 790 3 MP +PP +0 sg +2444 790 mt 2492 794 L +2492 794 mt 2589 767 L +2589 767 mt 2444 790 L +c26 +0 0 145 -23 2444 790 3 MP +PP +0 sg +2444 790 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +41 -30 56 3 2492 794 3 MP +PP +0 sg +2492 794 mt 2548 797 L +2548 797 mt 2589 767 L +2589 767 mt 2492 794 L +c26 +0 0 97 -27 2492 794 3 MP +PP +0 sg +2492 794 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +0 0 41 -30 2548 797 3 MP +PP +0 sg +2548 797 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +79 5 -59 1 2569 761 3 MP +PP +0 sg +2569 761 mt 2510 762 L +2510 762 mt 2589 767 L +2589 767 mt 2569 761 L +c26 +0 0 20 6 2569 761 3 MP +PP +0 sg +2569 761 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +130 2 -51 3 2510 762 3 MP +PP +0 sg +2510 762 mt 2459 765 L +2459 765 mt 2589 767 L +2589 767 mt 2510 762 L +c26 +0 0 79 5 2510 762 3 MP +PP +0 sg +2510 762 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +168 -2 -38 4 2459 765 3 MP +PP +0 sg +2459 765 mt 2421 769 L +2421 769 mt 2589 767 L +2589 767 mt 2459 765 L +c26 +0 0 130 2 2459 765 3 MP +PP +0 sg +2459 765 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +190 -7 -22 5 2421 769 3 MP +PP +0 sg +2421 769 mt 2399 774 L +2399 774 mt 2589 767 L +2589 767 mt 2421 769 L +c26 +0 0 168 -2 2421 769 3 MP +PP +0 sg +2421 769 mt 2589 767 L +2589 767 mt 2589 767 L +c26 +145 -23 33 5 2411 785 3 MP +PP +0 sg +2411 785 mt 2444 790 L +2444 790 mt 2589 767 L +2589 767 mt 2411 785 L +c25 +39 -55 113 6 2396 846 3 MP +PP +0 sg +2396 846 mt 2509 852 L +2509 852 mt 2548 797 L +c25 +56 3 96 -52 2396 846 3 MP +PP +0 sg +2396 846 mt 2492 794 L +2492 794 mt 2548 797 L +c24 +-39 -21 56 3 2492 2822 3 MP +PP +0 sg +2492 2822 mt 2548 2825 L +2548 2825 mt 2509 2804 L +gr + +24 W +1 sg +2537 1175 PD +gs 655 283 3870 3023 rc +gr + +24 W +2536 1368 PD +gs 655 283 3870 3023 rc +c24 +-185 -44 -22 5 2421 2797 3 MP +PP +0 sg +2421 2797 mt 2399 2802 L +2399 2802 mt 2214 2758 L +c24 +-43 10 -164 -49 2421 2797 3 MP +PP +0 sg +2421 2797 mt 2257 2748 L +2257 2748 mt 2214 2758 L +c24 +-76 8 -126 -52 2459 2792 3 MP +PP +0 sg +2459 2792 mt 2333 2740 L +2333 2740 mt 2257 2748 L +c24 +-164 -49 -38 5 2459 2792 3 MP +PP +0 sg +2459 2792 mt 2421 2797 L +2421 2797 mt 2257 2748 L +c22 +-38 -45 113 5 2396 2799 3 MP +PP +0 sg +2396 2799 mt 2509 2804 L +2509 2804 mt 2471 2759 L +c23 +38 -77 165 7 2306 922 3 MP +PP +0 sg +2306 922 mt 2471 929 L +2471 929 mt 2509 852 L +c23 +113 6 90 -76 2306 922 3 MP +PP +0 sg +2306 922 mt 2396 846 L +2396 846 mt 2509 852 L +c24 +113 5 -96 -23 2492 2822 3 MP +PP +0 sg +2492 2822 mt 2396 2799 L +2396 2799 mt 2509 2804 L +gr + +0 sg +24 W +1 sg +2499 1242 PD +gs 655 283 3870 3023 rc +gr + +24 W +2494 1130 PD +gs 655 283 3870 3023 rc +c21 +-148 7 67 -69 2293 897 3 MP +PP +0 sg +2293 897 mt 2360 828 L +2360 828 mt 2212 835 L +c23 +121 -47 -148 7 2360 828 3 MP +PP +0 sg +2360 828 mt 2212 835 L +2212 835 mt 2333 788 L +c25 +96 -52 93 8 2303 838 3 MP +PP +0 sg +2303 838 mt 2396 846 L +2396 846 mt 2492 794 L +c25 +48 4 141 -48 2303 838 3 MP +PP +0 sg +2303 838 mt 2444 790 L +2444 790 mt 2492 794 L +c24 +-96 -23 48 4 2444 2818 3 MP +PP +0 sg +2444 2818 mt 2492 2822 L +2492 2822 mt 2396 2799 L +gr + +0 sg +24 W +1 sg +2486 1310 PD +gs 655 283 3870 3023 rc +gr + +24 W +2473 1335 PD +gs 655 283 3870 3023 rc +c21 +35 -99 213 10 2223 1018 3 MP +PP +0 sg +2223 1018 mt 2436 1028 L +2436 1028 mt 2471 929 L +c22 +165 8 -90 -48 2396 2799 3 MP +PP +0 sg +2396 2799 mt 2306 2751 L +2306 2751 mt 2471 2759 L +c22 +-111 11 -121 -75 2333 2740 3 MP +PP +0 sg +2333 2740 mt 2212 2665 L +2212 2665 mt 2101 2676 L +c22 +-156 -72 -76 8 2333 2740 3 MP +PP +0 sg +2333 2740 mt 2257 2748 L +2257 2748 mt 2101 2676 L +c22 +-148 8 -73 -78 2433 2735 3 MP +PP +0 sg +2433 2735 mt 2360 2657 L +2360 2657 mt 2212 2665 L +c22 +-121 -75 -100 5 2433 2735 3 MP +PP +0 sg +2433 2735 mt 2333 2740 L +2333 2740 mt 2212 2665 L +c20 +-35 -69 165 8 2306 2751 3 MP +PP +0 sg +2306 2751 mt 2471 2759 L +2471 2759 mt 2436 2690 L +c21 +165 7 83 -96 2223 1018 3 MP +PP +0 sg +2223 1018 mt 2306 922 L +2306 922 mt 2471 929 L +gr + +0 sg +24 W +1 sg +2469 1460 PD +gs 655 283 3870 3023 rc +gr + +24 W +2468 1452 PD +gs 655 283 3870 3023 rc +gr + +24 W +2455 1166 PD +gs 655 283 3870 3023 rc +c25 +141 -48 65 10 2238 828 3 MP +PP +0 sg +2238 828 mt 2303 838 L +2303 838 mt 2444 790 L +c25 +33 5 173 -43 2238 828 3 MP +PP +0 sg +2238 828 mt 2411 785 L +2411 785 mt 2444 790 L +c24 +31 11 -189 -37 2396 2807 3 MP +PP +0 sg +2396 2807 mt 2207 2770 L +2207 2770 mt 2238 2781 L +c24 +-173 -32 15 6 2396 2807 3 MP +PP +0 sg +2396 2807 mt 2411 2813 L +2411 2813 mt 2238 2781 L +c24 +-141 -27 33 5 2411 2813 3 MP +PP +0 sg +2411 2813 mt 2444 2818 L +2444 2818 mt 2303 2791 L +c24 +-189 -37 -3 5 2399 2802 3 MP +PP +0 sg +2399 2802 mt 2396 2807 L +2396 2807 mt 2207 2770 L +c24 +-7 12 -185 -44 2399 2802 3 MP +PP +0 sg +2399 2802 mt 2214 2758 L +2214 2758 mt 2207 2770 L +c24 +93 8 -141 -27 2444 2818 3 MP +PP +0 sg +2444 2818 mt 2303 2791 L +2303 2791 mt 2396 2799 L +c20 +213 10 -83 -71 2306 2751 3 MP +PP +0 sg +2306 2751 mt 2223 2680 L +2223 2680 mt 2436 2690 L +c20 +-192 10 -67 -99 2360 2657 3 MP +PP +0 sg +2360 2657 mt 2293 2558 L +2293 2558 mt 2101 2568 L +c20 +-111 -97 -148 8 2360 2657 3 MP +PP +0 sg +2360 2657 mt 2212 2665 L +2212 2665 mt 2101 2568 L +c18 +-31 -92 213 10 2223 2680 3 MP +PP +0 sg +2223 2680 mt 2436 2690 L +2436 2690 mt 2405 2598 L +c15 +-264 14 42 -129 2140 1228 3 MP +PP +0 sg +2140 1228 mt 2182 1099 L +2182 1099 mt 1918 1113 L +c19 +31 -118 257 12 2148 1134 3 MP +PP +0 sg +2148 1134 mt 2405 1146 L +2405 1146 mt 2436 1028 L +c17 +84 -113 -264 14 2182 1099 3 MP +PP +0 sg +2182 1099 mt 1918 1113 L +1918 1113 mt 2002 1000 L +c17 +-231 12 51 -111 2182 1099 3 MP +PP +0 sg +2182 1099 mt 2233 988 L +2233 988 mt 2002 1000 L +c19 +213 10 75 -116 2148 1134 3 MP +PP +0 sg +2148 1134 mt 2223 1018 L +2223 1018 mt 2436 1028 L +gr + +0 sg +24 W +1 sg +2433 1138 PD +gs 655 283 3870 3023 rc +gr + +24 W +2423 1068 PD +gs 655 283 3870 3023 rc +gr + +24 W +2422 1192 PD +gs 655 283 3870 3023 rc +c25 +164 -27 -76 8 2333 788 3 MP +PP +0 sg +2333 788 mt 2257 796 L +2257 796 mt 2421 769 L +c25 +-22 5 164 -27 2257 796 3 MP +PP +0 sg +2257 796 mt 2421 769 L +2421 769 mt 2399 774 L +gr + +0 sg +24 W +1 sg +2417 1377 PD +gs 655 283 3870 3023 rc +gr + +24 W +2416 1137 PD +gs 655 283 3870 3023 rc +gr + +24 W +2412 1295 PD +gs 655 283 3870 3023 rc +c23 +156 -51 -111 12 2212 835 3 MP +PP +0 sg +2212 835 mt 2101 847 L +2101 847 mt 2257 796 L +c23 +-76 8 121 -47 2212 835 3 MP +PP +0 sg +2212 835 mt 2333 788 L +2333 788 mt 2257 796 L +c25 +173 -43 31 11 2207 817 3 MP +PP +0 sg +2207 817 mt 2238 828 L +2238 828 mt 2411 785 L +c25 +15 6 189 -38 2207 817 3 MP +PP +0 sg +2207 817 mt 2396 779 L +2396 779 mt 2411 785 L +c24 +65 10 -173 -32 2411 2813 3 MP +PP +0 sg +2411 2813 mt 2238 2781 L +2238 2781 mt 2303 2791 L +c18 +-99 -116 -192 10 2293 2558 3 MP +PP +0 sg +2293 2558 mt 2101 2568 L +2101 2568 mt 2002 2452 L +c18 +-231 12 -60 -118 2293 2558 3 MP +PP +0 sg +2293 2558 mt 2233 2440 L +2233 2440 mt 2002 2452 L +c16 +-27 -111 257 12 2148 2586 3 MP +PP +0 sg +2148 2586 mt 2405 2598 L +2405 2598 mt 2378 2487 L +c20 +-144 -93 -111 11 2212 2665 3 MP +PP +0 sg +2212 2665 mt 2101 2676 L +2101 2676 mt 1957 2583 L +c20 +-144 15 -111 -97 2212 2665 3 MP +PP +0 sg +2212 2665 mt 2101 2568 L +2101 2568 mt 1957 2583 L +c18 +257 12 -75 -94 2223 2680 3 MP +PP +0 sg +2223 2680 mt 2148 2586 L +2148 2586 mt 2405 2598 L +c13 +-290 14 30 -142 2110 1370 3 MP +PP +0 sg +2110 1370 mt 2140 1228 L +2140 1228 mt 1850 1242 L +c15 +68 -129 -290 14 2140 1228 3 MP +PP +0 sg +2140 1228 mt 1850 1242 L +1850 1242 mt 1918 1113 L +c17 +257 12 63 -133 2085 1267 3 MP +PP +0 sg +2085 1267 mt 2148 1134 L +2148 1134 mt 2405 1146 L +c17 +27 -134 293 13 2085 1267 3 MP +PP +0 sg +2085 1267 mt 2378 1280 L +2378 1280 mt 2405 1146 L +gr + +0 sg +24 W +1 sg +2402 1483 PD +gs 655 283 3870 3023 rc +c23 +-43 10 156 -51 2101 847 3 MP +PP +0 sg +2101 847 mt 2257 796 L +2257 796 mt 2214 806 L +c25 +-3 5 185 -32 2214 806 3 MP +PP +0 sg +2214 806 mt 2399 774 L +2399 774 mt 2396 779 L +c25 +185 -32 -43 10 2257 796 3 MP +PP +0 sg +2257 796 mt 2214 806 L +2214 806 mt 2399 774 L +c21 +111 -72 -192 10 2293 897 3 MP +PP +0 sg +2293 897 mt 2101 907 L +2101 907 mt 2212 835 L +c19 +-192 10 60 -91 2233 988 3 MP +PP +0 sg +2233 988 mt 2293 897 L +2293 897 mt 2101 907 L +c23 +93 8 134 -72 2169 910 3 MP +PP +0 sg +2169 910 mt 2303 838 L +2303 838 mt 2396 846 L +c23 +90 -76 137 12 2169 910 3 MP +PP +0 sg +2169 910 mt 2306 922 L +2306 922 mt 2396 846 L +c22 +-90 -48 93 8 2303 2791 3 MP +PP +0 sg +2303 2791 mt 2396 2799 L +2396 2799 mt 2306 2751 L +c25 +189 -38 -7 11 2214 806 3 MP +PP +0 sg +2214 806 mt 2207 817 L +2207 817 mt 2396 779 L +gr + +0 sg +24 W +1 sg +2395 1533 PD +gs 655 283 3870 3023 rc +gr + +24 W +2380 1458 PD +gs 655 283 3870 3023 rc +c12 +-310 15 18 -152 2092 1522 3 MP +PP +0 sg +2092 1522 mt 2110 1370 L +2110 1370 mt 1800 1385 L +c13 +50 -143 -310 15 2110 1370 3 MP +PP +0 sg +2110 1370 mt 1800 1385 L +1800 1385 mt 1850 1242 L +c15 +293 13 51 -145 2034 1412 3 MP +PP +0 sg +2034 1412 mt 2085 1267 L +2085 1267 mt 2378 1280 L +c15 +21 -147 323 15 2034 1412 3 MP +PP +0 sg +2034 1412 mt 2357 1427 L +2357 1427 mt 2378 1280 L +c16 +293 14 -63 -113 2148 2586 3 MP +PP +0 sg +2148 2586 mt 2085 2473 L +2085 2473 mt 2378 2487 L +c16 +-84 -133 -231 12 2233 2440 3 MP +PP +0 sg +2233 2440 mt 2002 2452 L +2002 2452 mt 1918 2319 L +c16 +-264 13 -51 -134 2233 2440 3 MP +PP +0 sg +2233 2440 mt 2182 2306 L +2182 2306 mt 1918 2319 L +c14 +-21 -128 293 14 2085 2473 3 MP +PP +0 sg +2085 2473 mt 2378 2487 L +2378 2487 mt 2357 2359 L +gr + +0 sg +24 W +1 sg +2377 1363 PD +gs 655 283 3870 3023 rc +gr + +24 W +2371 1171 PD +gs 655 283 3870 3023 rc +gr + +24 W +2363 1468 PD +gs 655 283 3870 3023 rc +gr + +24 W +2362 1090 PD +gs 655 283 3870 3023 rc +c14 +323 15 -51 -129 2085 2473 3 MP +PP +0 sg +2085 2473 mt 2034 2344 L +2034 2344 mt 2357 2359 L +c14 +-290 14 -42 -146 2182 2306 3 MP +PP +0 sg +2182 2306 mt 2140 2160 L +2140 2160 mt 1850 2174 L +c14 +-68 -145 -264 13 2182 2306 3 MP +PP +0 sg +2182 2306 mt 1918 2319 L +1918 2319 mt 1850 2174 L +c11 +-16 -142 323 15 2034 2344 3 MP +PP +0 sg +2034 2344 mt 2357 2359 L +2357 2359 mt 2341 2217 L +c8 +-323 16 6 -159 2086 1681 3 MP +PP +0 sg +2086 1681 mt 2092 1522 L +2092 1522 mt 1769 1538 L +c13 +16 -155 345 16 1996 1566 3 MP +PP +0 sg +1996 1566 mt 2341 1582 L +2341 1582 mt 2357 1427 L +c12 +31 -153 -323 16 2092 1522 3 MP +PP +0 sg +2092 1522 mt 1769 1538 L +1769 1538 mt 1800 1385 L +c13 +323 15 38 -154 1996 1566 3 MP +PP +0 sg +1996 1566 mt 2034 1412 L +2034 1412 mt 2357 1427 L +gr + +0 sg +24 W +1 sg +2352 1286 PD +gs 655 283 3870 3023 rc +gr + +24 W +2349 1525 PD +gs 655 283 3870 3023 rc +gr + +24 W +2343 1285 PD +gs 655 283 3870 3023 rc +c8 +10 -160 -327 17 2086 1681 3 MP +PP +0 sg +2086 1681 mt 1759 1698 L +1759 1698 mt 1769 1538 L +c9 +-327 17 -6 -162 2092 1843 3 MP +PP +0 sg +2092 1843 mt 2086 1681 L +2086 1681 mt 1759 1698 L +c12 +345 16 22 -160 1974 1726 3 MP +PP +0 sg +1974 1726 mt 1996 1566 L +1996 1566 mt 2341 1582 L +c11 +345 16 -38 -143 2034 2344 3 MP +PP +0 sg +2034 2344 mt 1996 2201 L +1996 2201 mt 2341 2217 L +c12 +9 -161 358 17 1974 1726 3 MP +PP +0 sg +1974 1726 mt 2332 1743 L +2332 1743 mt 2341 1582 L +c11 +-310 16 -30 -156 2140 2160 3 MP +PP +0 sg +2140 2160 mt 2110 2004 L +2110 2004 mt 1800 2020 L +c11 +-50 -154 -290 14 2140 2160 3 MP +PP +0 sg +2140 2160 mt 1850 2174 L +1850 2174 mt 1800 2020 L +c10 +-9 -153 345 16 1996 2201 3 MP +PP +0 sg +1996 2201 mt 2341 2217 L +2341 2217 mt 2332 2064 L +gr + +0 sg +24 W +1 sg +2336 1394 PD +gs 655 283 3870 3023 rc +gr + +24 W +2334 1123 PD +gs 655 283 3870 3023 rc +gr + +24 W +2334 1344 PD +gs 655 283 3870 3023 rc +c10 +-323 17 -18 -161 2110 2004 3 MP +PP +0 sg +2110 2004 mt 2092 1843 L +2092 1843 mt 1769 1860 L +c10 +-31 -160 -310 16 2110 2004 3 MP +PP +0 sg +2110 2004 mt 1800 2020 L +1800 2020 mt 1769 1860 L +c9 +-3 -159 358 17 1974 2047 3 MP +PP +0 sg +1974 2047 mt 2332 2064 L +2332 2064 mt 2329 1905 L +c10 +358 17 -22 -154 1996 2201 3 MP +PP +0 sg +1996 2201 mt 1974 2047 L +1974 2047 mt 2332 2064 L +c9 +-10 -162 -323 17 2092 1843 3 MP +PP +0 sg +2092 1843 mt 1769 1860 L +1769 1860 mt 1759 1698 L +c8 +3 -162 363 17 1966 1888 3 MP +PP +0 sg +1966 1888 mt 2329 1905 L +2329 1905 mt 2332 1743 L +c8 +358 17 8 -162 1966 1888 3 MP +PP +0 sg +1966 1888 mt 1974 1726 L +1974 1726 mt 2332 1743 L +c9 +363 17 -8 -159 1974 2047 3 MP +PP +0 sg +1974 2047 mt 1966 1888 L +1966 1888 mt 2329 1905 L +gr + +0 sg +24 W +1 sg +2319 1083 PD +gs 655 283 3870 3023 rc +c19 +99 -93 -231 12 2233 988 3 MP +PP +0 sg +2233 988 mt 2002 1000 L +2002 1000 mt 2101 907 L +c21 +83 -96 178 15 2045 1003 3 MP +PP +0 sg +2045 1003 mt 2223 1018 L +2223 1018 mt 2306 922 L +c21 +137 12 124 -93 2045 1003 3 MP +PP +0 sg +2045 1003 mt 2169 910 L +2169 910 mt 2306 922 L +c22 +-64 15 -156 -72 2257 2748 3 MP +PP +0 sg +2257 2748 mt 2101 2676 L +2101 2676 mt 2037 2691 L +c22 +-177 -67 -43 10 2257 2748 3 MP +PP +0 sg +2257 2748 mt 2214 2758 L +2214 2758 mt 2037 2691 L +c22 +137 12 -134 -52 2303 2791 3 MP +PP +0 sg +2303 2791 mt 2169 2739 L +2169 2739 mt 2306 2751 L +c20 +-83 -71 137 12 2169 2739 3 MP +PP +0 sg +2169 2739 mt 2306 2751 L +2306 2751 mt 2223 2680 L +c21 +144 -75 -144 15 2101 907 3 MP +PP +0 sg +2101 907 mt 1957 922 L +1957 922 mt 2101 847 L +c21 +-111 12 111 -72 2101 907 3 MP +PP +0 sg +2101 907 mt 2212 835 L +2212 835 mt 2101 847 L +c23 +134 -72 96 15 2073 895 3 MP +PP +0 sg +2073 895 mt 2169 910 L +2169 910 mt 2303 838 L +c22 +-9 17 -177 -67 2214 2758 3 MP +PP +0 sg +2214 2758 mt 2037 2691 L +2037 2691 mt 2028 2708 L +c22 +-179 -62 -7 12 2214 2758 3 MP +PP +0 sg +2214 2758 mt 2207 2770 L +2207 2770 mt 2028 2708 L +c22 +-134 -52 65 10 2238 2781 3 MP +PP +0 sg +2238 2781 mt 2303 2791 L +2303 2791 mt 2169 2739 L +c23 +65 10 165 -67 2073 895 3 MP +PP +0 sg +2073 895 mt 2238 828 L +2238 828 mt 2303 838 L +gr + +0 sg +24 W +1 sg +2296 1466 PD +gs 655 283 3870 3023 rc +gr + +24 W +2296 1226 PD +gs 655 283 3870 3023 rc +gr + +24 W +2283 1362 PD +gs 655 283 3870 3023 rc +gr + +24 W +2282 1224 PD +gs 655 283 3870 3023 rc +gr + +24 W +2278 1568 PD +gs 655 283 3870 3023 rc +gr + +24 W +2277 1304 PD +gs 655 283 3870 3023 rc +gr + +24 W +2277 1508 PD +gs 655 283 3870 3023 rc +gr + +24 W +2276 1112 PD +gs 655 283 3870 3023 rc +gr + +24 W +2275 1509 PD +gs 655 283 3870 3023 rc +gr + +24 W +2275 1469 PD +gs 655 283 3870 3023 rc +gr + +24 W +2266 1343 PD +gs 655 283 3870 3023 rc +gr + +24 W +2255 1272 PD +gs 655 283 3870 3023 rc +gr + +24 W +2254 1571 PD +gs 655 283 3870 3023 rc +gr + +24 W +2246 1094 PD +gs 655 283 3870 3023 rc +gr + +24 W +2240 1103 PD +gs 655 283 3870 3023 rc +c21 +-64 15 144 -75 1957 922 3 MP +PP +0 sg +1957 922 mt 2101 847 L +2101 847 mt 2037 862 L +c23 +165 -67 45 17 2028 878 3 MP +PP +0 sg +2028 878 mt 2073 895 L +2073 895 mt 2238 828 L +c22 +45 16 -179 -62 2207 2770 3 MP +PP +0 sg +2207 2770 mt 2028 2708 L +2028 2708 mt 2073 2724 L +c22 +-165 -57 31 11 2207 2770 3 MP +PP +0 sg +2207 2770 mt 2238 2781 L +2238 2781 mt 2073 2724 L +c22 +96 15 -165 -57 2238 2781 3 MP +PP +0 sg +2238 2781 mt 2073 2724 L +2073 2724 mt 2169 2739 L +c23 +31 11 179 -61 2028 878 3 MP +PP +0 sg +2028 878 mt 2207 817 L +2207 817 mt 2238 828 L +gr + +0 sg +24 W +1 sg +2236 1229 PD +gs 655 283 3870 3023 rc +gr + +24 W +2231 1383 PD +gs 655 283 3870 3023 rc +gr + +24 W +2230 1121 PD +gs 655 283 3870 3023 rc +gr + +24 W +2229 1442 PD +gs 655 283 3870 3023 rc +gr + +24 W +2228 1318 PD +gs 655 283 3870 3023 rc +gr + +24 W +2223 1194 PD +gs 655 283 3870 3023 rc +c20 +-82 19 -144 -93 2101 2676 3 MP +PP +0 sg +2101 2676 mt 1957 2583 L +1957 2583 mt 1875 2602 L +c20 +-162 -89 -64 15 2101 2676 3 MP +PP +0 sg +2101 2676 mt 2037 2691 L +2037 2691 mt 1875 2602 L +c18 +-75 -94 178 16 2045 2664 3 MP +PP +0 sg +2045 2664 mt 2223 2680 L +2223 2680 mt 2148 2586 L +c19 +178 15 110 -113 1935 1116 3 MP +PP +0 sg +1935 1116 mt 2045 1003 L +2045 1003 mt 2223 1018 L +c19 +75 -116 213 18 1935 1116 3 MP +PP +0 sg +1935 1116 mt 2148 1134 L +2148 1134 mt 2223 1018 L +c20 +178 16 -124 -75 2169 2739 3 MP +PP +0 sg +2169 2739 mt 2045 2664 L +2045 2664 mt 2223 2680 L +c23 +177 -56 -64 15 2101 847 3 MP +PP +0 sg +2101 847 mt 2037 862 L +2037 862 mt 2214 806 L +c23 +-7 11 177 -56 2037 862 3 MP +PP +0 sg +2037 862 mt 2214 806 L +2214 806 mt 2207 817 L +gr + +0 sg +24 W +1 sg +2208 1555 PD +gs 655 283 3870 3023 rc +c23 +179 -61 -9 16 2037 862 3 MP +PP +0 sg +2037 862 mt 2028 878 L +2028 878 mt 2207 817 L +gr + +0 sg +24 W +1 sg +2198 1227 PD +gs 655 283 3870 3023 rc +gr + +24 W +2198 1472 PD +gs 655 283 3870 3023 rc +c19 +128 -96 -173 18 2002 1000 3 MP +PP +0 sg +2002 1000 mt 1829 1018 L +1829 1018 mt 1957 922 L +c19 +-144 15 99 -93 2002 1000 3 MP +PP +0 sg +2002 1000 mt 2101 907 L +2101 907 mt 1957 922 L +c21 +124 -93 124 19 1921 984 3 MP +PP +0 sg +1921 984 mt 2045 1003 L +2045 1003 mt 2169 910 L +c21 +96 15 152 -89 1921 984 3 MP +PP +0 sg +1921 984 mt 2073 895 L +2073 895 mt 2169 910 L +c20 +-124 -75 96 15 2073 2724 3 MP +PP +0 sg +2073 2724 mt 2169 2739 L +2169 2739 mt 2045 2664 L +gr + +0 sg +24 W +1 sg +2156 1272 PD +gs 655 283 3870 3023 rc +c13 +-219 23 50 -143 1800 1385 3 MP +PP +0 sg +1800 1385 mt 1850 1242 L +1850 1242 mt 1631 1265 L +c15 +88 -132 -219 23 1850 1242 3 MP +PP +0 sg +1850 1242 mt 1631 1265 L +1631 1265 mt 1719 1133 L +c15 +-199 20 68 -129 1850 1242 3 MP +PP +0 sg +1850 1242 mt 1918 1113 L +1918 1113 mt 1719 1133 L +c17 +213 18 94 -129 1841 1245 3 MP +PP +0 sg +1841 1245 mt 1935 1116 L +1935 1116 mt 2148 1134 L +c17 +63 -133 244 22 1841 1245 3 MP +PP +0 sg +1841 1245 mt 2085 1267 L +2085 1267 mt 2148 1134 L +c18 +-99 23 -128 -113 1957 2583 3 MP +PP +0 sg +1957 2583 mt 1829 2470 L +1829 2470 mt 1730 2493 L +c18 +-128 -113 -144 15 2101 2568 3 MP +PP +0 sg +2101 2568 mt 1957 2583 L +1957 2583 mt 1829 2470 L +c18 +-173 18 -99 -116 2101 2568 3 MP +PP +0 sg +2101 2568 mt 2002 2452 L +2002 2452 mt 1829 2470 L +c16 +-63 -113 213 18 1935 2568 3 MP +PP +0 sg +1935 2568 mt 2148 2586 L +2148 2586 mt 2085 2473 L +c18 +-145 -109 -82 19 1957 2583 3 MP +PP +0 sg +1957 2583 mt 1875 2602 L +1875 2602 mt 1730 2493 L +c18 +213 18 -110 -96 2045 2664 3 MP +PP +0 sg +2045 2664 mt 1935 2568 L +1935 2568 mt 2148 2586 L +gr + +0 sg +24 W +1 sg +2147 1174 PD +gs 655 283 3870 3023 rc +gr + +24 W +2145 1460 PD +gs 655 283 3870 3023 rc +gr + +24 W +2144 1415 PD +gs 655 283 3870 3023 rc +gr + +24 W +2139 1245 PD +gs 655 283 3870 3023 rc +gr + +24 W +2133 1357 PD +gs 655 283 3870 3023 rc +gr + +24 W +2119 1506 PD +gs 655 283 3870 3023 rc +gr + +24 W +2104 1104 PD +gs 655 283 3870 3023 rc +gr + +24 W +2088 1296 PD +gs 655 283 3870 3023 rc +gr + +24 W +2085 1566 PD +gs 655 283 3870 3023 rc +c13 +64 -145 -233 25 1800 1385 3 MP +PP +0 sg +1800 1385 mt 1567 1410 L +1567 1410 mt 1631 1265 L +c15 +244 22 76 -143 1765 1388 3 MP +PP +0 sg +1765 1388 mt 1841 1245 L +1841 1245 mt 2085 1267 L +c16 +-110 -130 -173 18 2002 2452 3 MP +PP +0 sg +2002 2452 mt 1829 2470 L +1829 2470 mt 1719 2340 L +c16 +244 21 -94 -116 1935 2568 3 MP +PP +0 sg +1935 2568 mt 1841 2452 L +1841 2452 mt 2085 2473 L +c12 +-233 25 31 -153 1769 1538 3 MP +PP +0 sg +1769 1538 mt 1800 1385 L +1800 1385 mt 1567 1410 L +c15 +51 -145 269 24 1765 1388 3 MP +PP +0 sg +1765 1388 mt 2034 1412 L +2034 1412 mt 2085 1267 L +c16 +-199 21 -84 -133 2002 2452 3 MP +PP +0 sg +2002 2452 mt 1918 2319 L +1918 2319 mt 1719 2340 L +c14 +-51 -129 244 21 1841 2452 3 MP +PP +0 sg +1841 2452 mt 2085 2473 L +2085 2473 mt 2034 2344 L +gr + +0 sg +24 W +1 sg +2084 1577 PD +gs 655 283 3870 3023 rc +gr + +24 W +2082 1468 PD +gs 655 283 3870 3023 rc +gr + +24 W +2081 1270 PD +gs 655 283 3870 3023 rc +gr + +24 W +2080 1114 PD +gs 655 283 3870 3023 rc +gr + +24 W +2080 1148 PD +gs 655 283 3870 3023 rc +gr + +24 W +2078 1200 PD +gs 655 283 3870 3023 rc +c19 +-82 19 128 -96 1829 1018 3 MP +PP +0 sg +1829 1018 mt 1957 922 L +1957 922 mt 1875 941 L +c21 +152 -89 59 22 1862 962 3 MP +PP +0 sg +1862 962 mt 1921 984 L +1921 984 mt 2073 895 L +c20 +-166 -85 -9 17 2037 2691 3 MP +PP +0 sg +2037 2691 mt 2028 2708 L +2028 2708 mt 1862 2623 L +c20 +-13 21 -162 -89 2037 2691 3 MP +PP +0 sg +2037 2691 mt 1875 2602 L +1875 2602 mt 1862 2623 L +c20 +124 19 -152 -79 2073 2724 3 MP +PP +0 sg +2073 2724 mt 1921 2645 L +1921 2645 mt 2045 2664 L +c20 +-152 -79 45 16 2028 2708 3 MP +PP +0 sg +2028 2708 mt 2073 2724 L +2073 2724 mt 1921 2645 L +c21 +162 -79 -82 19 1957 922 3 MP +PP +0 sg +1957 922 mt 1875 941 L +1875 941 mt 2037 862 L +c21 +45 17 166 -84 1862 962 3 MP +PP +0 sg +1862 962 mt 2028 878 L +2028 878 mt 2073 895 L +gr + +0 sg +24 W +1 sg +2072 1177 PD +gs 655 283 3870 3023 rc +gr + +24 W +2066 1251 PD +gs 655 283 3870 3023 rc +gr + +24 W +2063 1542 PD +gs 655 283 3870 3023 rc +gr + +24 W +2057 1488 PD +gs 655 283 3870 3023 rc +gr + +24 W +2047 1486 PD +gs 655 283 3870 3023 rc +gr + +24 W +2046 1220 PD +gs 655 283 3870 3023 rc +c17 +110 -115 -199 20 1918 1113 3 MP +PP +0 sg +1918 1113 mt 1719 1133 L +1719 1133 mt 1829 1018 L +c17 +-173 18 84 -113 1918 1113 3 MP +PP +0 sg +1918 1113 mt 2002 1000 L +2002 1000 mt 1829 1018 L +c19 +110 -113 149 23 1786 1093 3 MP +PP +0 sg +1786 1093 mt 1935 1116 L +1935 1116 mt 2045 1003 L +c19 +124 19 135 -109 1786 1093 3 MP +PP +0 sg +1786 1093 mt 1921 984 L +1921 984 mt 2045 1003 L +c18 +-110 -96 124 19 1921 2645 3 MP +PP +0 sg +1921 2645 mt 2045 2664 L +2045 2664 mt 1935 2568 L +c21 +-9 16 162 -79 1875 941 3 MP +PP +0 sg +1875 941 mt 2037 862 L +2037 862 mt 2028 878 L +gr + +0 sg +24 W +1 sg +2037 1353 PD +gs 655 283 3870 3023 rc +c12 +40 -154 -242 26 1769 1538 3 MP +PP +0 sg +1769 1538 mt 1527 1564 L +1527 1564 mt 1567 1410 L +c13 +269 24 56 -153 1709 1541 3 MP +PP +0 sg +1709 1541 mt 1765 1388 L +1765 1388 mt 2034 1412 L +c8 +-242 26 10 -160 1759 1698 3 MP +PP +0 sg +1759 1698 mt 1769 1538 L +1769 1538 mt 1527 1564 L +c13 +38 -154 287 25 1709 1541 3 MP +PP +0 sg +1709 1541 mt 1996 1566 L +1996 1566 mt 2034 1412 L +c14 +-88 -143 -199 21 1918 2319 3 MP +PP +0 sg +1918 2319 mt 1719 2340 L +1719 2340 mt 1631 2197 L +c14 +269 24 -76 -132 1841 2452 3 MP +PP +0 sg +1841 2452 mt 1765 2320 L +1765 2320 mt 2034 2344 L +c14 +-219 23 -68 -145 1918 2319 3 MP +PP +0 sg +1918 2319 mt 1850 2174 L +1850 2174 mt 1631 2197 L +c11 +-38 -143 269 24 1765 2320 3 MP +PP +0 sg +1765 2320 mt 2034 2344 L +2034 2344 mt 1996 2201 L +gr + +0 sg +24 W +1 sg +2028 1244 PD +gs 655 283 3870 3023 rc +c20 +59 22 -166 -85 2028 2708 3 MP +PP +0 sg +2028 2708 mt 1862 2623 L +1862 2623 mt 1921 2645 L +c21 +166 -84 -13 21 1875 941 3 MP +PP +0 sg +1875 941 mt 1862 962 L +1862 962 mt 2028 878 L +gr + +0 sg +24 W +1 sg +2026 1236 PD +gs 655 283 3870 3023 rc +gr + +24 W +2022 1406 PD +gs 655 283 3870 3023 rc +gr + +24 W +2015 1452 PD +gs 655 283 3870 3023 rc +gr + +24 W +2010 1495 PD +gs 655 283 3870 3023 rc +gr + +24 W +1997 1384 PD +gs 655 283 3870 3023 rc +c8 +13 -160 -245 26 1759 1698 3 MP +PP +0 sg +1759 1698 mt 1514 1724 L +1514 1724 mt 1527 1564 L +c12 +287 25 33 -159 1676 1700 3 MP +PP +0 sg +1676 1700 mt 1709 1541 L +1709 1541 mt 1996 1566 L +c11 +-64 -153 -219 23 1850 2174 3 MP +PP +0 sg +1850 2174 mt 1631 2197 L +1631 2197 mt 1567 2044 L +c11 +-233 24 -50 -154 1850 2174 3 MP +PP +0 sg +1850 2174 mt 1800 2020 L +1800 2020 mt 1567 2044 L +c10 +-22 -154 287 25 1709 2176 3 MP +PP +0 sg +1709 2176 mt 1996 2201 L +1996 2201 mt 1974 2047 L +c11 +287 25 -56 -144 1765 2320 3 MP +PP +0 sg +1765 2320 mt 1709 2176 L +1709 2176 mt 1996 2201 L +c9 +-245 26 -10 -162 1769 1860 3 MP +PP +0 sg +1769 1860 mt 1759 1698 L +1759 1698 mt 1514 1724 L +c12 +22 -160 298 26 1676 1700 3 MP +PP +0 sg +1676 1700 mt 1974 1726 L +1974 1726 mt 1996 1566 L +gr + +0 sg +24 W +1 sg +1994 1140 PD +gs 655 283 3870 3023 rc +gr + +24 W +1990 1286 PD +gs 655 283 3870 3023 rc +gr + +24 W +1987 1174 PD +gs 655 283 3870 3023 rc +gr + +24 W +1984 1190 PD +gs 655 283 3870 3023 rc +gr + +24 W +1983 1305 PD +gs 655 283 3870 3023 rc +c10 +-40 -159 -233 24 1800 2020 3 MP +PP +0 sg +1800 2020 mt 1567 2044 L +1567 2044 mt 1527 1885 L +c10 +298 25 -33 -154 1709 2176 3 MP +PP +0 sg +1709 2176 mt 1676 2022 L +1676 2022 mt 1974 2047 L +c9 +-13 -161 -242 25 1769 1860 3 MP +PP +0 sg +1769 1860 mt 1527 1885 L +1527 1885 mt 1514 1724 L +c10 +-242 25 -31 -160 1800 2020 3 MP +PP +0 sg +1800 2020 mt 1769 1860 L +1769 1860 mt 1527 1885 L +c8 +8 -162 302 26 1664 1862 3 MP +PP +0 sg +1664 1862 mt 1966 1888 L +1966 1888 mt 1974 1726 L +c9 +-8 -159 298 25 1676 2022 3 MP +PP +0 sg +1676 2022 mt 1974 2047 L +1974 2047 mt 1966 1888 L +c8 +298 26 12 -162 1664 1862 3 MP +PP +0 sg +1664 1862 mt 1676 1700 L +1676 1700 mt 1974 1726 L +gr + +0 sg +24 W +1 sg +1973 1206 PD +gs 655 283 3870 3023 rc +gr + +24 W +1966 1393 PD +gs 655 283 3870 3023 rc +gr + +24 W +1966 1276 PD +gs 655 283 3870 3023 rc +c9 +302 26 -12 -160 1676 2022 3 MP +PP +0 sg +1676 2022 mt 1664 1862 L +1664 1862 mt 1966 1888 L +gr + +0 sg +24 W +1 sg +1955 1192 PD +gs 655 283 3870 3023 rc +gr + +24 W +1948 1369 PD +gs 655 283 3870 3023 rc +c18 +-147 -104 -13 21 1875 2602 3 MP +PP +0 sg +1875 2602 mt 1862 2623 L +1862 2623 mt 1715 2519 L +c18 +-15 26 -145 -109 1875 2602 3 MP +PP +0 sg +1875 2602 mt 1730 2493 L +1730 2493 mt 1715 2519 L +c18 +149 24 -135 -101 1921 2645 3 MP +PP +0 sg +1921 2645 mt 1786 2544 L +1786 2544 mt 1935 2568 L +c17 +149 23 116 -126 1670 1219 3 MP +PP +0 sg +1670 1219 mt 1786 1093 L +1786 1093 mt 1935 1116 L +c17 +94 -129 171 26 1670 1219 3 MP +PP +0 sg +1670 1219 mt 1841 1245 L +1841 1245 mt 1935 1116 L +c16 +-94 -116 149 24 1786 2544 3 MP +PP +0 sg +1786 2544 mt 1935 2568 L +1935 2568 mt 1841 2452 L +gr + +0 sg +24 W +1 sg +1934 1411 PD +gs 655 283 3870 3023 rc +gr + +24 W +1930 1469 PD +gs 655 283 3870 3023 rc +gr + +24 W +1926 1292 PD +gs 655 283 3870 3023 rc +gr + +24 W +1922 1459 PD +gs 655 283 3870 3023 rc +c18 +-135 -101 59 22 1862 2623 3 MP +PP +0 sg +1862 2623 mt 1921 2645 L +1921 2645 mt 1786 2544 L +c17 +124 -119 -113 27 1719 1133 3 MP +PP +0 sg +1719 1133 mt 1606 1160 L +1606 1160 mt 1730 1041 L +c17 +-99 23 110 -115 1719 1133 3 MP +PP +0 sg +1719 1133 mt 1829 1018 L +1829 1018 mt 1730 1041 L +c19 +145 -100 -99 23 1829 1018 3 MP +PP +0 sg +1829 1018 mt 1730 1041 L +1730 1041 mt 1875 941 L +c19 +59 22 147 -105 1715 1067 3 MP +PP +0 sg +1715 1067 mt 1862 962 L +1862 962 mt 1921 984 L +c19 +135 -109 71 26 1715 1067 3 MP +PP +0 sg +1715 1067 mt 1786 1093 L +1786 1093 mt 1921 984 L +gr + +0 sg +24 W +1 sg +1914 1488 PD +gs 655 283 3870 3023 rc +gr + +24 W +1898 1444 PD +gs 655 283 3870 3023 rc +gr + +24 W +1894 1426 PD +gs 655 283 3870 3023 rc +c19 +-13 21 145 -100 1730 1041 3 MP +PP +0 sg +1730 1041 mt 1875 941 L +1875 941 mt 1862 962 L +c19 +147 -105 -15 26 1730 1041 3 MP +PP +0 sg +1730 1041 mt 1715 1067 L +1715 1067 mt 1862 962 L +c18 +71 25 -147 -104 1862 2623 3 MP +PP +0 sg +1862 2623 mt 1715 2519 L +1715 2519 mt 1786 2544 L +gr + +0 sg +24 W +1 sg +1862 1389 PD +gs 655 283 3870 3023 rc +c13 +-125 29 64 -145 1567 1410 3 MP +PP +0 sg +1567 1410 mt 1631 1265 L +1631 1265 mt 1506 1294 L +c15 +76 -143 188 29 1577 1359 3 MP +PP +0 sg +1577 1359 mt 1765 1388 L +1765 1388 mt 1841 1245 L +c15 +171 26 93 -140 1577 1359 3 MP +PP +0 sg +1577 1359 mt 1670 1219 L +1670 1219 mt 1841 1245 L +c16 +-113 27 -110 -130 1829 2470 3 MP +PP +0 sg +1829 2470 mt 1719 2340 L +1719 2340 mt 1606 2367 L +c16 +-124 -126 -99 23 1829 2470 3 MP +PP +0 sg +1829 2470 mt 1730 2493 L +1730 2493 mt 1606 2367 L +c16 +171 26 -116 -118 1786 2544 3 MP +PP +0 sg +1786 2544 mt 1670 2426 L +1670 2426 mt 1841 2452 L +c14 +-76 -132 171 26 1670 2426 3 MP +PP +0 sg +1670 2426 mt 1841 2452 L +1841 2452 mt 1765 2320 L +c16 +-17 29 -124 -126 1730 2493 3 MP +PP +0 sg +1730 2493 mt 1606 2367 L +1606 2367 mt 1589 2396 L +c16 +-126 -123 -15 26 1730 2493 3 MP +PP +0 sg +1730 2493 mt 1715 2519 L +1715 2519 mt 1589 2396 L +c16 +-116 -118 71 25 1715 2519 3 MP +PP +0 sg +1715 2519 mt 1786 2544 L +1786 2544 mt 1670 2426 L +c15 +100 -134 -125 29 1631 1265 3 MP +PP +0 sg +1631 1265 mt 1506 1294 L +1506 1294 mt 1606 1160 L +c15 +-113 27 88 -132 1631 1265 3 MP +PP +0 sg +1631 1265 mt 1719 1133 L +1719 1133 mt 1606 1160 L +c17 +71 26 126 -122 1589 1189 3 MP +PP +0 sg +1589 1189 mt 1715 1067 L +1715 1067 mt 1786 1093 L +c17 +116 -126 81 30 1589 1189 3 MP +PP +0 sg +1589 1189 mt 1670 1219 L +1670 1219 mt 1786 1093 L +c12 +-134 31 40 -154 1527 1564 3 MP +PP +0 sg +1527 1564 mt 1567 1410 L +1567 1410 mt 1433 1441 L +c13 +56 -153 200 31 1509 1510 3 MP +PP +0 sg +1509 1510 mt 1709 1541 L +1709 1541 mt 1765 1388 L +c13 +73 -147 -134 31 1567 1410 3 MP +PP +0 sg +1567 1410 mt 1433 1441 L +1433 1441 mt 1506 1294 L +c13 +188 29 68 -151 1509 1510 3 MP +PP +0 sg +1509 1510 mt 1577 1359 L +1577 1359 mt 1765 1388 L +c14 +-100 -141 -113 27 1719 2340 3 MP +PP +0 sg +1719 2340 mt 1606 2367 L +1606 2367 mt 1506 2226 L +c14 +-125 29 -88 -143 1719 2340 3 MP +PP +0 sg +1719 2340 mt 1631 2197 L +1631 2197 mt 1506 2226 L +c14 +188 29 -93 -135 1670 2426 3 MP +PP +0 sg +1670 2426 mt 1577 2291 L +1577 2291 mt 1765 2320 L +c11 +-56 -144 188 29 1577 2291 3 MP +PP +0 sg +1577 2291 mt 1765 2320 L +1765 2320 mt 1709 2176 L +c17 +-15 26 124 -119 1606 1160 3 MP +PP +0 sg +1606 1160 mt 1730 1041 L +1730 1041 mt 1715 1067 L +c16 +81 30 -126 -123 1715 2519 3 MP +PP +0 sg +1715 2519 mt 1589 2396 L +1589 2396 mt 1670 2426 L +c17 +126 -122 -17 29 1606 1160 3 MP +PP +0 sg +1606 1160 mt 1589 1189 L +1589 1189 mt 1715 1067 L +c12 +44 -155 -138 32 1527 1564 3 MP +PP +0 sg +1527 1564 mt 1389 1596 L +1389 1596 mt 1433 1441 L +c8 +-138 32 13 -160 1514 1724 3 MP +PP +0 sg +1514 1724 mt 1527 1564 L +1527 1564 mt 1389 1596 L +c12 +200 31 42 -158 1467 1668 3 MP +PP +0 sg +1467 1668 mt 1509 1510 L +1509 1510 mt 1709 1541 L +c12 +33 -159 209 32 1467 1668 3 MP +PP +0 sg +1467 1668 mt 1676 1700 L +1676 1700 mt 1709 1541 L +c11 +-73 -151 -125 29 1631 2197 3 MP +PP +0 sg +1631 2197 mt 1506 2226 L +1506 2226 mt 1433 2075 L +c11 +-134 31 -64 -153 1631 2197 3 MP +PP +0 sg +1631 2197 mt 1567 2044 L +1567 2044 mt 1433 2075 L +c10 +-33 -154 200 32 1509 2144 3 MP +PP +0 sg +1509 2144 mt 1709 2176 L +1709 2176 mt 1676 2022 L +c11 +200 32 -68 -147 1577 2291 3 MP +PP +0 sg +1577 2291 mt 1509 2144 L +1509 2144 mt 1709 2176 L +c10 +-138 32 -40 -159 1567 2044 3 MP +PP +0 sg +1567 2044 mt 1527 1885 L +1527 1885 mt 1389 1917 L +c10 +-44 -158 -134 31 1567 2044 3 MP +PP +0 sg +1567 2044 mt 1433 2075 L +1433 2075 mt 1389 1917 L +c9 +-12 -160 209 33 1467 1989 3 MP +PP +0 sg +1467 1989 mt 1676 2022 L +1676 2022 mt 1664 1862 L +c8 +15 -160 -140 32 1514 1724 3 MP +PP +0 sg +1514 1724 mt 1374 1756 L +1374 1756 mt 1389 1596 L +c9 +-15 -161 -138 32 1527 1885 3 MP +PP +0 sg +1527 1885 mt 1389 1917 L +1389 1917 mt 1374 1756 L +c9 +-140 32 -13 -161 1527 1885 3 MP +PP +0 sg +1527 1885 mt 1514 1724 L +1514 1724 mt 1374 1756 L +c8 +209 32 14 -161 1453 1829 3 MP +PP +0 sg +1453 1829 mt 1467 1668 L +1467 1668 mt 1676 1700 L +c8 +12 -162 211 33 1453 1829 3 MP +PP +0 sg +1453 1829 mt 1664 1862 L +1664 1862 mt 1676 1700 L +c10 +209 33 -42 -155 1509 2144 3 MP +PP +0 sg +1509 2144 mt 1467 1989 L +1467 1989 mt 1676 2022 L +c14 +-101 -137 -17 29 1606 2367 3 MP +PP +0 sg +1606 2367 mt 1589 2396 L +1589 2396 mt 1488 2259 L +c14 +-18 33 -100 -141 1606 2367 3 MP +PP +0 sg +1606 2367 mt 1506 2226 L +1506 2226 mt 1488 2259 L +c14 +-93 -135 81 30 1589 2396 3 MP +PP +0 sg +1589 2396 mt 1670 2426 L +1670 2426 mt 1577 2291 L +c13 +-18 32 73 -147 1433 1441 3 MP +PP +0 sg +1433 1441 mt 1506 1294 L +1506 1294 mt 1488 1326 L +c15 +93 -140 89 33 1488 1326 3 MP +PP +0 sg +1488 1326 mt 1577 1359 L +1577 1359 mt 1670 1219 L +c15 +81 30 101 -137 1488 1326 3 MP +PP +0 sg +1488 1326 mt 1589 1189 L +1589 1189 mt 1670 1219 L +c9 +211 33 -14 -160 1467 1989 3 MP +PP +0 sg +1467 1989 mt 1453 1829 L +1453 1829 mt 1664 1862 L +c15 +-17 29 100 -134 1506 1294 3 MP +PP +0 sg +1506 1294 mt 1606 1160 L +1606 1160 mt 1589 1189 L +c15 +101 -137 -18 32 1506 1294 3 MP +PP +0 sg +1506 1294 mt 1488 1326 L +1488 1326 mt 1589 1189 L +c14 +89 32 -101 -137 1589 2396 3 MP +PP +0 sg +1589 2396 mt 1488 2259 L +1488 2259 mt 1577 2291 L +c12 +-20 34 44 -155 1389 1596 3 MP +PP +0 sg +1389 1596 mt 1433 1441 L +1433 1441 mt 1413 1475 L +c13 +68 -151 96 35 1413 1475 3 MP +PP +0 sg +1413 1475 mt 1509 1510 L +1509 1510 mt 1577 1359 L +c11 +-75 -149 -18 33 1506 2226 3 MP +PP +0 sg +1506 2226 mt 1488 2259 L +1488 2259 mt 1413 2110 L +c11 +-20 35 -73 -151 1506 2226 3 MP +PP +0 sg +1506 2226 mt 1433 2075 L +1433 2075 mt 1413 2110 L +c11 +-68 -147 89 32 1488 2259 3 MP +PP +0 sg +1488 2259 mt 1577 2291 L +1577 2291 mt 1509 2144 L +c13 +75 -149 -20 34 1433 1441 3 MP +PP +0 sg +1433 1441 mt 1413 1475 L +1413 1475 mt 1488 1326 L +c13 +89 33 75 -149 1413 1475 3 MP +PP +0 sg +1413 1475 mt 1488 1326 L +1488 1326 mt 1577 1359 L +c8 +-21 36 15 -160 1374 1756 3 MP +PP +0 sg +1374 1756 mt 1389 1596 L +1389 1596 mt 1368 1632 L +c12 +45 -157 -21 36 1389 1596 3 MP +PP +0 sg +1389 1596 mt 1368 1632 L +1368 1632 mt 1413 1475 L +c12 +96 35 45 -157 1368 1632 3 MP +PP +0 sg +1368 1632 mt 1413 1475 L +1413 1475 mt 1509 1510 L +c10 +-21 36 -44 -158 1433 2075 3 MP +PP +0 sg +1433 2075 mt 1389 1917 L +1389 1917 mt 1368 1953 L +c10 +-45 -157 -20 35 1433 2075 3 MP +PP +0 sg +1433 2075 mt 1413 2110 L +1413 2110 mt 1368 1953 L +c10 +-42 -155 96 34 1413 2110 3 MP +PP +0 sg +1413 2110 mt 1509 2144 L +1509 2144 mt 1467 1989 L +c12 +42 -158 99 36 1368 1632 3 MP +PP +0 sg +1368 1632 mt 1467 1668 L +1467 1668 mt 1509 1510 L +c11 +96 34 -75 -149 1488 2259 3 MP +PP +0 sg +1488 2259 mt 1413 2110 L +1413 2110 mt 1509 2144 L +c9 +-21 36 -15 -161 1389 1917 3 MP +PP +0 sg +1389 1917 mt 1374 1756 L +1374 1756 mt 1353 1792 L +c8 +14 -161 100 37 1353 1792 3 MP +PP +0 sg +1353 1792 mt 1453 1829 L +1453 1829 mt 1467 1668 L +c8 +15 -160 -21 36 1374 1756 3 MP +PP +0 sg +1374 1756 mt 1353 1792 L +1353 1792 mt 1368 1632 L +c8 +99 36 15 -160 1353 1792 3 MP +PP +0 sg +1353 1792 mt 1368 1632 L +1368 1632 mt 1467 1668 L +c10 +99 36 -45 -157 1413 2110 3 MP +PP +0 sg +1413 2110 mt 1368 1953 L +1368 1953 mt 1467 1989 L +c9 +-14 -160 99 36 1368 1953 3 MP +PP +0 sg +1368 1953 mt 1467 1989 L +1467 1989 mt 1453 1829 L +c9 +-15 -161 -21 36 1389 1917 3 MP +PP +0 sg +1389 1917 mt 1368 1953 L +1368 1953 mt 1353 1792 L +c9 +100 37 -15 -161 1368 1953 3 MP +PP +0 sg +1368 1953 mt 1353 1792 L +1353 1792 mt 1453 1829 L +gr + +0 sg + +end %%Color Dict + +eplot +%%EndObject + +epage +end + +showpage + +%%Trailer +%%EOF diff --git a/src/spectrum/doc/spectrum.rst b/src/spectrum/doc/spectrum.rst index cec4b617f..d9a246f52 100644 --- a/src/spectrum/doc/spectrum.rst +++ b/src/spectrum/doc/spectrum.rst @@ -437,3 +437,168 @@ following conditions are satisfied: +Additional Models +***************** + +TV Transmitter Model +==================== + +A TV Transmitter model is implemented by the ``TvSpectrumTransmitter`` class. +This model enables transmission of realistic TV signals to be simulated and can +be used for interference modeling. It provides a customizable power spectral +density (PSD) model, with configurable attributes including the type of +modulation (with models for analog, 8-VSB, and COFDM), signal bandwidth, +power spectral density level, frequency, and transmission duration. A helper +class, ``TvSpectrumTransmitterHelper``, is also provided to assist users in +setting up simulations. + +Main Model Class +################ + +The main TV Transmitter model class, ``TvSpectrumTransmitter``, provides a +user-configurable PSD model that can be transmitted on the ``SpectrumChannel``. +It inherits from ``SpectrumPhy`` and is comprised of attributes and methods to +create and transmit the signal on the channel. + +.. _spectrum-tv-cofdm: + +.. figure:: figures/spectrum-tv-cofdm.* + :align: center + + 8K COFDM signal spectrum generated from ``TvSpectrumTransmitter`` (Left) and + theoretical COFDM signal spectrum [KoppCOFDM] (Right) + +One of the user-configurable attributes is the type of modulation for the TV +transmitter to use. The options are 8-VSB (Eight-Level Vestigial Sideband +Modulation) which is notably used in the North America ATSC digital television +standard, COFDM (Coded Orthogonal Frequency Division Multiplexing) which is +notably used in the DVB-T and ISDB-T digital television standards adopted by +various countries around the world, and analog modulation which is a legacy +technology but is still being used by some countries today. To accomplish +realistic PSD models for these modulation types, the signals’ PSDs were +approximated from real standards and developed into models that are scalable by +frequency and power. The COFDM PSD is approximated from Figure 12 (8k mode) of +[KoppCOFDM], the 8-VSB PSD is approximated from Figure 3 of [Baron8VSB], and the +analog PSD is approximated from Figure 4 of [QualcommAnalog]. Note that the +analog model is approximated from the NTSC standard, but other analog modulation +standards such as PAL have similar signals. The approximated COFDM PSD model is +in 8K mode. The other configurable attributes are the start frequency, +signal/channel bandwidth, channel number, base PSD, antenna type, starting time, +and transmit duration. + +``TvSpectrumTransmitter`` uses ``IsotropicAntennaModel`` as its antenna model by +default, but any model that inherits from ``AntennaModel`` is selectable, so +directional antenna models can also be used. The propagation loss models used +in simulation are configured in the ``SpectrumChannel`` that the user chooses to +use. Terrain and spherical Earth/horizon effects may be supported in future ns-3 +propagation loss models. + +After the attributes are set, along with the ``SpectrumChannel``, +``MobilityModel``, and node locations, the PSD of the TV transmitter signal can +be created and transmitted on the channel. + +.. _sec-tv-helper-class: + +Helper Class +############ + +The helper class, ``TvSpectrumTransmitterHelper``, consists of features to +assist users in setting up TV transmitters for their simulations. Functionality +is also provided to easily simulate real-world scenarios. + +.. _spectrum-tv-8vsb: + +.. figure:: figures/spectrum-tv-8vsb.* + :align: center + + North America ATSC channel 19 & 20 signals generated using + ``TvSpectrumTransmitterHelper`` (Left) and theoretical 8-VSB signal + [Baron8VSB] (Right). Note that the theoretical signal is not shown in dB + while the ns-3 generated signals are. + +Using this helper class, users can easily set up TV transmitters right after +configuring attributes. Multiple transmitters can be created at a time. Also +included are real characteristics of specific geographic regions that can be +used to run realistic simulations. The regions currently included are +North America, Europe, and Japan. The frequencies and bandwidth of each TV +channel for each these regions are provided. + +.. _spectrum-tv-rand-geo-points: + +.. figure:: figures/spectrum-tv-rand-geo-points.* + :align: center + + Plot from MATLAB implementation of CreateRegionalTvTransmitters method in + ``TvSpectrumTransmitterHelper``. Shows 100 random points on Earth’s surface + (with altitude 0) corresponding to TV transmitter locations within a 2000 km + radius of 35° latitude and -100° longitude. + +A method (CreateRegionalTvTransmitters) is provided that enables users to +randomly generate multiple TV transmitters from a specified region with a given +density within a chosen radius around a point on Earth’s surface. The region, +which determines the channel frequencies of the generated TV transmitters, can +be specified to be one of the three provided, while the density determines the +amount of transmitters generated. The TV transmitters' antenna heights +(altitude) above Earth's surface can also be randomly generated to be within a +given maximum altitude. This method models Earth as a perfect sphere, and +generated location points are referenced accordingly in Earth-Centered +Earth-Fixed Cartesian coordinates. Note that bodies of water on Earth are not +considered in location point generation--TV transmitters can be generated +anywhere on Earth around the origin point within the chosen maximum radius. + +Examples +######## + +Two example simulations are provided that demonstrate the functionality of the +TV transmitter model. ``tv-trans-example`` simulates two 8-VSB TV transmitters +with adjacent channel frequencies. ``tv-trans-regional-example`` simulates +randomly generated COFDM TV transmitters (modeling the DVB-T standard) +located around the Paris, France area with channel frequencies and bandwidths +corresponding to the European television channel allocations. + +Testing +####### + +The ``tv-spectrum-transmitter`` test suite verifies the accuracy of the +spectrum/PSD model in ``TvSpectrumTransmitter`` by testing if the maximum power +spectral density, start frequency, and end frequency comply with expected values +for various test cases. + +The ``tv-helper-distribution`` test suite verifies the functionality of the +method in ``TvSpectrumTransmitterHelper`` that generates a random number of TV +transmitters based on the given density (low, medium, or high) and maximum +number of TV channels. It verifies that the number of TV transmitters generated +does not exceed the expected bounds. + +The CreateRegionalTvTransmitters method in ``TvSpectrumTransmitterHelper`` +described in :ref:`sec-tv-helper-class` uses two methods from the +``GeographicPositions`` class in the Mobility module to generate the random +Cartesian points on or above earth's surface around an origin point which +correspond to TV transmitter positions. The first method converts Earth +geographic coordinates to Earth-Centered Earth-Fixed (ECEF) Cartesian +coordinates, and is tested in the ``geo-to-cartesian`` test suite by comparing +(with 10 meter tolerance) its output with the output of the geographic to ECEF +conversion function [MatlabGeo] of the MATLAB Mapping Toolbox for numerous +test cases. The other used method generates random ECEF Cartesian points around +the given geographic origin point, and is tested in the ``rand-cart-around-geo`` +test suite by verifying that the generated points do not exceed the given +maximum distance radius from the origin point. + +References +########## + +.. [Baron8VSB] Baron, Stanley. "First-Hand:Digital Television: The Digital + Terrestrial Television Broadcasting (DTTB) Standard." IEEE Global History + Network. . + +.. [KoppCOFDM] Kopp, Carlo. "High Definition Television." High Definition + Television. Air Power Australia. . + +.. [MatlabGeo] "Geodetic2ecef." Convert Geodetic to Geocentric (ECEF) + Coordinates. The MathWorks, Inc. + . + +.. [QualcommAnalog] Stephen Shellhammer, Ahmed Sadek, and Wenyi Zhang. + "Technical Challenges for Cognitive Radio in the TV White Space Spectrum." + Qualcomm Incorporated. + diff --git a/src/spectrum/examples/tv-trans-example.cc b/src/spectrum/examples/tv-trans-example.cc new file mode 100644 index 000000000..973ccb7a0 --- /dev/null +++ b/src/spectrum/examples/tv-trans-example.cc @@ -0,0 +1,110 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Benjamin Cizdziel + */ + +#include +#include +#include +#include +#include +#include +#include + +using namespace ns3; + +/** + * This example uses the TvSpectrumTransmitterHelper class to set up two 8-VSB + * TV transmitters with adjacent channels. Each transmitter's spectrum has a + * bandwidth of 6 MHz. The first TV transmitter has a start frequency of + * 524 MHz while the second has a start frequency of 530 MHz. These transmitters + * model ATSC (North American digital TV standard) channels 23 and 24. + * + * A spectrum analyzer is used to measure the transmitted spectra from the + * TV transmitters. The file "spectrum-analyzer-tv-sim-2-0.tr" contains its + * output post simulation (and can be plotted with Gnuplot or MATLAB). + */ +int main (int argc, char** argv) +{ + /* nodes and positions */ + NodeContainer tvTransmitterNodes; + NodeContainer spectrumAnalyzerNodes; + NodeContainer allNodes; + tvTransmitterNodes.Create (2); + spectrumAnalyzerNodes.Create (1); + allNodes.Add (tvTransmitterNodes); + allNodes.Add (spectrumAnalyzerNodes); + MobilityHelper mobility; + Ptr nodePositionList = CreateObject (); + nodePositionList->Add (Vector (128000.0, 0.0, 0.0)); // TV Transmitter 1; 128 km away from spectrum analyzer + nodePositionList->Add (Vector (0.0, 24000.0, 0.0)); // TV Transmitter 2; 24 km away from spectrum analyzer + nodePositionList->Add (Vector (0.0, 0.0, 0.0)); // Spectrum Analyzer + mobility.SetPositionAllocator (nodePositionList); + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + mobility.Install (allNodes); + + /* channel and propagation */ + SpectrumChannelHelper channelHelper = SpectrumChannelHelper::Default (); + channelHelper.SetChannel ("ns3::MultiModelSpectrumChannel"); + // constant path loss added just to show capability to set different propagation loss models + // FriisSpectrumPropagationLossModel already added by default in SpectrumChannelHelper + channelHelper.AddSpectrumPropagationLoss ("ns3::ConstantSpectrumPropagationLossModel"); + Ptr channel = channelHelper.Create (); + + /* TV transmitter setup */ + TvSpectrumTransmitterHelper tvTransHelper; + tvTransHelper.SetChannel (channel); + tvTransHelper.SetAttribute ("StartFrequency", DoubleValue (524e6)); + tvTransHelper.SetAttribute ("ChannelBandwidth", DoubleValue (6e6)); + // channel number not required in this example but shown for clarity + tvTransHelper.SetAttribute ("ChannelNumber", UintegerValue (23)); + tvTransHelper.SetAttribute ("StartingTime", TimeValue (Seconds (0))); + tvTransHelper.SetAttribute ("TransmitDuration", TimeValue (Seconds (0.2))); + // 22.22 dBm/Hz from 1000 kW ERP transmit power, flat 6 MHz PSD spectrum assumed for this approximation + tvTransHelper.SetAttribute ("BasePsd", DoubleValue (22.22)); + tvTransHelper.SetAttribute ("TvType", EnumValue (TvSpectrumTransmitter::TVTYPE_8VSB)); + tvTransHelper.SetAttribute ("Antenna", StringValue ("ns3::IsotropicAntennaModel")); + tvTransHelper.InstallAdjacent (tvTransmitterNodes); + + /* frequency range for spectrum analyzer */ + std::vector freqs; + for (int i = 0; i < 200; ++i) + { + freqs.push_back ((i + 5200) * 1e5); + } + Ptr spectrumAnalyzerFreqModel = Create (freqs); + + /* spectrum analyzer setup */ + SpectrumAnalyzerHelper spectrumAnalyzerHelper; + spectrumAnalyzerHelper.SetChannel (channel); + spectrumAnalyzerHelper.SetRxSpectrumModel (spectrumAnalyzerFreqModel); + spectrumAnalyzerHelper.SetPhyAttribute ("NoisePowerSpectralDensity", DoubleValue (1e-15)); // -120 dBm/Hz + spectrumAnalyzerHelper.EnableAsciiAll ("spectrum-analyzer-tv-sim"); + NetDeviceContainer spectrumAnalyzerDevices = spectrumAnalyzerHelper.Install (spectrumAnalyzerNodes); + + Simulator::Stop (Seconds (0.4)); + + Simulator::Run (); + + Simulator::Destroy (); + + std::cout << "simulation done!" << std::endl; + std::cout << "see spectrum analyzer output file" << std::endl; + + return 0; +} diff --git a/src/spectrum/examples/tv-trans-regional-example.cc b/src/spectrum/examples/tv-trans-regional-example.cc new file mode 100644 index 000000000..c88203369 --- /dev/null +++ b/src/spectrum/examples/tv-trans-regional-example.cc @@ -0,0 +1,111 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Benjamin Cizdziel + */ + +#include +#include +#include +#include +#include +#include +#include + +using namespace ns3; + +/** + * This example uses the TvSpectrumTransmitterHelper class to generate a random + * number of COFDM TV transmitters within a 250 km radius around latitude + * 48.86 degrees and longitude 2.35 degrees (Paris, France). The transmitters' + * frequencies and bandwidths correspond to the European TV channel allocations. + * These TV transmitters model the digital DVB-T standard. + * + * A spectrum analyzer is used to measure the transmitted spectra from the + * TV transmitters. The file "spectrum-analyzer-tv-sim-regional-0-0.tr" contains + * its output post simulation (and can be plotted with Gnuplot or MATLAB). + */ +int main (int argc, char** argv) +{ + /* random seed and run number; adjust these to change random draws */ + RngSeedManager::SetSeed(1); + RngSeedManager::SetRun(3); + + /* nodes and positions */ + NodeContainer spectrumAnalyzerNodes; + spectrumAnalyzerNodes.Create (1); + MobilityHelper mobility; + Ptr nodePositionList = CreateObject (); + Vector coordinates = GeographicPositions::GeographicToCartesianCoordinates (48.86, + 2.35, + 0, + GeographicPositions::SPHERE); + nodePositionList->Add (coordinates); // spectrum analyzer + mobility.SetPositionAllocator (nodePositionList); + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + mobility.Install (spectrumAnalyzerNodes); + + /* channel and propagation */ + SpectrumChannelHelper channelHelper = SpectrumChannelHelper::Default (); + channelHelper.SetChannel ("ns3::MultiModelSpectrumChannel"); + Ptr channel = channelHelper.Create (); + + /* TV transmitter setup */ + TvSpectrumTransmitterHelper tvTransHelper; + tvTransHelper.SetChannel (channel); + tvTransHelper.SetAttribute ("StartingTime", TimeValue (Seconds (0.1))); + tvTransHelper.SetAttribute ("TransmitDuration", TimeValue (Seconds (0.1))); + // 7.96 dBm/Hz from 50 kW ERP transmit power, flat 8 MHz PSD spectrum assumed for this approximation + tvTransHelper.SetAttribute ("BasePsd", DoubleValue (7.96)); + tvTransHelper.SetAttribute ("TvType", EnumValue (TvSpectrumTransmitter::TVTYPE_COFDM)); + tvTransHelper.SetAttribute ("Antenna", StringValue ("ns3::IsotropicAntennaModel")); + + tvTransHelper.AssignStreams (300); + tvTransHelper.CreateRegionalTvTransmitters(TvSpectrumTransmitterHelper::REGION_EUROPE, + TvSpectrumTransmitterHelper::DENSITY_MEDIUM, + 48.86, + 2.35, + 0, + 250000); + + /* frequency range for spectrum analyzer */ + std::vector freqs; + for (int i = 0; i < 6860; i = i + 5) + { + freqs.push_back ((i + 1740) * 1e5); + } + Ptr spectrumAnalyzerFreqModel = Create (freqs); + + /* spectrum analyzer setup */ + SpectrumAnalyzerHelper spectrumAnalyzerHelper; + spectrumAnalyzerHelper.SetChannel (channel); + spectrumAnalyzerHelper.SetRxSpectrumModel (spectrumAnalyzerFreqModel); + spectrumAnalyzerHelper.SetPhyAttribute ("NoisePowerSpectralDensity", DoubleValue (4.14e-21)); // approx -174 dBm/Hz + spectrumAnalyzerHelper.EnableAsciiAll ("spectrum-analyzer-tv-sim-regional"); + NetDeviceContainer spectrumAnalyzerDevices = spectrumAnalyzerHelper.Install (spectrumAnalyzerNodes); + + Simulator::Stop (Seconds (0.4)); + + Simulator::Run (); + + Simulator::Destroy (); + + std::cout << "simulation done!" << std::endl; + std::cout << "see spectrum analyzer output file" << std::endl; + + return 0; +} diff --git a/src/spectrum/examples/wscript b/src/spectrum/examples/wscript index cdf99855a..6e2b77fa3 100644 --- a/src/spectrum/examples/wscript +++ b/src/spectrum/examples/wscript @@ -13,4 +13,10 @@ def build(bld): ['spectrum', 'mobility', 'internet', 'applications']) obj.source = 'adhoc-aloha-ideal-phy-with-microwave-oven.cc' + obj = bld.create_ns3_program('tv-trans-example', + ['spectrum', 'mobility', 'core']) + obj.source = 'tv-trans-example.cc' + obj = bld.create_ns3_program('tv-trans-regional-example', + ['spectrum', 'mobility', 'core']) + obj.source = 'tv-trans-regional-example.cc' diff --git a/src/spectrum/helper/tv-spectrum-transmitter-helper.cc b/src/spectrum/helper/tv-spectrum-transmitter-helper.cc new file mode 100644 index 000000000..f66281da1 --- /dev/null +++ b/src/spectrum/helper/tv-spectrum-transmitter-helper.cc @@ -0,0 +1,448 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Benjamin Cizdziel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tv-spectrum-transmitter-helper.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("TvSpectrumTransmitterHelper"); + +// NORTH AMERICA: 84 elements (index 0 - 83); valid channels = 2 - 83 +const int northAmericaArrayLength = 84; +const double northAmericaStartFrequencies[84] = {0, 0, 54e6, 60e6, 66e6, 76e6, + 82e6, 174e6, 180e6, 186e6, 192e6, 198e6, 204e6, 210e6, 470e6, 476e6, 482e6, + 488e6, 494e6, 500e6, 506e6, 512e6, 518e6, 524e6, 530e6, 536e6, 542e6, 548e6, + 554e6, 560e6, 566e6, 572e6, 578e6, 584e6, 590e6, 596e6, 602e6, 608e6, 614e6, + 620e6, 626e6, 632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6, 674e6, 680e6, + 686e6, 692e6, 698e6, 704e6, 710e6, 716e6, 722e6, 728e6, 734e6, 740e6, 746e6, + 752e6, 758e6, 764e6, 770e6, 776e6, 782e6, 788e6, 794e6, 800e6, 806e6, 812e6, + 818e6, 824e6, 830e6, 836e6, 842e6, 848e6, 854e6, 860e6, 866e6, 872e6, 878e6, + 884e6}; +const double northAmericaEndFrequencies[84] = {0, 0, 60e6, 66e6, 72e6, 82e6, + 88e6, 180e6, 186e6, 192e6, 198e6, 204e6, 210e6, 216e6, 476e6, 482e6, 488e6, + 494e6, 500e6, 506e6, 512e6, 518e6, 524e6, 530e6, 536e6, 542e6, 548e6, 554e6, + 560e6, 566e6, 572e6, 578e6, 584e6, 590e6, 596e6, 602e6, 608e6, 614e6, 620e6, + 626e6, 632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6, 674e6, 680e6, 686e6, + 692e6, 698e6, 704e6, 710e6, 716e6, 722e6, 728e6, 734e6, 740e6, 746e6, 752e6, + 758e6, 764e6, 770e6, 776e6, 782e6, 788e6, 794e6, 800e6, 806e6, 812e6, 818e6, + 824e6, 830e6, 836e6, 842e6, 848e6, 854e6, 860e6, 866e6, 872e6, 878e6, 884e6, + 890e6}; + +// EUROPE: 70 elements (index 0 - 69); valid channels = 5 - 12, 21 - 69 +const int europeArrayLength = 70; +const double europeStartFrequencies[70] = {0, 0, 0, 0, 0, 174e6, 181e6, 188e6, + 195e6, 202e6, 209e6, 216e6, 223e6, 0, 0, 0, 0, 0, 0, 0, 0, 470e6, 478e6, + 486e6, 494e6, 502e6, 510e6, 518e6, 526e6, 534e6, 542e6, 550e6, 558e6, 566e6, + 574e6, 582e6, 590e6, 598e6, 606e6, 614e6, 622e6, 630e6, 638e6, 646e6, 654e6, + 662e6, 670e6, 678e6, 686e6, 694e6, 702e6, 710e6, 718e6, 726e6, 734e6, 742e6, + 750e6, 758e6, 766e6, 774e6, 782e6, 790e6, 798e6, 806e6, 814e6, 822e6, 830e6, + 838e6, 846e6, 854e6}; +const double europeEndFrequencies[70] = {0, 0, 0, 0, 0, 181e6, 188e6, 195e6, + 202e6, 209e6, 216e6, 223e6, 230e6, 0, 0, 0, 0, 0, 0, 0, 0, 478e6, 486e6, + 494e6, 502e6, 510e6, 518e6, 526e6, 534e6, 542e6, 550e6, 558e6, 566e6, 574e6, + 582e6, 590e6, 598e6, 606e6, 614e6, 622e6, 630e6, 638e6, 646e6, 654e6, 662e6, + 670e6, 678e6, 686e6, 694e6, 702e6, 710e6, 718e6, 726e6, 734e6, 742e6, 750e6, + 758e6, 766e6, 774e6, 782e6, 790e6, 798e6, 806e6, 814e6, 822e6, 830e6, 838e6, + 846e6, 854e6, 862e6}; + +// JAPAN: 63 elements (index 0 - 62); valid channels = 1 - 62 +const int japanArrayLength = 63; +const double japanStartFrequencies[63] = {0, 90e6, 96e6, 102e6, 170e6, 176e6, + 182e6, 188e6, 192e6, 198e6, 204e6, 210e6, 216e6, 470e6, 476e6, 482e6, 488e6, + 494e6, 500e6, 506e6, 512e6, 518e6, 524e6, 530e6, 536e6, 542e6, 548e6, 554e6, + 560e6, 566e6, 572e6, 578e6, 584e6, 590e6, 596e6, 602e6, 608e6, 614e6, 620e6, + 626e6, 632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6, 674e6, 680e6, 686e6, + 692e6, 698e6, 704e6, 710e6, 716e6, 722e6, 728e6, 734e6, 740e6, 746e6, 752e6, + 758e6, 764e6}; +const double japanEndFrequencies[63] = {0, 96e6, 102e6, 108e6, 176e6, 182e6, + 188e6, 194e6, 198e6, 204e6, 210e6, 216e6, 222e6, 476e6, 482e6, 488e6, 494e6, + 500e6, 506e6, 512e6, 518e6, 524e6, 530e6, 536e6, 542e6, 548e6, 554e6, 560e6, + 566e6, 572e6, 578e6, 584e6, 590e6, 596e6, 602e6, 608e6, 614e6, 620e6, 626e6, + 632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6, 674e6, 680e6, 686e6, 692e6, + 698e6, 704e6, 710e6, 716e6, 722e6, 728e6, 734e6, 740e6, 746e6, 752e6, 758e6, + 764e6, 770e6}; + +TvSpectrumTransmitterHelper::TvSpectrumTransmitterHelper () + : m_channel (0), + m_channelNumber (0), + m_uniRand (CreateObject ()) +{ + NS_LOG_FUNCTION (this); + m_factory.SetTypeId ("ns3::TvSpectrumTransmitter"); +} + +TvSpectrumTransmitterHelper::~TvSpectrumTransmitterHelper () +{ + m_channel = 0; + m_uniRand = 0; + NS_LOG_FUNCTION (this); +} + +void +TvSpectrumTransmitterHelper::SetChannel (Ptr c) +{ + NS_LOG_FUNCTION (this << c); + m_channel = c; +} + +void +TvSpectrumTransmitterHelper::SetAttribute (std::string name, const AttributeValue &val) +{ + m_factory.Set (name, val); + if (name.compare ("ChannelNumber") == 0) + { + const AttributeValue * aval = &val; + const UintegerValue * ival; + ival = dynamic_cast (aval); + m_channelNumber = (uint16_t) ival->Get (); // store channel number + } +} + + +NetDeviceContainer +TvSpectrumTransmitterHelper::Install (NodeContainer nodeCont) +{ + NS_LOG_FUNCTION (this); + NetDeviceContainer devCont; + //iterate over node container to make one transmitter for each given node + for (NodeContainer::Iterator i = nodeCont.Begin (); i != nodeCont.End (); ++i) + { + Ptr node = *i; + Ptr phy = m_factory.Create ()->GetObject (); + phy->CreateTvPsd (); + Ptr dev = CreateObject (); + NS_ASSERT (phy); + dev->SetPhy (phy); + NS_ASSERT (node); + phy->SetMobility (node->GetObject ()); + NS_ASSERT (dev); + phy->SetDevice (dev); + NS_ASSERT (m_channel); + phy->SetChannel (m_channel); + dev->SetChannel (m_channel); + node->AddDevice (dev); + devCont.Add (dev); + phy->Start (); + } + return devCont; +} + + +NetDeviceContainer +TvSpectrumTransmitterHelper::Install (NodeContainer nodeCont, Region region) +{ + NS_LOG_FUNCTION (this); + NetDeviceContainer devCont; + double startFrequency; + double channelBandwidth; + if (region == REGION_NORTH_AMERICA) + { + startFrequency = northAmericaStartFrequencies[m_channelNumber]; + channelBandwidth = northAmericaEndFrequencies[m_channelNumber] - + northAmericaStartFrequencies[m_channelNumber]; + } + else if (region == REGION_EUROPE) + { + startFrequency = europeStartFrequencies[m_channelNumber]; + channelBandwidth = europeEndFrequencies[m_channelNumber] - + europeStartFrequencies[m_channelNumber]; + } + else if (region == REGION_JAPAN) + { + startFrequency = japanStartFrequencies[m_channelNumber]; + channelBandwidth = japanEndFrequencies[m_channelNumber] - + japanStartFrequencies[m_channelNumber]; + } + //iterate over node container to make one transmitter for each given node + for (NodeContainer::Iterator i = nodeCont.Begin (); i != nodeCont.End (); ++i) + { + Ptr node = *i; + Ptr phy = m_factory.Create ()->GetObject (); + phy->SetAttribute ("StartFrequency", DoubleValue (startFrequency)); + phy->SetAttribute ("ChannelBandwidth", DoubleValue (channelBandwidth)); + phy->CreateTvPsd (); + Ptr dev = CreateObject (); + NS_ASSERT (phy); + dev->SetPhy (phy); + NS_ASSERT (node); + phy->SetMobility (node->GetObject ()); + NS_ASSERT (dev); + phy->SetDevice (dev); + NS_ASSERT (m_channel); + phy->SetChannel (m_channel); + dev->SetChannel (m_channel); + node->AddDevice (dev); + devCont.Add (dev); + phy->Start (); + } + return devCont; +} + + +NetDeviceContainer +TvSpectrumTransmitterHelper::InstallAdjacent (NodeContainer nodeCont) +{ + NS_LOG_FUNCTION (this); + NetDeviceContainer devCont; + int index = 0; + DoubleValue startFrequency; + DoubleValue channelBandwidth; + //iterate over node container to make one transmitter for each given node + for (NodeContainer::Iterator i = nodeCont.Begin (); i != nodeCont.End (); ++i) + { + Ptr node = *i; + Ptr phy = m_factory.Create ()->GetObject (); + phy->GetAttribute ("StartFrequency", startFrequency); + phy->GetAttribute ("ChannelBandwidth", channelBandwidth); + phy->SetAttribute ("StartFrequency", DoubleValue (startFrequency.Get () + + (index * channelBandwidth.Get ()))); + phy->SetAttribute ("ChannelNumber", UintegerValue (m_channelNumber + index)); + phy->CreateTvPsd (); + Ptr dev = CreateObject (); + NS_ASSERT (phy); + dev->SetPhy (phy); + NS_ASSERT (node); + phy->SetMobility (node->GetObject ()); + NS_ASSERT (dev); + phy->SetDevice (dev); + NS_ASSERT (m_channel); + phy->SetChannel (m_channel); + dev->SetChannel (m_channel); + node->AddDevice (dev); + devCont.Add (dev); + phy->Start (); + index++; + } + return devCont; +} + + +NetDeviceContainer +TvSpectrumTransmitterHelper::InstallAdjacent (NodeContainer nodeCont, Region region) +{ + NS_LOG_FUNCTION (this); + NetDeviceContainer devCont; + double startFrequency; + double channelBandwidth; + int index = 0; + //iterate over node container to make one transmitter for each given node + for (NodeContainer::Iterator i = nodeCont.Begin (); i != nodeCont.End (); ++i) + { + if (region == REGION_NORTH_AMERICA) + { + startFrequency = northAmericaStartFrequencies[m_channelNumber + index]; + channelBandwidth = northAmericaEndFrequencies[m_channelNumber + index] + - northAmericaStartFrequencies[m_channelNumber + index]; + } + else if (region == REGION_EUROPE) + { + startFrequency = europeStartFrequencies[m_channelNumber + index]; + channelBandwidth = europeEndFrequencies[m_channelNumber + index] - + europeStartFrequencies[m_channelNumber + index]; + } + else if (region == REGION_JAPAN) + { + startFrequency = japanStartFrequencies[m_channelNumber + index]; + channelBandwidth = japanEndFrequencies[m_channelNumber + index] - + japanStartFrequencies[m_channelNumber + index]; + } + Ptr node = *i; + Ptr phy = m_factory.Create ()->GetObject (); + phy->SetAttribute ("StartFrequency", DoubleValue (startFrequency)); + phy->SetAttribute ("ChannelBandwidth", DoubleValue (channelBandwidth)); + phy->SetAttribute ("ChannelNumber", UintegerValue (m_channelNumber + index)); + phy->CreateTvPsd (); + Ptr dev = CreateObject (); + NS_ASSERT (phy); + dev->SetPhy (phy); + NS_ASSERT (node); + phy->SetMobility (node->GetObject ()); + NS_ASSERT (dev); + phy->SetDevice (dev); + NS_ASSERT (m_channel); + phy->SetChannel (m_channel); + dev->SetChannel (m_channel); + node->AddDevice (dev); + devCont.Add (dev); + phy->Start (); + index++; + } + return devCont; +} + + +int64_t +TvSpectrumTransmitterHelper::AssignStreams (int64_t streamNum) +{ + m_uniRand->SetStream (streamNum); + return 1; +} + + +void +TvSpectrumTransmitterHelper::CreateRegionalTvTransmitters (Region region, + Density density, + double originLatitude, + double originLongitude, + double maxAltitude, + double maxRadius) +{ + NS_LOG_FUNCTION (this); + std::list transmitterIndicesToCreate; + if (region == REGION_NORTH_AMERICA) + { + transmitterIndicesToCreate = GenerateRegionalTransmitterIndices + (northAmericaStartFrequencies, + northAmericaArrayLength, + density); + } + else if (region == REGION_EUROPE) + { + transmitterIndicesToCreate = GenerateRegionalTransmitterIndices + (europeStartFrequencies, + europeArrayLength, + density); + } + else if (region == REGION_JAPAN) + { + transmitterIndicesToCreate = GenerateRegionalTransmitterIndices + (japanStartFrequencies, + japanArrayLength, + density); + } + std::list tvTransmitterLocations = + GeographicPositions::RandCartesianPointsAroundGeographicPoint (originLatitude, + originLongitude, + maxAltitude, + transmitterIndicesToCreate.size(), + maxRadius, + m_uniRand); + InstallRandomRegionalTransmitters (region, + transmitterIndicesToCreate, + tvTransmitterLocations); +} + + +std::list +TvSpectrumTransmitterHelper::GenerateRegionalTransmitterIndices (const double startFrequencies[], + const int startFrequenciesLength, + Density density) +{ + std::vector startFreqVector; //stores all non-zero start frequencies + for (int i = 0; i < startFrequenciesLength; i++) + { + double element = startFrequencies[i]; + //add all non-zero frequencies to vector (0 means unused channel) + if (element != 0) startFreqVector.push_back(element); + } + + //randomly generate number of transmitters to create based on density + uint32_t freqVectorSize = startFreqVector.size(); + int randNumTransmitters = GetRandomNumTransmitters (density, freqVectorSize); + + //stores start frequencies that transmitters will be created to transmit + std::vector transmitterStartFreqsToCreate; + for (int i = 0; i < randNumTransmitters; i++) + { + //get random index from start frequency vector + uint32_t randIndex = m_uniRand->GetInteger (0, startFreqVector.size () - 1); + //add start frequency corresponding to random index to vector + transmitterStartFreqsToCreate.push_back(startFreqVector[randIndex]); + //remove selected start frequency from vector so it is not selected again + startFreqVector.erase(startFreqVector.begin() + randIndex); + } + + //find indices on startFrequencies[] containing each start frequency that is + //selected to be transmitted and add to list + std::list transmitterIndicesToCreate; + for (int i = 0; i < (int)transmitterStartFreqsToCreate.size(); i++) + { + for (int channelNumberIndex = 0; + channelNumberIndex < startFrequenciesLength; channelNumberIndex++) + { + if (startFrequencies[channelNumberIndex] == transmitterStartFreqsToCreate[i]) + { + transmitterIndicesToCreate.push_back(channelNumberIndex); + break; + } + } + } + return transmitterIndicesToCreate; +} + + +int +TvSpectrumTransmitterHelper::GetRandomNumTransmitters (Density density, + uint32_t numChannels) +{ + int numTransmitters; + if (density == DENSITY_LOW) + { + numTransmitters = m_uniRand->GetInteger (1, ceil (0.33 * numChannels)); + } + else if (density == DENSITY_MEDIUM) + { + numTransmitters = m_uniRand->GetInteger (ceil (0.33 * numChannels) + 1, ceil (0.66 * numChannels)); + } + else + { + numTransmitters = m_uniRand->GetInteger (ceil (0.66 * numChannels) + 1, numChannels); + } + return numTransmitters; +} + + +void +TvSpectrumTransmitterHelper::InstallRandomRegionalTransmitters (Region region, + std::list transmitterIndicesToCreate, + std::list transmitterLocations) +{ + int numTransmitters = (int)transmitterIndicesToCreate.size(); + for (int transNum = 0; transNum < numTransmitters; transNum++) + { + Ptr nodePosition = CreateObject (); + // add generated coordinate point to node position + nodePosition->Add (transmitterLocations.front()); + MobilityHelper mobility; + mobility.SetPositionAllocator (nodePosition); + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + NodeContainer tvNode; // contains position of transmitter to be created + tvNode.Create (1); + mobility.Install (tvNode); + // set channel number for this transmitter + m_channelNumber = (uint16_t) transmitterIndicesToCreate.front(); + Install (tvNode, region); //install tv transmitter + transmitterLocations.pop_front(); // remove created transmitter location + transmitterIndicesToCreate.pop_front(); // remove created transmitter index + } +} + +} // namespace ns3 + diff --git a/src/spectrum/helper/tv-spectrum-transmitter-helper.h b/src/spectrum/helper/tv-spectrum-transmitter-helper.h new file mode 100644 index 000000000..9a97e0793 --- /dev/null +++ b/src/spectrum/helper/tv-spectrum-transmitter-helper.h @@ -0,0 +1,328 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Benjamin Cizdziel + */ + +#ifndef TV_SPECTRUM_TRANSMITTER_HELPER_H +#define TV_SPECTRUM_TRANSMITTER_HELPER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ns3/object-factory.h" + +namespace ns3 +{ + +/** + * \ingroup spectrum + * + * Helper class which uses TvSpectrumTransmitter class to create customizable + * TV transmitter(s) that transmit PSD spectrum specified by user-set attributes. + * Has functionality to create TV transmitter(s) with actual frequencies of + * specific geographic regions. + * Provides method to create a random set of transmitters within a given region + * and location. + * + * Here is an example of how to use this class: + * + * TvSpectrumTransmitterHelper tvTransHelper; + * tvTransHelper.SetChannel (channel); // provided that user has a Ptr ready. + * tvTransHelper.SetAttribute ("StartFrequency", DoubleValue (524e6)); + * tvTransHelper.SetAttribute ("ChannelBandwidth", DoubleValue (6e6)); + * tvTransHelper.SetAttribute ("StartingTime", TimeValue (Seconds (0))); + * tvTransHelper.SetAttribute ("TransmitDuration", TimeValue (Seconds (0.2))); + * tvTransHelper.SetAttribute ("BasePsd", DoubleValue (22.22)); + * tvTransHelper.SetAttribute ("TvType", EnumValue (TvSpectrumTransmitter::TVTYPE_8VSB)); + * tvTransHelper.SetAttribute ("Antenna", StringValue ("ns3::IsotropicAntennaModel")); + * tvTransHelper.Install (tvTransmitterNode); //provided that user has a NodeContainer ready. + */ +class TvSpectrumTransmitterHelper +{ + +public: + /** + * geographical region that TV transmitters are being set up in + */ + enum Region + { + REGION_NORTH_AMERICA, + REGION_JAPAN, + REGION_EUROPE + }; + + /** + * density of location that TV transmitters are being set up in + */ + enum Density + { + DENSITY_LOW, + DENSITY_MEDIUM, + DENSITY_HIGH + }; + + TvSpectrumTransmitterHelper (); //!< Default constructor + virtual ~TvSpectrumTransmitterHelper (); //!< Destructor + + /** + * Set the spectrum channel for the device(s) to transmit on + * + * @param c a pointer to the spectrum channel + */ + void SetChannel (Ptr c); + + /** + * Set attribute for each TvSpectrumTransmitter instance to be created + * + * @param name the name of the attribute to set + * @param val the value of the attribute to set + */ + void SetAttribute (std::string name, const AttributeValue &val); + + /** + * Set up and start the TV Transmitter's transmission on the spectrum channel. + * Creates one TV Transmitter for each node given as an input, with settings + * selected from attributes. + * Use SetAttribute() to select settings for the TV Transmitter(s). + * If multiple transmitters created, all will have same settings (frequency, + * PSD, etc.) except for position/location, which depends on the positions + * in the input NodeContainer. + * + * @param nodes a container containing the node(s) which the TV + * transmitter(s) will be attached to + * + * @return a device container which contains all the devices created by this + * method + */ + NetDeviceContainer Install (NodeContainer nodes); + + /** + * Set up and start the TV Transmitter's transmission on the spectrum channel. + * Creates one TV Transmitter for each node given as an input, with settings + * selected from attributes. + * Use SetAttribute() to select settings for the TV Transmitter(s). + * Must set ChannelNumber attribute to select the TV channel in the + * user-selected region that the transmitter(s) will be modeled after. + * If ChannelNumber attribute is not set by the user, it defaults to 5. + * If multiple transmitters created, all will have same settings (frequency, + * PSD, etc.) except for position/location, which depends on the positions + * in the input NodeContainer. + * Transmitter(s) will be created with the frequencies corresponding to the + * channel numbers of the user-selected region. + * + * @param nodes a container containing the node(s) which the TV + * transmitter(s) will be attached to + * @param region the region of which the transmitter(s) will be characterized + * + * @return a device container which contains all the devices created by this + * method + */ + NetDeviceContainer Install (NodeContainer nodes, Region region); + + /** + * Set up and start the TV Transmitter's transmission on the spectrum channel. + * Consecutively created transmitters (consecutive in input NodeContainer) + * will have adjacent channels, i.e. a transmitter's frequency spectrum will + * border (but not overlap) the frequency spectrum of the transmitter created + * directly before it and the transmitter created directly after it. + * Creates one TV Transmitter for each node given as an input, with settings + * selected from attributes. + * Use SetAttribute() to select settings for the TV Transmitter(s). + * If multiple transmitters created, they will have same settings except for + * frequency, channel number, and position/location. + * Channel number will be incremented by 1 for each node, and start frequency + * will be incremented by the channel bandwidth that is set. + * For example, if two nodes are given as inputs to InstallAdjacent with + * start frequency set to 500 MHz, channel bandwidth set to 6 MHz, and + * channel number set to 19, the first node will be a transmitter set as + * channel 19 ranging from 500 MHz to 506 MHz and the second node will be a + * transmitter set as channel 20 ranging from 506 MHz to 512 MHz. + * + * @param nodes a container containing the node(s) which the TV + * transmitter(s) will be attached to + * + * @return a device container which contains all the devices created by this + * method + */ + NetDeviceContainer InstallAdjacent (NodeContainer nodes); + + /** + * Set up and start the TV Transmitter's transmission on the spectrum channel. + * Consecutively created transmitters (consecutive in input NodeContainer) + * will have adjacent channels, with the frequency spectrum and bandwidth of + * each channel determined by the user-selected region. + * Creates one TV Transmitter for each node given as an input, with settings + * selected from attributes. + * Use SetAttribute() to select settings for the TV Transmitter(s). + * Must set ChannelNumber attribute to select the TV channel in the + * user-selected region that the first created transmitter will be modeled + * after. + * Each subsequently created transmitter will be modeled after the channel + * number following the previous one, for example if the first created + * transmitter is modeled after channel 1, the next one created will be + * modeled after channel 2. + * If ChannelNumber attribute is not set by the user, it defaults to 5. + * If multiple transmitters created, they will have same settings except for + * frequency, channel number, and position/location. + * Channel number will be incremented by 1 for each node, and start frequency + * will be incremented by the channel bandwidth according to the + * user-selected region. + * Transmitter(s) will be created with the frequencies corresponding to the + * channel numbers of the user-selected region. + * + * @param nodes a container containing the node(s) which the TV + * transmitter(s) will be attached to + * @param region the region of which the transmitter(s) will be characterized + * + * @return a device container which contains all the devices created by this + * method + */ + NetDeviceContainer InstallAdjacent (NodeContainer nodes, Region region); + + /** + * Assigns the stream number for the uniform random number generator to use + * + * @param stream first stream index to use + * @return the number of stream indices assigned by this helper + */ + int64_t AssignStreams (int64_t streamNum); + + /** + * Generates and installs (starts transmission on the spectrum channel) a + * random number of TV transmitters with channel frequencies corresponding + * to the given region at random locations on or above earth. + * The generated transmitters are located at randomly selected points within a + * given altitude above earth's surface centered around a given origin point + * (on earth's surface) within a given distance radius, corresponding to a + * uniform distribution. + * Distance radius is measured as if all points are on earth's surface + * (with altitude = 0). + * Assumes earth is a perfect sphere. + * The given region's channel numbers that the generated TV transmitters' + * frequency spectra are modeled after are uniformly selected at random. + * These channel numbers are never repeated. + * The number of transmitters generated is uniformly random based on given + * density. + * Each transmitter has BasePsd and TvType set from SetAttribute(), which + * should be set before calling this method. + * + * @param region the region that the transmitters are in + * @param density the density (high, medium, or low) of the location being + * simulated, which determines how many transmitters are created and how many + * channels are occupied. Low density will generate between one and one third + * of the number of TV channels in the given region, medium density will + * generate between one third and two thirds, and high density will generate + * between two thirds and all of the channels. + * @param originLatitude origin point latitude in degrees + * @param originLongitude origin point longitude in degrees + * @param maxAltitude maximum altitude in meters above earth's surface with + * which random points can be generated + * @param maxRadius max distance in meters from origin with which random + * transmitters can be generated (all transmitters are less than or equal to + * this distance from the origin, relative to points being on earth's surface) + */ + void CreateRegionalTvTransmitters (Region region, + Density density, + double originLatitude, + double originLongitude, + double maxAltitude, + double maxRadius); + + +private: + Ptr m_channel; //!< Pointer to spectrum channel object + + /** + * Generates random indices of given region frequency array (ignoring indices + * referring to invalid channels). + * Number of indices generated (which is number of TV transmitters to be + * created) is random based on given density. + * Indices generated refer to frequencies that TV transmitters will be + * created with. + * + * @param startFrequencies array containing all channel start frequencies for + * a particular region + * @param startFrequenciesLength number of elements in startFrequencies array + * @param density the density (high, medium, or low) of the location being + * simulated, which determines how many transmitters are created + * + * @return a list contaning the indices in startFrequencies that transmitters + * will be created for + */ + std::list GenerateRegionalTransmitterIndices (const double startFrequencies[], + const int startFrequenciesLength, + Density density); + + /** + * Randomly generates the number of TV transmitters to be created based on + * given density and number of possible TV channels. + * Low density will generate a transmitter for between one (a single + * transmitter) and one third of the number of possible channels, medium + * density will generate a transmitter for between one third and two thirds, + * and high density will generate a transmitter for between two thirds and all + * of the possible channels. + * These ratios are approximated in the implementation, but there is no + * overlap possible in the number of transmitters generated between adjacent + * densities. + * For example, given 60 possible channels, for low density between 1 and 20 + * transmitters can be created, for medium density between 21 and 40 + * transmitters can be created, and for high density between 41 and 60 + * transmitters can be created (all inclusive). + * + * @param density the density (high, medium, or low) of the location being + * simulated + * @param numChannels the number of possible TV channels in the region being + * simulated + * + * @return the number of TV transmitters that will be created + */ + int GetRandomNumTransmitters (Density density, uint32_t numChannels); + + /** + * Installs each randomly generated regional TV transmitter + * + * @param region the region that the transmitters are in + * @param transmitterIndicesToCreate a list contaning the channel number + * indices (for region's start frequencies array) that transmitters will be + * created for; this is returned from GenerateRegionalTransmitterIndices() + * @param transmitterLocations a list containing the vectors + * (x, y, z location) of each TV transmitter to be generated; this is + * returned from RandGeographicCoordsAroundPoint() + */ + void InstallRandomRegionalTransmitters (Region region, + std::list transmitterIndicesToCreate, + std::list transmitterLocations); + + ObjectFactory m_factory; //!< Object factory for attribute setting + uint16_t m_channelNumber; //!< Channel number of TV transmitter to be created + Ptr m_uniRand; //!< Object to generate uniform random numbers + +}; + +} // namespace ns3 + +#endif /* TV_SPECTRUM_TRANSMITTER_HELPER_H */ diff --git a/src/spectrum/model/tv-spectrum-transmitter.cc b/src/spectrum/model/tv-spectrum-transmitter.cc new file mode 100644 index 000000000..956914fbe --- /dev/null +++ b/src/spectrum/model/tv-spectrum-transmitter.cc @@ -0,0 +1,591 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Benjamin Cizdziel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tv-spectrum-transmitter.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("TvSpectrumTransmitter"); + +NS_OBJECT_ENSURE_REGISTERED (TvSpectrumTransmitter); + +TvSpectrumTransmitter::TvSpectrumTransmitter () + : m_mobility (0), + m_antenna (CreateObject ()), + m_netDevice (0), + m_channel (0), + m_tvType (TVTYPE_8VSB), + m_startFrequency (500e6), + m_channelBandwidth (6e6), + m_channelNumber (0), + m_basePsd (20), + m_txPsd (0), + m_startingTime (Seconds (0)), + m_transmitDuration (Seconds (0.2)), + m_active (false) +{ + NS_LOG_FUNCTION (this); +} + +TvSpectrumTransmitter::~TvSpectrumTransmitter () +{ + m_mobility = 0; + m_antenna = 0; + m_netDevice = 0; + m_channel = 0; + m_txPsd = 0; + NS_LOG_FUNCTION (this); +} + +TypeId +TvSpectrumTransmitter::GetTypeId(void) +{ + static TypeId tid = TypeId("ns3::TvSpectrumTransmitter") + .SetParent () + .AddConstructor () + .AddAttribute ("TvType", + "The type of TV transmitter/modulation to be used.", + EnumValue (TvSpectrumTransmitter::TVTYPE_8VSB), + MakeEnumAccessor (&TvSpectrumTransmitter::m_tvType), + MakeEnumChecker (TvSpectrumTransmitter::TVTYPE_8VSB, "8vsb", + TvSpectrumTransmitter::TVTYPE_COFDM, "cofdm", + TvSpectrumTransmitter::TVTYPE_ANALOG, "analog")) + .AddAttribute ("StartFrequency", + "The lower end frequency (in Hz) of the TV transmitter's " + "signal. Must be greater than or equal to 0.", + DoubleValue (500e6), + MakeDoubleAccessor (&TvSpectrumTransmitter::m_startFrequency), + MakeDoubleChecker (0, std::numeric_limits::max ())) + .AddAttribute ("ChannelBandwidth", + "The bandwidth (in Hz) of the TV transmitter's signal. Must " + "be greater than or equal to 0.", + DoubleValue (6e6), + MakeDoubleAccessor (&TvSpectrumTransmitter::m_channelBandwidth), + MakeDoubleChecker (0, std::numeric_limits::max ())) + .AddAttribute ("ChannelNumber", + "The channel number to name the TV transmitter (channel 0, " + "1, 2, 3, etc.). Must be greater than or equal to 0. This " + "is only required to be set when setting up regional " + "transmitters from TvSpectrumTransmitterHelper class using " + "methods that take Region as an argument (i.e. the " + "TvSpectrumTransmitterHelper::CreateRegionalTvTransmitters method).", + UintegerValue (5), + MakeUintegerAccessor (&TvSpectrumTransmitter::m_channelNumber), + MakeUintegerChecker (0, std::numeric_limits::max ())) + .AddAttribute ("BasePsd", + "The base power spectral density (in dBm/Hz) of the TV " + "transmitter's transmitted spectrum. Base PSD is the " + "maximum PSD of the spectrum excluding pilots. For analog " + "and COFDM transmitters this is the maximum PSD, but for " + "8-VSB transmitters this is the maximum PSD of the main " + "signal spectrum (flat-top segment) since the pilot " + "actually has the maximum PSD overall.", + DoubleValue (20), + MakeDoubleAccessor (&TvSpectrumTransmitter::m_basePsd), + MakeDoubleChecker ()) + .AddAttribute ("Antenna", + "The AntennaModel to be used. Allows classes inherited " + "from ns3::AntennaModel. Defaults to ns3::IsotropicAntennaModel.", + StringValue ("ns3::IsotropicAntennaModel"), + MakePointerAccessor (&TvSpectrumTransmitter::m_antenna), + MakePointerChecker ()) + .AddAttribute ("StartingTime", + "The time point after the simulation begins in which the TV " + "transmitter will begin transmitting.", + TimeValue (Seconds (0)), + MakeTimeAccessor (&TvSpectrumTransmitter::m_startingTime), + MakeTimeChecker ()) + .AddAttribute ("TransmitDuration", + "The duration of time that the TV transmitter will transmit for.", + TimeValue (Seconds (0.2)), + MakeTimeAccessor (&TvSpectrumTransmitter::m_transmitDuration), + MakeTimeChecker ()) + ; + return tid; +} + +void +TvSpectrumTransmitter::SetChannel (Ptr c) +{ + NS_LOG_FUNCTION (this << c); + m_channel = c; +} + +void +TvSpectrumTransmitter::SetMobility (Ptr m) +{ + NS_LOG_FUNCTION (this << m); + m_mobility = m; +} + +void +TvSpectrumTransmitter::SetDevice (Ptr d) +{ + NS_LOG_FUNCTION (this << d); + m_netDevice = d; +} + +Ptr +TvSpectrumTransmitter::GetMobility () +{ + NS_LOG_FUNCTION (this); + return m_mobility; +} + +Ptr +TvSpectrumTransmitter::GetDevice () +{ + NS_LOG_FUNCTION (this); + return m_netDevice; +} + +Ptr +TvSpectrumTransmitter::GetRxSpectrumModel () const +{ + NS_LOG_FUNCTION (this); + return 0; +} + +Ptr +TvSpectrumTransmitter::GetRxAntenna () +{ + NS_LOG_FUNCTION (this); + return m_antenna; +} + +void +TvSpectrumTransmitter::StartRx (Ptr params) +{ + NS_LOG_FUNCTION (this << params); +} + + +Ptr +TvSpectrumTransmitter::GetChannel () const +{ + NS_LOG_FUNCTION (this); + return m_channel; +} + +// Used as key for map containing created spectrum models +struct TvSpectrumModelId +{ + TvSpectrumModelId (double stFreq, double bwidth); + double startFrequency; + double bandwidth; +}; + +TvSpectrumModelId::TvSpectrumModelId (double stFreq, double bwidth) + : startFrequency (stFreq), + bandwidth (bwidth) +{ +} + +bool +operator < (const TvSpectrumModelId& a, const TvSpectrumModelId& b) +{ + return ( (a.startFrequency < b.startFrequency) || + ( (a.startFrequency == b.startFrequency) && (a.bandwidth < b.bandwidth) ) ); +} + +// Stores created spectrum models +static std::map > g_tvSpectrumModelMap; + +/** + * 8-VSB PSD approximated from Figure 3 of the following article: + * Baron, Stanley. "First-Hand:Digital Television: The Digital Terrestrial + * Television Broadcasting (DTTB) Standard." IEEE Global History Network. + * . + * + * COFDM PSD approximated from Figure 12 (8k mode) of the following article: + * Kopp, Carlo. "High Definition Television." High Definition Television. Air + * Power Australia. . + * + * Analog PSD approximated from Figure 4 of the following paper: + * Stephen Shellhammer, Ahmed Sadek, and Wenyi Zhang. "Technical Challenges for + * Cognitive Radio in the TV White Space Spectrum." Qualcomm Incorporated. + */ +void +TvSpectrumTransmitter::CreateTvPsd () +{ + NS_LOG_FUNCTION (this); + NS_ASSERT (m_channelBandwidth != 0); + Ptr model; + TvSpectrumModelId key (m_startFrequency, m_channelBandwidth); + std::map >::iterator iter = g_tvSpectrumModelMap.find (key); + if (iter != g_tvSpectrumModelMap.end ()) + { + model = iter->second; //set SpectrumModel to previously created one + } + else // no previously created SpectrumModel with same frequency and bandwidth + { + Bands bands; + double halfSubBand = 0.5 * (m_channelBandwidth / 100); + for (double fl = m_startFrequency - halfSubBand; fl <= (m_startFrequency - + halfSubBand) + m_channelBandwidth; fl += m_channelBandwidth / 100) + { + BandInfo bi; + bi.fl = fl; + bi.fc = fl + halfSubBand; + bi.fh = fl + (2 * halfSubBand); + bands.push_back (bi); + } + model = Create (bands); + g_tvSpectrumModelMap.insert (std::pair > (key, model)); + } + Ptr psd = Create (model); + double basePsdWattsHz = pow (10.0, (m_basePsd - 30) / 10.0); //convert dBm to W/Hz + switch (m_tvType) + { + case TVTYPE_8VSB: + { + for (int i = 0; i <= 100; i++) + { + switch (i) + { + case 0: + case 100: + (*psd) [i] = 0.015 * basePsdWattsHz; + break; + case 1: + case 99: + (*psd) [i] = 0.019 * basePsdWattsHz; + break; + case 2: + case 98: + (*psd) [i] = 0.034 * basePsdWattsHz; + break; + case 3: + case 97: + (*psd) [i] = 0.116 * basePsdWattsHz; + break; + case 4: + case 96: + (*psd) [i] = 0.309 * basePsdWattsHz; + break; + case 5: + (*psd) [i] = (0.502 * basePsdWattsHz) + (21.577 * basePsdWattsHz); //pilot + break; + case 6: + case 94: + (*psd) [i] = 0.696 * basePsdWattsHz; + break; + case 7: + case 93: + (*psd) [i] = 0.913 * basePsdWattsHz; + break; + case 8: + case 92: + (*psd) [i] = 0.978 * basePsdWattsHz; + break; + case 9: + case 91: + (*psd) [i] = 0.990 * basePsdWattsHz; + break; + case 95: + (*psd) [i] = 0.502 * basePsdWattsHz; + break; + default: + (*psd) [i] = basePsdWattsHz; + break; + } + } + break; + } + case TVTYPE_COFDM: + { + for (int i = 0; i <= 100; i++) + { + switch (i) + { + case 0: + case 100: + (*psd) [i] = 1.52e-4 * basePsdWattsHz; + break; + case 1: + case 99: + (*psd) [i] = 2.93e-4 * basePsdWattsHz; + break; + case 2: + case 98: + (*psd) [i] = 8.26e-4 * basePsdWattsHz; + break; + case 3: + case 97: + (*psd) [i] = 0.0927 * basePsdWattsHz; + break; + default: + (*psd) [i] = basePsdWattsHz; + break; + } + } + break; + } + case TVTYPE_ANALOG: + { + for (int i = 0; i <= 100; i++) + { + switch (i) + { + case 0: + case 1: + case 2: + case 3: + (*psd) [i] = 27.07946e-08 * basePsdWattsHz; + break; + case 4: + case 5: + case 6: + (*psd) [i] = 2.51189e-07 * basePsdWattsHz; + break; + case 7: + case 8: + case 9: + (*psd) [i] = 1e-06 * basePsdWattsHz; + break; + case 10: + case 11: + case 12: + (*psd) [i] = 2.39883e-06 * basePsdWattsHz; + break; + case 13: + case 14: + case 15: + (*psd) [i] = 5.62341e-06 * basePsdWattsHz; + break; + case 16: + case 17: + case 18: + (*psd) [i] = 6.68344e-06 * basePsdWattsHz; + break; + case 19: + case 20: + case 21: + (*psd) [i] = 1.25893e-05 * basePsdWattsHz; + break; + case 22: + case 23: + case 24: + (*psd) [i] = 3.16228e-05 * basePsdWattsHz; + break; + case 25: + (*psd) [i] = 0.000158489 * basePsdWattsHz; + break; + case 26: + (*psd) [i] = basePsdWattsHz; + break; + case 27: + (*psd) [i] = 7.49894e-05 * basePsdWattsHz; + break; + case 28: + case 29: + case 30: + (*psd) [i] = 2.37137e-05 * basePsdWattsHz; + break; + case 31: + case 32: + case 33: + (*psd) [i] = 1.14815e-05 * basePsdWattsHz; + break; + case 34: + case 35: + case 36: + (*psd) [i] = 7.49894e-06 * basePsdWattsHz; + break; + case 37: + case 38: + case 39: + (*psd) [i] = 5.62341e-06 * basePsdWattsHz; + break; + case 40: + case 41: + case 42: + (*psd) [i] = 4.21697e-06 * basePsdWattsHz; + break; + case 43: + case 44: + case 45: + (*psd) [i] = 3.16228e-06 * basePsdWattsHz; + break; + case 46: + case 47: + case 48: + (*psd) [i] = 1.99526e-06 * basePsdWattsHz; + break; + case 49: + case 50: + case 51: + (*psd) [i] = 1.25893e-06 * basePsdWattsHz; + break; + case 52: + case 53: + case 54: + (*psd) [i] = 8.41395e-07 * basePsdWattsHz; + break; + case 55: + case 56: + case 57: + (*psd) [i] = 6.30957e-07 * basePsdWattsHz; + break; + case 58: + case 59: + case 60: + (*psd) [i] = 5.88844e-07 * basePsdWattsHz; + break; + case 61: + case 62: + case 63: + (*psd) [i] = 5.62341e-07 * basePsdWattsHz; + break; + case 64: + case 65: + case 66: + (*psd) [i] = 5.30884e-07 * basePsdWattsHz; + break; + case 67: + case 68: + case 69: + (*psd) [i] = 5.01187e-07 * basePsdWattsHz; + break; + case 70: + case 71: + case 72: + (*psd) [i] = 5.30884e-07 * basePsdWattsHz; + break; + case 73: + case 74: + case 75: + (*psd) [i] = 7.49894e-07 * basePsdWattsHz; + break; + case 76: + case 77: + case 78: + (*psd) [i] = 1.77828e-06 * basePsdWattsHz; + break; + case 79: + (*psd) [i] = 5.62341e-06 * basePsdWattsHz; + break; + case 80: + (*psd) [i] = 0.000177828 * basePsdWattsHz; + break; + case 81: + (*psd) [i] = 4.21697e-06 * basePsdWattsHz; + break; + case 82: + case 83: + case 84: + (*psd) [i] = 3.16228e-06 * basePsdWattsHz; + break; + case 85: + case 86: + case 87: + (*psd) [i] = 3.16228e-06 * basePsdWattsHz; + break; + case 88: + case 89: + case 90: + (*psd) [i] = 4.73151e-06 * basePsdWattsHz; + break; + case 91: + case 92: + case 93: + (*psd) [i] = 7.49894e-06 * basePsdWattsHz; + break; + case 94: + (*psd) [i] = 7.49894e-05 * basePsdWattsHz; + break; + case 95: + (*psd) [i] = 0.1 * basePsdWattsHz; + break; + case 96: + (*psd) [i] = 7.49894e-05 * basePsdWattsHz; + break; + case 97: + case 98: + case 99: + case 100: + (*psd) [i] = 1.77828e-06 * basePsdWattsHz; + break; + } + } + break; + } + default: + { + NS_LOG_ERROR ("no valid TvType selected"); + break; + } + } + m_txPsd = psd; +} + +Ptr +TvSpectrumTransmitter::GetTxPsd () const +{ + NS_LOG_FUNCTION (this); + return m_txPsd; +} + +void +TvSpectrumTransmitter::SetupTx () +{ + NS_LOG_FUNCTION (this); + NS_ASSERT (m_txPsd); + Ptr signal = Create (); + signal->duration = m_transmitDuration; + signal->psd = m_txPsd; + signal->txPhy = GetObject (); + signal->txAntenna = m_antenna; + m_channel->StartTx (signal); +} + +void +TvSpectrumTransmitter::Start () +{ + NS_LOG_FUNCTION (this); + if (!m_active) + { + NS_LOG_LOGIC ("starting TV transmitter"); + m_active = true; + Simulator::Schedule (m_startingTime, &TvSpectrumTransmitter::SetupTx, this); + } +} + +void +TvSpectrumTransmitter::Stop () +{ + NS_LOG_FUNCTION (this); + m_active = false; +} + +} // namespace ns3 + diff --git a/src/spectrum/model/tv-spectrum-transmitter.h b/src/spectrum/model/tv-spectrum-transmitter.h new file mode 100644 index 000000000..953331092 --- /dev/null +++ b/src/spectrum/model/tv-spectrum-transmitter.h @@ -0,0 +1,153 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Benjamin Cizdziel + */ + +#ifndef TV_SPECTRUM_TRANSMITTER_H +#define TV_SPECTRUM_TRANSMITTER_H + +#include +#include +#include +#include +#include +#include +#include + +namespace ns3 +{ + + +/** + * \ingroup spectrum + * + * SpectrumPhy implementation that creates a customizable TV transmitter which + * transmits a PSD spectrum specified by user-set attributes. + * + * + * This PHY model supports a single antenna model instance which is + * used for transmission (this PHY model never receives). + */ +class TvSpectrumTransmitter : public SpectrumPhy +{ + +public: + /** + * types of TV transmitters: analog, digital 8-VSB, or digital COFDM + */ + enum TvType + { + TVTYPE_ANALOG, + TVTYPE_8VSB, + TVTYPE_COFDM + }; + + TvSpectrumTransmitter (); //!< Default constructor + virtual ~TvSpectrumTransmitter (); //!< Destructor + + /** + * Register this type. + * \return The object TypeId. + */ + static TypeId GetTypeId (void); + + // inherited from SpectrumPhy + void SetChannel (Ptr c); + void SetMobility (Ptr m); + void SetDevice (Ptr d); + Ptr GetMobility (); + Ptr GetDevice (); + // device does not use Rx but these pure virtual methods must be implemented + Ptr GetRxSpectrumModel () const; + Ptr GetRxAntenna (); + void StartRx (Ptr params); + + /** + * Get the spectrum channel + * + * @return a pointer to the assigned spectrum channel + */ + Ptr GetChannel () const; + + /** + * Creates power spectral density (PSD) spectrum of the TV transmitter and + * sets it for transmission. + * Before calling this method, must set attributes and parameters that are + * applicable to your transmitter. + * + * 8-VSB PSD approximated from Figure 3 of the following article: + * Baron, Stanley. "First-Hand:Digital Television: The Digital Terrestrial + * Television Broadcasting (DTTB) Standard." IEEE Global History Network. + * . + * + * COFDM PSD approximated from Figure 12 (8k mode) of the following article: + * Kopp, Carlo. "High Definition Television." High Definition Television. Air + * Power Australia. . + * + * Analog PSD approximated from Figure 4 of the following paper: + * Stephen Shellhammer, Ahmed Sadek, and Wenyi Zhang. "Technical Challenges + * for Cognitive Radio in the TV White Space Spectrum." Qualcomm Incorporated. + * + * + * @return a pointer to the power spectral density of the TV transmitter + */ + virtual void CreateTvPsd (); + + /** + * Get the power spectral density of the TV transmitter's signal + * + * @return a pointer to the PSD + */ + Ptr GetTxPsd () const; + + /** + * Starts the TV Transmitter's transmission on the spectrum channel + */ + virtual void Start (); + + /** + * Stops the TV Transmitter's transmission on the spectrum channel + */ + virtual void Stop (); + + +private: + Ptr m_mobility; //!< Pointer to mobility model object + Ptr m_antenna; //!< Pointer to antenna model object + Ptr m_netDevice; //!< Pointer to net device object + Ptr m_channel; //!< Pointer to spectrum channel object + + /** Sets up signal to be transmitted */ + virtual void SetupTx (); + + int m_tvType; //!< Type of TV transmitter + double m_startFrequency; //!< Start frequency (in Hz) of TV transmitter's signal + double m_channelBandwidth; //!< Bandwidth (in Hz) of TV transmitter's signal + uint16_t m_channelNumber; //!< Channel number of TV transmitter + double m_basePsd; //!< Base power spectral density value (in dBm/Hz) of TV transmitter's signal + Ptr m_txPsd; //!< Pointer to power spectral density of TV transmitter's signal + Time m_startingTime; //!< Timepoint after simulation begins that TV transmitter will begin transmitting + Time m_transmitDuration; //!< Length of time that TV transmitter will transmit for + bool m_active; //!< True if TV transmitter is transmitting + +}; + +} // namespace ns3 + +#endif /* TV_SPECTRUM_TRANSMITTER_H */ diff --git a/src/spectrum/test/tv-helper-distribution-test.cc b/src/spectrum/test/tv-helper-distribution-test.cc new file mode 100644 index 000000000..a655ad098 --- /dev/null +++ b/src/spectrum/test/tv-helper-distribution-test.cc @@ -0,0 +1,142 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Benjamin Cizdziel + */ + +#define private public //to make private method testable + +#include +#include +#include + +/** + * This test verifies the accuracy of the private GetRandomNumTransmitters() + * method in the TvSpectrumTransmitterHelper class. The method generates a + * random number corresponding to the number of TV transmitters to create based + * on the given location density (low, medium, or high) and maximum possible + * number of TV channels. Low density will generate a transmitter for between + * one (a single transmitter) and one third of the number of possible channels, + * medium density will generate a transmitter for between one third and two + * thirds, and high density will generate a transmitter for between two thirds + * and all of the possible channels. In this test, it is verified that the + * lower (1) and upper (max number of possible channels input) bounds are not + * exceeded and that the number of transmitters to be generated does not overlap + * between adjacent densities. For example, given 60 possible channels, for low + * density between 1 and 20 transmitters can be created, for medium density + * between 21 and 40 transmitters can be created, and for high density between + * 41 and 60 transmitters can be created (all inclusive). This is tested with + * various cases. + */ +NS_LOG_COMPONENT_DEFINE ("TvHelperDistributionTest"); + +using namespace ns3; + + +class TvHelperDistributionTestCase : public TestCase +{ +public: + TvHelperDistributionTestCase (uint32_t maxNumTransmitters); + virtual ~TvHelperDistributionTestCase (); + +private: + virtual void DoRun (void); + static std::string Name (uint32_t maxNumTransmitters); + uint32_t m_maxNumTransmitters; +}; + +std::string +TvHelperDistributionTestCase::Name (uint32_t maxNumTransmitters) +{ + std::ostringstream oss; + oss << "Max Number of Transmitters = " << maxNumTransmitters; + return oss.str(); +} + +TvHelperDistributionTestCase::TvHelperDistributionTestCase (uint32_t maxNumTransmitters) + : TestCase (Name (maxNumTransmitters)), + m_maxNumTransmitters (maxNumTransmitters) +{ +} + +TvHelperDistributionTestCase::~TvHelperDistributionTestCase () +{ +} + +void +TvHelperDistributionTestCase::DoRun (void) +{ + NS_LOG_FUNCTION (m_maxNumTransmitters); + TvSpectrumTransmitterHelper tvTransHelper; + uint32_t rand; + uint32_t maxLow = 0; + uint32_t minMid = m_maxNumTransmitters; + uint32_t maxMid = 0; + uint32_t minHigh = m_maxNumTransmitters; + for (int i = 0; i < 30; i ++) + { + rand = tvTransHelper.GetRandomNumTransmitters (TvSpectrumTransmitterHelper::DENSITY_LOW, m_maxNumTransmitters); + NS_TEST_ASSERT_MSG_GT (rand, 0, "lower bound exceeded"); + if (rand > maxLow) + { + maxLow = rand; + } + } + for (int i = 0; i < 30; i ++) + { + rand = tvTransHelper.GetRandomNumTransmitters (TvSpectrumTransmitterHelper::DENSITY_MEDIUM, m_maxNumTransmitters); + if (rand < minMid) + { + minMid = rand; + } + if (rand > maxMid) + { + maxMid = rand; + } + } + for (int i = 0; i < 30; i ++) + { + rand = tvTransHelper.GetRandomNumTransmitters (TvSpectrumTransmitterHelper::DENSITY_HIGH, m_maxNumTransmitters); + NS_TEST_ASSERT_MSG_LT (rand, m_maxNumTransmitters + 1, "upper bound exceeded"); + if (rand < minHigh) + { + minHigh = rand; + } + } + NS_TEST_ASSERT_MSG_LT (maxLow, minMid, "low density overlaps with medium density"); + NS_TEST_ASSERT_MSG_LT (maxMid, minHigh, "medium density overlaps with high density"); +} + + +class TvHelperDistributionTestSuite : public TestSuite +{ +public: + TvHelperDistributionTestSuite (); +}; + +TvHelperDistributionTestSuite::TvHelperDistributionTestSuite () + : TestSuite ("tv-helper-distribution", UNIT) +{ + NS_LOG_INFO ("creating TvHelperDistributionTestSuite"); + for (uint32_t maxNumTransmitters = 3; maxNumTransmitters <= 203; maxNumTransmitters+= 10) + { + AddTestCase (new TvHelperDistributionTestCase (maxNumTransmitters), + TestCase::QUICK); + } +} + +static TvHelperDistributionTestSuite g_TvHelperDistributionTestSuite; diff --git a/src/spectrum/test/tv-spectrum-transmitter-test.cc b/src/spectrum/test/tv-spectrum-transmitter-test.cc new file mode 100644 index 000000000..02284b1ac --- /dev/null +++ b/src/spectrum/test/tv-spectrum-transmitter-test.cc @@ -0,0 +1,205 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Benjamin Cizdziel + */ + +#include +#include +#include +#include +#include +#include + +/** + * This test verifies the accuracy of the spectrum/PSD model in the + * TvSpectrumTransmitter class. To do so, it tests if the max power spectral + * density, start frequency, and end frequency comply with expected values. + * Values for TV/modulation type, start frequency, channel bandwidth, and + * base PSD are swept and tested for each case. + */ +NS_LOG_COMPONENT_DEFINE ("TvSpectrumTransmitterTest"); + +using namespace ns3; + +const double TOLERANCE = 1e-15; + + +class TvSpectrumTransmitterTestCase : public TestCase +{ +public: + TvSpectrumTransmitterTestCase (double startFrequency, + double channelBandwidth, + double basePsd, + TvSpectrumTransmitter::TvType tvType); + virtual ~TvSpectrumTransmitterTestCase (); + +private: + virtual void DoRun (void); + static std::string Name (TvSpectrumTransmitter::TvType tvType, + double startFrequency, + double channelBandwidth, + double basePsd); + + double m_startFrequency; + double m_channelBandwidth; + double m_basePsd; + TvSpectrumTransmitter::TvType m_tvType; +}; + + +std::string +TvSpectrumTransmitterTestCase::Name (TvSpectrumTransmitter::TvType tvType, + double startFrequency, + double channelBandwidth, + double basePsd) +{ + std::ostringstream oss; + oss << "TV type = " << tvType << ", " + << "start frequency = " << startFrequency << " Hz, " + << "channel bandwidth = " << channelBandwidth << " Hz, " + << "base PSD = " << basePsd << " dBm per Hz"; + return oss.str(); +} + +TvSpectrumTransmitterTestCase::TvSpectrumTransmitterTestCase (double startFrequency, + double channelBandwidth, + double basePsd, + TvSpectrumTransmitter::TvType tvType) + : TestCase (Name (tvType, startFrequency, channelBandwidth, basePsd)), + m_startFrequency (startFrequency), + m_channelBandwidth (channelBandwidth), + m_basePsd (basePsd), + m_tvType (tvType) +{ +} + +TvSpectrumTransmitterTestCase::~TvSpectrumTransmitterTestCase () +{ +} + +void +TvSpectrumTransmitterTestCase::DoRun (void) +{ + NS_LOG_FUNCTION (m_startFrequency << m_basePsd << m_tvType); + + /* TV transmitter setup */ + Ptr phy = CreateObject(); + phy->SetAttribute ("StartFrequency", DoubleValue (m_startFrequency)); + phy->SetAttribute ("ChannelBandwidth", DoubleValue (m_channelBandwidth)); + phy->SetAttribute ("BasePsd", DoubleValue (m_basePsd)); + phy->SetAttribute ("TvType", EnumValue (m_tvType)); + phy->CreateTvPsd (); + + /* Test max PSD value */ + Ptr psd = phy->GetTxPsd (); + Values::const_iterator psdIter = psd->ConstValuesBegin (); + double maxValue = 0; + while (psdIter != psd->ConstValuesEnd ()) + { + if (*psdIter > maxValue) + { + maxValue = *psdIter; + } + ++psdIter; + } + double basePsdWattsHz = pow (10.0, (m_basePsd - 30) / 10.0); // convert dBm to W/Hz + if (m_tvType == TvSpectrumTransmitter::TVTYPE_8VSB) // pilot has highest PSD + { + double expectedPsd = (0.502 * basePsdWattsHz) + (21.577 * basePsdWattsHz); + NS_TEST_ASSERT_MSG_EQ_TOL (maxValue, + expectedPsd, + TOLERANCE, + "peak PSD value (" << maxValue << ") is incorrect"); + } + else // highest PSD is base PSD + { + NS_TEST_ASSERT_MSG_EQ_TOL (maxValue, + basePsdWattsHz, + TOLERANCE, + "peak PSD value (" << maxValue << ") is incorrect"); + } + + /* Test frequency range */ + Bands::const_iterator bandStart = psd->ConstBandsBegin (); + Bands::const_iterator bandEnd = psd->ConstBandsEnd (); + NS_TEST_ASSERT_MSG_EQ_TOL ((*bandStart).fc, + m_startFrequency, + TOLERANCE, + "start frequency value (" << (*bandStart).fc << ") is incorrect"); + NS_TEST_ASSERT_MSG_EQ_TOL ((*(bandEnd - 1)).fc, + m_startFrequency + m_channelBandwidth, + TOLERANCE, + "end frequency value (" << (*(bandEnd - 1)).fc << ") is incorrect"); +} + + +class TvSpectrumTransmitterTestSuite : public TestSuite +{ +public: + TvSpectrumTransmitterTestSuite (); +}; + +TvSpectrumTransmitterTestSuite::TvSpectrumTransmitterTestSuite () + : TestSuite ("tv-spectrum-transmitter", UNIT) +{ + NS_LOG_INFO ("creating TvSpectrumTransmitterTestSuite"); + for (double startFreq = 100; startFreq < 1e15; startFreq *= 10) + { + for (double bandwidth = 100; bandwidth < 1e15; bandwidth *= 10) + { + for (double psd = -100; psd <= 100; psd += 20) + { + AddTestCase (new TvSpectrumTransmitterTestCase (startFreq, + bandwidth, + psd, + TvSpectrumTransmitter::TVTYPE_8VSB), + TestCase::QUICK); + } + } + } + for (double startFreq = 100; startFreq < 1e15; startFreq *= 10) + { + for (double bandwidth = 100; bandwidth < 1e15; bandwidth *= 10) + { + for (double psd = -100; psd <= 100; psd += 20) + { + AddTestCase (new TvSpectrumTransmitterTestCase (startFreq, + bandwidth, + psd, + TvSpectrumTransmitter::TVTYPE_COFDM), + TestCase::QUICK); + } + } + } + for (double startFreq = 100; startFreq < 1e15; startFreq *= 10) + { + for (double bandwidth = 100; bandwidth < 1e15; bandwidth *= 10) + { + for (double psd = -100; psd <= 100; psd += 20) + { + AddTestCase (new TvSpectrumTransmitterTestCase (startFreq, + bandwidth, + psd, + TvSpectrumTransmitter::TVTYPE_ANALOG), + TestCase::QUICK); + } + } + } +} + +static TvSpectrumTransmitterTestSuite g_tvSpectrumTransmitterTestSuite; diff --git a/src/spectrum/wscript b/src/spectrum/wscript index 1114f9028..9d55709e6 100644 --- a/src/spectrum/wscript +++ b/src/spectrum/wscript @@ -28,10 +28,12 @@ def build(bld): 'model/half-duplex-ideal-phy-signal-parameters.cc', 'model/non-communicating-net-device.cc', 'model/microwave-oven-spectrum-value-helper.cc', + 'model/tv-spectrum-transmitter.cc', 'helper/spectrum-helper.cc', 'helper/adhoc-aloha-noack-ideal-phy-helper.cc', 'helper/waveform-generator-helper.cc', 'helper/spectrum-analyzer-helper.cc', + 'helper/tv-spectrum-transmitter-helper.cc', ] module_test = bld.create_ns3_module_test_library('spectrum') @@ -40,6 +42,8 @@ def build(bld): 'test/spectrum-value-test.cc', 'test/spectrum-ideal-phy-test.cc', 'test/spectrum-waveform-generator-test.cc', + 'test/tv-helper-distribution-test.cc', + 'test/tv-spectrum-transmitter-test.cc', ] headers = bld(features='ns3header') @@ -69,10 +73,12 @@ def build(bld): 'model/half-duplex-ideal-phy-signal-parameters.h', 'model/non-communicating-net-device.h', 'model/microwave-oven-spectrum-value-helper.h', + 'model/tv-spectrum-transmitter.h', 'helper/spectrum-helper.h', 'helper/adhoc-aloha-noack-ideal-phy-helper.h', 'helper/waveform-generator-helper.h', 'helper/spectrum-analyzer-helper.h', + 'helper/tv-spectrum-transmitter-helper.h', 'test/spectrum-test.h', ]