Restyle React WVS map with static visual grammar
Co-Authored-By: PI[gpt-5.6-terra] <288921227+claudypoo@users.noreply.github.com>
@@ -6,7 +6,7 @@
|
||||
<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<cc:Work>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:date>2026-09-17T05:19:31.264745</dc:date>
|
||||
<dc:date>2026-09-17T07:39:16.812532</dc:date>
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
@@ -40,12 +40,12 @@ z
|
||||
<g id="line2d_1">
|
||||
<path d="M 7.2 307.061102
|
||||
L 593.1 307.061102
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; stroke: #c9c4b4; stroke-linecap: square"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; stroke: #c9c4b4; stroke-linecap: square"/>
|
||||
</g>
|
||||
<g id="line2d_2">
|
||||
<path d="M 374.646013 478.44
|
||||
L 374.646013 7.2
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; stroke: #c9c4b4; stroke-linecap: square"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; stroke: #c9c4b4; stroke-linecap: square"/>
|
||||
</g>
|
||||
<g id="patch_3">
|
||||
<path d="M 460.672215 354.573939
|
||||
@@ -124,7 +124,7 @@ L 432.341897 240.328544
|
||||
L 432.657919 241.363717
|
||||
L 460.672215 354.573939
|
||||
z
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; opacity: 0.9; stroke: #4e79a7; stroke-width: 1.8; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; opacity: 0.9; stroke: #4e79a7; stroke-width: 1.8; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_4">
|
||||
<path d="M 565.722763 445.406749
|
||||
@@ -202,7 +202,7 @@ L 529.24505 356.592771
|
||||
L 529.622397 357.410928
|
||||
L 565.722763 445.406749
|
||||
z
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; opacity: 0.9; stroke: #9c755f; stroke-width: 1.8; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; opacity: 0.9; stroke: #9c755f; stroke-width: 1.8; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_5">
|
||||
<path d="M 427.552655 294.036952
|
||||
@@ -278,7 +278,7 @@ L 448.994455 271.368217
|
||||
L 448.206289 272.285915
|
||||
L 427.552655 294.036952
|
||||
z
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; opacity: 0.9; stroke: #e15759; stroke-width: 1.8; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; opacity: 0.9; stroke: #e15759; stroke-width: 1.8; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="patch_6">
|
||||
<path d="M 477.08923 426.781044
|
||||
@@ -353,74 +353,74 @@ L 497.456869 287.072533
|
||||
L 497.357187 288.23378
|
||||
L 477.08923 426.781044
|
||||
z
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; opacity: 0.9; stroke: #f28e2b; stroke-width: 1.8; stroke-linejoin: miter"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; opacity: 0.9; stroke: #f28e2b; stroke-width: 1.8; stroke-linejoin: miter"/>
|
||||
</g>
|
||||
<g id="matplotlib.axis_1"/>
|
||||
<g id="matplotlib.axis_2"/>
|
||||
<g id="line2d_3">
|
||||
<path d="M 265.821686 65.242906
|
||||
L 273.608851 65.242906
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
</g>
|
||||
<g id="line2d_4">
|
||||
<path d="M 273.72292 128.994617
|
||||
L 281.510085 128.994617
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
</g>
|
||||
<g id="line2d_5">
|
||||
<path d="M 317.399078 112.352855
|
||||
L 325.186244 112.352855
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
</g>
|
||||
<g id="line2d_6">
|
||||
<path d="M 254.220972 66.42372
|
||||
L 246.433806 66.42372
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
</g>
|
||||
<g id="line2d_7">
|
||||
<path d="M 173.700249 154.412965
|
||||
L 173.700249 163.155935
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
</g>
|
||||
<g id="line2d_8">
|
||||
<path d="M 240.873037 102.435712
|
||||
L 248.721037 102.435712
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
</g>
|
||||
<g id="line2d_9">
|
||||
<path d="M 88.378442 125.475465
|
||||
L 88.378442 115.422669
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
</g>
|
||||
<g id="line2d_10">
|
||||
<path d="M 96.275705 125.475465
|
||||
L 96.275705 106.715907
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
</g>
|
||||
<g id="line2d_11">
|
||||
<path d="M 164.561609 124.010844
|
||||
L 164.561609 108.621646
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
</g>
|
||||
<g id="line2d_12">
|
||||
<path d="M 158.285126 93.91631
|
||||
L 158.285126 86.391284
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
</g>
|
||||
<g id="line2d_13">
|
||||
<path d="M 110.927272 105.119392
|
||||
L 110.927272 89.730194
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
</g>
|
||||
<g id="line2d_14">
|
||||
<path d="M 207.707901 134.494611
|
||||
L 207.707901 125.751641
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
</g>
|
||||
<g id="line2d_15">
|
||||
<path d="M 144.376434 146.08259
|
||||
L 152.163599 146.08259
|
||||
" clip-path="url(#p284a2c037e)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
" clip-path="url(#pcffe460afc)" style="fill: none; stroke: #9a958a; stroke-width: 0.6; stroke-linecap: square"/>
|
||||
</g>
|
||||
<g id="patch_7">
|
||||
<path d="M 7.2 478.44
|
||||
@@ -444,7 +444,7 @@ L 593.1 7.2
|
||||
</g>
|
||||
<g id="PathCollection_1">
|
||||
<defs>
|
||||
<path id="C0_0_101e784b91" d="M 0 2.54951
|
||||
<path id="C0_0_c54b5a2406" d="M 0 2.54951
|
||||
C 0.676138 2.54951 1.324674 2.280877 1.802776 1.802776
|
||||
C 2.280877 1.324674 2.54951 0.676138 2.54951 -0
|
||||
C 2.54951 -0.676138 2.280877 -1.324674 1.802776 -1.802776
|
||||
@@ -456,280 +456,280 @@ C -1.324674 2.280877 -0.676138 2.54951 0 2.54951
|
||||
z
|
||||
"/>
|
||||
</defs>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="332.716887" y="288.405446" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="332.716887" y="288.405446" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="446.872282" y="356.931149" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="446.872282" y="356.931149" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="483.371544" y="286.821497" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="483.371544" y="286.821497" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="436.112075" y="353.443478" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="436.112075" y="353.443478" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="352.652534" y="341.786089" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="352.652534" y="341.786089" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="189.223499" y="212.196811" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="189.223499" y="212.196811" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="222.740981" y="231.256825" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="222.740981" y="231.256825" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="461.35631" y="402.023286" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="461.35631" y="402.023286" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="434.002768" y="303.214249" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="434.002768" y="303.214249" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="420.242303" y="410.3978" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="420.242303" y="410.3978" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="377.890249" y="340.534897" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="377.890249" y="340.534897" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="320.715038" y="388.628986" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="320.715038" y="388.628986" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="441.131078" y="250.96642" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="441.131078" y="250.96642" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="127.267138" y="192.448802" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="127.267138" y="192.448802" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="388.513622" y="318.744486" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="388.513622" y="318.744486" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="370.183058" y="180.969225" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="370.183058" y="180.969225" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="352.629385" y="399.279763" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="352.629385" y="399.279763" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="312.705456" y="306.96705" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="312.705456" y="306.96705" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="376.299808" y="364.687842" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="376.299808" y="364.687842" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="287.157686" y="177.054555" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="287.157686" y="177.054555" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="75.956035" y="143.010513" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="75.956035" y="143.010513" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="434.998609" y="415.27298" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="434.998609" y="415.27298" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="552.387551" y="449.183137" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="552.387551" y="449.183137" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="361.437937" y="215.675321" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="361.437937" y="215.675321" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="477.345741" y="419.502482" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="477.345741" y="419.502482" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="135.388348" y="183.701276" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="135.388348" y="183.701276" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="185.512" y="217.183409" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="185.512" y="217.183409" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="457.472324" y="370.386977" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="457.472324" y="370.386977" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="156.669212" y="201.573603" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="156.669212" y="201.573603" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="151.824347" y="182.209227" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="151.824347" y="182.209227" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="352.149813" y="305.988816" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="352.149813" y="305.988816" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="373.804272" y="308.840193" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="373.804272" y="308.840193" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="314.307541" y="223.504316" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="314.307541" y="223.504316" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="418.857985" y="243.720927" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="418.857985" y="243.720927" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="47.919629" y="172.872693" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="47.919629" y="172.872693" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="500.84226" y="392.82664" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="500.84226" y="392.82664" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="417.530188" y="341.954098" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="417.530188" y="341.954098" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="479.344712" y="417.633112" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="479.344712" y="417.633112" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="261.4019" y="287.548328" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="261.4019" y="287.548328" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="259.733956" y="147.506448" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="259.733956" y="147.506448" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="505.676125" y="424.458379" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="505.676125" y="424.458379" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="488.70183" y="316.97461" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="488.70183" y="316.97461" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="382.168125" y="387.428372" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="382.168125" y="387.428372" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="516.287185" y="361.187316" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="516.287185" y="361.187316" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="388.343633" y="216.527794" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="388.343633" y="216.527794" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="482.326841" y="340.540461" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="482.326841" y="340.540461" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="478.531386" y="445.068726" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="478.531386" y="445.068726" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="357.179923" y="234.437476" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="357.179923" y="234.437476" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="325.073809" y="198.177892" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="325.073809" y="198.177892" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="359.010529" y="338.749121" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="359.010529" y="338.749121" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="367.306452" y="420.293909" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="367.306452" y="420.293909" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="426.084075" y="378.586191" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="426.084075" y="378.586191" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="287.046305" y="232.45598" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="287.046305" y="232.45598" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="336.09127" y="329.590021" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="336.09127" y="329.590021" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="351.341174" y="368.55246" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="351.341174" y="368.55246" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="505.972983" y="372.28468" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="505.972983" y="372.28468" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="134.915918" y="180.657991" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="134.915918" y="180.657991" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="106.267927" y="171.077216" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="106.267927" y="171.077216" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="463.103587" y="425.368761" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="463.103587" y="425.368761" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="458.669556" y="433.087906" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="458.669556" y="433.087906" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="395.176289" y="329.572782" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="395.176289" y="329.572782" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="158.653732" y="249.350586" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="158.653732" y="249.350586" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="89.752085" y="150.270727" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="89.752085" y="150.270727" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="461.767876" y="429.291619" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="461.767876" y="429.291619" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="432.548059" y="397.819715" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="432.548059" y="397.819715" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="433.042783" y="380.414017" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="433.042783" y="380.414017" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="350.263503" y="341.068676" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="350.263503" y="341.068676" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="375.487754" y="296.175092" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="375.487754" y="296.175092" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="324.253753" y="371.865996" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="324.253753" y="371.865996" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="453.406434" y="329.960865" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="453.406434" y="329.960865" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="441.463379" y="283.612135" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="441.463379" y="283.612135" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="361.422397" y="307.155154" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="361.422397" y="307.155154" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="416.491777" y="286.78703" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="416.491777" y="286.78703" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="315.231776" y="264.961507" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="315.231776" y="264.961507" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="293.799687" y="192.23101" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="293.799687" y="192.23101" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="346.540771" y="165.062943" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="346.540771" y="165.062943" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="229.226586" y="237.883093" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="229.226586" y="237.883093" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="72.283559" y="121.440289" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="72.283559" y="121.440289" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="135.970876" y="197.744949" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="135.970876" y="197.744949" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="347.828122" y="262.392439" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="347.828122" y="262.392439" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="494.988787" y="361.242527" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="494.988787" y="361.242527" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="385.258765" y="273.210394" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="385.258765" y="273.210394" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="484.209252" y="342.704663" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="484.209252" y="342.704663" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="432.1942" y="363.306493" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="432.1942" y="363.306493" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="416.391335" y="294.07469" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="416.391335" y="294.07469" style="fill: #888888; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="189.97154" y="260.841058" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="189.97154" y="260.841058" style="fill: #4e79a7; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="312.738645" y="272.63482" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="312.738645" y="272.63482" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="393.917976" y="395.462505" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="393.917976" y="395.462505" style="fill: #f28e2b; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="437.145411" y="265.035993" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="437.145411" y="265.035993" style="fill: #e15759; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C0_0_101e784b91" x="486.285233" y="428.419065" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C0_0_c54b5a2406" x="486.285233" y="428.419065" style="fill: #9c755f; fill-opacity: 0.85; stroke: #ffffff; stroke-opacity: 0.85; stroke-width: 0.5"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="PathCollection_2">
|
||||
<defs>
|
||||
<path id="C1_0_cbf314fc02" d="M 0 -7.582875
|
||||
<path id="C1_0_fe6979fb3d" d="M 0 -7.582875
|
||||
L -1.702462 -2.343237
|
||||
L -7.211743 -2.343237
|
||||
L -2.754641 0.895037
|
||||
@@ -742,197 +742,197 @@ L 1.702462 -2.343237
|
||||
z
|
||||
"/>
|
||||
</defs>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="240.473577" y="99.500099" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="240.473577" y="99.500099" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="176.480108" y="182.551046" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="176.480108" y="182.551046" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="222.203561" y="92.305195" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="222.203561" y="92.305195" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="265.821686" y="65.242906" style="fill: #7c3aed; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="265.821686" y="65.242906" style="fill: #7c3aed; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="260.590732" y="93.87816" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="260.590732" y="93.87816" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="273.72292" y="128.994617" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="273.72292" y="128.994617" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="317.399078" y="112.352855" style="fill: #14b8a6; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="317.399078" y="112.352855" style="fill: #14b8a6; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="218.926759" y="139.253507" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="218.926759" y="139.253507" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="135.762022" y="138.598075" style="fill: #2b2d42; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="135.762022" y="138.598075" style="fill: #2b2d42; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="139.220873" y="119.306621" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="139.220873" y="119.306621" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="230.529182" y="86.107635" style="fill: #0ea5e9; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="230.529182" y="86.107635" style="fill: #0ea5e9; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="254.220972" y="66.42372" style="fill: #2b2d42; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="254.220972" y="66.42372" style="fill: #2b2d42; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="151.556548" y="125.475465" style="fill: #ec4899; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="151.556548" y="125.475465" style="fill: #ec4899; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="246.323708" y="99.230245" style="fill: #2563eb; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="246.323708" y="99.230245" style="fill: #2563eb; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="173.700249" y="154.412965" style="fill: #ec4899; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="173.700249" y="154.412965" style="fill: #ec4899; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="204.393001" y="161.761591" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="204.393001" y="161.761591" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="71.966082" y="147.782678" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="71.966082" y="147.782678" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="240.873037" y="102.435712" style="fill: #2563eb; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="240.873037" y="102.435712" style="fill: #2563eb; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="88.378442" y="125.475465" style="fill: #2ca02c; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="88.378442" y="125.475465" style="fill: #2ca02c; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="127.864758" y="151.720685" style="fill: #14b8a6; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="127.864758" y="151.720685" style="fill: #14b8a6; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="96.275705" y="125.475465" style="fill: #6d5ae0; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="96.275705" y="125.475465" style="fill: #6d5ae0; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="128.829283" y="138.302608" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="128.829283" y="138.302608" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="86.060242" y="159.232817" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="86.060242" y="159.232817" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="128.395769" y="186.989059" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="128.395769" y="186.989059" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="125.841694" y="132.887309" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="125.841694" y="132.887309" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="206.837392" y="105.79155" style="fill: #2563eb; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="206.837392" y="105.79155" style="fill: #2563eb; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="167.351075" y="66.42372" style="fill: #ec4899; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="167.351075" y="66.42372" style="fill: #ec4899; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="112.070232" y="197.64982" style="fill: #6d5ae0; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="112.070232" y="197.64982" style="fill: #6d5ae0; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="180.323343" y="195.208071" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="180.323343" y="195.208071" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="174.603212" y="119.355167" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="174.603212" y="119.355167" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="177.455951" y="112.673405" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="177.455951" y="112.673405" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="164.561609" y="124.010844" style="fill: #dc2626; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="164.561609" y="124.010844" style="fill: #dc2626; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="200.661996" y="108.130057" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="200.661996" y="108.130057" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="92.25537" y="188.595693" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="92.25537" y="188.595693" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="270.015498" y="46.739805" style="fill: #2563eb; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="270.015498" y="46.739805" style="fill: #2563eb; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="122.9463" y="155.448789" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="122.9463" y="155.448789" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="87.245469" y="162.865378" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="87.245469" y="162.865378" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="191.297259" y="105.857548" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="191.297259" y="105.857548" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="94.103082" y="180.921536" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="94.103082" y="180.921536" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="125.768303" y="154.511148" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="125.768303" y="154.511148" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="94.904652" y="208.993653" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="94.904652" y="208.993653" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="203.943971" y="118.698688" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="203.943971" y="118.698688" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="99.938374" y="172.327654" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="99.938374" y="172.327654" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="205.478897" y="157.174375" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="205.478897" y="157.174375" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="139.748096" y="154.862636" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="139.748096" y="154.862636" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="130.476287" y="195.152278" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="130.476287" y="195.152278" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="185.161429" y="109.023362" style="fill: #2563eb; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="185.161429" y="109.023362" style="fill: #2563eb; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="145.385704" y="88.747195" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="145.385704" y="88.747195" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="114.021044" y="153.2857" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="114.021044" y="153.2857" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="158.285126" y="93.91631" style="fill: #0891b2; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="158.285126" y="93.91631" style="fill: #0891b2; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="122.982782" y="151.412976" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="122.982782" y="151.412976" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="166.587644" y="158.594521" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="166.587644" y="158.594521" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="110.927272" y="105.119392" style="fill: #a16207; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="110.927272" y="105.119392" style="fill: #a16207; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="129.891305" y="117.88834" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="129.891305" y="117.88834" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="122.739229" y="190.229933" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="122.739229" y="190.229933" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="116.974683" y="163.567486" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="116.974683" y="163.567486" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="99.187143" y="165.351688" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="99.187143" y="165.351688" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="76.344517" y="84.599147" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="76.344517" y="84.599147" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="135.762022" y="151.720685" style="fill: #c026d3; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="135.762022" y="151.720685" style="fill: #c026d3; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="110.670452" y="191.657639" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="110.670452" y="191.657639" style="fill: #7e22ce; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="119.967495" y="164.843295" style="fill: #c026d3; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="119.967495" y="164.843295" style="fill: #c026d3; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="207.707901" y="134.494611" style="fill: #0ea5e9; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="207.707901" y="134.494611" style="fill: #0ea5e9; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="144.376434" y="146.08259" style="fill: #c026d3; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="144.376434" y="146.08259" style="fill: #c026d3; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
<g clip-path="url(#p284a2c037e)">
|
||||
<use xlink:href="#C1_0_cbf314fc02" x="104.172968" y="132.03677" style="fill: #c026d3; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
<g clip-path="url(#pcffe460afc)">
|
||||
<use xlink:href="#C1_0_fe6979fb3d" x="104.172968" y="132.03677" style="fill: #c026d3; stroke: #ffffff; stroke-width: 0.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="text_1">
|
||||
@@ -14793,7 +14793,7 @@ z
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="p284a2c037e">
|
||||
<clipPath id="pcffe460afc">
|
||||
<rect x="7.2" y="7.2" width="585.9" height="471.24"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
|
Before Width: | Height: | Size: 493 KiB After Width: | Height: | Size: 493 KiB |
@@ -0,0 +1 @@
|
||||
<svg fill="#D97757" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Claude</title><path d="m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>DeepSeek</title><circle cx="12" cy="12" r="11" fill="#5786fe"/><text x="12" y="16" text-anchor="middle" font-family="Arial,sans-serif" font-size="12" font-weight="700" fill="white">D</text></svg>
|
||||
|
After Width: | Height: | Size: 262 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#8E75B2" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Google Gemini</title><path d="M11.04 19.32Q12 21.51 12 24q0-2.49.93-4.68.96-2.19 2.58-3.81t3.81-2.55Q21.51 12 24 12q-2.49 0-4.68-.93a12.3 12.3 0 0 1-3.81-2.58 12.3 12.3 0 0 1-2.58-3.81Q12 2.49 12 0q0 2.49-.96 4.68-.93 2.19-2.55 3.81a12.3 12.3 0 0 1-3.81 2.58Q2.49 12 0 12q2.49 0 4.68.96 2.19.93 3.81 2.55t2.55 3.81"/></svg>
|
||||
|
After Width: | Height: | Size: 416 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#0467DF" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Meta</title><path d="M6.915 4.03c-1.968 0-3.683 1.28-4.871 3.113C.704 9.208 0 11.883 0 14.449c0 .706.07 1.369.21 1.973a6.624 6.624 0 0 0 .265.86 5.297 5.297 0 0 0 .371.761c.696 1.159 1.818 1.927 3.593 1.927 1.497 0 2.633-.671 3.965-2.444.76-1.012 1.144-1.626 2.663-4.32l.756-1.339.186-.325c.061.1.121.196.183.3l2.152 3.595c.724 1.21 1.665 2.556 2.47 3.314 1.046.987 1.992 1.22 3.06 1.22 1.075 0 1.876-.355 2.455-.843a3.743 3.743 0 0 0 .81-.973c.542-.939.861-2.127.861-3.745 0-2.72-.681-5.357-2.084-7.45-1.282-1.912-2.957-2.93-4.716-2.93-1.047 0-2.088.467-3.053 1.308-.652.57-1.257 1.29-1.82 2.05-.69-.875-1.335-1.547-1.958-2.056-1.182-.966-2.315-1.303-3.454-1.303zm10.16 2.053c1.147 0 2.188.758 2.992 1.999 1.132 1.748 1.647 4.195 1.647 6.4 0 1.548-.368 2.9-1.839 2.9-.58 0-1.027-.23-1.664-1.004-.496-.601-1.343-1.878-2.832-4.358l-.617-1.028a44.908 44.908 0 0 0-1.255-1.98c.07-.109.141-.224.211-.327 1.12-1.667 2.118-2.602 3.358-2.602zm-10.201.553c1.265 0 2.058.791 2.675 1.446.307.327.737.871 1.234 1.579l-1.02 1.566c-.757 1.163-1.882 3.017-2.837 4.338-1.191 1.649-1.81 1.817-2.486 1.817-.524 0-1.038-.237-1.383-.794-.263-.426-.464-1.13-.464-2.046 0-2.221.63-4.535 1.66-6.088.454-.687.964-1.226 1.533-1.533a2.264 2.264 0 0 1 1.088-.285z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Mistral</title><circle cx="12" cy="12" r="11" fill="#2ca02c"/><text x="12" y="16" text-anchor="middle" font-family="Arial,sans-serif" font-size="12" font-weight="700" fill="white">M</text></svg>
|
||||
|
After Width: | Height: | Size: 261 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#000000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Kimi</title><path d="M21.765.351C22.998.351 24 1.353 24 2.586S22.998 4.82 21.765 4.82h-1.974c-.15 0-.26-.12-.26-.26V2.586A2.237 2.237 0 0 1 21.765.35M9.41 13.388l8.447-8.377c.16-.16.07-.471-.14-.471h-4.55s-.1.02-.14.06l-9.099 9.029c-.14.14-.35.02-.35-.21V4.81c0-.15-.1-.27-.221-.27H.22c-.12 0-.22.12-.22.27v18.57c0 .15.1.27.22.27h3.137c.12 0 .22-.12.22-.27v-3.79c0-.08.03-.16.08-.21l2.826-2.796c.07-.07.16-.08.241-.03l7.546 5.551a8.9 8.9 0 0 0 4.018 1.493c.12.01.23-.11.23-.27V19.76c0-.14-.08-.25-.19-.26a5.8 5.8 0 0 1-2.355-.942l-6.533-4.73c-.14-.09-.15-.32-.03-.441"/></svg>
|
||||
|
After Width: | Height: | Size: 669 B |
@@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>OpenAI</title><circle cx="12" cy="12" r="11" fill="#111827"/><text x="12" y="16" text-anchor="middle" font-family="Arial,sans-serif" font-size="12" font-weight="700" fill="white">O</text></svg>
|
||||
|
After Width: | Height: | Size: 260 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#6950EF" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>QWen</title><path d="M23.919 14.545 20.817 9.17l1.47-2.544a.56.56 0 0 0 0-.566l-1.633-2.83a.57.57 0 0 0-.49-.283h-6.207L12.487.402a.57.57 0 0 0-.49-.284H8.732a.56.56 0 0 0-.49.284L5.139 5.775h-2.94a.56.56 0 0 0-.49.284L.077 8.887a.56.56 0 0 0 0 .567L3.18 14.83l-1.47 2.545a.56.56 0 0 0 0 .566l1.634 2.83a.57.57 0 0 0 .49.283h6.205l1.47 2.545a.56.56 0 0 0 .49.284h3.266a.57.57 0 0 0 .49-.284l3.104-5.375h2.94a.57.57 0 0 0 .49-.283l1.634-2.828a.55.55 0 0 0-.004-.568M8.733.686l1.634 2.828-1.634 2.828H21.8L20.164 9.17H7.425L5.63 6.06Zm1.306 19.801-6.205-.002 1.634-2.83h3.265L2.201 6.344h3.267q3.182 5.517 6.367 11.032zm10.124-5.66L18.53 12l-6.532 11.315-1.634-2.83c2.129-3.673 4.25-7.351 6.373-11.028h3.592l3.102 5.374z"/></svg>
|
||||
|
After Width: | Height: | Size: 820 B |
@@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Thinking Machines</title><circle cx="12" cy="12" r="11" fill="#0891b2"/><text x="12" y="16" text-anchor="middle" font-family="Arial,sans-serif" font-size="11" font-weight="700" fill="white">TM</text></svg>
|
||||
|
After Width: | Height: | Size: 272 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#000000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>X</title><path d="M14.234 10.162 22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299-.929-1.329L3.076 1.56h3.182l5.965 8.532.929 1.329 7.754 11.09h-3.182z"/></svg>
|
||||
|
After Width: | Height: | Size: 314 B |
@@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Z.ai</title><circle cx="12" cy="12" r="11" fill="#dc2626"/><text x="12" y="16" text-anchor="middle" font-family="Arial,sans-serif" font-size="12" font-weight="700" fill="white">Z</text></svg>
|
||||
|
After Width: | Height: | Size: 258 B |
@@ -0,0 +1 @@
|
||||
:root{--ink:#333;--muted:#8a857a;--rule:#eceadf;--canvas:#faf8f2}*{box-sizing:border-box}body{background:var(--canvas);color:var(--ink);margin:0;font:16px/1.5 -apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}main{max-width:1200px;margin:auto;padding:1.5rem 1rem 3rem}h1{margin:0 0 .35rem;font-size:1.65rem;line-height:1.2}.lede,.caption{color:#59544b;max-width:75ch}.controls{flex-wrap:wrap;gap:.35rem;margin:1rem 0;display:flex}.chip{color:var(--ink);cursor:pointer;background:#fff;border:1px solid #d9d5ca;border-radius:999px;align-items:center;gap:.3rem;padding:.22rem .48rem;font:600 .78rem/1 inherit;display:flex}.chip img{width:13px;height:13px}.chip:hover{border-color:#8a857a}.chip:focus-visible,.model-mark:focus-visible{outline-offset:2px;outline:2px solid #2563eb}.chip[aria-pressed=false]{color:#8a857a;background:#f6f4ef;text-decoration:line-through}.chip[aria-pressed=false] img{opacity:.3}.chart-shell{position:relative}.chart-shell svg{background:var(--canvas);border:1px solid #ded9cc;width:100%;height:auto;display:block}.canvas{fill:var(--canvas)}.grid line{stroke:var(--rule);stroke-width:.7px}.median{stroke:#c9c4b4;stroke-width:1.2px}.zone{fill:none;stroke-width:2px;opacity:.9}.country{stroke:#fff;stroke-width:.7px;opacity:.88}.country-label,.model-label,.zone-label,.poles text{paint-order:stroke;stroke:var(--canvas);stroke-width:4px;stroke-linejoin:round}.country-label{fill:#222;font-size:11px}.model-ring{fill:#fff;stroke-width:2px}.model-mark{cursor:default}.model-mark:focus{outline:none}.model-label{fill:#222;font-size:13px;font-weight:700}.leader{stroke:#aaa398;stroke-width:1px}.zone-label{font-size:15px;font-style:italic;font-weight:700}.poles line{stroke:#999;stroke-width:1.8px}.arrow{fill:#999}.poles text{fill:#555;font-size:18px;font-weight:700}.map-title{fill:#333;font-size:14px;font-weight:700}.map-note{fill:var(--muted);font-size:10px}.tooltip{z-index:2;pointer-events:none;background:#fffffff7;border:1px solid #ddd7ca;border-radius:5px;max-width:275px;padding:.45rem .6rem;font-size:.82rem;line-height:1.35;position:absolute;transform:translate(14px,14px);box-shadow:0 2px 8px #0002}.tooltip strong,.tooltip span{display:block}.tooltip span{color:#5b554b}.caption{margin-top:1rem;font-size:.9rem}@media (width<=700px){main{padding:.9rem .5rem 2rem}.chip{font-size:.7rem}.poles text{font-size:14px}.country-label,.model-label{font-size:10px}.tooltip{max-width:230px;font-size:.75rem}}
|
||||
@@ -1 +0,0 @@
|
||||
body{color:#292524;background:#faf8f2;margin:0;font:16px system-ui,sans-serif}main{max-width:1100px;margin:auto;padding:1rem}.controls{flex-wrap:wrap;gap:.4rem;margin:1rem 0;display:flex}button{border:2px solid var(--color);background:var(--color);color:#fff;border-radius:1rem;padding:.3rem .7rem;font-weight:600}button.off{color:#292524;opacity:.5;background:#fff;text-decoration:line-through}svg{background:#faf8f2;border:1px solid #292524;width:100%;height:auto}.axis{stroke:#c9c4b4}.zone{fill:none;stroke:#94a3b8;stroke-width:2px;stroke-dasharray:5 3}.zoneLabel{fill:#475569;text-anchor:middle;font-style:italic;font-weight:700}.country{fill:#64748b;stroke:#fff;stroke-width:.6px}.star{stroke:#fff;stroke-width:1px}.modelLabel{font-size:10px;font-weight:700}
|
||||
@@ -1,3 +1,3 @@
|
||||
<script type="module" crossorigin src="./assets/index-CCNzz5z-.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-Bn48Fufr.css">
|
||||
<script type="module" crossorigin src="./assets/index-DbBL7VOr.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-BFIE5goS.css">
|
||||
<div id="root"></div>
|
||||
|
||||
@@ -420,23 +420,73 @@ def main() -> None:
|
||||
label_sources[family] = "explicit legacy release-order choice"
|
||||
model_labels[latest] = latest.replace("claude-", "")
|
||||
if args.web_data:
|
||||
# This artifact is the shared geometry contract for the static, vanilla SVG and React maps.
|
||||
# It stores the already-oriented coordinates and the static renderer's annotation policy.
|
||||
from shapely.geometry import MultiPoint
|
||||
|
||||
zones_all, _ = zones_for(countries)
|
||||
zones = maps.select_spread_zones(P, countries, zones_all, 4)
|
||||
sx, sy = maps.orient_geographic(P, countries, zones_all)
|
||||
Pplot = P * np.array([sx, sy])
|
||||
zones, dot_cols, label_set = maps._map_annotations(Pplot, countries, zones_all, emph, "#888888")
|
||||
cidx = {country: i for i, country in enumerate(countries)}
|
||||
buf = 0.022 * float(np.hypot(*(Pplot.max(0) - Pplot.min(0))))
|
||||
zone_hulls = []
|
||||
for zone, members in zones.items():
|
||||
pts = [tuple(Pplot[cidx[country]]) for country in members if country in cidx]
|
||||
if len(pts) < 2:
|
||||
raise ValueError(f"zone {zone} lacks two plotted countries")
|
||||
coords = np.asarray(MultiPoint(pts).convex_hull.buffer(buf, quad_segs=16).exterior.coords)
|
||||
# The static renderer's region allocator starts from the whole hull perimeter. The
|
||||
# browser's expanding-ring allocator starts from the centroid, so its first viable
|
||||
# candidate remains adjacent to the corresponding coloured boundary.
|
||||
centroid = coords[:-1].mean(axis=0)
|
||||
zone_hulls.append({"name": zone, "color": maps.ZONE_COLORS[zone],
|
||||
"points": coords.tolist(), "label_anchor": centroid.tolist()})
|
||||
|
||||
completed = {entry["display_key"].replace(" (rated)", ""): entry
|
||||
for entry in cache["completed"].values()}
|
||||
family_logos = {
|
||||
"claude": "logos/anthropic.svg", "deepseek": "logos/deepseek.svg",
|
||||
"gemini": "logos/google.svg", "gemma": "logos/google.svg",
|
||||
"glm": "logos/z-ai.svg", "gpt": "logos/openai.svg", "grok": "logos/x-ai.svg",
|
||||
"inkling": "logos/thinkingmachines.svg", "kimi": "logos/moonshotai.svg",
|
||||
"llama": "logos/meta.svg", "mistral": "logos/mistral.svg", "muse": "logos/meta.svg",
|
||||
"qwen": "logos/qwen.svg",
|
||||
}
|
||||
|
||||
def model_provenance(name: str) -> dict[str, object]:
|
||||
panel = completed.get(name)
|
||||
catalog = metadata.get(name)
|
||||
if panel is None:
|
||||
return {"readout": "recovered rounded historical coordinate", "items": None,
|
||||
"samples": None, "run_id": None, "protocol_id": None,
|
||||
"release_created": None, "release_source": "historical coordinate"}
|
||||
return {"readout": "rated categorical response", "items": panel["n_items"],
|
||||
"samples": panel["n_samples"], "run_id": panel["run_id"],
|
||||
"protocol_id": panel["protocol_id"],
|
||||
"release_created": catalog["created"] if catalog else None,
|
||||
"release_source": "catalog" if catalog else "request ledger"}
|
||||
|
||||
args.web_data.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.web_data.write_text(json.dumps({
|
||||
"schema": 1,
|
||||
"schema": 2,
|
||||
"title": "Frontier LLMs on the\nWorld Values Survey",
|
||||
"note": f"{len(plot_models)} models, rated sampling\ngithub.com/wassname/moral-maps",
|
||||
"axis": {"x": (["Self-expression", "Survival"] if sx < 0 else ["Survival", "Self-expression"]),
|
||||
"y": (["Secular-Rational", "Traditional"] if sy < 0 else ["Traditional", "Secular-Rational"])},
|
||||
"median": {"x": float(np.median(P[:, 0]) * sx), "y": float(np.median(P[:, 1]) * sy)},
|
||||
"countries": [{"name": name, "x": float(x * sx), "y": float(y * sy)}
|
||||
for name, (x, y) in zip(countries, P)],
|
||||
"median": {"x": float(np.median(Pplot[:, 0])), "y": float(np.median(Pplot[:, 1]))},
|
||||
"countries": [{"name": name, "x": float(x), "y": float(y), "color": color,
|
||||
"label": name if name in label_set else None}
|
||||
for name, (x, y), color in zip(countries, Pplot, dot_cols)],
|
||||
"zones": zones,
|
||||
"zone_hulls": zone_hulls,
|
||||
"logos": family_logos,
|
||||
"latest_by_family": {family: {"name": name, "source": label_sources[family]}
|
||||
for family, names in fams.items() for name in names if name in model_labels},
|
||||
"models": [{"name": name, "x": float(v[0] * sx), "y": float(v[1] * sy),
|
||||
"family": maps.model_family(name), "color": maps.model_family_color(name),
|
||||
"label": model_labels.get(name)} for name, v in plot_models.items()],
|
||||
"label": model_labels.get(name), "provenance": model_provenance(name)}
|
||||
for name, v in plot_models.items()],
|
||||
}, indent=2, sort_keys=True) + "\n")
|
||||
# Poles in NATURAL data order (x_neg, x_pos, y_neg, y_pos): raw X is high on Self-expression, raw Y
|
||||
# high on Secular-Rational. plot_value_map's orient_geographic then flips X so the cultural West
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import fs from 'node:fs';
|
||||
import { assertLayout } from './src/layout.js';
|
||||
|
||||
const path = process.argv[2] ?? '../../docs/wvs/wvs_map_data.json';
|
||||
const data = JSON.parse(fs.readFileSync(path));
|
||||
const { labels, geometry } = assertLayout(data);
|
||||
const kinds = Object.values(labels).reduce((count, label) => ({ ...count, [label.kind]: (count[label.kind] ?? 0) + 1 }), {});
|
||||
console.log(JSON.stringify({
|
||||
labels: Object.keys(labels).length,
|
||||
kinds,
|
||||
bounds: geometry.bounds,
|
||||
policy: 'expanding rings, increasing steps, marker obstacles, pairwise overlap and bounds assertions',
|
||||
}, null, 2));
|
||||
@@ -0,0 +1,79 @@
|
||||
export const VIEW = { width: 1200, height: 900, pad: { left: 76, right: 46, top: 55, bottom: 82 } };
|
||||
|
||||
// Ported from ml-bench: try near each anchor before growing an expanding ring.
|
||||
export const RINGS = [[0, -1], [0, 1], [-1, 0], [1, 0], [-1, -1], [1, -1], [-1, 1], [1, 1]];
|
||||
export const LABEL_STEPS = [22, 34, 48, 64, 82, 104, 130, 160, 196];
|
||||
|
||||
export const box = (cx, cy, width, height) => ({ cx, cy, width, height });
|
||||
export const hits = (a, b) => Math.abs(a.cx - b.cx) * 2 < a.width + b.width && Math.abs(a.cy - b.cy) * 2 < a.height + b.height;
|
||||
export const inside = (candidate, bounds) => candidate.cx - candidate.width / 2 >= bounds.left &&
|
||||
candidate.cx + candidate.width / 2 <= bounds.right && candidate.cy - candidate.height / 2 >= bounds.top &&
|
||||
candidate.cy + candidate.height / 2 <= bounds.bottom;
|
||||
|
||||
export function projectGeometry(data) {
|
||||
const points = [...data.countries, ...data.models];
|
||||
const minX = Math.min(...points.map(point => point.x));
|
||||
const maxX = Math.max(...points.map(point => point.x));
|
||||
const minY = Math.min(...points.map(point => point.y));
|
||||
const maxY = Math.max(...points.map(point => point.y));
|
||||
const xMargin = (maxX - minX) * 0.17;
|
||||
const yMargin = (maxY - minY) * 0.17;
|
||||
const limits = { x0: minX - xMargin, x1: maxX + xMargin, y0: minY - yMargin, y1: maxY + yMargin * 1.22 };
|
||||
const bounds = { left: VIEW.pad.left, right: VIEW.width - VIEW.pad.right, top: VIEW.pad.top, bottom: VIEW.height - VIEW.pad.bottom };
|
||||
const x = value => bounds.left + (value - limits.x0) / (limits.x1 - limits.x0) * (bounds.right - bounds.left);
|
||||
const y = value => bounds.bottom - (value - limits.y0) / (limits.y1 - limits.y0) * (bounds.bottom - bounds.top);
|
||||
return { x, y, bounds, limits };
|
||||
}
|
||||
|
||||
function labelSize(text, kind) {
|
||||
const font = kind === 'zone' ? 15 : kind === 'model' ? 13 : 11;
|
||||
return { width: text.length * font * 0.59 + 10, height: font + 7 };
|
||||
}
|
||||
|
||||
export function placeLabels(data, geometry) {
|
||||
const { x, y, bounds } = geometry;
|
||||
const taken = [
|
||||
...data.countries.map(point => box(x(point.x), y(point.y), 10, 10)),
|
||||
...data.models.map(point => box(x(point.x), y(point.y), 22, 22)),
|
||||
];
|
||||
const labels = [
|
||||
...data.models.filter(point => point.label).map(point => ({ id: `model:${point.name}`, point, text: point.label, kind: 'model' })),
|
||||
...data.countries.filter(point => point.label).map(point => ({ id: `country:${point.name}`, point, text: point.name, kind: 'country' })),
|
||||
...data.zone_hulls.map(zone => ({ id: `zone:${zone.name}`, point: { x: zone.label_anchor[0], y: zone.label_anchor[1] }, text: zone.name, kind: 'zone' })),
|
||||
];
|
||||
const placements = {};
|
||||
for (const label of labels) {
|
||||
const anchor = { x: x(label.point.x), y: y(label.point.y) };
|
||||
const size = labelSize(label.text, label.kind);
|
||||
let found = null;
|
||||
for (const step of LABEL_STEPS) {
|
||||
for (const [dx, dy] of RINGS) {
|
||||
const candidate = box(anchor.x + dx * (step + size.width / 3), anchor.y + dy * step, size.width, size.height);
|
||||
if (inside(candidate, bounds) && !taken.some(obstacle => hits(candidate, obstacle))) {
|
||||
found = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
if (!found) throw new Error(`no collision-free label location for ${label.id}`);
|
||||
placements[label.id] = { ...found, anchor, kind: label.kind, text: label.text };
|
||||
taken.push(found);
|
||||
}
|
||||
return placements;
|
||||
}
|
||||
|
||||
export function assertLayout(data) {
|
||||
const geometry = projectGeometry(data);
|
||||
const labels = placeLabels(data, geometry);
|
||||
const entries = Object.entries(labels);
|
||||
for (const [id, candidate] of entries) {
|
||||
if (!inside(candidate, geometry.bounds)) throw new Error(`label out of bounds: ${id}`);
|
||||
}
|
||||
for (let i = 0; i < entries.length; i += 1) {
|
||||
for (let j = i + 1; j < entries.length; j += 1) {
|
||||
if (hits(entries[i][1], entries[j][1])) throw new Error(`label overlap: ${entries[i][0]}, ${entries[j][0]}`);
|
||||
}
|
||||
}
|
||||
return { labels, geometry };
|
||||
}
|
||||
@@ -1,29 +1,94 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { VIEW, assertLayout } from './layout.js';
|
||||
import './style.css';
|
||||
|
||||
const hull = points => {
|
||||
const p = [...points].sort((a, b) => a.x - b.x || a.y - b.y);
|
||||
const cross = (o, a, b) => (a.x-o.x)*(b.y-o.y) - (a.y-o.y)*(b.x-o.x);
|
||||
const half = xs => { const out = []; for (const point of xs) { while (out.length > 1 && cross(out.at(-2), out.at(-1), point) <= 0) out.pop(); out.push(point); } return out; };
|
||||
return [...half(p), ...half([...p].reverse()).slice(1, -1)];
|
||||
};
|
||||
function Tooltip({ active, geometry, data }) {
|
||||
if (!active) return null;
|
||||
const { provenance } = active;
|
||||
const left = `${Math.min(86, geometry.x(active.x) / VIEW.width * 100)}%`;
|
||||
const top = `${Math.min(82, geometry.y(active.y) / VIEW.height * 100)}%`;
|
||||
const samples = provenance.items === null ? 'historical coordinate' : `${provenance.items} items x ${provenance.samples} samples`;
|
||||
return <aside id="model-tooltip" className="tooltip" style={{ left, top }} role="status">
|
||||
<strong>{active.name}</strong>
|
||||
<span>{active.family}</span>
|
||||
<span>{data.axis.x[0]} {'->'} {data.axis.x[1]}: {active.x.toFixed(3)}</span>
|
||||
<span>{data.axis.y[0]} {'->'} {data.axis.y[1]}: {active.y.toFixed(3)}</span>
|
||||
<span>{provenance.readout}, {samples}</span>
|
||||
<span>{provenance.release_created ? `release ${provenance.release_created}` : provenance.release_source}</span>
|
||||
</aside>;
|
||||
}
|
||||
|
||||
function ModelMarker({ model, placement, geometry, setActive, clearActive, markerRef, logo }) {
|
||||
const cx = geometry.x(model.x), cy = geometry.y(model.y);
|
||||
const label = model.label ? placement[`model:${model.name}`] : null;
|
||||
const leader = label && Math.hypot(label.cx - cx, label.cy - cy) > 20;
|
||||
return <g ref={markerRef} className="model-mark" data-family={model.family} data-model={model.name} data-x={model.x} data-y={model.y}
|
||||
tabIndex="0" role="button" aria-label={`${model.name}, ${model.family}`} aria-describedby="model-tooltip"
|
||||
onPointerEnter={() => setActive(model)} onPointerLeave={clearActive}
|
||||
onFocus={() => setActive(model)} onBlur={clearActive}>
|
||||
{leader && <line className="leader" x1={cx} y1={cy} x2={label.cx} y2={label.cy} />}
|
||||
<circle className="model-ring" cx={cx} cy={cy} r="11" stroke={model.color} />
|
||||
<image href={`../${logo}`} x={cx - 7} y={cy - 7} width="14" height="14" preserveAspectRatio="xMidYMid meet" />
|
||||
{label && <text className="model-label" x={label.cx} y={label.cy + 4} textAnchor="middle">{model.label}</text>}
|
||||
</g>;
|
||||
}
|
||||
|
||||
function Map({ data }) {
|
||||
const [hidden, setHidden] = useState(() => new Set(new URLSearchParams(location.search).get('hide')?.split(',').filter(Boolean)));
|
||||
const all = [...data.countries, ...data.models];
|
||||
const [minX, maxX] = [Math.min(...all.map(p => p.x)), Math.max(...all.map(p => p.x))];
|
||||
const [minY, maxY] = [Math.min(...all.map(p => p.y)), Math.max(...all.map(p => p.y))];
|
||||
const x = v => 70 + (v-minX)/(maxX-minX)*860, y = v => 650 - (v-minY)/(maxY-minY)*580;
|
||||
const query = new URLSearchParams(location.search);
|
||||
const [hidden, setHidden] = useState(() => new Set(query.get('hide')?.split(',').filter(Boolean)));
|
||||
const [active, setActive] = useState(() => data.models.find(model => model.name === (query.get('tooltip') || query.get('focus'))) ?? null);
|
||||
const focusName = query.get('focus');
|
||||
const focusRef = useRef(null);
|
||||
const groups = useMemo(() => Object.groupBy(data.models, model => model.family), [data]);
|
||||
const offsets = { grok:{dx:-72,dy:-30}, muse:{dx:12,dy:-11}, mistral:{dx:-96,dy:-26}, llama:{dx:-96,dy:12} };
|
||||
return <><div className="controls">{Object.entries(groups).map(([family, models]) => <button key={family} className={hidden.has(family) ? 'off' : ''} style={{'--color': models[0].color}} onClick={() => setHidden(old => { const next = new Set(old); next.has(family) ? next.delete(family) : next.add(family); return next; })}>{family}: {data.latest_by_family[family].name}</button>)}</div>
|
||||
<svg viewBox="0 0 1000 720" aria-label="React WVS cultural map"><line x1="70" y1={y(data.median.y)} x2="930" y2={y(data.median.y)} className="axis"/><line x1={x(data.median.x)} y1="70" x2={x(data.median.x)} y2="650" className="axis"/>
|
||||
{Object.entries(data.zones).map(([name, names]) => { const h=hull(data.countries.filter(p=>names.includes(p.name))); const c=h.reduce((s,p)=>({x:s.x+p.x/h.length,y:s.y+p.y/h.length}),{x:0,y:0}); return <g key={name}><polygon points={h.map(p=>`${x(p.x)},${y(p.y)}`).join(' ')} className="zone"/><text x={x(c.x)} y={y(c.y)} className="zoneLabel">{name}</text></g>; })}
|
||||
{data.countries.map(p => <circle key={p.name} cx={x(p.x)} cy={y(p.y)} r="3" className="country"><title>{p.name}</title></circle>)}
|
||||
{Object.entries(groups).map(([family, models]) => <g key={family} display={hidden.has(family) ? 'none' : 'inline'}>{models.map(p => { const o=offsets[family] ?? {dx:11,dy:-11}; return <g key={p.name}><path d={`M ${x(p.x)} ${y(p.y)-8} L ${x(p.x)+2.4} ${y(p.y)-2.4} L ${x(p.x)+8} ${y(p.y)-2.4} L ${x(p.x)+3.6} ${y(p.y)+1.6} L ${x(p.x)+5.2} ${y(p.y)+7} L ${x(p.x)} ${y(p.y)+4} L ${x(p.x)-5.2} ${y(p.y)+7} L ${x(p.x)-3.6} ${y(p.y)+1.6} L ${x(p.x)-8} ${y(p.y)-2.4} L ${x(p.x)-2.4} ${y(p.y)-2.4} Z`} fill={p.color} className="star"><title>{p.name}</title></path>{p.label && <><line x1={x(p.x)} y1={y(p.y)} x2={x(p.x)+o.dx*.82} y2={y(p.y)+o.dy*.82} stroke={p.color}/><text x={x(p.x)+o.dx} y={y(p.y)+o.dy} fill={p.color} className="modelLabel">{p.label}</text></>}</g>; })}</g>)}
|
||||
<text x="70" y="690" className="axisLabel">{data.axis.x[0]}</text><text x="930" y="690" textAnchor="end" className="axisLabel">{data.axis.x[1]}</text><text x="500" y="30" textAnchor="middle" className="axisLabel">{data.axis.y[1]}</text><text x="500" y="710" textAnchor="middle" className="axisLabel">{data.axis.y[0]}</text>
|
||||
</svg></>;
|
||||
const { labels, geometry } = useMemo(() => assertLayout(data), [data]);
|
||||
|
||||
useEffect(() => {
|
||||
if (focusName) focusRef.current?.focus();
|
||||
}, [focusName]);
|
||||
|
||||
const clearActive = event => {
|
||||
if (event.currentTarget.matches(':focus')) return;
|
||||
setActive(null);
|
||||
};
|
||||
const toggle = family => setHidden(old => {
|
||||
const next = new Set(old);
|
||||
if (next.has(family)) next.delete(family); else next.add(family);
|
||||
return next;
|
||||
});
|
||||
const xMedian = geometry.x(data.median.x), yMedian = geometry.y(data.median.y);
|
||||
return <>
|
||||
<section className="controls" aria-label="Model-family visibility">{Object.entries(groups).map(([family, models]) => {
|
||||
const visible = !hidden.has(family);
|
||||
const latest = data.latest_by_family[family].name;
|
||||
return <button key={family} className="chip" type="button" aria-pressed={visible} onClick={() => toggle(family)}>
|
||||
<img src={`../${data.logos[family]}`} alt="" />{family}: {latest}
|
||||
</button>;
|
||||
})}</section>
|
||||
<div className="chart-shell">
|
||||
<svg viewBox={`0 0 ${VIEW.width} ${VIEW.height}`} role="img" aria-label="Frontier LLMs on the World Values Survey" data-median-x={data.median.x} data-median-y={data.median.y}>
|
||||
<defs><marker id="arrow" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto"><path d="M0,0 L0,6 L6,3 z" className="arrow" /></marker></defs>
|
||||
<rect className="canvas" width={VIEW.width} height={VIEW.height} />
|
||||
<g className="grid">{Array.from({ length: 8 }, (_, index) => <line key={`v${index}`} x1={geometry.bounds.left + index * (geometry.bounds.right - geometry.bounds.left) / 7} y1={geometry.bounds.top} x2={geometry.bounds.left + index * (geometry.bounds.right - geometry.bounds.left) / 7} y2={geometry.bounds.bottom} />)}{Array.from({ length: 6 }, (_, index) => <line key={`h${index}`} x1={geometry.bounds.left} y1={geometry.bounds.top + index * (geometry.bounds.bottom - geometry.bounds.top) / 5} x2={geometry.bounds.right} y2={geometry.bounds.top + index * (geometry.bounds.bottom - geometry.bounds.top) / 5} />)}</g>
|
||||
<line className="median" x1={geometry.bounds.left} y1={yMedian} x2={geometry.bounds.right} y2={yMedian} />
|
||||
<line className="median" x1={xMedian} y1={geometry.bounds.top} x2={xMedian} y2={geometry.bounds.bottom} />
|
||||
{data.zone_hulls.map(zone => <polygon key={zone.name} className="zone" points={zone.points.map(([px, py]) => `${geometry.x(px)},${geometry.y(py)}`).join(' ')} stroke={zone.color} />)}
|
||||
{data.countries.map(country => <g key={country.name}><circle className="country" data-country={country.name} data-x={country.x} data-y={country.y} cx={geometry.x(country.x)} cy={geometry.y(country.y)} r="3.5" fill={country.color} />{country.label && <text className="country-label" x={labels[`country:${country.name}`].cx} y={labels[`country:${country.name}`].cy + 4} textAnchor="middle">{country.name}</text>}</g>)}
|
||||
{data.zone_hulls.map(zone => <text key={zone.name} className="zone-label" x={labels[`zone:${zone.name}`].cx} y={labels[`zone:${zone.name}`].cy + 5} textAnchor="middle" fill={zone.color}>{zone.name}</text>)}
|
||||
{Object.entries(groups).map(([family, models]) => <g key={family} data-family={family} display={hidden.has(family) ? 'none' : 'inline'}>{models.map(model => <ModelMarker key={model.name} model={model} placement={labels} geometry={geometry} setActive={setActive} clearActive={clearActive} markerRef={model.name === focusName ? focusRef : null} logo={data.logos[model.family]} />)}</g>)}
|
||||
<g className="poles"><line x1={xMedian} y1="62" x2={xMedian} y2={geometry.bounds.top} markerEnd="url(#arrow)" /><line x1={xMedian} y1={geometry.bounds.bottom} x2={xMedian} y2="838" markerEnd="url(#arrow)" /><line x1="64" y1={yMedian} x2={geometry.bounds.left} y2={yMedian} markerEnd="url(#arrow)" /><line x1={geometry.bounds.right} y1={yMedian} x2="1184" y2={yMedian} markerEnd="url(#arrow)" /><text x={xMedian} y="40" textAnchor="middle">{data.axis.y[1]}</text><text x={xMedian} y="870" textAnchor="middle">{data.axis.y[0]}</text><text x="25" y={yMedian + 7}>{data.axis.x[0]}</text><text x="1136" y={yMedian + 7} textAnchor="end">{data.axis.x[1]}</text></g>
|
||||
<text className="map-title" x={geometry.bounds.left + 8} y={geometry.bounds.bottom - 34}>{data.title.split('\n').map((line, index) => <tspan key={line} x={geometry.bounds.left + 8} dy={index ? 17 : 0}>{line}</tspan>)}</text>
|
||||
<text className="map-note" x={geometry.bounds.left + 8} y={geometry.bounds.bottom - 7}>{data.note.split('\n').map((line, index) => <tspan key={line} x={geometry.bounds.left + 8} dy={index ? 11 : 0}>{line}</tspan>)}</text>
|
||||
</svg>
|
||||
<Tooltip active={active} geometry={geometry} data={data} />
|
||||
</div>
|
||||
</>;
|
||||
}
|
||||
function App() { const [data, setData] = useState(null); useEffect(() => { fetch('../wvs_map_data.json').then(r=>r.json()).then(setData); }, []); return <main><h1>Frontier LLMs on the World Values Survey</h1><p>React/SVG renderer using the shared WVS coordinate artifact. Filled chips show a family; outlined chips hide its stars and latest label.</p>{data && <Map data={data}/>}</main>; }
|
||||
|
||||
function App() {
|
||||
const [data, setData] = useState(null);
|
||||
useEffect(() => { fetch('../wvs_map_data.json').then(response => response.json()).then(setData); }, []);
|
||||
return <main><h1>Frontier LLMs on the World Values Survey</h1><p className="lede">React/SVG rendering of the shared WVS coordinate artifact. White-ring marks use locally saved lab logos. Focus or hover a model for its measured readout and release provenance.</p>{data && <Map data={data} />}<p className="caption">Historical coordinates are recovered rounded display values. Coder and vision-language Qwen variants are visible but not used in direct-instruct family trends. The static map remains available at <a href="../">/wvs/</a>.</p></main>;
|
||||
}
|
||||
|
||||
createRoot(document.getElementById('root')).render(<App/>);
|
||||
|
||||
@@ -1 +1 @@
|
||||
body{margin:0;background:#faf8f2;color:#292524;font:16px system-ui,sans-serif}main{max-width:1100px;margin:auto;padding:1rem}.controls{display:flex;flex-wrap:wrap;gap:.4rem;margin:1rem 0}button{border:2px solid var(--color);border-radius:1rem;padding:.3rem .7rem;background:var(--color);color:white;font-weight:600}button.off{background:white;color:#292524;opacity:.5;text-decoration:line-through}svg{width:100%;height:auto;background:#faf8f2;border:1px solid #292524}.axis{stroke:#c9c4b4}.zone{fill:none;stroke:#94a3b8;stroke-width:2;stroke-dasharray:5 3}.zoneLabel{fill:#475569;font-style:italic;font-weight:700;text-anchor:middle}.country{fill:#64748b;stroke:white;stroke-width:.6}.star{stroke:white;stroke-width:1}.modelLabel{font-size:10px;font-weight:700}
|
||||
:root{--ink:#333;--muted:#8a857a;--rule:#eceadf;--canvas:#faf8f2}*{box-sizing:border-box}body{margin:0;background:var(--canvas);color:var(--ink);font:16px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif}main{max-width:1200px;margin:auto;padding:1.5rem 1rem 3rem}h1{font-size:1.65rem;line-height:1.2;margin:0 0 .35rem}.lede,.caption{max-width:75ch;color:#59544b}.controls{display:flex;flex-wrap:wrap;gap:.35rem;margin:1rem 0}.chip{display:flex;align-items:center;gap:.3rem;padding:.22rem .48rem;border:1px solid #d9d5ca;border-radius:999px;background:white;color:var(--ink);font:600 .78rem/1 inherit;cursor:pointer}.chip img{width:13px;height:13px}.chip:hover{border-color:#8a857a}.chip:focus-visible,.model-mark:focus-visible{outline:2px solid #2563eb;outline-offset:2px}.chip[aria-pressed="false"]{color:#8a857a;background:#f6f4ef;text-decoration:line-through}.chip[aria-pressed="false"] img{opacity:.3}.chart-shell{position:relative}.chart-shell svg{display:block;width:100%;height:auto;border:1px solid #ded9cc;background:var(--canvas)}.canvas{fill:var(--canvas)}.grid line{stroke:var(--rule);stroke-width:.7}.median{stroke:#c9c4b4;stroke-width:1.2}.zone{fill:none;stroke-width:2;opacity:.9}.country{stroke:white;stroke-width:.7;opacity:.88}.country-label,.model-label,.zone-label,.poles text{paint-order:stroke;stroke:var(--canvas);stroke-width:4px;stroke-linejoin:round}.country-label{fill:#222;font-size:11px}.model-ring{fill:white;stroke-width:2}.model-mark{cursor:default}.model-mark:focus{outline:none}.model-label{fill:#222;font-size:13px;font-weight:700}.leader{stroke:#aaa398;stroke-width:1}.zone-label{font-size:15px;font-style:italic;font-weight:700}.poles line{stroke:#999;stroke-width:1.8}.arrow{fill:#999}.poles text{fill:#555;font-size:18px;font-weight:700}.map-title{fill:#333;font-size:14px;font-weight:700}.map-note{fill:var(--muted);font-size:10px}.tooltip{position:absolute;z-index:2;max-width:275px;transform:translate(14px,14px);pointer-events:none;border:1px solid #ddd7ca;border-radius:5px;padding:.45rem .6rem;background:rgba(255,255,255,.97);box-shadow:0 2px 8px #0002;font-size:.82rem;line-height:1.35}.tooltip strong,.tooltip span{display:block}.tooltip span{color:#5b554b}.caption{font-size:.9rem;margin-top:1rem}@media(max-width:700px){main{padding:.9rem .5rem 2rem}.chip{font-size:.7rem}.poles text{font-size:14px}.country-label,.model-label{font-size:10px}.tooltip{max-width:230px;font-size:.75rem}}
|
||||
@@ -0,0 +1,116 @@
|
||||
"""Playwright UAT for the production React WVS SVG. No network calls leave localhost."""
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image, ImageDraw
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
OUT = ROOT / "slop/research/wvs/20260916_openrouter"
|
||||
BASE = "http://localhost:8081/wvs"
|
||||
VIEWPORT = {"width": 1440, "height": 1800}
|
||||
|
||||
|
||||
def screenshot(page, url: str, name: str) -> Path:
|
||||
page.goto(url, wait_until="networkidle")
|
||||
page.screenshot(path=OUT / name, full_page=True)
|
||||
return OUT / name
|
||||
|
||||
|
||||
def main() -> None:
|
||||
OUT.mkdir(parents=True, exist_ok=True)
|
||||
chrome = shutil.which("google-chrome")
|
||||
if chrome is None:
|
||||
raise RuntimeError("google-chrome is required for the Playwright UAT")
|
||||
data = json.loads((ROOT / "docs/wvs/wvs_map_data.json").read_text())
|
||||
assert data["schema"] == 2
|
||||
assert len(data["models"]) == 64
|
||||
assert len(data["countries"]) == 90
|
||||
assert len(data["zone_hulls"]) == 4
|
||||
assert len(data["latest_by_family"]) == 13
|
||||
assert all(len(zone["points"]) >= 30 for zone in data["zone_hulls"])
|
||||
|
||||
with sync_playwright() as playwright:
|
||||
browser = playwright.chromium.launch(executable_path=chrome, headless=True, args=["--no-sandbox"])
|
||||
page = browser.new_page(viewport=VIEWPORT)
|
||||
errors: list[str] = []
|
||||
page.on("pageerror", lambda error: errors.append(str(error)))
|
||||
|
||||
screenshot(page, "http://localhost:8081/img/wvs/wvs_map_iw.png", "wvs_static_playwright.png")
|
||||
screenshot(page, f"{BASE}/", "wvs_vanilla_playwright.png")
|
||||
screenshot(page, f"{BASE}/react/", "wvs_react_playwright_default.png")
|
||||
page.wait_for_selector("svg .model-mark")
|
||||
assert float(page.locator("svg").get_attribute("data-median-x")) == data["median"]["x"]
|
||||
assert float(page.locator("svg").get_attribute("data-median-y")) == data["median"]["y"]
|
||||
rendered_models = page.locator(".model-mark").evaluate_all(
|
||||
"nodes => nodes.map(node => [node.dataset.model, Number(node.dataset.x), Number(node.dataset.y)])"
|
||||
)
|
||||
assert sorted(rendered_models) == sorted([[model["name"], model["x"], model["y"]] for model in data["models"]])
|
||||
rendered_countries = page.locator("circle.country").evaluate_all(
|
||||
"nodes => nodes.map(node => [node.dataset.country, Number(node.dataset.x), Number(node.dataset.y)])"
|
||||
)
|
||||
assert rendered_countries == [[country["name"], country["x"], country["y"]] for country in data["countries"]]
|
||||
country_before = page.locator("circle.country").evaluate_all(
|
||||
"nodes => nodes.map(node => [node.getAttribute('cx'), node.getAttribute('cy')])"
|
||||
)
|
||||
qwen_group = page.locator('svg > g[data-family="qwen"]')
|
||||
assert qwen_group.get_attribute("display") in (None, "inline")
|
||||
assert page.locator('svg [data-family="qwen"] .model-label').count() == 1
|
||||
|
||||
page.get_by_role("button", name="qwen: qwen3.8-flash").click()
|
||||
page.wait_for_timeout(100)
|
||||
assert qwen_group.get_attribute("display") == "none"
|
||||
assert page.locator('svg [data-family="qwen"] .model-label').count() == 1
|
||||
assert page.locator('svg [data-family="muse"] .model-label').count() == 1
|
||||
country_after = page.locator("circle.country").evaluate_all(
|
||||
"nodes => nodes.map(node => [node.getAttribute('cx'), node.getAttribute('cy')])"
|
||||
)
|
||||
assert country_after == country_before
|
||||
page.screenshot(path=OUT / "wvs_react_playwright_qwen_hidden.png", full_page=True)
|
||||
|
||||
page.get_by_role("button", name="qwen: qwen3.8-flash").click()
|
||||
marker = page.locator('[data-model="qwen3.8-flash"]')
|
||||
marker.locator(".model-ring").hover()
|
||||
page.wait_for_selector("#model-tooltip")
|
||||
tooltip_text = page.locator("#model-tooltip").inner_text()
|
||||
for required in ("qwen3.8-flash", "qwen", "rated categorical response", "12 items x 12 samples"):
|
||||
assert required in tooltip_text, required
|
||||
page.screenshot(path=OUT / "wvs_react_playwright_tooltip_hover.png", full_page=True)
|
||||
|
||||
marker.focus()
|
||||
assert page.evaluate("document.activeElement.dataset.model") == "qwen3.8-flash"
|
||||
assert page.locator("#model-tooltip").is_visible()
|
||||
page.screenshot(path=OUT / "wvs_react_playwright_keyboard_focus.png", full_page=True)
|
||||
browser.close()
|
||||
|
||||
if errors:
|
||||
raise RuntimeError(f"React page errors: {errors}")
|
||||
static = Image.open(OUT / "wvs_static_playwright.png").convert("RGB")
|
||||
react = Image.open(OUT / "wvs_react_playwright_default.png").convert("RGB")
|
||||
height = max(static.height, react.height)
|
||||
comparison = Image.new("RGB", (static.width + react.width, height + 26), "white")
|
||||
comparison.paste(static, (0, 26))
|
||||
comparison.paste(react, (static.width, 26))
|
||||
draw = ImageDraw.Draw(comparison)
|
||||
draw.text((6, 5), "Static WVS figure", fill="black")
|
||||
draw.text((static.width + 6, 5), "React WVS production page", fill="black")
|
||||
comparison.save(OUT / "wvs_static_react_playwright_side_by_side.png")
|
||||
hashes = {path.name: hashlib.sha256(path.read_bytes()).hexdigest() for path in (
|
||||
ROOT / "docs/wvs/wvs_map_data.json",
|
||||
ROOT / "docs/wvs/react/index.html",
|
||||
)}
|
||||
print(json.dumps({
|
||||
"shared": {"models": 64, "countries": 90, "buffered_hulls": 4, "latest_labels": 13,
|
||||
"numeric_model_country_median_equality": "verified against DOM data attributes"},
|
||||
"qwen_toggle": "clicked, family group hidden, country coordinates invariant",
|
||||
"tooltip": "pointer hover and focus show model, family, coordinates, readout, samples and release metadata",
|
||||
"hashes": hashes,
|
||||
}, indent=2))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"labels": 27,
|
||||
"kinds": {
|
||||
"model": 13,
|
||||
"country": 10,
|
||||
"zone": 4
|
||||
},
|
||||
"bounds": {
|
||||
"left": 76,
|
||||
"right": 1154,
|
||||
"top": 55,
|
||||
"bottom": 818
|
||||
},
|
||||
"policy": "expanding rings, increasing steps, marker obstacles, pairwise overlap and bounds assertions"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"shared": {
|
||||
"models": 64,
|
||||
"countries": 90,
|
||||
"buffered_hulls": 4,
|
||||
"latest_labels": 13,
|
||||
"numeric_model_country_median_equality": "verified against DOM data attributes"
|
||||
},
|
||||
"qwen_toggle": "clicked, family group hidden, country coordinates invariant",
|
||||
"tooltip": "pointer hover and focus show model, family, coordinates, readout, samples and release metadata",
|
||||
"hashes": {
|
||||
"wvs_map_data.json": "b45e8cd6396b2d78570af67a5a01992a85ec7b2bb3bca776264aaeaa7057589a",
|
||||
"index.html": "f376a62a94a4df7bac9bfb6252b227fa7aac77647e6c32d5b0a2158dd11fd04b"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 253 KiB |
|
After Width: | Height: | Size: 262 KiB |
|
After Width: | Height: | Size: 228 KiB |
|
After Width: | Height: | Size: 262 KiB |
|
After Width: | Height: | Size: 381 KiB |
|
After Width: | Height: | Size: 654 KiB |
|
After Width: | Height: | Size: 235 KiB |
@@ -0,0 +1,20 @@
|
||||
# React WVS visual parity review
|
||||
|
||||
Reviewer: reviewer-openai, image-only review, 2026-09-17.
|
||||
|
||||
Verdict: changes needed, narrowly for regional-label placement; otherwise substantial visual-parity improvement.
|
||||
|
||||
Observed:
|
||||
|
||||
- `wvs_react_playwright_default.png` restores the static reference's off-white background, four rounded/buffered coloured hulls, country colours and labels, pole names, and in-plot caption. Neutral logo chips and white-ring model marks are visible; latest-model labels are readable, though leader lines cross.
|
||||
- "East Asia" floats far above its red hull. "Latin America" sits in the red/brown overlap above the orange hull. Move each label adjacent to its corresponding boundary.
|
||||
- Vertical pole arrows are visible. The static reference's rightward Survival arrow is not clearly discernible at the reviewed resolution.
|
||||
- Tooltip hover and focus show qwen3.8-flash, family, coordinates, rated categorical response, 12 items x 12 samples, and release date.
|
||||
- Qwen hidden strikes through the Qwen chip and removes Qwen marks/label without apparent country movement.
|
||||
- Geometry retains the same arrangement and orientation, models upper-left and Egypt lower-right.
|
||||
|
||||
Limits:
|
||||
|
||||
Images do not establish exact coordinate equality, keyboard navigation, or local logo loading. The saved Playwright audit reports those checks but the reviewer did not independently reproduce them.
|
||||
|
||||
-- PI[gpt-5.6-terra], preserving reviewer-openai observations
|
||||
@@ -0,0 +1,17 @@
|
||||
# React WVS visual parity review, final acceptance
|
||||
|
||||
Reviewer: reviewer-openai, image-only review, 2026-09-17.
|
||||
|
||||
Verdict: PASS, image-only acceptance.
|
||||
|
||||
Observed:
|
||||
|
||||
- A clear rightward arrow follows Survival, including in the side-by-side capture.
|
||||
- Region-label adjacency, buffered hulls, country-dot colours, captions, neutral logo chips and white-ring model marks match the intended visual grammar.
|
||||
- Model labels remain readable despite the dense cluster.
|
||||
- Qwen-hidden removes its marks and label without visible country displacement.
|
||||
- Hover and keyboard-focus screenshots show readable Qwen metadata tooltips.
|
||||
|
||||
Limit: numeric invariance and local-logo provenance are reported by the UAT JSON rather than independently established from images.
|
||||
|
||||
-- PI[gpt-5.6-terra], preserving reviewer-openai observations
|
||||
@@ -0,0 +1,19 @@
|
||||
# React WVS visual parity review, regional-label correction
|
||||
|
||||
Reviewer: reviewer-openai, image-only review, 2026-09-17.
|
||||
|
||||
Verdict: changes needed, the React Survival arrow remains invisible.
|
||||
|
||||
Observed:
|
||||
|
||||
- East Asia and Latin America now sit adjacent to their respective coloured hulls.
|
||||
- Static visual grammar, relative geometry, logo chips, white-ring marks and captions are coherent.
|
||||
- Qwen-hidden removes Qwen marks and its plot label, strikes through its chip, and preserves country/hull positions.
|
||||
- Hover and keyboard-focus screenshots show a readable Qwen tooltip with coordinates, readout, sample counts and release date.
|
||||
- The horizontal axis ends beneath Survival without a discernible rightward arrowhead. The static image shows an arrow after Survival.
|
||||
|
||||
Required correction: reserve space after the React Survival label and expose the arrowhead at the reviewed viewport.
|
||||
|
||||
Limits: image review cannot establish local asset provenance, actual keyboard navigation or exact coordinate equality. The Playwright audit reports those checks but was not independently reproduced.
|
||||
|
||||
-- PI[gpt-5.6-terra], preserving reviewer-openai observations
|
||||